packages feed

HXQ 0.10.0 → 0.11.0

raw patch · 26 files changed

+1045/−602 lines, 26 filesdep −mtlPVP ok

version bump matches the API change (PVP)

Dependencies removed: mtl

API changes (from Hackage documentation)

+ Text.XML.HXQ.XQuery: XNull :: XTree
+ Text.XML.HXQ.XQuery: commit :: conn -> IO ()
+ Text.XML.HXQ.XQuery: rollback :: conn -> IO ()
- Text.XML.HXQ.XQuery: createIndex :: (IConnection conn) => conn -> String -> String -> IO ()
+ Text.XML.HXQ.XQuery: createIndex :: Connection -> String -> String -> IO ()
- Text.XML.HXQ.XQuery: genSchema :: (IConnection conn) => conn -> String -> String -> IO Table
+ Text.XML.HXQ.XQuery: genSchema :: Connection -> String -> String -> IO Table
- Text.XML.HXQ.XQuery: prepareSQL :: (IConnection conn) => conn -> String -> IO Statement
+ Text.XML.HXQ.XQuery: prepareSQL :: Connection -> String -> IO Statement
- Text.XML.HXQ.XQuery: printSchema :: (IConnection conn) => conn -> String -> IO ()
+ Text.XML.HXQ.XQuery: printSchema :: Connection -> String -> IO ()
- Text.XML.HXQ.XQuery: shred :: (IConnection conn) => conn -> String -> String -> IO ()
+ Text.XML.HXQ.XQuery: shred :: Connection -> String -> String -> IO ()
- Text.XML.HXQ.XQuery: xfileDB :: (IConnection conn) => String -> conn -> IO XSeq
+ Text.XML.HXQ.XQuery: xfileDB :: String -> Connection -> IO XSeq
- Text.XML.HXQ.XQuery: xqueryDB :: (IConnection conn) => String -> conn -> IO XSeq
+ Text.XML.HXQ.XQuery: xqueryDB :: String -> Connection -> IO XSeq

Files

HXQ.cabal view
@@ -1,6 +1,6 @@ Cabal-Version:       >= 1.2 Name:                HXQ-Version:             0.10.0+Version:             0.11.0 Synopsis:            A Compiler from XQuery to Haskell Description:                  HXQ is a fast and space-efficient compiler from XQuery (the standard@@ -30,8 +30,8 @@   Test2.hs   TestDB.hs   TestDB2.hs-  TestDBPL1.hs-  TestDBPL2.hs+  TestDBLP1.hs+  TestDBLP2.hs   compile   compile.bat data-files:@@ -54,7 +54,7 @@   src/hxml-0.2/00-README.txt  Flag mysql-  Description: provides database connectivity using HDBC and HDBC-odbc.+  Description: provides database connectivity using HDBC and MySql through HDBC-odbc.   Default:     False  Flag sqlite@@ -68,7 +68,7 @@                        Text.XML.HXQ.OptionalDB, HXML, DTD, LLParsing, TreeBuild, XMLParse,                        ETree, Misc, Tree, XMLScanner, AssocList, PrintXML, XML   hs-source-dirs:      . src src/hxml-0.2-  Build-Depends:       base, haskell98, array, template-haskell, mtl+  Build-Depends:       base, haskell98, array, template-haskell   if os(windows)      hs-source-dirs:   src/readline      Other-Modules:    System.Console.Readline@@ -90,7 +90,6 @@ Executable xquery   Main-is:             Main.hs   hs-source-dirs:      . src src/hxml-0.2-  Build-Depends:       base, haskell98, array, template-haskell, mtl   if os(windows)      hs-source-dirs:   src/readline      Other-Modules:    System.Console.Readline
Main.hs view
@@ -6,18 +6,25 @@ - ---------------------------------------------------------------} +{-# OPTIONS -cpp #-}  module Main where  import System.Environment-import qualified Control.Exception+import qualified Control.Exception as C import Text.XML.HXQ.Functions(functions) import Text.XML.HXQ.Interpreter(evalInput,xqueryE) import Text.XML.HXQ.XQuery -version = "0.10.0"+#if __GLASGOW_HASKELL__ >= 609+type E = C.SomeException+#else+type E = C.Exception+#endif +version = "0.11.0" + parseEnv :: [String] -> [(String,String)] parseEnv [] = [("o","Temp.hs")] parseEnv ("-help":xs) = ("help",""):(parseEnv xs)@@ -30,7 +37,7 @@ parseEnv (file:xs) = ("r",file):(parseEnv xs)  -noDBerror _ = error "Missing Database Connection"+noDBerror = error "Missing Database Connection; use -db in xquery"   main = do senv <- getArgs@@ -64,6 +71,7 @@                           Just file -> case lookup "db" env of                                          Just filepath -> do db <- connect filepath                                                              result <- xfileDB file db+                                                             commit db                                                              putXSeq result                                          _ -> do query <- readFile file                                                  (result,_,_) <- xqueryE query [] [] noDBerror verbose@@ -75,13 +83,14 @@                                          case lookup "db" env of                                            Just filepath                                                -> do db <- connect filepath-                                                     evalInput (\s vs fs-> Control.Exception.catch-                                                                          (do (result,nvs,nfs) <- xqueryE s vs fs (prepareSQL db) verbose+                                                     evalInput (\s vs fs-> C.catch+                                                                          (do (result,nvs,nfs) <- xqueryE s vs fs db verbose                                                                               putXSeq result+                                                                              commit db                                                                               return (nvs,nfs))-                                                                          (\e -> do putStrLn (show e); return (vs,fs))) [] []-                                           _ -> evalInput (\s vs fs-> Control.Exception.catch+                                                                          (\e -> do putStrLn (show (e::E)); return (vs,fs))) [] []+                                           _ -> evalInput (\s vs fs-> C.catch                                                                       (do (result,nvs,nfs) <- xqueryE s vs fs noDBerror verbose                                                                           putXSeq result                                                                           return (nvs,nfs))-                                                                      (\e -> do putStrLn (show e); return (vs,fs))) [] []+                                                                      (\e -> do putStrLn (show (e::E)); return (vs,fs))) [] []
Makefile view
@@ -16,10 +16,6 @@ all:    $(parser) Main.hs 	$(ghc) --make Main.hs -o xquery -# on-the-fly compiler: unstable; use xquery instead-hxqc:   $(parser) HXQ-unstable.hs-	$(ghc) -optl-s -no-recomp -package ghc --make HXQ-unstable.hs -o hxqc- # generate the XQuery parser using happy $(parser): XQueryParser.y 	happy -g -a -c -o $(parser) XQueryParser.y@@ -40,12 +36,12 @@ 	$(ghc) --make TestDB2.hs -o a.out 	./a.out -dbpl1:  $(parser) TestDBPL1.hs-	$(ghc) --make TestDBPL1.hs -o a.out+dblp1:  $(parser) TestDBLP1.hs+	$(ghc) --make TestDBLP1.hs -o a.out 	./a.out +RTS -H200m -K100m -dbpl2:  $(parser) TestDBPL2.hs-	$(ghc) --make TestDBPL2.hs -o a.out+dblp2:  $(parser) TestDBLP2.hs+	$(ghc) --make TestDBLP2.hs -o a.out 	./a.out  # run in the ghci interpreter and load HXQ
Test1.hs view
@@ -6,7 +6,8 @@ - ---------------------------------------------------------------} -{-# OPTIONS_GHC -fth #-}+{-# LANGUAGE TemplateHaskell #-}+  module Main where 
Test2.hs view
@@ -7,7 +7,7 @@ - ---------------------------------------------------------------} -{-# OPTIONS_GHC -fth #-}+{-# LANGUAGE TemplateHaskell #-}  module Main where 
TestDB.hs view
@@ -8,7 +8,7 @@ - ---------------------------------------------------------------} -{-# OPTIONS_GHC -fth #-}+{-# LANGUAGE TemplateHaskell #-}  module Main where 
TestDB2.hs view
@@ -7,7 +7,7 @@ - ---------------------------------------------------------------} -{-# OPTIONS_GHC -fth #-}+{-# LANGUAGE TemplateHaskell #-}  module Main where 
+ TestDBLP1.hs view
@@ -0,0 +1,9 @@+module Main where++import Text.XML.HXQ.XQuery+++main = do db <- connect "hxq"+          -- Generate the relational schema for the DBPL database using hybrid inlining. Ignore HTML tags+          genSchema db "data/dblp.xml" "d" ["i","sub","sup","tt"]+          -- genSchema db "data/dblp.xml" "d" []
+ TestDBLP2.hs view
@@ -0,0 +1,12 @@+{-# LANGUAGE TemplateHaskell #-}++module Main where++import Text.XML.HXQ.XQuery+++main = do db <- connect "hxq"+          -- populate the DBPL database (it takes about 12 minutes)+          $(shredC "hxq" "data/dblp.xml" "d")+          -- create an index on author name+          createIndex db "d" "author"
− TestDBPL1.hs
@@ -1,8 +0,0 @@-module Main where--import Text.XML.HXQ.XQuery---main = do db <- connect "hxq"-          -- generate the relational schema for the DBPL database using hybrid inlining-          genSchema db "data/dblp.xml" "d"
− TestDBPL2.hs
@@ -1,12 +0,0 @@-{-# OPTIONS_GHC -fth #-}--module Main where--import Text.XML.HXQ.XQuery---main = do db <- connect "hxq"-          -- populate the DBPL database (it takes about 12 minutes)-          $(shredC "hxq" "data/dblp.xml" "d")-          -- create an index on author name-          createIndex db "d" "author"
XQueryParser.y view
@@ -89,6 +89,12 @@ 	'.' 		{ DOT } 	';' 		{ SEMI } 	':' 		{ COLON }+	'insert'        { INSERT }+	'delete'	{ DELETE }+	'replace'	{ REPLACE }+	'into'		{ INTO }+	'from'		{ FROM}+	'with'		{ WITH } 	'Variable' 	{ Variable $$ } 	'XMLtext' 	{ XMLtext $$ } 	'Integer' 	{ TInteger $$ }@@ -97,6 +103,7 @@   %nonassoc	'for' 'let' 'satisfies' 'return'+%nonassoc	'with' 'from' 'into' %nonassoc	'else' %left		'intersect' 'union' 'except' %right		'or'@@ -180,6 +187,9 @@ 		|   string				{ $1 } 		|   'Integer'				{ Aint $1 } 		|   'Double'				{ Afloat $1 }+		|   'insert' expr 'into' expr		{ call "insert" [$2,Ast "destination" [$4]] }+		|   'delete' 'from' expr		{ call "delete" [$3] }+		|   'replace' expr 'with' expr		{ call "replace" [$2,$4] }  expl           :: { [ Ast ] } expl		:   expr				{ [$1] }@@ -388,7 +398,8 @@   | AND | OR | NOT | UNION | INTERSECT | EXCEPT | FOR | LET | IN | COMMA   | ASSIGN | WHERE | ORDER | BY | ASCENDING | DESCENDING | ELEMENT   | ATTRIBUTE | STAG | ETAG | SATISFIES | ATSIGN | SLASH | DECLARE | SEMI | COLON-  | FUNCTION | VARIABLE |AT | DOT | DOTS | TokenEOF | PRE | POST | IS+  | FUNCTION | VARIABLE | AT | DOT | DOTS | TokenEOF | PRE | POST | IS+  | INSERT | INTO | DELETE | FROM | REPLACE | WITH   | QName String | Variable String | XMLtext String | TInteger Int   | TFloat Float | TString String | TError String     deriving Eq@@ -418,6 +429,7 @@              (BY,"by"),(ASCENDING,"ascending"),(DESCENDING,"descending"),(ELEMENT,"element"),              (ATTRIBUTE,"attribute"),(STAG,"</"),(ETAG,"/>"),(SATISFIES,"satisfies"),(ATSIGN,"@"),              (SLASH,"/"),(DECLARE,"declare"),(FUNCTION,"function"),(VARIABLE,"variable"),+  	     (INSERT,"insert"),(INTO,"into"),(DELETE,"delete"),(FROM,"from"),(REPLACE,"replace"),(WITH,"with"),              (AT,"at"),(DOTS,".."),(DOT,"."),(SEMI,";"),(COLON,":")]  @@ -607,6 +619,12 @@           "gt" -> SGT           "ge" -> SGE           "is" -> IS+	  "insert" -> INSERT+	  "into" -> INTO+	  "delete" -> DELETE+	  "from" -> FROM+	  "replace" -> REPLACE+	  "with" -> WITH           var -> QName var        ) : lexer rest n }
db.html view
@@ -3,7 +3,7 @@ <body> <center> <h1>HXQ with Database Connectivity</h1>-<h3>Download <a href="/HXQ-0.10.0.tar.gz">HXQ-0.10.0.tar.gz</a></h3>+<h3>Download <a href="/HXQ-0.11.0.tar.gz">HXQ-0.11.0.tar.gz</a></h3> </center> <p> <h2>Installation Instructions (HXQ with database connectivity)</h2>@@ -40,6 +40,8 @@ <a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/HDBC-1.1.4">HDBC 1.1.4</a> (but not version 1.1.5) and the <a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/HDBC-odbc">HDBC-odbc</a> driver.+(For ghc 6.10, you may have to change <tt>import Control.Exception</tt> to <tt>import Control.OldException</tt>+in Utils.hsc.) Then you do: <pre> runhaskell Setup.lhs configure -fmysql@@ -55,6 +57,8 @@ <a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/HDBC-1.1.4">HDBC 1.1.4</a> (but not version 1.1.5) and the <a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/HDBC-sqlite3">HDBC-sqlite3</a> driver.+(For ghc 6.10, you may have to change <tt>import Control.Exception</tt> to <tt>import Control.OldException</tt>+in Utils.hsc and Statement.hsc.) Then you do: <pre> runhaskell Setup.lhs configure -fsqlite@@ -67,7 +71,7 @@ HXQ provides an interface to HDBC to query relational data inside an XQuery. For the HXQ compiler, the main function that allows database connectivity is: <pre>-$(xqdb query) :: (IConnection conn) => conn -> IO XSeq+$(xqdb query) :: Connection -> IO XSeq </pre> For example, if the database name is "hxq", then <pre>@@ -76,7 +80,7 @@ </pre> For the HXQ interpreter, the function is: <pre>-xqueryDB :: (IConnection conn) => String -> conn -> IO XSeq+xqueryDB :: String -> Connection -> IO XSeq </pre> The <tt>xquery</tt> executable can also run XQueries that use a database by specifying the database name using the -db option, eg. <tt>xquery -db hxq</tt>.@@ -95,18 +99,20 @@ <p> <h2>Shredding</h2> <p>-To synthesize a relational schema <tt>schemaname</tt> to store an XML document located at <tt>pathname</tt>, use the following Haskell function:+To synthesize a relational schema <tt>schemaname</tt> to store an XML document+located at <tt>pathname</tt>, use the following Haskell function: <pre>-genSchema :: (IConnection conn) => conn -> String -> String -> IO ()-genSchema db pathname schemaname+genSchema :: Connection -> String -> String -> [String] -> IO ()+genSchema db pathname schemaname excludedtags </pre>-for a database <tt>db</tt>. HXQ will find a good-relational schema (using hybrid inlining) to store the XML data by+for a database <tt>db</tt>, where the excluded tags are HTML tags to be ignored (skipped)+when the XML data are document-centric+HXQ will find a good relational schema (using hybrid inlining) to store the XML data by scanning the document to extract its structural summary and then deriving a good relational schema from the summary. To actually store the data from the XML document into the relational schema, use the following Haskell function: <pre>-shred :: (IConnection conn) => conn -> String -> String -> IO ()+shred :: Connection -> String -> String -> IO () shred db pathname schemaname </pre> For example,@@ -115,7 +121,10 @@    genSchema db "data/cs.xml" "c"    shred db "data/cs.xml" "c" </pre>-For large XML documents, you better use the compiled version of <tt>shred</tt>, <tt>$(shredC db pathname schemaname)</tt>.+For large XML documents, you better use the compiled version of <tt>shred</tt>:+<pre>+$(shredC dbname pathname schemaname)+</pre> <p> The Haskell function <pre>@@ -141,16 +150,48 @@ thus deriving an efficient execution. One example is <a href="TestDB2.hs">TestDB2.hs</a>. <p>-<h2>Example: Installing and Querying the DBPL Database</h2>+<h2>Updates</h2> <p>-First download and uncompress <tt>dbpl.xml.gz</tt> from <a href="http://dblp.uni-trier.de/xml/">DBLP</a>.-To install the DBPL database using MySQL, compile and execute first-<a href="TestDBPL1.hs">TestDBPL1.hs</a> and then-<a href="TestDBPL2.hs">TestDBPL2.hs</a>.-Then you may evaluete queries, such as <a href="data/q4.xq">data/q4.xq</a>, using the HXQ interpreter,-which takes about 4 seconds.-+The XQuery syntax has been extended with the following expressions in HXQ:+<pre>+   insert e1 into e2+   delete from e+   replace e2 with e1+</pre>+where <tt>e2</tt> and <tt>e</tt> are XQuery expressions that return XML elements extracted from shredded documents stored in the relational database.+That is, you can not update XML text files or constructed XML elements.+In addition, <tt>e2</tt> must return a singleton sequence (exactly one XML element) and+the returned XML sequence from <tt>e1</tt> must be compatible to the document structural summary at the point of the update.+These updates are evaluated using SQL updates+over the underlying relational database. The insert expression makes <tt>e1</tt> a new child of <tt>e2</tt> and returns <tt>e1</tt>.+The delete expression removes the element <tt>e</tt> from its parent and returns <tt>()</tt>.+The replace expression replaces <tt>e2</tt> with <tt>e1</tt> and returns <tt>e1</tt>.+These updates are not automatically committed; the programmer must commit them explicitly using the <tt>commit db</tt> function.+(The <tt>xquery</tt> program though commits at the end of each xquery automatically.) <p>+Examples of updates:+<pre>+replace publish('hxq','c')//gradstudent[name/lastname="Smith"]/gpa with 3.7+insert &lt;zip&gt;12345&lt;/zip&gt; into publish('hxq','c')//gradstudent[name/lastname="Smith"]/address+for $e in publish('hxq','e')//employee return replace $e/salary with $e/salary*1.5+</pre>+<p>+<h2>Example: Installing and Querying the DBLP Database</h2>+<p>+First download and uncompress <tt>dblp.xml.gz</tt> from <a href="http://dblp.uni-trier.de/xml/">DBLP</a>.+To install the DBLP database using MySQL, compile and execute+<a href="TestDBLP1.hs">TestDBLP1.hs</a> first (using ghc options <tt>+RTS -H200m -K100m</tt>) and then+<a href="TestDBLP2.hs">TestDBLP2.hs</a>.+Then, you may evaluate queries, such as <a href="data/q4.xq">data/q4.xq</a>, using the HXQ interpreter,+<tt>xquery -db hxq data/q4.xq</tt>, which takes about 0.1 seconds.+<p>+<h2>Status</h2>+<p>+<ul>+<li> XML elements are not stored in document order. Thus, element indexing may return unpredictable results.+<li> HXQ does better job in stroring data-centric than document-centric XML data (especially those with  mixed content).+</ul>+<p> <hr> <p>-<address>Last modified: 10/26/08 by <a href="http://lambda.uta.edu/">Leonidas Fegaras</a></address>+<address>Last modified: 11/24/08 by <a href="http://lambda.uta.edu/">Leonidas Fegaras</a></address>
index.html view
@@ -3,7 +3,7 @@ <body> <center> <h1>HXQ: A Compiler from XQuery to Haskell</h1>-<h3>Download <a href="/HXQ-0.10.0.tar.gz">HXQ-0.10.0.tar.gz</a></h3>+<h3>Download <a href="/HXQ-0.11.0.tar.gz">HXQ-0.11.0.tar.gz</a></h3> </center> <p> <h2>Description</h2>@@ -29,7 +29,7 @@ (using 1150MB of heap space). (All results are taken on an Intel Core 2 Duo 2.2GHz 2GB running ghc-6.8.2 on Linux 2.6.23 kernel.) <p> Finally, HXQ can store XML documents in a relational database-(currently SQLite), by shredding XML into relational tuples, and by+(currently MySQL or SQLite), by shredding XML into relational tuples, and by translating XQueries over the shredded documents into optimized SQL queries. <p>@@ -46,7 +46,7 @@ if you want to modify the XQuery parser, you need to install the parser generator for Haskell, <a href="http://www.haskell.org/happy/">happy</a>.  Then,-download <a href="/HXQ-0.10.0.tar.gz">HXQ version 0.10.0</a> and untar+download <a href="/HXQ-0.11.0.tar.gz">HXQ version 0.11.0</a> and untar it (using <tt>tar xfz</tt> on Linux or <a href="http://www.7-zip.org/">7z x</a> on Windows).  Then, you do:@@ -55,8 +55,10 @@ runhaskell Setup.lhs build runhaskell Setup.lhs install </pre>-On Linux, the last command must be run as root.  This will create the-executable <tt>xquery</tt>, which is the XQuery interpreter, and the+On linux, the last command must be run as root.+If you get an error during configuration that the readline package is missing, install+<a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/readline">readline</a> before HXQ.+HXQ consists of the executable <tt>xquery</tt>, which is the XQuery interpreter, and the HXQ library.  To use the HXQ library in a Haskell program, simply <tt>import Text.XML.HXQ.XQuery</tt>. <p>@@ -161,4 +163,4 @@ <p> <hr> <p>-<address>Last modified: 10/25/08 by <a href="http://lambda.uta.edu/">Leonidas Fegaras</a></address>+<address>Last modified: 10/27/08 by <a href="http://lambda.uta.edu/">Leonidas Fegaras</a></address>
src/Text/XML/HXQ/Compiler.hs view
@@ -4,7 +4,7 @@ - Programmer: Leonidas Fegaras - Email: fegaras@cse.uta.edu - Web: http://lambda.uta.edu/-- Creation: 02/15/08, last update: 10/20/08+- Creation: 02/15/08, last update: 11/14/08 -  - Copyright (c) 2008 by Leonidas Fegaras, the University of Texas at Arlington. All rights reserved. - This material is provided as is, with absolutely no warranty expressed or implied.@@ -14,19 +14,21 @@ --------------------------------------------------------------------------------------}  -{-# OPTIONS_GHC -fth #-}+{-# LANGUAGE TemplateHaskell #-} + module Text.XML.HXQ.Compiler where  import Control.Monad import Char(toLower) import List(sortBy)-import Language.Haskell.TH import XMLParse(parseDocument) import Text.XML.HXQ.Parser import Text.XML.HXQ.XTree import Text.XML.HXQ.Optimizer import Text.XML.HXQ.Functions+import Text.XML.HXQ.OptionalDB+import Language.Haskell.TH   undef1 = [| error "Undefined XQuery context (.)" |]@@ -81,6 +83,11 @@ qName e = error ("Invalid QName: "++(show e))  +makeAttribute :: XSeq -> XSeq -> [(String,String)]+makeAttribute ac vc+    = if vc==[XNull] then [] else [(qName ac,showXS vc)]++ -- Each XPath predicate must calculate position() and last() from its input XSeq -- if last() is used, then the evaluation is blocking (need to store the whole input XSeq) compilePredicates :: [Ast] -> Q Exp -> Bool -> Q Exp@@ -127,6 +134,7 @@                   in [| [ XFloat $x ] |]       Astring s -> let x = litE (StringL s)                    in [| [ XText $x ] |]+      Ast "nonIO" [u] -> compile u context position last effective_axis       Ast "context" [v,Astring dp,body]           -> [| foldr (\x r -> $(compile body [| x |] position last dp)++r)                       [] $(compile v context position last effective_axis) |]@@ -140,13 +148,19 @@       Ast "step" (Avar "descendant_any":Ast "tags" tags:e:preds)           -> let bc = compile e context position last effective_axis                  ts = listE (map (\(Avar tag) -> litE (stringL tag)) tags)-             in [| foldr (\x r -> $(compilePredicates preds [| descendant_any_with_tagged_children $ts x |] True)++r)-                         [] $bc |]+             in [| let v = $bc+                   in if v==[XNull]+                      then v+                      else foldr (\x r -> $(compilePredicates preds [| descendant_any_with_tagged_children $ts x |] True)++r)+                                 [] v |]       Ast "step" (Avar step:Astring tag:e:preds)           -> let bc = compile e context position last effective_axis                  tc = litE (stringL tag)-             in [| foldr (\x r -> $(compilePredicates preds [| $(findV step paths) $tc x |] True)++r)-                         [] $bc |]+             in [| let v = $bc+                   in if v==[XNull]+                      then v+                      else foldr (\x r -> $(compilePredicates preds [| $(findV step paths) $tc x |] True)++r)+                           [] v |]       Ast "filter" (e:preds)           -> compilePredicates preds (compile e context position last effective_axis) True       Ast "predicate" [condition,body]@@ -155,6 +169,9 @@                 else [] |]       Ast "append" args           -> [| appendText $(listE (map (\x -> compile x context position last effective_axis) args)) |]+      Ast "call" ((Avar f):_)+          | elem f ["insert","delete","replace"]+          -> error "Updates must be over XML data stored in databases"       Ast "call" ((Avar f):args)           -> callF f (map (\x -> compile x context position last effective_axis) args)       Ast "construction" [Astring tag,id,parent,Ast "attributes" [],body]@@ -163,20 +180,20 @@                  cid = compile id context position last effective_axis                  cparent = compile parent context position last effective_axis              in [| let [XText vid] = $cid-                       [vparent] = $cparent-                   in [ XElem $ct [] (read vid) vparent $bc ] |]+                       vparent = $cparent+                   in [ XElem $ct [] (read vid) (if null vparent then parent_error else head vparent) $bc ] |]       Ast "construction" [tag,id,parent,Ast "attributes" al,body]           -> let alc = foldr (\(Ast "pair" [a,v]) r                                   -> let ac = compile a context position last effective_axis                                          vc = compile v context position last effective_axis-                                     in [| (qName $ac,showXS $vc) : $r |]) [| [] |] al+                                     in [| (makeAttribute $ac $vc) ++ $r |]) [| [] |] al                  ct = compile tag context position last effective_axis                  bc = compile body context position last effective_axis                  cid = compile id context position last effective_axis                  cparent = compile parent context position last effective_axis              in [| let [XText vid] = $cid-                       [vparent] = $cparent-                   in [ XElem (qName $ct) $alc (read vid) vparent $bc ] |]+                       vparent = $cparent+                   in [ XElem (qName $ct) $alc (read vid) (if null vparent then parent_error else head vparent) $bc ] |]       Ast "let" [Avar var,source,body]           -> do s <- compile source context position last effective_axis                 b <- compile body context position last effective_axis@@ -279,17 +296,20 @@           -> let bc = compileM e context position last effective_axis                  ts = listE (map (\(Avar tag) -> litE (stringL tag)) tags)              in [| do vs <- $bc-                      foldr (\x r -> (liftM2 (++)) $(compilePredicatesM preds-                                                         [| descendant_any_with_tagged_children $ts x |] True) r)-                            (return []) vs |]+                      if vs==[XNull]+                         then return vs+                         else foldr (\x r -> (liftM2 (++)) $(compilePredicatesM preds+                                                               [| descendant_any_with_tagged_children $ts x |] True) r)+                                    (return []) vs |]       Ast "step" (Avar step:Astring tag:e:preds)           -> let bc = compileM e context position last effective_axis                  tc = litE (stringL tag)              in [| do vs <- $bc-                      foldr (\x r -> (liftM2 (++)) $(compilePredicatesM preds-                                                           [| $(findV step paths) $tc x |] True) r)-                            (return []) vs |]-+                      if vs==[XNull]+                         then return vs+                         else foldr (\x r -> (liftM2 (++)) $(compilePredicatesM preds+                                                               [| $(findV step paths) $tc x |] True) r)+                                    (return []) vs |]       Ast "filter" (e:preds)           ->[| do vs <- $(compileM e context position last effective_axis)                   $(compilePredicatesM preds [| vs |] True) |]@@ -305,6 +325,25 @@           -> let binds = zipWith (\i x -> (mkName ("x"++(show i)),x)) [1..(length args)] args              in foldr (\(n,x) r -> [| $(compileM x context position last effective_axis) >>= $(lamE [varP n] r) |])                       [| return (appendText $(listE (map (\(n,_) -> varE n) binds))) |] binds+      Ast "call" [Avar "insert",e1,e2]+          -> let vc1 = compileM e1 context position last effective_axis+                 vc2 = compileM e2 context position last effective_axis+                 db = varE (mkName "_db")+             in [| do v1 <- $vc1+                      v2 <- $vc2+                      insertDB $db v1 v2 |]+      Ast "call" [Avar "delete",e]+          -> let vc = compileM e context position last effective_axis+                 db = varE (mkName "_db")+             in [| do v <- $vc+                      deleteDB $db v |]+      Ast "call" [Avar "replace",e1,e2]+          -> let vc1 = compileM e1 context position last effective_axis+                 vc2 = compileM e2 context position last effective_axis+                 db = varE (mkName "_db")+             in [| do v1 <- $vc1+                      v2 <- $vc2+                      replaceDB $db v1 v2 |]       Ast "call" ((Avar f):args)           -> let binds = zipWith (\i x -> (mkName ("x"++(show i)),x)) [1..(length args)] args              in foldr (\(n,x) r -> [| $(compileM x context position last effective_axis) >>= $(lamE [varP n] r) |])@@ -316,14 +355,14 @@                  cparent = compile parent context position last effective_axis              in [| do b <- $bc                       let [XText vid] = $cid-                          [vparent] = $cparent-                      return [ XElem $ct [] (read vid) vparent b ] |]+                          vparent = $cparent+                      return [ XElem $ct [] (read vid) (if null vparent then parent_error else head vparent) b ] |]       Ast "construction" [tag,id,parent,Ast "attributes" al,body]           -> let alc = foldr (\(Ast "pair" [a,v]) r                                   -> [| do ac <- $(compileM a context position last effective_axis)                                            vc <- $(compileM v context position last effective_axis)                                            s <- $r-                                           return ((qName ac,showXS vc):s) |]) [| return [] |] al+                                           return ((makeAttribute ac vc)++s) |]) [| return [] |] al                  ct = compileM tag context position last effective_axis                  bc = compileM body context position last effective_axis                  cid = compile id context position last effective_axis@@ -332,8 +371,8 @@                       c <- $ct                       b <- $bc                       let [XText vid] = $cid-                          [vparent] = $cparent-                      return [ XElem (qName c) a (read vid) vparent b ] |]+                          vparent = $cparent+                      return [ XElem (qName c) a (read vid) (if null vparent then parent_error else head vparent) b ] |]       Ast "let" [Avar var,source,body]           -> [|  $(compileM source context position last effective_axis)                  >>= $(lamE [varP (mkName var)] (compileM body context position last effective_axis)) |]@@ -378,7 +417,9 @@  -- functions that need IO interaction (document reader, DB access, etc) ioSources :: [ String ]-ioSources = ["executeSQL","doc","fn:doc","sql","fn:sql","publish","fn:publish"]+ioSources+    = is ++ map (\x -> "fn:"++x) is+      where is = ["executeSQL","doc","sql","publish","insert","delete","replace"]   -- steps that need the parent XTree link in evaluation (with a potential space leak)@@ -424,6 +465,7 @@ -- true if there is no need to lift to the IO monad noIO :: Ast -> Bool noIO (Ast nm _) | elem nm ioSources = False+noIO (Ast "call" (Avar nm:_)) | elem nm ioSources = False noIO (Ast n args) = all noIO args noIO _ = True @@ -433,6 +475,7 @@     = let (ast,_,_,ns) = pullIOSources query 0 False           f x = case x of                   Ast nm _ | elem nm ["attributes","tags"] -> x+                   Ast _ _ | noIO x -> Ast "nonIO" [x]                   _ -> case x of                          Ast "call" ((Avar nm):args)@@ -483,6 +526,7 @@           code = compileM ast undef1 undef2 undef3 ""           rest = compileQueryM xs       in foldl (\r (n,b,e) -> let d = lamE [varP (mkName n)] r+                                  bc = if b then [| True |] else [| False |]  -- needed due to a bug in template haskell                               in case e of                                    Avar m -> [| $d $(varE (mkName m)) |]                                    Ast "prepareSQL" [Astring sql]@@ -491,7 +535,7 @@                                                      $(litE (StringL sql))) >>= $d |]                                    _ -> [| do let [XText f] = $(compileAst e)                                               doc <- readFile f-                                              $d [materialize b (parseDocument doc)] |])+                                              $d [materialize $bc (parseDocument doc)] |])                [| (liftM2 (++)) $code $rest |] ns compileQueryM [] = [| return [] |] @@ -509,6 +553,6 @@   -- | Run an XQuery that reads XML documents and queries databases.--- When evaluated, it returns (IConnection conn) => conn -> IO XSeq.+-- When evaluated, it returns @(IConnection conn) => conn -> IO XSeq@. xqdb :: String -> Q Exp xqdb query = lamE [varP (mkName "_db")] (compileQueryM (parse (scan query)))
src/Text/XML/HXQ/Functions.hs view
@@ -4,7 +4,7 @@ - Programmer: Leonidas Fegaras - Email: fegaras@cse.uta.edu - Web: http://lambda.uta.edu/-- Creation: 08/15/08, last update: 08/18/08+- Creation: 08/15/08, last update: 11/18/08 -  - Copyright (c) 2008 by Leonidas Fegaras, the University of Texas at Arlington. All rights reserved. - This material is provided as is, with absolutely no warranty expressed or implied.@@ -14,15 +14,17 @@ --------------------------------------------------------------------------------------}  -{-# OPTIONS_GHC -fth -fbang-patterns #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE BangPatterns #-} + module Text.XML.HXQ.Functions where  import Data.List(foldl') import Char(isDigit)-import Language.Haskell.TH import HXML(AttList) import Text.XML.HXQ.XTree+import Language.Haskell.TH   {--------------- XPath Steps ---------------------------------------------------------}@@ -41,7 +43,7 @@ child_step tag x     = case x of         XElem _ _ _ _ bs-            -> foldl' (\s b -> case b of+            -> foldr (\b s -> case b of                                  XElem t _ _ _ _ | (t==tag || tag=="*") -> b:s                                  _ -> s) [] bs         _ -> []@@ -68,7 +70,7 @@ -- After examining 100 children it gives up: this avoids space leaks descendant_any_with_tagged_children :: [Tag] -> XTree -> XSeq descendant_any_with_tagged_children tags (x@(XElem t _ _ _ cs))-    | all (\tag -> foldl' (\s b -> case b of+    | all (\tag -> foldr (\b s -> case b of                                      (XElem k _ _ _ _) -> s || k == tag                                      _ -> s) False cs100) tags     = x:(concatMap (descendant_any_with_tagged_children tags) cs)@@ -82,18 +84,18 @@ attribute_step :: Tag -> XTree -> XSeq attribute_step attr x     = case x of-        XElem _ al _ _ _ -> foldl' (\s (a,v) -> if a==attr || attr=="*"-                                                then (XText v):s-                                                else s) [] al+        XElem _ al _ _ _ -> foldr (\(a,v) s -> if a==attr || attr=="*"+                                               then (XText v):s+                                               else s) [] al         _ -> []   -- XPath step //@attr or //@* attribute_descendant_step :: Tag -> XTree -> XSeq attribute_descendant_step attr (x@(XElem _ al _ _ cs))-    = foldl' (\s (a,v) -> if a==attr || attr=="*"-                          then (XText v):s-                          else s)+    = foldr (\(a,v) s -> if a==attr || attr=="*"+                         then (XText v):s+                         else s)             (concatMap (attribute_descendant_step attr) cs) al attribute_descendant_step _ _ = [] @@ -237,9 +239,9 @@   text :: XSeq -> XSeq-text xs = foldl' (\r x -> case x of+text xs = foldr (\x r -> case x of                             XElem _ _ _ _ zs-                                -> (filter (\a -> case a of XText _ -> True; XInt _ -> True;+                                -> (filter (\a -> case a of XText _ -> True; XInt _ -> True; XNull -> True;                                                             XFloat _ -> True; XBool _ -> True; _ -> False) zs)++r                             XText _ -> x:r                             XInt _ -> x:r@@ -265,7 +267,7 @@   toNum :: XSeq -> XSeq-toNum xs = foldl' (\r x -> case x of+toNum xs = foldr (\x r -> case x of                              XInt n -> x:r                              XFloat n -> x:r                              XText s -> case readNum s of@@ -432,16 +434,17 @@  -- make a function call callF :: Tag -> Function-callF fname args = case filter (\(n,_,_) -> n == fname || ("fn:"++n)==fname) functions of-                     (_,len,f):_ -> if (length args) == len-                                       then f args-                                    else error ("wrong number of arguments in function call: " ++ fname)-                     _ ->     -- otherwise, it must be a Haskell function of type (XSeq,...,XSeq) -> XSeq-                          let itp = case args of-                                      [] -> [t| () |]-                                      [_] -> [t| XSeq |]-                                      _ -> foldr (\_ r -> appT r [t| XSeq |]) (appT (tupleT (length args)) [t| XSeq |])-                                                 (tail args)-                              fn = sigE (varE (mkName fname))-                                        (appT (appT arrowT itp) [t| XSeq |])-                          in appE fn (tupE args)+callF fname args+    = case filter (\(n,_,_) -> n == fname || ("fn:"++n)==fname) functions of+        (_,len,f):_ -> if (length args) == len+                       then f args+                       else error ("wrong number of arguments in function call: " ++ fname)+        _ ->     -- otherwise, it must be a Haskell function of type (XSeq,...,XSeq) -> XSeq+             let itp = case args of+                         [] -> [t| () |]+                         [_] -> [t| XSeq |]+                         _ -> foldr (\_ r -> appT r [t| XSeq |]) (appT (tupleT (length args)) [t| XSeq |])+                                    (tail args)+                 fn = sigE (varE (mkName fname))+                           (appT (appT arrowT itp) [t| XSeq |])+             in appE fn (tupE args)
src/Text/XML/HXQ/Interpreter.hs view
@@ -4,7 +4,7 @@ - Programmer: Leonidas Fegaras - Email: fegaras@cse.uta.edu - Web: http://lambda.uta.edu/-- Creation: 03/22/08, last update: 10/20/08+- Creation: 03/22/08, last update: 11/14/08 -  - Copyright (c) 2008 by Leonidas Fegaras, the University of Texas at Arlington. All rights reserved. - This material is provided as is, with absolutely no warranty expressed or implied.@@ -14,7 +14,8 @@ --------------------------------------------------------------------------------------}  -{-# OPTIONS_GHC -fth -fglasgow-exts #-}+{-# OPTIONS_GHC -fglasgow-exts #-}+{-# LANGUAGE TemplateHaskell #-}   module Text.XML.HXQ.Interpreter where@@ -104,12 +105,16 @@           -> eval (Ast "step" (Avar effective_axis:tag:Avar ".":preds)) context position last "" env fncs       Ast "step" (Avar "descendant_any":Ast "tags" tags:e:preds)           -> let ts = map (\(Avar tag) -> tag) tags-             in foldr (\x r -> (applyPredicates preds (descendant_any_with_tagged_children ts x) True env fncs)++r)-                      [] (eval e context position last effective_axis env fncs)+                 v = eval e context position last effective_axis env fncs+             in if v==[XNull]+                then v+                else foldr (\x r -> (applyPredicates preds (descendant_any_with_tagged_children ts x) True env fncs)++r) [] v       Ast "step" (Avar step:Astring tag:e:preds)           -> let step_fnc = findV step pathFunctions-             in foldr (\x r -> (applyPredicates preds (step_fnc tag x) True env fncs)++r)-                      [] (eval e context position last effective_axis env fncs)+                 v = eval e context position last effective_axis env fncs+             in if v==[XNull]+                then v+                else foldr (\x r -> (applyPredicates preds (step_fnc tag x) True env fncs)++r) [] v       Ast "filter" (e:preds)           -> applyPredicates preds (eval e context position last effective_axis env fncs) True env fncs       Ast "predicate" [condition,body]@@ -118,32 +123,37 @@              else []       Ast "append" args           -> appendText (map (\x -> eval x context position last effective_axis env fncs) args)+      Ast "call" ((Avar f):_)+          | elem f ["insert","delete","replace"]+          -> error "Updates must be over XML data stored in databases"       Ast "call" ((Avar fname):args)-          -> case filter (\(n,_,_) -> n == fname || ("fn:"++n) == fname) systemFunctions of-               [(_,len,f)] -> if (length args) == len-                              then f (map (\x -> eval x context position last effective_axis env fncs) args)-                              else error ("Wrong number of arguments in system call: "++fname)-               _ -> case filter (\(n,_,_) -> n == fname) fncs of-                      (_,params,body):_ -> if (length params) == (length args)-                                           then eval body context undefv2 undefv3 ""-                                                    ((zipWith (\p a -> (p,eval a context position last effective_axis env fncs))-                                                              params args)++env) fncs-                                           else error ("Wrong number of arguments in function call: "++fname)-                      _ -> error ("Undefined function: "++fname)+          -> let vs = map (\x -> eval x context position last effective_axis env fncs) args+             in case filter (\(n,_,_) -> n == fname || ("fn:"++n) == fname) systemFunctions of+                       [(_,len,f)] -> if (length args) == len+                                      then f vs+                                      else error ("Wrong number of arguments in system call: "++fname)+                       _ -> case filter (\(n,_,_) -> n == fname) fncs of+                              (_,params,body):_+                                  -> if (length params) == (length args)+                                     then eval body context undefv2 undefv3 ""+                                              ((zipWith (\p v -> (p,v)) params vs)++env) fncs+                                     else error ("Wrong number of arguments in function call: "++fname)+                              _ -> error ("Undefined function: "++fname)       Ast "construction" [Astring tag,id,parent,Ast "attributes" [],body]           -> let [XText vid] = eval id context position last effective_axis env fncs-                 [vparent] = eval parent context position last effective_axis env fncs-             in [ XElem tag [] (read vid) vparent (eval body context position last effective_axis env fncs) ]+                 vparent = eval parent context position last effective_axis env fncs+             in [ XElem tag [] (read vid) (if null vparent then parent_error else head vparent)+                            (eval body context position last effective_axis env fncs) ]       Ast "construction" [tag,id,parent,Ast "attributes" al,body]-             -> let alc = map (\(Ast "pair" [a,v])+             -> let alc = concatMap (\(Ast "pair" [a,v])                                      -> let ac = eval a context position last effective_axis env fncs                                             vc = eval v context position last effective_axis env fncs-                                        in (qName ac,showXS vc)) al+                                        in if vc==[XNull] then [] else [(qName ac,showXS vc)]) al                     ct = eval tag context position last effective_axis env fncs                     bc = eval body context position last effective_axis env fncs                     [XText vid] = eval id context position last effective_axis env fncs-                    [vparent] = eval parent context position last effective_axis env fncs-                in [ XElem (qName ct) alc (read vid) vparent bc ]+                    vparent = eval parent context position last effective_axis env fncs+                in [ XElem (qName ct) alc (read vid) (if null vparent then parent_error else head vparent) bc ]       Ast "let" [Avar var,source,body]           -> eval body context position last effective_axis                   ((var,eval source context position last effective_axis env fncs):env) fncs@@ -178,38 +188,38 @@   -- The monadic applyPredicates that propagates IO state-applyPredicatesM :: [Ast] -> XSeq -> Bool -> Environment -> Functions -> Statements -> IO XSeq-applyPredicatesM [] xs _ _ _ _ = return $! xs-applyPredicatesM ((Aint n):preds) xs _ env fncs stmts   -- shortcut that improves laziness-    = applyPredicatesM preds [xs !! (n-1)] True env fncs stmts-applyPredicatesM (pred:preds) xs True env fncs stmts    -- top-k like+applyPredicatesM :: [Ast] -> XSeq -> Bool -> Environment -> Functions -> Connection -> Statements -> IO XSeq+applyPredicatesM [] xs _ _ _ _ _ = return $! xs+applyPredicatesM ((Aint n):preds) xs _ env fncs db stmts   -- shortcut that improves laziness+    = applyPredicatesM preds [xs !! (n-1)] True env fncs db stmts+applyPredicatesM (pred:preds) xs True env fncs db stmts    -- top-k like     | maxPosition pathPosition pred > 0-    = applyPredicatesM (pred:preds) (take (maxPosition pathPosition pred) xs) False env fncs stmts-applyPredicatesM (pred:preds) xs _ env fncs stmts+    = applyPredicatesM (pred:preds) (take (maxPosition pathPosition pred) xs) False env fncs db stmts+applyPredicatesM (pred:preds) xs _ env fncs db stmts     | containsLast pred         -- blocking: use only when last() is used in the predicate     = do let last = length xs-         vs <- foldir (\x i r -> do vs <- evalM pred x i last "" env fncs stmts+         vs <- foldir (\x i r -> do vs <- evalM pred x i last "" env fncs db stmts                                     s <- r                                     return $! (if case vs of                                                     [XInt k] -> k == i               -- indexing                                                     b -> conditionTest b                                                then x:s else s))                       (return []) xs 1-         applyPredicatesM preds vs True env fncs stmts-applyPredicatesM (pred:preds) xs _ env fncs stmts-    = do vs <- foldir (\x i r -> do vs <- evalM pred x i undefv3 "" env fncs stmts+         applyPredicatesM preds vs True env fncs db stmts+applyPredicatesM (pred:preds) xs _ env fncs db stmts+    = do vs <- foldir (\x i r -> do vs <- evalM pred x i undefv3 "" env fncs db stmts                                     s <- r                                     return $! (if case vs of                                                     [XInt k] -> k == i               -- indexing                                                     b -> conditionTest b                                                then x:s else s))                       (return []) xs 1-         applyPredicatesM preds vs True env fncs stmts+         applyPredicatesM preds vs True env fncs db stmts   -- The monadic XQuery interpreter; it is like eval but has plumbing to propagate IO state-evalM :: Ast -> XTree -> Int -> Int -> String -> Environment -> Functions -> Statements -> IO XSeq-evalM e context position last effective_axis env fncs stmts+evalM :: Ast -> XTree -> Int -> Int -> String -> Environment -> Functions -> Connection -> Statements -> IO XSeq+evalM e context position last effective_axis env fncs db stmts   = case e of       Avar "." -> return $! [ context ]       Avar v -> return $! (findV v env)@@ -219,90 +229,108 @@       -- for non-IO XQuery, use the regular eval       Ast "nonIO" [u] -> return $! (eval u context position last effective_axis env fncs)       Ast "context" [v,Astring dp,body]-          -> do vs <- evalM v context position last effective_axis env fncs stmts-                foldr (\x r -> (liftM2 (++)) (evalM body x position last dp env fncs stmts) r)+          -> do vs <- evalM v context position last effective_axis env fncs db stmts+                foldr (\x r -> (liftM2 (++)) (evalM body x position last dp env fncs db stmts) r)                       (return []) vs       Ast "call" [Avar "position"] -> return $! [XInt position]       Ast "call" [Avar "last"] -> return $! [XInt last]       Ast "step" (Avar "child":tag:Avar ".":preds)           | effective_axis /= ""-          -> evalM (Ast "step" (Avar effective_axis:tag:Avar ".":preds)) context position last "" env fncs stmts+          -> evalM (Ast "step" (Avar effective_axis:tag:Avar ".":preds)) context position last "" env fncs db stmts       Ast "step" (Avar "descendant_any":Ast "tags" tags:e:preds)-          -> do vs <- evalM e context position last effective_axis env fncs stmts+          -> do vs <- evalM e context position last effective_axis env fncs db stmts                 let ts = map (\(Avar tag) -> tag) tags-                foldr (\x r -> (liftM2 (++)) (applyPredicatesM preds (descendant_any_with_tagged_children ts x) True env fncs stmts) r)-                      (return []) vs+                if vs==[XNull]+                      then return vs+                      else foldr (\x r -> (liftM2 (++)) (applyPredicatesM preds (descendant_any_with_tagged_children ts x)+                                                                          True env fncs db stmts) r)+                                 (return []) vs       Ast "step" (Avar step:Astring tag:e:preds)           -> let step_fnc = findV step pathFunctions-             in do vs <- evalM e context position last effective_axis env fncs stmts-                   foldr (\x r -> (liftM2 (++)) (applyPredicatesM preds (step_fnc tag x) True env fncs stmts) r)-                         (return []) vs+             in do vs <- evalM e context position last effective_axis env fncs db stmts+                   if vs==[XNull]+                      then return vs+                      else foldr (\x r -> (liftM2 (++)) (applyPredicatesM preds (step_fnc tag x)+                                                                          True env fncs db stmts) r)+                                 (return []) vs       Ast "filter" (e:preds)-          -> do vs <- evalM e context position last effective_axis env fncs stmts-                applyPredicatesM preds vs True env fncs stmts+          -> do vs <- evalM e context position last effective_axis env fncs db stmts+                applyPredicatesM preds vs True env fncs db stmts       Ast "predicate" [condition,body]-          -> do eb <- evalM condition undefv1 undefv2 undefv3 "" env fncs stmts+          -> do eb <- evalM condition undefv1 undefv2 undefv3 "" env fncs db stmts                 if conditionTest eb-                   then evalM body context position last effective_axis env fncs stmts+                   then evalM body context position last effective_axis env fncs db stmts                    else return []       Ast "executeSQL" [Avar var,args]-          -> do as <- evalM args context position last effective_axis env fncs stmts+          -> do as <- evalM args context position last effective_axis env fncs db stmts                 executeSQL (findV var stmts) as+      Ast "append" args+          -> (liftM appendText) (mapM (\x -> evalM x context position last effective_axis env fncs db stmts) args)       Ast "call" [Avar nm,c,t,e]     -- this is the only lazy function           | elem nm ["if","fn:if"]-          -> do ce <- evalM c context position last effective_axis env fncs stmts-                evalM (if conditionTest ce then t else e) context position last effective_axis env fncs stmts-      Ast "append" args-          -> (liftM appendText) (mapM (\x -> evalM x context position last effective_axis env fncs stmts) args)+          -> do ce <- evalM c context position last effective_axis env fncs db stmts+                evalM (if conditionTest ce then t else e) context position last effective_axis env fncs db stmts+      Ast "call" [Avar "insert",e1,e2]+          -> do v1 <- evalM e1 context position last effective_axis env fncs db stmts+                v2 <- evalM e2 context position last effective_axis env fncs db stmts+                insertDB db v1 v2+      Ast "call" [Avar "delete",e]+          -> do v <- evalM e context position last effective_axis env fncs db stmts+                deleteDB db v+      Ast "call" [Avar "replace",e1,e2]+          -> do v1 <- evalM e1 context position last effective_axis env fncs db stmts+                v2 <- evalM e2 context position last effective_axis env fncs db stmts+                replaceDB db v1 v2       Ast "call" ((Avar fname):args)        -- Note: strict function application           -> case filter (\(n,_,_) -> n == fname || ("fn:"++n) == fname) systemFunctions of                [(_,len,f)] -> if (length args) == len-                              then (liftM f) (mapM (\x -> evalM x context position last effective_axis env fncs stmts) args)+                              then do vs <- mapM (\x -> evalM x context position last effective_axis env fncs db stmts) args+                                      return $ f vs                               else error ("Wrong number of arguments in system call: "++fname)                _ -> case filter (\(n,_,_) -> n == fname) fncs of                       (_,params,body):_ -> if (length params) == (length args)-                                           then do vs <- mapM (\a -> evalM a context position last effective_axis env fncs stmts) args+                                           then do vs <- mapM (\a -> evalM a context position last effective_axis env fncs db stmts) args                                                    evalM body context undefv2 undefv3 ""-                                                             ((zipWith (\p a -> (p,a)) params vs)++env) fncs stmts+                                                             ((zipWith (\p a -> (p,a)) params vs)++env) fncs db stmts                                            else error ("Wrong number of arguments in function call: "++fname)                       _ -> error ("Undefined function: "++fname)       Ast "construction" [Astring tag,id,parent,Ast "attributes" [],body]-          -> do b <- evalM body context position last effective_axis env fncs stmts-                [XText vid] <- evalM id context position last effective_axis env fncs stmts-                [vparent] <- evalM parent context position last effective_axis env fncs stmts-                return $! [ XElem tag [] (read vid) vparent b ]+          -> do b <- evalM body context position last effective_axis env fncs db stmts+                [XText vid] <- evalM id context position last effective_axis env fncs db stmts+                vparent <- evalM parent context position last effective_axis env fncs db stmts+                return $! [ XElem tag [] (read vid) (if null vparent then parent_error else head vparent) b ]       Ast "construction" [tag,id,parent,Ast "attributes" al,body]-             -> do alc <- mapM (\(Ast "pair" [a,v])-                                     -> do ac <- evalM a context position last effective_axis env fncs stmts-                                           vc <- evalM v context position last effective_axis env fncs stmts-                                           return $! (qName ac,showXS vc)) al-                   ct <- evalM tag context position last effective_axis env fncs stmts-                   bc <- evalM body context position last effective_axis env fncs stmts-                   [XText vid] <- evalM id context position last effective_axis env fncs stmts-                   [vparent] <- evalM parent context position last effective_axis env fncs stmts-                   return $! [ XElem (qName ct) alc (read vid) vparent bc ]+             -> do alc <- foldM (\r (Ast "pair" [a,v])+                                     -> do ac <- evalM a context position last effective_axis env fncs db stmts+                                           vc <- evalM v context position last effective_axis env fncs db stmts+                                           if vc==[XNull] then return r else return $! (qName ac,showXS vc):r) [] al+                   ct <- evalM tag context position last effective_axis env fncs db stmts+                   bc <- evalM body context position last effective_axis env fncs db stmts+                   [XText vid] <- evalM id context position last effective_axis env fncs db stmts+                   vparent <- evalM parent context position last effective_axis env fncs db stmts+                   return $! [ XElem (qName ct) alc (read vid) (if null vparent then parent_error else head vparent) bc ]       Ast "let" [Avar var,source,body]-          -> do s <- evalM source context position last effective_axis env fncs stmts-                evalM body context position last effective_axis ((var,s):env) fncs stmts+          -> do s <- evalM source context position last effective_axis env fncs db stmts+                evalM body context position last effective_axis ((var,s):env) fncs db stmts       Ast "for" [Avar var,Avar "$",source,body]      -- a for-loop without an index-          -> do vs <- evalM source context position last effective_axis env fncs stmts-                foldr (\a r -> (liftM2 (++)) (evalM body a undefv2 undefv3 "" ((var,[a]):env) fncs stmts) r)+          -> do vs <- evalM source context position last effective_axis env fncs db stmts+                foldr (\a r -> (liftM2 (++)) (evalM body a undefv2 undefv3 "" ((var,[a]):env) fncs db stmts) r)                       (return []) vs       Ast "for" [Avar var,Avar ivar,source,body]     -- a for-loop with an index           -> do let p = maxPosition (Avar ivar) body                     ns = if p > 0              -- there is a top-k like restriction                             then Ast "step" [source,Ast "call" [Avar "<=",pathPosition,Aint p]]                             else source -                vs <- evalM ns context position last effective_axis env fncs stmts-                foldir (\a i r -> (liftM2 (++)) (evalM body a i undefv3 "" ((var,[a]):(ivar,[XInt i]):env) fncs stmts) r)+                vs <- evalM ns context position last effective_axis env fncs db stmts+                foldir (\a i r -> (liftM2 (++)) (evalM body a i undefv3 "" ((var,[a]):(ivar,[XInt i]):env) fncs db stmts) r)                        (return []) vs 1       Ast "sortTuple" (exp:orderBys)             -- prepare each FLWOR tuple for sorting-          -> do vs <- evalM exp context position last effective_axis env fncs stmts-                os <- mapM (\a -> evalM a context position last effective_axis env fncs stmts) orderBys+          -> do vs <- evalM exp context position last effective_axis env fncs db stmts+                os <- mapM (\a -> evalM a context position last effective_axis env fncs db stmts) orderBys                 return $! [ XElem "" [] 0 parent_error (foldl (\r a -> r++[XElem "" [] 0 parent_error (text a)])                                                               [XElem "" [] 0 parent_error vs] os) ]       Ast "sort" (exp:ordList)                   -- blocking-          -> do vs <- evalM exp context position last effective_axis env fncs stmts+          -> do vs <- evalM exp context position last effective_axis env fncs db stmts                 let ce = map (\(XElem _ _ _ _ xs) -> map (\(XElem _ _ _ _ ys) -> ys) xs) vs                     ordering = foldr (\(Avar ord) r (x:xs) (y:ys)                                        -> case compareXSeqs (ord == "ascending") x y of@@ -341,16 +369,16 @@                     evalInput eval nvs nfs  -evalQueryM :: [Ast] -> Environment -> Functions -> (String -> IO Statement) -> Bool -> IO (XSeq,Environment,Functions)-evalQueryM [] variables functions dbmapper verbose+evalQueryM :: [Ast] -> Environment -> Functions -> Connection -> Bool -> IO (XSeq,Environment,Functions)+evalQueryM [] variables functions db verbose     = return $! ([],variables,functions)-evalQueryM (query:xs) variables functions dbmapper verbose+evalQueryM (query:xs) variables functions db verbose     = case query of         Ast "function" ((Avar f):b:args)-            -> evalQueryM xs variables ((f,map (\(Avar v) -> v) args,optimize b):functions) dbmapper verbose+            -> evalQueryM xs variables ((f,map (\(Avar v) -> v) args,optimize b):functions) db verbose         Ast "variable" [Avar v,u]-            -> do uv <- evalM (optimize u) undefv1 undefv2 undefv3 "" variables functions []-                  evalQueryM xs ((v,uv):variables) functions dbmapper verbose+            -> do uv <- evalM (optimize u) undefv1 undefv2 undefv3 "" variables functions db []+                  evalQueryM xs ((v,uv):variables) functions db verbose         _ -> do let opt = optimize query                     (ast,ns) = liftIOSources opt                 if verbose@@ -373,23 +401,23 @@                 stmts <- foldr (\(n,_,s) r -> case s of                                                 Ast "prepareSQL" [Astring sql]                                                     -> do stmts <- r-                                                          t <- dbmapper sql+                                                          t <- prepareSQL db sql                                                           return $! ((n,t):stmts)                                                 _ -> r)                                (return []) ns-                result <- evalM ast undefv1 undefv2 undefv3 "" (env++variables) functions stmts-                (rest,renv,rfuns) <- evalQueryM xs variables functions dbmapper verbose+                result <- evalM ast undefv1 undefv2 undefv3 "" (env++variables) functions db stmts+                (rest,renv,rfuns) <- evalQueryM xs variables functions db verbose                 return $! (result++rest,renv,rfuns)  -xqueryE :: String -> Environment -> Functions -> (String -> IO Statement) -> Bool -> IO (XSeq,Environment,Functions)-xqueryE query variables functions dbmapper verbose-    = evalQueryM (parse (scan query)) variables functions dbmapper verbose+xqueryE :: String -> Environment -> Functions -> Connection -> Bool -> IO (XSeq,Environment,Functions)+xqueryE query variables functions db verbose+    = evalQueryM (parse (scan query)) variables functions db verbose   -- | Evaluate the XQuery using the interpreter. xquery :: String -> IO XSeq-xquery query = do (u,_,_) <- xqueryE query [] [] (\sql -> error "No database connectivity") False+xquery query = do (u,_,_) <- xqueryE query [] [] (error "No database connectivity") False                   return $! u  @@ -400,12 +428,12 @@   -- | Evaluate the XQuery with database connectivity using the interpreter.-xqueryDB :: (IConnection conn) => String -> conn -> IO XSeq-xqueryDB query db = do (u,_,_) <- xqueryE query [] [] (prepareSQL db) False+xqueryDB :: String -> Connection -> IO XSeq+xqueryDB query db = do (u,_,_) <- xqueryE query [] [] db False                        return $! u   -- | Read an XQuery with database connectivity from a file and run it using the interpreter.-xfileDB :: (IConnection conn) => String -> conn -> IO XSeq+xfileDB :: String -> Connection -> IO XSeq xfileDB file db = do query <- readFile file                      xqueryDB query db
src/Text/XML/HXQ/Optimizer.hs view
@@ -4,7 +4,7 @@ - Programmer: Leonidas Fegaras - Email: fegaras@cse.uta.edu - Web: http://lambda.uta.edu/-- Creation: 05/01/08, last update: 10/25/08+- Creation: 05/01/08, last update: 11/23/08 -  - Copyright (c) 2008 by Leonidas Fegaras, the University of Texas at Arlington. All rights reserved. - This material is provided as is, with absolutely no warranty expressed or implied.@@ -23,7 +23,6 @@ import Text.XML.HXQ.Parser import Text.XML.HXQ.XTree import Text.XML.HXQ.OptionalDB-import Debug.Trace   empty = Ast "call" [Avar "empty"]@@ -174,7 +173,7 @@     = case collect_attributes content of         (nc,(Ast "pair" [Astring "_id",id]):(Ast "pair" [Astring "_parent",parent]):attrs)             -> simplify (Ast "construction" [tag,id,parent,Ast "attributes" (as++attrs),nc])-        (nc,attrs) -> simplify (Ast "construction" [tag,Astring "0",Aint 0,Ast "attributes" (as++attrs),nc])+        (nc,attrs) -> simplify (Ast "construction" [tag,Astring "0",Ast "call" [Avar "empty"],Ast "attributes" (as++attrs),nc]) -- if //* collect all children tagnames to use descendant_any simplify (Ast "for" [Avar var,i,Ast "step" (Avar "descendant-or-self":Astring "*":path:preds),body])     | not (null ((tagged_children var body))) || any (not . null . (tagged_children ".")) preds@@ -274,12 +273,12 @@             -> orAll (map (predToSQL tables) xs)         Ast "call" [Avar "text",x]             -> predToSQL tables x-        Ast "call" [Avar cmp,Ast "for" [Avar v,i,Ast "call" [Avar "SQL",_,Ast "call" ((Avar "from"):t),pred],x],y]+        Ast "call" [Avar cmp,Ast "for" [Avar v,i,Ast "call" [Avar "SQL",_,Ast "call" ((Avar "tables"):t),pred],x],y]             | any (\(f,_) -> f==cmp) sqlComparisson             -> let ts = [ x | Avar x <- t ]                    (p,ps,ts') = predToSQL (tables++ts) (call "and" [Ast "call" [Avar cmp,x,y],pred])                in (p,ps,union ts' ts)-        Ast "call" [Avar cmp,x,Ast "for" [Avar v,i,Ast "call" [Avar "SQL",_,Ast "call" ((Avar "from"):t),pred]],y]+        Ast "call" [Avar cmp,x,Ast "for" [Avar v,i,Ast "call" [Avar "SQL",_,Ast "call" ((Avar "tables"):t),pred]],y]             | any (\(f,_) -> f==cmp) sqlComparisson             -> let ts = [ x | Avar x <- t ]                    (p,ps,ts') = predToSQL (tables++ts) (call "and" [Ast "call" [Avar cmp,x,y],pred])@@ -346,9 +345,10 @@                then "select * from "++ts                else "select "++cs++" from "++ts,[])          else let (p,args,nts) = predToSQL (tables++tnames) pred+                  pp = if p=="" then "" else " where "++p               in (if null cs-                  then "select * from "++combine (union tnames nts)++" where "++p-                  else "select "++cs++" from "++combine (union tnames nts)++" where "++p,args)+                  then "select * from "++combine (union tnames nts)++pp+                  else "select "++cs++" from "++combine (union tnames nts)++pp,args)   findAttr :: String -> [Ast] -> Ast@@ -525,6 +525,8 @@         -- ((),x)  ->  x         Ast "call" [Avar "concatenate",Ast "call" [Avar "empty"],x]             -> norm x+        Ast "append" ((Ast "call" [Avar "empty"]):xs)+            -> norm (Ast "append" xs)         Ast "call" [Avar "=",x,y]             | x == empty && y == empty             -> (true,True,count)@@ -614,48 +616,55 @@             -> norm (Ast "call" [Avar "concatenate",predicates (findAttr tag as) preds,                                  Ast "step" (Avar "attribute_descendant":Astring tag:concatenateAll x:preds)]) -- SQL folding-        Ast "for" [Avar v1,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s1),Ast "call" ((Avar "from"):f1),pred1],-                   Ast "for" [Avar v2,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s2),Ast "call" ((Avar "from"):f2),pred2],+        Ast "for" [Avar v1,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s1),Ast "call" ((Avar "tables"):f1),pred1],+                   Ast "for" [Avar v2,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s2),Ast "call" ((Avar "tables"):f2),pred2],                               b]]             | occurs v1 b == 0             -> norm (Ast "for" [Avar v2,Avar "$",                                 Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):(s1++s2)),-                                            Ast "call" ((Avar "from"):(f1++f2)),Ast "call" [Avar "and",pred1,pred2]],+                                            Ast "call" ((Avar "tables"):(f1++f2)),Ast "call" [Avar "and",pred1,pred2]],                                 b])-        Ast "for" [Avar v,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s),Ast "call" ((Avar "from"):tables),pred1],+        Ast "for" [Avar v,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s),Ast "call" ((Avar "tables"):tables),pred1],                    Ast "step" (Avar "self":Astring "*":x:pred2)]             | splitSqlPredicate [ v | Avar v <- tables ] (andAll pred2) /= Nothing             -> let Just(pred3,pred4) = splitSqlPredicate [ v | Avar v <- tables ] (andAll pred2)                in norm (Ast "for" [Avar v,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s),-                                                               Ast "call" ((Avar "from"):tables),Ast "call" [Avar "and",pred1,pred3]],+                                                               Ast "call" ((Avar "tables"):tables),Ast "call" [Avar "and",pred1,pred3]],                                    Ast "step" (Avar "self":Astring "*":x:pred4)])-        Ast "for" [Avar v1,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s1),Ast "call" ((Avar "from"):f1),pred1],-                   Ast "for" [Avar v2,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s2),Ast "call" ((Avar "from"):f2),pred2],+        Ast "for" [Avar v1,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s1),Ast "call" ((Avar "tables"):f1),pred1],+                   Ast "for" [Avar v2,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s2),Ast "call" ((Avar "tables"):f2),pred2],                               Ast "step" (Avar "self":Astring "*":b:predd)]]             | occurs v1 b == 0 && splitSqlPredicate [ v | Avar v <- f1 ] (andAll predd) /= Nothing             -> let Just(pred3,pred4) = splitSqlPredicate [ v | Avar v <- f1 ] (andAll predd)                in norm (Ast "for" [Avar v1,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s1),-                                                                Ast "call" ((Avar "from"):f1),Ast "call" [Avar "and",pred1,pred3]],+                                                                Ast "call" ((Avar "tables"):f1),Ast "call" [Avar "and",pred1,pred3]],                                    Ast "for" [Avar v2,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s2),-                                                                           Ast "call" ((Avar "from"):f2),pred2],+                                                                           Ast "call" ((Avar "tables"):f2),pred2],                                               Ast "step" (Avar "self":Astring"*":b:pred4)]])-        Ast "for" [Avar v,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s),Ast "call" ((Avar "from"):tables),pred1],+        Ast "for" [Avar v,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s),Ast "call" ((Avar "tables"):tables),pred1],                    Ast "predicate" [pred2,x]]             | splitSqlPredicate [ v | Avar v <- tables ] pred2 /= Nothing             -> let Just(pred3,pred4) = splitSqlPredicate [ v | Avar v <- tables ] pred2                in norm (Ast "for" [Avar v,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s),-                                                               Ast "call" ((Avar "from"):tables),Ast "call" [Avar "and",pred1,pred3]],+                                                               Ast "call" ((Avar "tables"):tables),Ast "call" [Avar "and",pred1,pred3]],                                    Ast "step" (Avar "self":Astring"*":x:pred4)])-        Ast "for" [Avar v1,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s1),Ast "call" ((Avar "from"):f1),pred1],-                   Ast "for" [Avar v2,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s2),Ast "call" ((Avar "from"):f2),pred2],+        Ast "for" [Avar v1,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s1),Ast "call" ((Avar "tables"):f1),pred1],+                   Ast "for" [Avar v2,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s2),Ast "call" ((Avar "tables"):f2),pred2],                               Ast "predicate" [predd,b]]]             | occurs v1 b == 0 && splitSqlPredicate [ v | Avar v <- f1 ] predd /= Nothing             -> let Just(pred3,pred4) = splitSqlPredicate [ v | Avar v <- f1 ] predd                in norm (Ast "for" [Avar v1,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s1),-                                                                Ast "call" ((Avar "from"):f1),Ast "call" [Avar "and",pred1,pred3]],+                                                                Ast "call" ((Avar "tables"):f1),Ast "call" [Avar "and",pred1,pred3]],                                    Ast "for" [Avar v2,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s2),-                                                                           Ast "call" ((Avar "from"):f2),pred2],+                                                                           Ast "call" ((Avar "tables"):f2),pred2],                                               Ast "step" (Avar "self":Astring"*":b:pred4)]])+-- ignore children from insertion destination+        Ast "destination" [Ast "for" [v,i,Ast "call" (Avar "SQL":sql),body]]+            -> norm (Ast "for" [v,i,Ast "call" (Avar "SQL":sql),Ast "destination" [body]])+        Ast "destination" [Ast "construction" [t,id,p,al,_]]+            -> norm (Ast "construction" [t,id,p,al,Ast "append" []])+        Ast "destination" [Ast f args]+            -> norm (Ast f args) -- default         Ast n args             -> let (r,b,c) = foldr (\a (r,b,c) -> let (x,s,i) = normalize a b c in (x:r,s,i))@@ -673,11 +682,11 @@ foldSQL e     = case e of         Ast "for" [Avar v,Avar "$",Ast "call" [Avar "SQL",Ast "call" [Avar "select"],-                                               Ast "call" ((Avar "from"):tables),pred],body]+                                               Ast "call" ((Avar "tables"):tables),pred],body]             | any (\(Avar x) -> x==v) tables             -> foldSQL (Ast "for" [Avar v,Avar "$",Ast "call" [Avar "SQL",Ast "call" [Avar "select",Avar (v++".*")],-                                                               Ast "call" ((Avar "from"):tables),pred],body])-        Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):cols),Ast "call" ((Avar "from"):tables),pred]+                                                               Ast "call" ((Avar "tables"):tables),pred],body])+        Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):cols),Ast "call" ((Avar "tables"):tables),pred]             -> let (sql,args) = makeSQL [] tables pred cols                in Ast "call" [Avar "sql",Astring sql,concatenateAll args]         Ast n args -> Ast n (map foldSQL args)
src/Text/XML/HXQ/Parser.hs view
@@ -191,21 +191,21 @@   happyActOffsets :: HappyAddr-happyActOffsets = HappyA# "\x45\x00\x45\x00\x00\x00\xee\x02\x00\x00\xd7\x01\x98\x00\x00\x00\x00\x00\x3e\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\xc4\x02\xc4\x02\x8b\x00\x5d\x00\x8b\x00\x8b\x00\x8b\x00\x00\x00\xcb\x02\x8b\x00\xc3\x02\xc3\x02\x2f\x00\x2b\x00\xfb\xff\xc2\x02\xf4\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x6a\x00\xbe\x02\x00\x00\x17\x00\xc9\x02\xba\x02\xdd\xff\x00\x00\xea\x02\xb8\x02\x8b\x00\xb6\x02\xe3\x02\xb3\x02\x8b\x00\xbf\x02\xbd\x02\xf3\xff\xb4\x02\x00\x00\xa5\x02\x00\x00\x00\x00\xd7\x01\xad\x00\x6c\x00\x00\x00\x03\x01\x44\x00\xea\xff\x29\x00\x8b\x00\x00\x00\x88\x00\x00\x00\xb5\x02\x9b\x02\x9b\x02\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\xff\xff\x4e\x00\x00\x00\x42\x02\x42\x02\x42\x02\x74\x02\x42\x02\x5b\x02\x1f\x01\x1f\x01\x1f\x01\x1f\x01\x1f\x01\x1f\x01\x1f\x01\x1f\x01\x1f\x01\x1f\x01\x1f\x01\x1f\x01\x1f\x01\x1f\x01\x1f\x01\x00\x00\x00\x00\x00\x00\x00\x00\xf9\x00\xf9\x00\xb1\x08\xd7\x01\xb0\x02\xad\x02\xcd\x02\xa2\x02\x00\x00\x73\x00\x8b\x00\x58\x00\x1f\x00\x91\x02\x00\x00\x00\x00\xac\x00\x8e\x02\x00\x00\x8b\x00\x9c\x00\x83\x02\x8b\x00\x8b\x00\x8b\x00\x00\x00\x8b\x00\x00\x00\xb1\x02\x89\x02\x8b\x00\x7d\x02\x7d\x02\x8b\x00\xbb\x01\xb2\x02\x8b\x00\x80\x02\x9e\x01\xa8\x02\x8b\x00\x29\x00\x00\x00\xf5\xff\x81\x02\xa4\x02\x68\x02\x00\x00\x0a\x00\x8b\x00\x00\x00\x00\x00\x71\x02\xa7\x00\x00\x00\x9c\x02\xa1\x00\x00\x00\x98\x02\xd7\x01\x72\x02\x76\x02\xd7\x01\x8a\x02\xfc\xff\xd7\x01\x26\x01\xd7\x01\xd7\x01\xed\xff\x00\x00\xfb\xff\xa6\x00\x00\x00\x47\x01\x00\x00\x00\x00\x7f\x02\x9e\x00\x00\x00\x8b\x00\x11\x02\x00\x00\x00\x00\x8b\x00\x8b\x00\x00\x00\xd7\x01\xdd\x00\x20\x02\x67\x02\x9d\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfb\xff\x00\x00\x41\x02\x8b\x00\x07\x02\x8b\x00\x00\x00\xfc\xff\x8b\x00\x8b\x00\x8b\x00\x00\x00\x8b\x00\x00\x00\xd7\x01\x02\x00\x00\x00\x3a\x02\x8b\x00\x36\x02\xfd\x01\x70\x00\x11\x00\xd7\x01\xd7\x01\x00\x00\xd7\x01\x13\x02\xd7\x01\x33\x02\x00\x00\x33\x02\x00\x00\x00\x00\x8b\x00\x00\x00\x00\x00\x00\x00\xdd\x00\x33\x02\x8b\x00\x00\x00\x00\x00\x00\x00\x8b\x00\x81\x01\x00\x00\x64\x01\xd7\x01\x00\x00\x00\x00\x00\x00"#+happyActOffsets = HappyA# "\xe3\x00\xe3\x00\x00\x00\x33\x02\x00\x00\xc0\x02\x4d\x00\x00\x00\x00\x00\x57\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\xf2\x01\xf2\x01\x2f\x01\x97\x00\x2f\x01\x2f\x01\x2f\x01\x00\x00\x00\x02\x2f\x01\xf0\x01\xf0\x01\x16\x00\x0b\x00\x17\x00\xd9\x01\xee\x00\x00\x00\x2f\x01\xd3\x01\x2f\x01\x00\x00\x00\x00\x00\x00\x00\x00\xd7\xff\xcf\x01\x00\x00\x4b\x00\x70\x01\x2f\x01\x8c\x01\xde\x01\xce\x01\xe0\xff\x00\x00\x0b\x02\xbc\x01\x2f\x01\xb3\x01\xe9\x01\xb9\x01\x2f\x01\xc5\x01\xc4\x01\xec\xff\xc3\x01\x00\x00\x7d\x01\x00\x00\x00\x00\xc0\x02\x7c\x00\x55\x00\x00\x00\xec\x01\x42\x00\xef\xff\xfd\xff\x2f\x01\x00\x00\x08\x00\x00\x00\x86\x01\x6d\x01\x6d\x01\x2f\x01\x2f\x01\x2f\x01\x2f\x01\x2f\x01\x2f\x01\x2f\x01\x2f\x01\x2f\x01\x2f\x01\x2f\x01\x2f\x01\x2f\x01\x2f\x01\x2f\x01\x2f\x01\x2f\x01\x2f\x01\x2f\x01\x2f\x01\x2f\x01\x2f\x01\x2f\x01\x2f\x01\x2f\x01\x2f\x01\x2f\x01\x2f\x01\x2f\x01\xff\xff\x36\x00\x00\x00\xac\x01\xac\x01\xac\x01\xf5\x02\xac\x01\xdc\x02\xa0\x00\xa0\x00\xa0\x00\xa0\x00\xa0\x00\xa0\x00\xa0\x00\xa0\x00\xa0\x00\xa0\x00\xa0\x00\xa0\x00\xa0\x00\xa0\x00\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x99\x00\x99\x00\xaf\x09\xc0\x02\x4d\x01\x42\x01\x6c\x01\x46\x01\x00\x00\xfc\xff\x2f\x01\x2d\x00\xfb\xff\x3d\x01\x00\x00\x00\x00\x78\x00\x3c\x01\x00\x00\x2f\x01\x24\x00\x28\x01\x2f\x01\x2f\x01\x2f\x01\x00\x00\x2f\x01\x00\x00\x58\x01\x36\x01\x2f\x01\x22\x01\x22\x01\x2f\x01\xa4\x02\x60\x01\x2f\x01\x2e\x01\x87\x02\x5a\x01\x2f\x01\xfd\xff\x00\x00\x2e\x00\x30\x01\x4e\x01\x2f\x01\xc0\x02\x2f\x01\x01\x01\x00\x00\xc0\x02\xc0\x02\x0f\x00\x2f\x01\x00\x00\x00\x00\x27\x01\x71\x00\x00\x00\x4b\x01\x70\x00\x00\x00\x4a\x01\xc0\x02\x1f\x01\x1e\x01\xc0\x02\x3e\x01\xfa\xff\xc0\x02\x0f\x02\xc0\x02\xc0\x02\xe5\xff\x00\x00\x17\x00\x31\x00\x00\x00\x30\x02\x00\x00\x00\x00\x37\x01\x67\x00\x00\x00\x2f\x01\x10\x01\x00\x00\x00\x00\x2f\x01\x2f\x01\x00\x00\xc0\x02\xc6\x01\x1c\x01\x24\x01\x66\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17\x00\x00\x00\x40\x01\x2f\x01\xfb\x00\x2f\x01\x00\x00\xfa\xff\x2f\x01\x2f\x01\x2f\x01\x00\x00\x2f\x01\x00\x00\xc0\x02\x02\x00\x00\x00\x3b\x01\x2f\x01\x38\x01\xf8\x00\x60\x00\x5e\x00\xc0\x02\xc0\x02\x00\x00\xc0\x02\x17\x01\xc0\x02\x39\x01\x00\x00\x39\x01\x00\x00\x00\x00\x2f\x01\x00\x00\x00\x00\x00\x00\xc6\x01\x39\x01\x2f\x01\x00\x00\x00\x00\x00\x00\x2f\x01\x6a\x02\x00\x00\x4d\x02\xc0\x02\x00\x00\x00\x00\x00\x00"#  happyGotoOffsets :: HappyAddr-happyGotoOffsets = HappyA# "\x00\x02\x34\x02\x00\x00\x00\x00\x00\x00\x00\x00\x35\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1f\x02\x00\x00\xe0\x00\xdf\x00\xa4\x08\x90\x03\x77\x03\x8b\x08\x72\x08\x00\x00\x30\x02\x59\x08\xbc\x00\xd9\x00\x2c\x02\x29\x02\xd1\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1a\x02\x24\x02\x1c\x02\x00\x00\x0c\x02\x00\x00\x1b\x02\x40\x08\x00\x00\x00\x00\x12\x02\x27\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x5e\x03\x00\x00\x41\x01\x00\x00\x0b\x02\x6d\x00\x6e\x00\x0e\x08\xf5\x07\xdc\x07\xc3\x07\xaa\x07\x91\x07\x78\x07\x5f\x07\x46\x07\x2d\x07\x14\x07\xfb\x06\xe2\x06\xc9\x06\xb0\x06\x97\x06\x7e\x06\x65\x06\x4c\x06\x33\x06\x1a\x06\x01\x06\xe8\x05\xcf\x05\xb6\x05\x9d\x05\x84\x05\x6b\x05\x52\x05\x45\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x2c\x03\x0f\x02\x0a\x02\x08\x02\x00\x00\x00\x00\x00\x00\xca\x00\x00\x00\x39\x05\xb7\x02\xff\x01\x20\x05\x07\x05\xee\x04\x00\x00\xd5\x04\x00\x00\x00\x00\x04\x02\xbc\x04\x4f\x01\x09\x01\xa3\x04\x00\x00\x00\x00\x13\x03\x00\x00\x00\x00\x00\x00\xfa\x02\xf0\x00\x00\x00\xe3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x02\x8a\x04\x00\x00\x00\x00\xc3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb5\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\x00\x9e\x02\x23\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1\x02\xd5\x00\x00\x00\x00\x00\xc8\x02\x71\x04\x00\x00\x00\x00\xa4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x87\x00\x09\x02\x69\x00\x00\x00\x58\x04\x60\x00\x3f\x04\x00\x00\x71\x00\x26\x04\x0d\x04\xaf\x02\x00\x00\x96\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf4\x03\x00\x00\x28\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\xdb\x03\x00\x00\x00\x00\x00\x00\xf9\xff\x00\x00\xc2\x03\x00\x00\x00\x00\x00\x00\xa9\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"#+happyGotoOffsets = HappyA# "\xb4\x00\x4c\x01\x00\x00\x00\x00\x00\x00\x00\x00\x31\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x21\x01\x00\x00\xce\x00\xc4\x00\xa2\x09\x11\x04\xf8\x03\x89\x09\x70\x09\x00\x00\x35\x01\x57\x09\xb6\x00\xd5\x00\x34\x01\x33\x01\x07\x01\x00\x00\x00\x00\x00\x00\x3e\x09\x00\x00\x25\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x0c\x09\x00\x00\x32\x01\x25\x01\x00\x00\x15\x01\x00\x00\x20\x01\xf3\x08\x00\x00\x00\x00\x1d\x01\xda\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0e\x01\xdf\x03\x00\x00\xe7\x00\x00\x00\x11\x01\x8d\x00\xcf\x00\xc1\x08\xa8\x08\x8f\x08\x76\x08\x5d\x08\x44\x08\x2b\x08\x12\x08\xf9\x07\xe0\x07\xc7\x07\xae\x07\x95\x07\x7c\x07\x63\x07\x4a\x07\x31\x07\x18\x07\xff\x06\xe6\x06\xcd\x06\xb4\x06\x9b\x06\x82\x06\x69\x06\x50\x06\x37\x06\x1e\x06\x05\x06\xc6\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xed\x00\xad\x03\x16\x01\x12\x01\x0f\x01\x00\x00\x00\x00\x00\x00\xf3\x00\x00\x00\xec\x05\xe6\x00\x02\x01\xd3\x05\xba\x05\xa1\x05\x00\x00\x88\x05\x00\x00\x00\x00\xeb\x00\x6f\x05\xff\x00\xfa\x00\x56\x05\x00\x00\x00\x00\x94\x03\x00\x00\x00\x00\x00\x00\x7b\x03\xe4\x00\x00\x00\xe9\x00\x00\x00\x00\x00\x3d\x05\x00\x00\x24\x05\x00\x00\x00\x00\x00\x00\x00\x00\xec\x00\x0b\x05\x00\x00\x00\x00\xd2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x53\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb8\x00\xdb\x00\xbb\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x62\x03\xdf\x00\x00\x00\x00\x00\x49\x03\xf2\x04\x00\x00\x00\x00\xaa\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xad\x00\x85\x00\x68\x00\x00\x00\xd9\x04\x9f\x00\xc0\x04\x00\x00\x19\x00\xa7\x04\x8e\x04\x30\x03\x00\x00\x17\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x75\x04\x00\x00\x7e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x5c\x04\x00\x00\x00\x00\x00\x00\x6b\x00\x00\x00\x43\x04\x00\x00\x00\x00\x00\x00\x2a\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"#  happyDefActions :: HappyAddr-happyDefActions = HappyA# "\x00\x00\x00\x00\x00\x00\x8a\xff\x87\xff\xfa\xff\xbb\xff\xeb\xff\xec\xff\x00\x00\xcb\xff\xa0\xff\xed\xff\x8d\xff\x8c\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8b\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\xff\x00\x00\x86\xff\xf2\xff\xca\xff\xc9\xff\x9f\xff\x00\x00\xfe\xff\xfd\xff\x00\x00\x00\x00\x00\x00\x00\x00\x8d\xff\x00\x00\x00\x00\x00\x00\xf6\xff\x00\x00\x00\x00\x00\x00\x00\x00\xc5\xff\x00\x00\xc6\xff\xcc\xff\xaa\xff\xcd\xff\xce\xff\xc8\xff\x00\x00\x00\x00\x84\xff\x00\x00\x00\x00\x00\x00\x99\xff\x00\x00\x9d\xff\x00\x00\xaf\xff\xb9\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x82\xff\xcf\xff\xd0\xff\xd1\xff\xd2\xff\xd3\xff\xd4\xff\xd5\xff\xd6\xff\xd7\xff\xd8\xff\xd9\xff\xda\xff\xdb\xff\xdc\xff\xdd\xff\xde\xff\xdf\xff\xe0\xff\xe1\xff\xe2\xff\xe3\xff\xe4\xff\xe5\xff\xe6\xff\xe7\xff\xe8\xff\xe9\xff\xea\xff\xbc\xff\xc3\xff\xc4\xff\x00\x00\x00\x00\xa5\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa6\xff\xa7\xff\x00\x00\x97\xff\x95\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x85\xff\x00\x00\x9e\xff\x00\x00\xa9\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x98\xff\xf5\xff\x00\x00\x00\x00\x00\x00\xfc\xff\xfb\xff\x00\x00\x00\x00\x89\xff\x88\xff\x96\xff\x00\x00\xb2\xff\x00\x00\x00\x00\xb3\xff\x00\x00\xbe\xff\x00\x00\x00\x00\xc2\xff\x00\x00\x00\x00\xc7\xff\x00\x00\xef\xff\xf0\xff\x00\x00\x8d\xff\x00\x00\x00\x00\x8f\xff\x00\x00\x94\xff\x9c\xff\x00\x00\x00\x00\xa1\xff\x00\x00\x00\x00\xa2\xff\xa3\xff\x00\x00\x00\x00\x83\xff\xf1\xff\xb4\xff\xba\xff\x00\x00\x00\x00\xa8\xff\xb0\xff\x8e\xff\x8d\xff\x00\x00\x8d\xff\x93\xff\x00\x00\x00\x00\x00\x00\x9b\xff\x00\x00\x00\x00\x00\x00\x00\x00\xac\xff\x00\x00\xab\xff\xf9\xff\x00\x00\xf4\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbd\xff\xc1\xff\x9a\xff\xee\xff\x00\x00\xc0\xff\x92\xff\x8d\xff\x91\xff\xa4\xff\xb1\xff\x00\x00\xb8\xff\xb6\xff\xb5\xff\xb4\xff\x90\xff\x00\x00\xae\xff\xad\xff\xf3\xff\x00\x00\x00\x00\xf7\xff\x00\x00\xbf\xff\xb7\xff\xf8\xff"#+happyDefActions = HappyA# "\x00\x00\x00\x00\x00\x00\x87\xff\x84\xff\xfa\xff\xb8\xff\xeb\xff\xec\xff\x00\x00\xcb\xff\x9d\xff\xed\xff\x8a\xff\x89\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x88\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\xff\x00\x00\x83\xff\x00\x00\x00\x00\x00\x00\xf2\xff\xca\xff\xc9\xff\x9c\xff\x00\x00\xfe\xff\xfd\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8a\xff\x00\x00\x00\x00\x00\x00\xf6\xff\x00\x00\x00\x00\x00\x00\x00\x00\xc2\xff\x00\x00\xc3\xff\xcc\xff\xa7\xff\xcd\xff\xce\xff\xc5\xff\x00\x00\x00\x00\x81\xff\x00\x00\x00\x00\x00\x00\x96\xff\x00\x00\x9a\xff\x00\x00\xac\xff\xb6\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\xff\xcf\xff\xd0\xff\xd1\xff\xd2\xff\xd3\xff\xd4\xff\xd5\xff\xd6\xff\xd7\xff\xd8\xff\xd9\xff\xda\xff\xdb\xff\xdc\xff\xdd\xff\xde\xff\xdf\xff\xe0\xff\xe1\xff\xe2\xff\xe3\xff\xe4\xff\xe5\xff\xe6\xff\xe7\xff\xe8\xff\xe9\xff\xea\xff\xb9\xff\xc0\xff\xc1\xff\x00\x00\x00\x00\xa2\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa3\xff\xa4\xff\x00\x00\x94\xff\x92\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x82\xff\x00\x00\x9b\xff\x00\x00\xa6\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95\xff\xf5\xff\x00\x00\x00\x00\x00\x00\x00\x00\xc7\xff\x00\x00\xfc\xff\xfb\xff\xc6\xff\xc8\xff\x00\x00\x00\x00\x86\xff\x85\xff\x93\xff\x00\x00\xaf\xff\x00\x00\x00\x00\xb0\xff\x00\x00\xbb\xff\x00\x00\x00\x00\xbf\xff\x00\x00\x00\x00\xc4\xff\x00\x00\xef\xff\xf0\xff\x00\x00\x8a\xff\x00\x00\x00\x00\x8c\xff\x00\x00\x91\xff\x99\xff\x00\x00\x00\x00\x9e\xff\x00\x00\x00\x00\x9f\xff\xa0\xff\x00\x00\x00\x00\x80\xff\xf1\xff\xb1\xff\xb7\xff\x00\x00\x00\x00\xa5\xff\xad\xff\x8b\xff\x8a\xff\x00\x00\x8a\xff\x90\xff\x00\x00\x00\x00\x00\x00\x98\xff\x00\x00\x00\x00\x00\x00\x00\x00\xa9\xff\x00\x00\xa8\xff\xf9\xff\x00\x00\xf4\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xba\xff\xbe\xff\x97\xff\xee\xff\x00\x00\xbd\xff\x8f\xff\x8a\xff\x8e\xff\xa1\xff\xae\xff\x00\x00\xb5\xff\xb3\xff\xb2\xff\xb1\xff\x8d\xff\x00\x00\xab\xff\xaa\xff\xf3\xff\x00\x00\x00\x00\xf7\xff\x00\x00\xbc\xff\xb4\xff\xf8\xff"#  happyCheck :: HappyAddr-happyCheck = HappyA# "\xff\xff\x02\x00\x03\x00\x04\x00\x09\x00\x10\x00\x0d\x00\x0b\x00\x09\x00\x0a\x00\x0b\x00\x10\x00\x0a\x00\x0e\x00\x0f\x00\x10\x00\x0b\x00\x02\x00\x0f\x00\x10\x00\x0a\x00\x16\x00\x2c\x00\x3a\x00\x2b\x00\x02\x00\x03\x00\x04\x00\x18\x00\x0c\x00\x2b\x00\x42\x00\x09\x00\x37\x00\x0b\x00\x14\x00\x25\x00\x0e\x00\x0f\x00\x10\x00\x29\x00\x2a\x00\x0b\x00\x3e\x00\x04\x00\x16\x00\x2c\x00\x3a\x00\x07\x00\x3e\x00\x33\x00\x34\x00\x09\x00\x3a\x00\x0b\x00\x38\x00\x09\x00\x3a\x00\x0b\x00\x40\x00\x25\x00\x2c\x00\x43\x00\x40\x00\x29\x00\x2a\x00\x43\x00\x47\x00\x45\x00\x46\x00\x47\x00\x02\x00\x03\x00\x04\x00\x33\x00\x34\x00\x47\x00\x43\x00\x09\x00\x38\x00\x0b\x00\x3a\x00\x3b\x00\x0e\x00\x0f\x00\x10\x00\x18\x00\x40\x00\x0a\x00\x3a\x00\x43\x00\x16\x00\x45\x00\x46\x00\x47\x00\x02\x00\x03\x00\x04\x00\x39\x00\x0b\x00\x04\x00\x3a\x00\x09\x00\x0a\x00\x0b\x00\x3a\x00\x25\x00\x0e\x00\x0f\x00\x10\x00\x29\x00\x2a\x00\x2c\x00\x04\x00\x04\x00\x16\x00\x36\x00\x08\x00\x0a\x00\x09\x00\x33\x00\x34\x00\x2c\x00\x37\x00\x0c\x00\x38\x00\x0b\x00\x3a\x00\x3b\x00\x18\x00\x25\x00\x12\x00\x13\x00\x40\x00\x29\x00\x2a\x00\x43\x00\x16\x00\x45\x00\x46\x00\x47\x00\x02\x00\x03\x00\x04\x00\x33\x00\x34\x00\x3a\x00\x0b\x00\x09\x00\x38\x00\x0b\x00\x3a\x00\x2c\x00\x0e\x00\x0f\x00\x10\x00\x2c\x00\x40\x00\x16\x00\x18\x00\x43\x00\x16\x00\x45\x00\x46\x00\x47\x00\x09\x00\x33\x00\x34\x00\x35\x00\x0c\x00\x0c\x00\x41\x00\x10\x00\x0c\x00\x18\x00\x09\x00\x25\x00\x0d\x00\x48\x00\x0c\x00\x29\x00\x2a\x00\x10\x00\x44\x00\x0c\x00\x0c\x00\x47\x00\x33\x00\x34\x00\x35\x00\x33\x00\x34\x00\x04\x00\x29\x00\x2a\x00\x38\x00\x08\x00\x3a\x00\x2e\x00\x12\x00\x13\x00\x2c\x00\x2c\x00\x40\x00\x44\x00\x2c\x00\x43\x00\x47\x00\x45\x00\x46\x00\x47\x00\x2c\x00\x38\x00\x39\x00\x3a\x00\x02\x00\x2c\x00\x2c\x00\x17\x00\x3f\x00\x40\x00\x04\x00\x38\x00\x43\x00\x3a\x00\x17\x00\x09\x00\x04\x00\x04\x00\x02\x00\x40\x00\x08\x00\x08\x00\x43\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x16\x00\x17\x00\x05\x00\x10\x00\x11\x00\x12\x00\x13\x00\x04\x00\x31\x00\x32\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x06\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x08\x00\x0f\x00\x10\x00\x11\x00\x04\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x00\x00\x01\x00\x02\x00\x04\x00\x04\x00\x05\x00\x02\x00\x07\x00\x03\x00\x04\x00\x02\x00\x02\x00\x02\x00\x04\x00\x0e\x00\x0f\x00\x10\x00\x02\x00\x12\x00\x13\x00\x02\x00\x15\x00\x0b\x00\x16\x00\x17\x00\x19\x00\x1a\x00\x01\x00\x02\x00\x02\x00\x04\x00\x05\x00\x04\x00\x07\x00\x19\x00\x1a\x00\x18\x00\x02\x00\x02\x00\x04\x00\x0e\x00\x0f\x00\x10\x00\x02\x00\x12\x00\x13\x00\x02\x00\x15\x00\x3c\x00\x3d\x00\x02\x00\x19\x00\x1a\x00\x01\x00\x02\x00\x18\x00\x04\x00\x05\x00\x07\x00\x07\x00\x19\x00\x1a\x00\x2b\x00\x0a\x00\x43\x00\x0b\x00\x0e\x00\x0f\x00\x10\x00\x0b\x00\x12\x00\x13\x00\x07\x00\x15\x00\x43\x00\x3a\x00\x2c\x00\x19\x00\x1a\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x18\x00\x25\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x18\x00\x02\x00\x25\x00\x04\x00\x05\x00\x06\x00\x07\x00\x14\x00\x2d\x00\x02\x00\x2b\x00\x04\x00\x0b\x00\x0e\x00\x0f\x00\x10\x00\x0b\x00\x12\x00\x13\x00\x39\x00\x15\x00\x44\x00\x09\x00\x2d\x00\x19\x00\x1a\x00\x02\x00\x0a\x00\x04\x00\x05\x00\x06\x00\x07\x00\x19\x00\x1a\x00\x02\x00\x3a\x00\x04\x00\x0a\x00\x0e\x00\x0f\x00\x10\x00\x43\x00\x12\x00\x13\x00\x3a\x00\x15\x00\x14\x00\x43\x00\x39\x00\x19\x00\x1a\x00\x02\x00\x3a\x00\x04\x00\x05\x00\x01\x00\x07\x00\x19\x00\x1a\x00\x30\x00\x02\x00\x0c\x00\x04\x00\x0e\x00\x0f\x00\x10\x00\x2c\x00\x12\x00\x13\x00\x2c\x00\x15\x00\x43\x00\x3a\x00\x2c\x00\x19\x00\x1a\x00\x02\x00\x2f\x00\x04\x00\x05\x00\x06\x00\x07\x00\x2c\x00\x19\x00\x1a\x00\x2d\x00\x3a\x00\x0b\x00\x0e\x00\x0f\x00\x10\x00\x3a\x00\x12\x00\x13\x00\x0b\x00\x15\x00\x09\x00\x42\x00\xff\xff\x19\x00\x1a\x00\x02\x00\x43\x00\x04\x00\x05\x00\x06\x00\x07\x00\x44\x00\x3a\x00\x42\x00\x3a\x00\x43\x00\x43\x00\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\x06\x00\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\x06\x00\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\x06\x00\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\x06\x00\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\x06\x00\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\x06\x00\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"#+happyCheck = HappyA# "\xff\xff\x02\x00\x03\x00\x04\x00\x07\x00\x0b\x00\x0b\x00\x0b\x00\x09\x00\x0a\x00\x0b\x00\x02\x00\x0a\x00\x0e\x00\x0f\x00\x10\x00\x2b\x00\x0b\x00\x16\x00\x0b\x00\x09\x00\x16\x00\x0b\x00\x2b\x00\x41\x00\x0a\x00\x3a\x00\x2c\x00\x18\x00\x14\x00\x16\x00\x09\x00\x09\x00\x0b\x00\x42\x00\x3e\x00\x25\x00\x4e\x00\x37\x00\x10\x00\x29\x00\x2a\x00\x3e\x00\x12\x00\x13\x00\x09\x00\x2c\x00\x33\x00\x34\x00\x35\x00\x33\x00\x34\x00\x10\x00\x3a\x00\x39\x00\x38\x00\x0b\x00\x3a\x00\x09\x00\x33\x00\x34\x00\x35\x00\x10\x00\x40\x00\x0a\x00\x10\x00\x43\x00\x44\x00\x45\x00\x3a\x00\x4a\x00\x4d\x00\x49\x00\x4d\x00\x4b\x00\x4c\x00\x4d\x00\x02\x00\x03\x00\x04\x00\x3a\x00\x3a\x00\x4a\x00\x4d\x00\x09\x00\x4d\x00\x0b\x00\x40\x00\x49\x00\x0e\x00\x0f\x00\x10\x00\x38\x00\x39\x00\x3a\x00\x0a\x00\x49\x00\x16\x00\x2c\x00\x3f\x00\x40\x00\x12\x00\x13\x00\x3a\x00\x3a\x00\x38\x00\x0c\x00\x3a\x00\x0c\x00\x49\x00\x2c\x00\x18\x00\x25\x00\x40\x00\x0c\x00\x0c\x00\x29\x00\x2a\x00\x29\x00\x2a\x00\x0d\x00\x37\x00\x49\x00\x2e\x00\x0c\x00\x0c\x00\x33\x00\x34\x00\x18\x00\x2c\x00\x04\x00\x38\x00\x0c\x00\x3a\x00\x3b\x00\x02\x00\x0c\x00\x04\x00\x2c\x00\x40\x00\x2c\x00\x36\x00\x43\x00\x44\x00\x45\x00\x04\x00\x2c\x00\x2c\x00\x49\x00\x08\x00\x4b\x00\x4c\x00\x4d\x00\x02\x00\x03\x00\x04\x00\x2c\x00\x2c\x00\x19\x00\x1a\x00\x09\x00\x0a\x00\x0b\x00\x04\x00\x2c\x00\x0e\x00\x0f\x00\x10\x00\x2c\x00\x10\x00\x11\x00\x12\x00\x13\x00\x16\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x00\x00\x01\x00\x02\x00\x0d\x00\x04\x00\x05\x00\x04\x00\x07\x00\x25\x00\x02\x00\x08\x00\x04\x00\x29\x00\x2a\x00\x0e\x00\x0f\x00\x10\x00\x18\x00\x12\x00\x13\x00\x04\x00\x15\x00\x33\x00\x34\x00\x08\x00\x19\x00\x1a\x00\x38\x00\x18\x00\x3a\x00\x04\x00\x04\x00\x19\x00\x1a\x00\x08\x00\x40\x00\x09\x00\x04\x00\x43\x00\x44\x00\x45\x00\x02\x00\x09\x00\x04\x00\x49\x00\x02\x00\x4b\x00\x4c\x00\x4d\x00\x02\x00\x03\x00\x04\x00\x02\x00\x17\x00\x04\x00\x02\x00\x09\x00\x02\x00\x0b\x00\x03\x00\x04\x00\x0e\x00\x0f\x00\x10\x00\x19\x00\x1a\x00\x0f\x00\x10\x00\x11\x00\x16\x00\x16\x00\x17\x00\x0f\x00\x10\x00\x04\x00\x19\x00\x1a\x00\x01\x00\x02\x00\x04\x00\x04\x00\x05\x00\x04\x00\x07\x00\x25\x00\x02\x00\x17\x00\x04\x00\x29\x00\x2a\x00\x0e\x00\x0f\x00\x10\x00\x02\x00\x12\x00\x13\x00\x02\x00\x15\x00\x33\x00\x34\x00\x02\x00\x19\x00\x1a\x00\x38\x00\x0b\x00\x3a\x00\x3b\x00\x02\x00\x19\x00\x1a\x00\x02\x00\x40\x00\x16\x00\x17\x00\x43\x00\x44\x00\x45\x00\x04\x00\x3c\x00\x3d\x00\x49\x00\x18\x00\x4b\x00\x4c\x00\x4d\x00\x02\x00\x03\x00\x04\x00\x02\x00\x02\x00\x02\x00\x02\x00\x09\x00\x18\x00\x0b\x00\x0a\x00\x18\x00\x0e\x00\x0f\x00\x10\x00\x07\x00\x49\x00\x2b\x00\x0b\x00\x49\x00\x16\x00\x0b\x00\x07\x00\x2c\x00\x2b\x00\x3a\x00\x4a\x00\x2d\x00\x01\x00\x02\x00\x18\x00\x04\x00\x05\x00\x14\x00\x07\x00\x25\x00\x0b\x00\x0b\x00\x09\x00\x29\x00\x2a\x00\x0e\x00\x0f\x00\x10\x00\x2d\x00\x12\x00\x13\x00\x39\x00\x15\x00\x33\x00\x34\x00\x0a\x00\x19\x00\x1a\x00\x38\x00\x3a\x00\x3a\x00\x0a\x00\x49\x00\x14\x00\x01\x00\x2c\x00\x40\x00\x3a\x00\x49\x00\x43\x00\x44\x00\x45\x00\x39\x00\x30\x00\x3a\x00\x49\x00\x2c\x00\x4b\x00\x4c\x00\x4d\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x2f\x00\x49\x00\x3a\x00\x48\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x46\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x2c\x00\x2c\x00\x05\x00\x2d\x00\x3a\x00\x0b\x00\x42\x00\x3a\x00\x31\x00\x32\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x06\x00\x0b\x00\x49\x00\x3a\x00\x4a\x00\x47\x00\x42\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x08\x00\x49\x00\x3a\x00\x49\x00\x09\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\xff\xff\x25\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\xff\xff\x02\x00\x25\x00\x04\x00\x05\x00\x06\x00\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\x06\x00\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\x0c\x00\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\x06\x00\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\x06\x00\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\x06\x00\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\x06\x00\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\x06\x00\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\x06\x00\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\x06\x00\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\x06\x00\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"#  happyTable :: HappyAddr-happyTable = HappyA# "\x00\x00\x10\x00\x11\x00\x12\x00\x13\x00\xb8\x00\x15\x01\x14\x00\x13\x00\x6b\x00\x14\x00\x17\x00\xf8\x00\x15\x00\x16\x00\x17\x00\x45\x00\xa0\x00\xd3\x00\x09\x00\xf6\x00\x18\x00\x9a\x00\xaf\x00\xe8\x00\x10\x00\x11\x00\x12\x00\x0b\x01\x0e\x01\xa3\x00\xb0\x00\x13\x00\x9b\x00\x14\x00\xa1\x00\x19\x00\x15\x00\x16\x00\x17\x00\x1a\x00\x1b\x00\x30\x00\xe9\x00\x0f\x01\x18\x00\xf9\x00\x31\x00\x98\x00\xa4\x00\x1c\x00\x1d\x00\x2f\x00\x1f\x00\x30\x00\x1e\x00\x33\x00\x1f\x00\x34\x00\x21\x00\x19\x00\x9f\x00\x22\x00\x21\x00\x1a\x00\x1b\x00\x22\x00\x25\x00\x23\x00\x24\x00\x25\x00\x10\x00\x11\x00\x12\x00\x1c\x00\x1d\x00\x46\x00\x22\x00\x13\x00\x1e\x00\x14\x00\x1f\x00\x20\x00\x15\x00\x16\x00\x17\x00\x47\x00\x21\x00\xdb\x00\x31\x00\x22\x00\x18\x00\x23\x00\x24\x00\x25\x00\x10\x00\x11\x00\x12\x00\x99\x00\x34\x00\xff\x00\x31\x00\x13\x00\x40\x00\x14\x00\x31\x00\x19\x00\x15\x00\x16\x00\x17\x00\x1a\x00\x1b\x00\x9a\x00\x36\x00\x34\x00\x18\x00\x48\x00\x89\x00\x9e\x00\x88\x00\x1c\x00\x1d\x00\x9f\x00\x9c\x00\x0f\x01\x1e\x00\xd5\x00\x1f\x00\x20\x00\x01\x01\x19\x00\xfd\x00\x0b\x00\x21\x00\x1a\x00\x1b\x00\x22\x00\x18\x00\x23\x00\x24\x00\x25\x00\x10\x00\x11\x00\x12\x00\x1c\x00\x1d\x00\x31\x00\x8f\x00\x13\x00\x1e\x00\x14\x00\x1f\x00\x9f\x00\x15\x00\x16\x00\x17\x00\x9f\x00\x21\x00\x18\x00\x03\x01\x22\x00\x18\x00\x23\x00\x24\x00\x25\x00\x13\x00\x90\x00\x91\x00\xd6\x00\x05\x01\xe1\x00\x29\x00\x17\x00\xf0\x00\xe6\x00\x13\x00\x19\x00\x07\x01\xff\xff\xf2\x00\x1a\x00\x1b\x00\x17\x00\xd7\x00\xd1\x00\xa0\x00\xd8\x00\x90\x00\x91\x00\x92\x00\x1c\x00\x1d\x00\x36\x00\x4a\x00\x4b\x00\x1e\x00\x37\x00\x1f\x00\x4c\x00\xea\x00\x0b\x00\x9f\x00\x9f\x00\x21\x00\x93\x00\x9f\x00\x22\x00\x94\x00\x23\x00\x24\x00\x25\x00\x9f\x00\xcc\x00\xcd\x00\x1f\x00\xde\x00\x9f\x00\x9f\x00\xcf\x00\xce\x00\x21\x00\x34\x00\xe5\x00\x22\x00\x1f\x00\xcf\x00\x35\x00\x36\x00\x36\x00\xb6\x00\x21\x00\x41\x00\x42\x00\x22\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\xb8\x00\x96\x00\x9d\x00\x50\x00\x51\x00\x52\x00\x53\x00\xc0\x00\x09\x01\x0a\x01\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\xea\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\xe3\x00\x8c\x00\x09\x00\x8d\x00\xc1\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x17\x01\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x13\x01\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\xbc\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\xbf\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x25\x00\x26\x00\x03\x00\xc9\x00\x04\x00\x05\x00\xc3\x00\x06\x00\xf3\x00\xf4\x00\xd1\x00\x03\x00\x2d\x00\x04\x00\x07\x00\x08\x00\x09\x00\x31\x00\x0a\x00\x0b\x00\xa7\x00\x0c\x00\x8a\x00\x95\x00\x96\x00\x0d\x00\x0e\x00\xb2\x00\x03\x00\xab\x00\x04\x00\x05\x00\xb0\x00\x06\x00\x02\x01\x0e\x00\xad\x00\x03\x00\xb1\x00\x04\x00\x07\x00\x08\x00\x09\x00\x2d\x00\x0a\x00\x0b\x00\x31\x00\x0c\x00\x2a\x00\x2b\x00\x39\x00\x0d\x00\x0e\x00\x02\x00\x03\x00\x43\x00\x04\x00\x05\x00\x98\x00\x06\x00\xe3\x00\x0e\x00\x0d\x01\x48\x00\x22\x00\x11\x01\x07\x00\x08\x00\x09\x00\xf7\x00\x0a\x00\x0b\x00\x98\x00\x0c\x00\x22\x00\x31\x00\x07\x01\x0d\x00\x0e\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x06\x01\x65\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\xe2\x00\x03\x00\x00\x00\x04\x00\x3c\x00\xf9\x00\x06\x00\xec\x00\xee\x00\x03\x00\xed\x00\x04\x00\xef\x00\x07\x00\x08\x00\x09\x00\xf1\x00\x0a\x00\x0b\x00\x99\x00\x0c\x00\xb4\x00\xb5\x00\xb6\x00\x0d\x00\x0e\x00\x03\x00\xbb\x00\x04\x00\x3c\x00\xfa\x00\x06\x00\xe5\x00\x0e\x00\x03\x00\xaf\x00\x04\x00\xbe\x00\x07\x00\x08\x00\x09\x00\x22\x00\x0a\x00\x0b\x00\x31\x00\x0c\x00\xc5\x00\x22\x00\x99\x00\x0d\x00\x0e\x00\x03\x00\x31\x00\x04\x00\xdc\x00\xda\x00\x06\x00\xca\x00\x0e\x00\xd9\x00\x03\x00\xdd\x00\x04\x00\x07\x00\x08\x00\x09\x00\x9a\x00\x0a\x00\x0b\x00\xa5\x00\x0c\x00\x22\x00\x31\x00\x9a\x00\x0d\x00\x0e\x00\x03\x00\x8c\x00\x04\x00\x3c\x00\xdf\x00\x06\x00\xa5\x00\x2c\x00\x0e\x00\xa6\x00\x31\x00\xa9\x00\x07\x00\x08\x00\x09\x00\x31\x00\x0a\x00\x0b\x00\xad\x00\x0c\x00\x69\x00\xaa\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x22\x00\x04\x00\x3c\x00\xb9\x00\x06\x00\x28\x00\x31\x00\x2c\x00\x31\x00\x22\x00\x22\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x3c\x00\xbc\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x3c\x00\xd2\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x3c\x00\x69\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x3c\x00\x94\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x3c\x00\x3d\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x3c\x00\x3e\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x13\x01\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x14\x01\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x0a\x01\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x11\x01\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xfb\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xfc\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xfe\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x00\x01\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xdb\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xf2\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xbf\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xc2\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xc5\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xc6\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xc7\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xc8\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xce\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x6b\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x6c\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x6d\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x6e\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x6f\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x70\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x71\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x72\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x73\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x74\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x75\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x76\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x77\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x78\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x79\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x7a\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x7b\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x7c\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x7d\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x7e\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x7f\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x80\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x81\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x82\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x83\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x84\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x85\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x86\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x87\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xa6\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xaa\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x38\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x3a\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x3b\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x40\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"#+happyTable = HappyA# "\x00\x00\x10\x00\x11\x00\x12\x00\x9e\x00\x14\x00\x36\x00\xe0\x00\x13\x00\x71\x00\x14\x00\xa6\x00\x03\x01\x15\x00\x16\x00\x17\x00\xf3\x00\x4b\x00\x18\x00\x95\x00\x35\x00\x18\x00\x36\x00\xa9\x00\x2c\x00\x01\x01\xb5\x00\xa0\x00\x16\x01\xa7\x00\x18\x00\x39\x00\x13\x00\x3a\x00\xb6\x00\xf4\x00\x19\x00\xff\xff\xa1\x00\x17\x00\x1a\x00\x1b\x00\xaa\x00\x08\x01\x0b\x00\x13\x00\x04\x01\x96\x00\x97\x00\xe1\x00\x1c\x00\x1d\x00\x17\x00\x37\x00\x9f\x00\x1e\x00\x3a\x00\x1f\x00\x13\x00\x96\x00\x97\x00\x98\x00\xc3\x00\x21\x00\xe6\x00\x17\x00\x22\x00\x23\x00\x24\x00\x37\x00\xe2\x00\x28\x00\x25\x00\xe3\x00\x26\x00\x27\x00\x28\x00\x10\x00\x11\x00\x12\x00\x37\x00\x1f\x00\x99\x00\x4c\x00\x13\x00\x9a\x00\x14\x00\x21\x00\x25\x00\x15\x00\x16\x00\x17\x00\xd7\x00\xd8\x00\x1f\x00\xa4\x00\x25\x00\x18\x00\xa5\x00\xd9\x00\x21\x00\xf5\x00\x0b\x00\x37\x00\x37\x00\xf0\x00\x19\x01\x1f\x00\x1a\x01\x25\x00\xa0\x00\x4d\x00\x19\x00\x21\x00\x10\x01\xec\x00\x1a\x00\x1b\x00\x50\x00\x51\x00\x20\x01\xa2\x00\x25\x00\x52\x00\xfb\x00\xfd\x00\x1c\x00\x1d\x00\x0c\x01\xa5\x00\x1a\x01\x1e\x00\xdc\x00\x1f\x00\x20\x00\x03\x00\xa6\x00\x04\x00\xa5\x00\x21\x00\xa5\x00\x4e\x00\x22\x00\x23\x00\x24\x00\x3c\x00\xa5\x00\xa5\x00\x25\x00\x8f\x00\x26\x00\x27\x00\x28\x00\x10\x00\x11\x00\x12\x00\xa5\x00\xa5\x00\x0d\x01\x0e\x00\x13\x00\x46\x00\x14\x00\x0a\x01\xa5\x00\x15\x00\x16\x00\x17\x00\xa5\x00\x56\x00\x57\x00\x58\x00\x59\x00\x18\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x28\x00\x29\x00\x03\x00\x12\x01\x04\x00\x05\x00\x3c\x00\x06\x00\x19\x00\x03\x00\x3d\x00\x04\x00\x1a\x00\x1b\x00\x07\x00\x08\x00\x09\x00\x0e\x01\x0a\x00\x0b\x00\x3c\x00\x0c\x00\x1c\x00\x1d\x00\x47\x00\x0d\x00\x0e\x00\x1e\x00\xf1\x00\x1f\x00\x3c\x00\x3a\x00\xee\x00\x0e\x00\x48\x00\x21\x00\x8e\x00\x3a\x00\x22\x00\x23\x00\x24\x00\x03\x00\x3b\x00\x04\x00\x25\x00\xe9\x00\x26\x00\x27\x00\x28\x00\x10\x00\x11\x00\x12\x00\x03\x00\xda\x00\x04\x00\xc1\x00\x13\x00\xce\x00\x14\x00\xfe\x00\xff\x00\x15\x00\x16\x00\x17\x00\xf0\x00\x0e\x00\x92\x00\x09\x00\x93\x00\x18\x00\xc3\x00\x9c\x00\xde\x00\x09\x00\xcb\x00\xd5\x00\x0e\x00\xbb\x00\x03\x00\xcc\x00\x04\x00\x05\x00\xd4\x00\x06\x00\x19\x00\x03\x00\xda\x00\x04\x00\x1a\x00\x1b\x00\x07\x00\x08\x00\x09\x00\xdc\x00\x0a\x00\x0b\x00\x33\x00\x0c\x00\x1c\x00\x1d\x00\x37\x00\x0d\x00\x0e\x00\x1e\x00\x90\x00\x1f\x00\x20\x00\xad\x00\x32\x00\x0e\x00\xb1\x00\x21\x00\x9b\x00\x9c\x00\x22\x00\x23\x00\x24\x00\xb6\x00\x30\x00\x31\x00\x25\x00\xb3\x00\x26\x00\x27\x00\x28\x00\x10\x00\x11\x00\x12\x00\xb7\x00\x33\x00\x37\x00\x3f\x00\x13\x00\x49\x00\x14\x00\x4e\x00\x11\x01\x15\x00\x16\x00\x17\x00\x9e\x00\x25\x00\x18\x01\x1c\x01\x25\x00\x18\x00\x02\x01\x9e\x00\x12\x01\xf8\x00\x37\x00\xbd\x00\xf9\x00\x02\x00\x03\x00\xed\x00\x04\x00\x05\x00\xf7\x00\x06\x00\x19\x00\xfa\x00\xfc\x00\xc0\x00\x1a\x00\x1b\x00\x07\x00\x08\x00\x09\x00\xc1\x00\x0a\x00\x0b\x00\x9f\x00\x0c\x00\x1c\x00\x1d\x00\xc6\x00\x0d\x00\x0e\x00\x1e\x00\xb5\x00\x1f\x00\xc9\x00\x25\x00\xd0\x00\xe5\x00\xa0\x00\x21\x00\x37\x00\x25\x00\x22\x00\x23\x00\x24\x00\x9f\x00\xe4\x00\x37\x00\x25\x00\xab\x00\x26\x00\x27\x00\x28\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x92\x00\x25\x00\x37\x00\xbb\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\xb9\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\xa0\x00\xab\x00\xa3\x00\xac\x00\x37\x00\xaf\x00\xb0\x00\x37\x00\x14\x01\x15\x01\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\xf5\x00\xb3\x00\x25\x00\x37\x00\x2b\x00\x2e\x00\x32\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\xee\x00\x25\x00\x37\x00\x25\x00\x6f\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x22\x01\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x1e\x01\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\xc7\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\xca\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x00\x00\x6b\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x00\x00\x03\x00\x00\x00\x04\x00\x42\x00\x04\x01\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x42\x00\x05\x01\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xe7\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe8\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x42\x00\xea\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x42\x00\xc4\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x42\x00\xc7\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x42\x00\xdd\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x42\x00\x6f\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x42\x00\x9a\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x42\x00\x43\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x42\x00\x44\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x1e\x01\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x1f\x01\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x15\x01\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x1c\x01\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x06\x01\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x07\x01\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x09\x01\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x0b\x01\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xe6\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xfd\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xbd\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xbe\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xca\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xcd\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xd0\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xd1\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xd2\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xd3\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xd9\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x71\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x72\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x73\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x74\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x75\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x76\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x77\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x78\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x79\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x7a\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x7b\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x7c\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x7d\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x7e\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x7f\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x80\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x81\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x82\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x83\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x84\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x85\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x86\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x87\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x88\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x89\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x8a\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x8b\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x8c\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x8d\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xac\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xb0\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xb9\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x2c\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x2e\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x3e\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x40\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x41\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x46\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"# -happyReduceArr = array (1, 125) [+happyReduceArr = array (1, 128) [ 	(1 , happyReduce_1), 	(2 , happyReduce_2), 	(3 , happyReduce_3),@@ -330,10 +330,13 @@ 	(122 , happyReduce_122), 	(123 , happyReduce_123), 	(124 , happyReduce_124),-	(125 , happyReduce_125)+	(125 , happyReduce_125),+	(126 , happyReduce_126),+	(127 , happyReduce_127),+	(128 , happyReduce_128) 	] -happy_n_terms = 73 :: Int+happy_n_terms = 79 :: Int happy_n_nonterms = 27 :: Int  happyReduce_1 = happySpecReduce_1  0# happyReduction_1@@ -868,15 +871,48 @@ 		 (Afloat happy_var_1 	)} -happyReduce_55 = happySpecReduce_1  6# happyReduction_55-happyReduction_55 happy_x_1+happyReduce_55 = happyReduce 4# 5# happyReduction_55+happyReduction_55 (happy_x_4 `HappyStk`+	happy_x_3 `HappyStk`+	happy_x_2 `HappyStk`+	happy_x_1 `HappyStk`+	happyRest)+	 = case happyOut9 happy_x_2 of { happy_var_2 -> +	case happyOut9 happy_x_4 of { happy_var_4 -> +	happyIn9+		 (call "insert" [happy_var_2,Ast "destination" [happy_var_4]]+	) `HappyStk` happyRest}}++happyReduce_56 = happySpecReduce_3  5# happyReduction_56+happyReduction_56 happy_x_3+	happy_x_2+	happy_x_1+	 =  case happyOut9 happy_x_3 of { happy_var_3 -> +	happyIn9+		 (call "delete" [happy_var_3]+	)}++happyReduce_57 = happyReduce 4# 5# happyReduction_57+happyReduction_57 (happy_x_4 `HappyStk`+	happy_x_3 `HappyStk`+	happy_x_2 `HappyStk`+	happy_x_1 `HappyStk`+	happyRest)+	 = case happyOut9 happy_x_2 of { happy_var_2 -> +	case happyOut9 happy_x_4 of { happy_var_4 -> +	happyIn9+		 (call "replace" [happy_var_2,happy_var_4]+	) `HappyStk` happyRest}}++happyReduce_58 = happySpecReduce_1  6# happyReduction_58+happyReduction_58 happy_x_1 	 =  case happyOut9 happy_x_1 of { happy_var_1 ->  	happyIn10 		 ([happy_var_1] 	)} -happyReduce_56 = happySpecReduce_3  6# happyReduction_56-happyReduction_56 happy_x_3+happyReduce_59 = happySpecReduce_3  6# happyReduction_59+happyReduction_59 happy_x_3 	happy_x_2 	happy_x_1 	 =  case happyOut10 happy_x_1 of { happy_var_1 -> @@ -885,24 +921,24 @@ 		 (happy_var_1++[happy_var_3] 	)}} -happyReduce_57 = happySpecReduce_2  7# happyReduction_57-happyReduction_57 happy_x_2+happyReduce_60 = happySpecReduce_2  7# happyReduction_60+happyReduction_60 happy_x_2 	happy_x_1 	 =  case happyOut12 happy_x_2 of { happy_var_2 ->  	happyIn11 		 (happy_var_2 	)} -happyReduce_58 = happySpecReduce_2  7# happyReduction_58-happyReduction_58 happy_x_2+happyReduce_61 = happySpecReduce_2  7# happyReduction_61+happyReduction_61 happy_x_2 	happy_x_1 	 =  case happyOut13 happy_x_2 of { happy_var_2 ->  	happyIn11 		 (happy_var_2 	)} -happyReduce_59 = happySpecReduce_3  7# happyReduction_59-happyReduction_59 happy_x_3+happyReduce_62 = happySpecReduce_3  7# happyReduction_62+happyReduction_62 happy_x_3 	happy_x_2 	happy_x_1 	 =  case happyOut11 happy_x_1 of { happy_var_1 -> @@ -911,8 +947,8 @@ 		 (happy_var_1 . happy_var_3 	)}} -happyReduce_60 = happySpecReduce_3  7# happyReduction_60-happyReduction_60 happy_x_3+happyReduce_63 = happySpecReduce_3  7# happyReduction_63+happyReduction_63 happy_x_3 	happy_x_2 	happy_x_1 	 =  case happyOut11 happy_x_1 of { happy_var_1 -> @@ -921,8 +957,8 @@ 		 (happy_var_1 . happy_var_3 	)}} -happyReduce_61 = happySpecReduce_3  8# happyReduction_61-happyReduction_61 happy_x_3+happyReduce_64 = happySpecReduce_3  8# happyReduction_64+happyReduction_64 happy_x_3 	happy_x_2 	happy_x_1 	 =  case happyOut8 happy_x_1 of { happy_var_1 -> @@ -931,8 +967,8 @@ 		 (\x -> Ast "for" [happy_var_1,Avar "$",happy_var_3,x] 	)}} -happyReduce_62 = happyReduce 5# 8# happyReduction_62-happyReduction_62 (happy_x_5 `HappyStk`+happyReduce_65 = happyReduce 5# 8# happyReduction_65+happyReduction_65 (happy_x_5 `HappyStk` 	happy_x_4 `HappyStk` 	happy_x_3 `HappyStk` 	happy_x_2 `HappyStk`@@ -945,8 +981,8 @@ 		 (\x -> Ast "for" [happy_var_1,happy_var_3,happy_var_5,x] 	) `HappyStk` happyRest}}} -happyReduce_63 = happyReduce 5# 8# happyReduction_63-happyReduction_63 (happy_x_5 `HappyStk`+happyReduce_66 = happyReduce 5# 8# happyReduction_66+happyReduction_66 (happy_x_5 `HappyStk` 	happy_x_4 `HappyStk` 	happy_x_3 `HappyStk` 	happy_x_2 `HappyStk`@@ -959,8 +995,8 @@ 		 (\x -> happy_var_1(Ast "for" [happy_var_3,Avar "$",happy_var_5,x]) 	) `HappyStk` happyRest}}} -happyReduce_64 = happyReduce 7# 8# happyReduction_64-happyReduction_64 (happy_x_7 `HappyStk`+happyReduce_67 = happyReduce 7# 8# happyReduction_67+happyReduction_67 (happy_x_7 `HappyStk` 	happy_x_6 `HappyStk` 	happy_x_5 `HappyStk` 	happy_x_4 `HappyStk`@@ -976,8 +1012,8 @@ 		 (\x -> happy_var_1(Ast "for" [happy_var_3,happy_var_5,happy_var_7,x]) 	) `HappyStk` happyRest}}}} -happyReduce_65 = happySpecReduce_3  9# happyReduction_65-happyReduction_65 happy_x_3+happyReduce_68 = happySpecReduce_3  9# happyReduction_68+happyReduction_68 happy_x_3 	happy_x_2 	happy_x_1 	 =  case happyOut8 happy_x_1 of { happy_var_1 -> @@ -986,8 +1022,8 @@ 		 (\x -> Ast "let" [happy_var_1,happy_var_3,x] 	)}} -happyReduce_66 = happyReduce 5# 9# happyReduction_66-happyReduction_66 (happy_x_5 `HappyStk`+happyReduce_69 = happyReduce 5# 9# happyReduction_69+happyReduction_69 (happy_x_5 `HappyStk` 	happy_x_4 `HappyStk` 	happy_x_3 `HappyStk` 	happy_x_2 `HappyStk`@@ -1000,21 +1036,21 @@ 		 (\x -> happy_var_1(Ast "let" [happy_var_3,happy_var_5,x]) 	) `HappyStk` happyRest}}} -happyReduce_67 = happySpecReduce_2  10# happyReduction_67-happyReduction_67 happy_x_2+happyReduce_70 = happySpecReduce_2  10# happyReduction_70+happyReduction_70 happy_x_2 	happy_x_1 	 =  case happyOut9 happy_x_2 of { happy_var_2 ->  	happyIn14 		 (\x -> Ast "predicate" [happy_var_2,x] 	)} -happyReduce_68 = happySpecReduce_0  10# happyReduction_68-happyReduction_68  =  happyIn14+happyReduce_71 = happySpecReduce_0  10# happyReduction_71+happyReduction_71  =  happyIn14 		 (id 	) -happyReduce_69 = happySpecReduce_3  11# happyReduction_69-happyReduction_69 happy_x_3+happyReduce_72 = happySpecReduce_3  11# happyReduction_72+happyReduction_72 happy_x_3 	happy_x_2 	happy_x_1 	 =  case happyOut16 happy_x_3 of { happy_var_3 -> @@ -1023,13 +1059,13 @@                                                            \x -> Ast "sort" (x:(snd happy_var_3))) 	)} -happyReduce_70 = happySpecReduce_0  11# happyReduction_70-happyReduction_70  =  happyIn15+happyReduce_73 = happySpecReduce_0  11# happyReduction_73+happyReduction_73  =  happyIn15 		 ((id,id) 	) -happyReduce_71 = happySpecReduce_2  12# happyReduction_71-happyReduction_71 happy_x_2+happyReduce_74 = happySpecReduce_2  12# happyReduction_74+happyReduction_74 happy_x_2 	happy_x_1 	 =  case happyOut9 happy_x_1 of { happy_var_1 ->  	case happyOut17 happy_x_2 of { happy_var_2 -> @@ -1037,8 +1073,8 @@ 		 (([happy_var_1],[happy_var_2]) 	)}} -happyReduce_72 = happyReduce 4# 12# happyReduction_72-happyReduction_72 (happy_x_4 `HappyStk`+happyReduce_75 = happyReduce 4# 12# happyReduction_75+happyReduction_75 (happy_x_4 `HappyStk` 	happy_x_3 `HappyStk` 	happy_x_2 `HappyStk` 	happy_x_1 `HappyStk`@@ -1050,25 +1086,25 @@ 		 (((fst happy_var_1)++[happy_var_3],(snd happy_var_1)++[happy_var_4]) 	) `HappyStk` happyRest}}} -happyReduce_73 = happySpecReduce_1  13# happyReduction_73-happyReduction_73 happy_x_1+happyReduce_76 = happySpecReduce_1  13# happyReduction_76+happyReduction_76 happy_x_1 	 =  happyIn17 		 (Avar "ascending" 	) -happyReduce_74 = happySpecReduce_1  13# happyReduction_74-happyReduction_74 happy_x_1+happyReduce_77 = happySpecReduce_1  13# happyReduction_77+happyReduction_77 happy_x_1 	 =  happyIn17 		 (Avar "descending" 	) -happyReduce_75 = happySpecReduce_0  13# happyReduction_75-happyReduction_75  =  happyIn17+happyReduce_78 = happySpecReduce_0  13# happyReduction_78+happyReduction_78  =  happyIn17 		 (Avar "ascending" 	) -happyReduce_76 = happyReduce 4# 14# happyReduction_76-happyReduction_76 (happy_x_4 `HappyStk`+happyReduce_79 = happyReduce 4# 14# happyReduction_79+happyReduction_79 (happy_x_4 `HappyStk` 	happy_x_3 `HappyStk` 	happy_x_2 `HappyStk` 	happy_x_1 `HappyStk`@@ -1078,8 +1114,8 @@ 		 (call "element" [Avar happy_var_3] 	) `HappyStk` happyRest} -happyReduce_77 = happyReduce 4# 14# happyReduction_77-happyReduction_77 (happy_x_4 `HappyStk`+happyReduce_80 = happyReduce 4# 14# happyReduction_80+happyReduction_80 (happy_x_4 `HappyStk` 	happy_x_3 `HappyStk` 	happy_x_2 `HappyStk` 	happy_x_1 `HappyStk`@@ -1089,8 +1125,8 @@ 		 (call "attribute" [Avar happy_var_3] 	) `HappyStk` happyRest} -happyReduce_78 = happyReduce 6# 15# happyReduction_78-happyReduction_78 (happy_x_6 `HappyStk`+happyReduce_81 = happyReduce 6# 15# happyReduction_81+happyReduction_81 (happy_x_6 `HappyStk` 	happy_x_5 `HappyStk` 	happy_x_4 `HappyStk` 	happy_x_3 `HappyStk`@@ -1107,8 +1143,8 @@                                                                                    ++(show (head happy_var_1))++" '"++happy_var_5++"'")] 	) `HappyStk` happyRest}}} -happyReduce_79 = happyReduce 5# 15# happyReduction_79-happyReduction_79 (happy_x_5 `HappyStk`+happyReduce_82 = happyReduce 5# 15# happyReduction_82+happyReduction_82 (happy_x_5 `HappyStk` 	happy_x_4 `HappyStk` 	happy_x_3 `HappyStk` 	happy_x_2 `HappyStk`@@ -1123,16 +1159,16 @@                                                                                    ++(show (head happy_var_1))++" '"++happy_var_4++"'")] 	) `HappyStk` happyRest}} -happyReduce_80 = happySpecReduce_2  15# happyReduction_80-happyReduction_80 happy_x_2+happyReduce_83 = happySpecReduce_2  15# happyReduction_83+happyReduction_83 happy_x_2 	happy_x_1 	 =  case happyOut20 happy_x_1 of { happy_var_1 ->  	happyIn19 		 (Ast "element_construction" (happy_var_1++[Ast "append" []]) 	)} -happyReduce_81 = happyReduce 7# 15# happyReduction_81-happyReduction_81 (happy_x_7 `HappyStk`+happyReduce_84 = happyReduce 7# 15# happyReduction_84+happyReduction_84 (happy_x_7 `HappyStk` 	happy_x_6 `HappyStk` 	happy_x_5 `HappyStk` 	happy_x_4 `HappyStk`@@ -1146,8 +1182,8 @@ 		 (Ast "element_construction" [happy_var_3,Ast "attributes" [],concatenateAll happy_var_6] 	) `HappyStk` happyRest}} -happyReduce_82 = happyReduce 7# 15# happyReduction_82-happyReduction_82 (happy_x_7 `HappyStk`+happyReduce_85 = happyReduce 7# 15# happyReduction_85+happyReduction_85 (happy_x_7 `HappyStk` 	happy_x_6 `HappyStk` 	happy_x_5 `HappyStk` 	happy_x_4 `HappyStk`@@ -1161,8 +1197,8 @@ 		 (Ast "attribute_construction" [happy_var_3,concatenateAll happy_var_6] 	) `HappyStk` happyRest}} -happyReduce_83 = happyReduce 5# 15# happyReduction_83-happyReduction_83 (happy_x_5 `HappyStk`+happyReduce_86 = happyReduce 5# 15# happyReduction_86+happyReduction_86 (happy_x_5 `HappyStk` 	happy_x_4 `HappyStk` 	happy_x_3 `HappyStk` 	happy_x_2 `HappyStk`@@ -1174,8 +1210,8 @@ 		 (Ast "element_construction" [Astring happy_var_2,Ast "attributes" [],concatenateAll happy_var_4] 	) `HappyStk` happyRest}} -happyReduce_84 = happyReduce 5# 15# happyReduction_84-happyReduction_84 (happy_x_5 `HappyStk`+happyReduce_87 = happyReduce 5# 15# happyReduction_87+happyReduction_87 (happy_x_5 `HappyStk` 	happy_x_4 `HappyStk` 	happy_x_3 `HappyStk` 	happy_x_2 `HappyStk`@@ -1187,16 +1223,16 @@ 		 (Ast "attribute_construction" [Astring happy_var_2,concatenateAll happy_var_4] 	) `HappyStk` happyRest}} -happyReduce_85 = happySpecReduce_2  16# happyReduction_85-happyReduction_85 happy_x_2+happyReduce_88 = happySpecReduce_2  16# happyReduction_88+happyReduction_88 happy_x_2 	happy_x_1 	 =  case happyOut6 happy_x_2 of { happy_var_2 ->  	happyIn20 		 ([Astring happy_var_2,Ast "attributes" []] 	)} -happyReduce_86 = happySpecReduce_3  16# happyReduction_86-happyReduction_86 happy_x_3+happyReduce_89 = happySpecReduce_3  16# happyReduction_89+happyReduction_89 happy_x_3 	happy_x_2 	happy_x_1 	 =  case happyOut6 happy_x_2 of { happy_var_2 -> @@ -1205,8 +1241,8 @@ 		 ([Astring happy_var_2,Ast "attributes" happy_var_3] 	)}} -happyReduce_87 = happySpecReduce_3  17# happyReduction_87-happyReduction_87 happy_x_3+happyReduce_90 = happySpecReduce_3  17# happyReduction_90+happyReduction_90 happy_x_3 	happy_x_2 	happy_x_1 	 =  case happyOut10 happy_x_2 of { happy_var_2 -> @@ -1214,29 +1250,29 @@ 		 ([concatenateAll happy_var_2] 	)} -happyReduce_88 = happySpecReduce_1  17# happyReduction_88-happyReduction_88 happy_x_1+happyReduce_91 = happySpecReduce_1  17# happyReduction_91+happyReduction_91 happy_x_1 	 =  case happyOutTok happy_x_1 of { (TString happy_var_1) ->  	happyIn21 		 ([Astring happy_var_1] 	)} -happyReduce_89 = happySpecReduce_1  17# happyReduction_89-happyReduction_89 happy_x_1+happyReduce_92 = happySpecReduce_1  17# happyReduction_92+happyReduction_92 happy_x_1 	 =  case happyOutTok happy_x_1 of { (XMLtext happy_var_1) ->  	happyIn21 		 ([Astring happy_var_1] 	)} -happyReduce_90 = happySpecReduce_1  17# happyReduction_90-happyReduction_90 happy_x_1+happyReduce_93 = happySpecReduce_1  17# happyReduction_93+happyReduction_93 happy_x_1 	 =  case happyOut19 happy_x_1 of { happy_var_1 ->  	happyIn21 		 ([happy_var_1] 	)} -happyReduce_91 = happyReduce 4# 17# happyReduction_91-happyReduction_91 (happy_x_4 `HappyStk`+happyReduce_94 = happyReduce 4# 17# happyReduction_94+happyReduction_94 (happy_x_4 `HappyStk` 	happy_x_3 `HappyStk` 	happy_x_2 `HappyStk` 	happy_x_1 `HappyStk`@@ -1247,8 +1283,8 @@ 		 (happy_var_1++[concatenateAll happy_var_3] 	) `HappyStk` happyRest}} -happyReduce_92 = happySpecReduce_2  17# happyReduction_92-happyReduction_92 happy_x_2+happyReduce_95 = happySpecReduce_2  17# happyReduction_95+happyReduction_95 happy_x_2 	happy_x_1 	 =  case happyOut21 happy_x_1 of { happy_var_1 ->  	case happyOutTok happy_x_2 of { (TString happy_var_2) -> @@ -1256,8 +1292,8 @@ 		 (happy_var_1++[Astring happy_var_2] 	)}} -happyReduce_93 = happySpecReduce_2  17# happyReduction_93-happyReduction_93 happy_x_2+happyReduce_96 = happySpecReduce_2  17# happyReduction_96+happyReduction_96 happy_x_2 	happy_x_1 	 =  case happyOut21 happy_x_1 of { happy_var_1 ->  	case happyOutTok happy_x_2 of { (XMLtext happy_var_2) -> @@ -1265,8 +1301,8 @@ 		 (happy_var_1++[Astring happy_var_2] 	)}} -happyReduce_94 = happySpecReduce_2  17# happyReduction_94-happyReduction_94 happy_x_2+happyReduce_97 = happySpecReduce_2  17# happyReduction_97+happyReduction_97 happy_x_2 	happy_x_1 	 =  case happyOut21 happy_x_1 of { happy_var_1 ->  	case happyOut19 happy_x_2 of { happy_var_2 -> @@ -1274,22 +1310,22 @@ 		 (happy_var_1++[happy_var_2] 	)}} -happyReduce_95 = happySpecReduce_1  18# happyReduction_95-happyReduction_95 happy_x_1+happyReduce_98 = happySpecReduce_1  18# happyReduction_98+happyReduction_98 happy_x_1 	 =  case happyOut23 happy_x_1 of { happy_var_1 ->  	happyIn22 		 (if length happy_var_1 == 1 then head happy_var_1 else Ast "append" happy_var_1 	)} -happyReduce_96 = happySpecReduce_1  19# happyReduction_96-happyReduction_96 happy_x_1+happyReduce_99 = happySpecReduce_1  19# happyReduction_99+happyReduction_99 happy_x_1 	 =  case happyOutTok happy_x_1 of { (TString happy_var_1) ->  	happyIn23 		 (if happy_var_1=="" then [] else [Astring happy_var_1] 	)} -happyReduce_97 = happySpecReduce_3  19# happyReduction_97-happyReduction_97 happy_x_3+happyReduce_100 = happySpecReduce_3  19# happyReduction_100+happyReduction_100 happy_x_3 	happy_x_2 	happy_x_1 	 =  case happyOut10 happy_x_2 of { happy_var_2 -> @@ -1297,8 +1333,8 @@ 		 ([concatenateAll happy_var_2] 	)} -happyReduce_98 = happySpecReduce_2  19# happyReduction_98-happyReduction_98 happy_x_2+happyReduce_101 = happySpecReduce_2  19# happyReduction_101+happyReduction_101 happy_x_2 	happy_x_1 	 =  case happyOut23 happy_x_1 of { happy_var_1 ->  	case happyOutTok happy_x_2 of { (TString happy_var_2) -> @@ -1306,8 +1342,8 @@ 		 (if happy_var_2=="" then happy_var_1 else happy_var_1++[Astring happy_var_2] 	)}} -happyReduce_99 = happyReduce 4# 19# happyReduction_99-happyReduction_99 (happy_x_4 `HappyStk`+happyReduce_102 = happyReduce 4# 19# happyReduction_102+happyReduction_102 (happy_x_4 `HappyStk` 	happy_x_3 `HappyStk` 	happy_x_2 `HappyStk` 	happy_x_1 `HappyStk`@@ -1318,8 +1354,8 @@ 		 (happy_var_1++[concatenateAll happy_var_3] 	) `HappyStk` happyRest}} -happyReduce_100 = happySpecReduce_3  20# happyReduction_100-happyReduction_100 happy_x_3+happyReduce_103 = happySpecReduce_3  20# happyReduction_103+happyReduction_103 happy_x_3 	happy_x_2 	happy_x_1 	 =  case happyOut6 happy_x_1 of { happy_var_1 -> @@ -1328,8 +1364,8 @@ 		 ([Ast "pair" [Astring happy_var_1,happy_var_3]] 	)}} -happyReduce_101 = happyReduce 4# 20# happyReduction_101-happyReduction_101 (happy_x_4 `HappyStk`+happyReduce_104 = happyReduce 4# 20# happyReduction_104+happyReduction_104 (happy_x_4 `HappyStk` 	happy_x_3 `HappyStk` 	happy_x_2 `HappyStk` 	happy_x_1 `HappyStk`@@ -1341,8 +1377,8 @@ 		 (happy_var_1++[Ast "pair" [Astring happy_var_2,happy_var_4]] 	) `HappyStk` happyRest}}} -happyReduce_102 = happySpecReduce_2  21# happyReduction_102-happyReduction_102 happy_x_2+happyReduce_105 = happySpecReduce_2  21# happyReduction_105+happyReduction_105 happy_x_2 	happy_x_1 	 =  case happyOut29 happy_x_1 of { happy_var_1 ->  	case happyOut28 happy_x_2 of { happy_var_2 -> @@ -1350,8 +1386,8 @@ 		 (happy_var_1 "child" (Avar ".") happy_var_2 	)}} -happyReduce_103 = happySpecReduce_3  21# happyReduction_103-happyReduction_103 happy_x_3+happyReduce_106 = happySpecReduce_3  21# happyReduction_106+happyReduction_106 happy_x_3 	happy_x_2 	happy_x_1 	 =  case happyOut29 happy_x_2 of { happy_var_2 -> @@ -1360,8 +1396,8 @@ 		 (happy_var_2 "attribute" (Avar ".") happy_var_3 	)}} -happyReduce_104 = happySpecReduce_3  21# happyReduction_104-happyReduction_104 happy_x_3+happyReduce_107 = happySpecReduce_3  21# happyReduction_107+happyReduction_107 happy_x_3 	happy_x_2 	happy_x_1 	 =  case happyOut29 happy_x_1 of { happy_var_1 -> @@ -1371,8 +1407,8 @@ 		 (happy_var_3 (happy_var_1 "child" (Avar ".") happy_var_2) 	)}}} -happyReduce_105 = happyReduce 4# 21# happyReduction_105-happyReduction_105 (happy_x_4 `HappyStk`+happyReduce_108 = happyReduce 4# 21# happyReduction_108+happyReduction_108 (happy_x_4 `HappyStk` 	happy_x_3 `HappyStk` 	happy_x_2 `HappyStk` 	happy_x_1 `HappyStk`@@ -1384,15 +1420,15 @@ 		 (happy_var_4 (happy_var_2 "attribute" (Avar ".") happy_var_3) 	) `HappyStk` happyRest}}} -happyReduce_106 = happySpecReduce_1  22# happyReduction_106-happyReduction_106 happy_x_1+happyReduce_109 = happySpecReduce_1  22# happyReduction_109+happyReduction_109 happy_x_1 	 =  case happyOut27 happy_x_1 of { happy_var_1 ->  	happyIn26 		 (happy_var_1 	)} -happyReduce_107 = happySpecReduce_2  22# happyReduction_107-happyReduction_107 happy_x_2+happyReduce_110 = happySpecReduce_2  22# happyReduction_110+happyReduction_110 happy_x_2 	happy_x_1 	 =  case happyOut26 happy_x_1 of { happy_var_1 ->  	case happyOut27 happy_x_2 of { happy_var_2 -> @@ -1400,8 +1436,8 @@ 		 (happy_var_2 . happy_var_1 	)}} -happyReduce_108 = happySpecReduce_3  23# happyReduction_108-happyReduction_108 happy_x_3+happyReduce_111 = happySpecReduce_3  23# happyReduction_111+happyReduction_111 happy_x_3 	happy_x_2 	happy_x_1 	 =  case happyOut29 happy_x_2 of { happy_var_2 -> @@ -1410,8 +1446,8 @@ 		 (\e -> happy_var_2 "child" e happy_var_3 	)}} -happyReduce_109 = happyReduce 4# 23# happyReduction_109-happyReduction_109 (happy_x_4 `HappyStk`+happyReduce_112 = happyReduce 4# 23# happyReduction_112+happyReduction_112 (happy_x_4 `HappyStk` 	happy_x_3 `HappyStk` 	happy_x_2 `HappyStk` 	happy_x_1 `HappyStk`@@ -1422,8 +1458,8 @@ 		 (\e -> happy_var_3 "attribute" e happy_var_4 	) `HappyStk` happyRest}} -happyReduce_110 = happyReduce 4# 23# happyReduction_110-happyReduction_110 (happy_x_4 `HappyStk`+happyReduce_113 = happyReduce 4# 23# happyReduction_113+happyReduction_113 (happy_x_4 `HappyStk` 	happy_x_3 `HappyStk` 	happy_x_2 `HappyStk` 	happy_x_1 `HappyStk`@@ -1434,8 +1470,8 @@ 		 (\e -> happy_var_3 "descendant-or-self" e happy_var_4 	) `HappyStk` happyRest}} -happyReduce_111 = happyReduce 5# 23# happyReduction_111-happyReduction_111 (happy_x_5 `HappyStk`+happyReduce_114 = happyReduce 5# 23# happyReduction_114+happyReduction_114 (happy_x_5 `HappyStk` 	happy_x_4 `HappyStk` 	happy_x_3 `HappyStk` 	happy_x_2 `HappyStk`@@ -1447,15 +1483,15 @@ 		 (\e -> happy_var_4 "attribute-descendant" e happy_var_5 	) `HappyStk` happyRest}} -happyReduce_112 = happySpecReduce_2  23# happyReduction_112-happyReduction_112 happy_x_2+happyReduce_115 = happySpecReduce_2  23# happyReduction_115+happyReduction_115 happy_x_2 	happy_x_1 	 =  happyIn27 		 (\e -> Ast "step" [Avar "parent",Astring "*",e] 	) -happyReduce_113 = happyReduce 4# 24# happyReduction_113-happyReduction_113 (happy_x_4 `HappyStk`+happyReduce_116 = happyReduce 4# 24# happyReduction_116+happyReduction_116 (happy_x_4 `HappyStk` 	happy_x_3 `HappyStk` 	happy_x_2 `HappyStk` 	happy_x_1 `HappyStk`@@ -1466,13 +1502,13 @@ 		 (happy_var_1 ++ [happy_var_3] 	) `HappyStk` happyRest}} -happyReduce_114 = happySpecReduce_0  24# happyReduction_114-happyReduction_114  =  happyIn28+happyReduce_117 = happySpecReduce_0  24# happyReduction_117+happyReduction_117  =  happyIn28 		 ([] 	) -happyReduce_115 = happySpecReduce_1  25# happyReduction_115-happyReduction_115 happy_x_1+happyReduce_118 = happySpecReduce_1  25# happyReduction_118+happyReduction_118 happy_x_1 	 =  case happyOut30 happy_x_1 of { happy_var_1 ->  	happyIn29 		 (\t e ps -> if null ps@@ -1480,14 +1516,14 @@                                                                      else Ast "filter" (happy_var_1 t e:ps) 	)} -happyReduce_116 = happySpecReduce_1  25# happyReduction_116-happyReduction_116 happy_x_1+happyReduce_119 = happySpecReduce_1  25# happyReduction_119+happyReduction_119 happy_x_1 	 =  happyIn29 		 (\t e ps -> Ast "step" ((Avar t):(Astring "*"):e:ps) 	) -happyReduce_117 = happySpecReduce_1  25# happyReduction_117-happyReduction_117 happy_x_1+happyReduce_120 = happySpecReduce_1  25# happyReduction_120+happyReduction_120 happy_x_1 	 =  case happyOut6 happy_x_1 of { happy_var_1 ->  	happyIn29 		 (\t e ps -> if elem happy_var_1 path_steps@@ -1495,8 +1531,8 @@                                                                      else Ast "step" ((Avar t):(Astring happy_var_1):e:ps) 	)} -happyReduce_118 = happyReduce 4# 25# happyReduction_118-happyReduction_118 (happy_x_4 `HappyStk`+happyReduce_121 = happyReduce 4# 25# happyReduction_121+happyReduction_121 (happy_x_4 `HappyStk` 	happy_x_3 `HappyStk` 	happy_x_2 `HappyStk` 	happy_x_1 `HappyStk`@@ -1511,8 +1547,8 @@                                                                      else parseError [TError ("Not a valid axis name: "++happy_var_1)] 	) `HappyStk` happyRest}} -happyReduce_119 = happyReduce 4# 25# happyReduction_119-happyReduction_119 (happy_x_4 `HappyStk`+happyReduce_122 = happyReduce 4# 25# happyReduction_122+happyReduction_122 (happy_x_4 `HappyStk` 	happy_x_3 `HappyStk` 	happy_x_2 `HappyStk` 	happy_x_1 `HappyStk`@@ -1526,21 +1562,21 @@                                                                      else parseError [TError ("Not a valid axis name: "++happy_var_1)] 	) `HappyStk` happyRest} -happyReduce_120 = happySpecReduce_1  26# happyReduction_120-happyReduction_120 happy_x_1+happyReduce_123 = happySpecReduce_1  26# happyReduction_123+happyReduction_123 happy_x_1 	 =  case happyOut8 happy_x_1 of { happy_var_1 ->  	happyIn30 		 (\_ _ -> happy_var_1 	)} -happyReduce_121 = happySpecReduce_1  26# happyReduction_121-happyReduction_121 happy_x_1+happyReduce_124 = happySpecReduce_1  26# happyReduction_124+happyReduction_124 happy_x_1 	 =  happyIn30 		 (\_ e -> e 	) -happyReduce_122 = happySpecReduce_3  26# happyReduction_122-happyReduction_122 happy_x_3+happyReduce_125 = happySpecReduce_3  26# happyReduction_125+happyReduction_125 happy_x_3 	happy_x_2 	happy_x_1 	 =  case happyOut10 happy_x_2 of { happy_var_2 -> @@ -1550,15 +1586,15 @@ 	                                                          else Ast "context" [e,Astring t,concatenateAll happy_var_2] 	)} -happyReduce_123 = happySpecReduce_2  26# happyReduction_123-happyReduction_123 happy_x_2+happyReduce_126 = happySpecReduce_2  26# happyReduction_126+happyReduction_126 happy_x_2 	happy_x_1 	 =  happyIn30 		 (\_ _ -> call "empty" [] 	) -happyReduce_124 = happyReduce 4# 26# happyReduction_124-happyReduction_124 (happy_x_4 `HappyStk`+happyReduce_127 = happyReduce 4# 26# happyReduction_127+happyReduction_127 (happy_x_4 `HappyStk` 	happy_x_3 `HappyStk` 	happy_x_2 `HappyStk` 	happy_x_1 `HappyStk`@@ -1571,8 +1607,8 @@                                                                   else Ast "context" [e,Astring t,call happy_var_1 happy_var_3] 	) `HappyStk` happyRest}} -happyReduce_125 = happySpecReduce_3  26# happyReduction_125-happyReduction_125 happy_x_3+happyReduce_128 = happySpecReduce_3  26# happyReduction_128+happyReduction_128 happy_x_3 	happy_x_2 	happy_x_1 	 =  case happyOut6 happy_x_1 of { happy_var_1 -> @@ -1581,7 +1617,7 @@ 	)}  happyNewToken action sts stk [] =-	happyDoAction 72# notHappyAtAll action sts stk []+	happyDoAction 78# notHappyAtAll action sts stk []  happyNewToken action sts stk (tk:tks) = 	let cont i = happyDoAction i tk action sts stk tks in@@ -1652,11 +1688,17 @@ 	DOT -> cont 64#; 	SEMI -> cont 65#; 	COLON -> cont 66#;-	Variable happy_dollar_dollar -> cont 67#;-	XMLtext happy_dollar_dollar -> cont 68#;-	TInteger happy_dollar_dollar -> cont 69#;-	TFloat happy_dollar_dollar -> cont 70#;-	TString happy_dollar_dollar -> cont 71#;+	INSERT -> cont 67#;+	DELETE -> cont 68#;+	REPLACE -> cont 69#;+	INTO -> cont 70#;+	FROM -> cont 71#;+	WITH -> cont 72#;+	Variable happy_dollar_dollar -> cont 73#;+	XMLtext happy_dollar_dollar -> cont 74#;+	TInteger happy_dollar_dollar -> cont 75#;+	TFloat happy_dollar_dollar -> cont 76#;+	TString happy_dollar_dollar -> cont 77#; 	_ -> happyError' (tk:tks) 	} @@ -1753,7 +1795,8 @@   | AND | OR | NOT | UNION | INTERSECT | EXCEPT | FOR | LET | IN | COMMA   | ASSIGN | WHERE | ORDER | BY | ASCENDING | DESCENDING | ELEMENT   | ATTRIBUTE | STAG | ETAG | SATISFIES | ATSIGN | SLASH | DECLARE | SEMI | COLON-  | FUNCTION | VARIABLE |AT | DOT | DOTS | TokenEOF | PRE | POST | IS+  | FUNCTION | VARIABLE | AT | DOT | DOTS | TokenEOF | PRE | POST | IS+  | INSERT | INTO | DELETE | FROM | REPLACE | WITH   | QName String | Variable String | XMLtext String | TInteger Int   | TFloat Float | TString String | TError String     deriving Eq@@ -1783,6 +1826,7 @@              (BY,"by"),(ASCENDING,"ascending"),(DESCENDING,"descending"),(ELEMENT,"element"),              (ATTRIBUTE,"attribute"),(STAG,"</"),(ETAG,"/>"),(SATISFIES,"satisfies"),(ATSIGN,"@"),              (SLASH,"/"),(DECLARE,"declare"),(FUNCTION,"function"),(VARIABLE,"variable"),+  	     (INSERT,"insert"),(INTO,"into"),(DELETE,"delete"),(FROM,"from"),(REPLACE,"replace"),(WITH,"with"),              (AT,"at"),(DOTS,".."),(DOT,"."),(SEMI,";"),(COLON,":")]  @@ -1972,6 +2016,12 @@           "gt" -> SGT           "ge" -> SGE           "is" -> IS+	  "insert" -> INSERT+	  "into" -> INTO+	  "delete" -> DELETE+	  "from" -> FROM+	  "replace" -> REPLACE+	  "with" -> WITH           var -> QName var        ) : lexer rest n {-# LINE 1 "templates/GenericTemplate.hs" #-}
src/Text/XML/HXQ/XQuery.hs view
@@ -28,13 +28,13 @@        -- * The XQuery Interpreter        xquery, xfile,        -- * The XQuery Compiler with Database Connectivity-       xqdb, connect, disconnect,+       xqdb,        -- * The XQuery Interpreter with Database Connectivity        xqueryDB, xfileDB,        -- * Shredding and Publishing XML Documents Using a Relational Database        genSchema, shred, shredC, printSchema, createIndex,-       -- * Other functions-       XMLEvent(..), prepareSQL, executeSQL+       -- * Other Functions+       XMLEvent(..), connect, disconnect, commit, rollback, prepareSQL, executeSQL     ) where  import HXML(AttList)
src/Text/XML/HXQ/XTree.hs view
@@ -4,7 +4,7 @@ - Programmer: Leonidas Fegaras - Email: fegaras@cse.uta.edu - Web: http://lambda.uta.edu/-- Creation: 05/01/08, last update: 10/24/08+- Creation: 05/01/08, last update: 11/14/08 -  - Copyright (c) 2008 by Leonidas Fegaras, the University of Texas at Arlington. All rights reserved. - This material is provided as is, with absolutely no warranty expressed or implied.@@ -20,6 +20,7 @@ module Text.XML.HXQ.XTree where  import System.IO+import Char(isSpace) import XMLParse(XMLEvent(..)) import HXML(AttList) import Text.XML.HXQ.Parser(Ast(..))@@ -41,6 +42,7 @@            |  XGERef   Tag		-- ^ general entity reference            |  XComment String		-- ^ comment            |  XError   String		-- ^ error report+           |  XNull                     -- ^ null value            |  XNoPad                    -- ^ marker for no padding in XSeq            deriving Eq @@ -48,13 +50,26 @@ type XSeq = [XTree]  +emptyElem :: XTree -> Bool+emptyElem e+    = case e of+        XElem _ al _ _ xs+              -> emptyAL al && all emptyElem xs+        XText text -> all isSpace text+        XNull -> True+        XNoPad -> True+        _ -> False+      where emptyAL = all (\(a,v) -> case (a,v) of (_,"") -> True; ('_':_,_) -> True; _ -> False)++ showAL :: AttList -> String-showAL = foldr (\(a,v) r -> " "++a++"=\""++v++"\""++r) []+showAL = foldr (\(a,v) r -> case (a,v) of (_,"") -> r; ('_':_,_) -> r; _ -> " "++a++"=\""++v++"\""++r) []  showXT :: XTree -> Bool -> String showXT e pad     = case e of-        XElem tag al _ _ [] -> "<"++tag++showAL al++"/>"+        XElem _ _ _ _ _ | emptyElem e -> ""+        XElem tag al _ _ xs | all emptyElem xs -> "<"++tag++showAL al++"/>"         XElem tag al _ _ xs -> "<"++tag++showAL al++">"++showXS xs++"</"++tag++">"         XText text -> p++text         XInt n -> p++show n@@ -63,6 +78,7 @@         XComment s -> "<!--"++s++"-->"         XPI n s -> "<?"++n++" "++s++">"         XError s -> error s+        XNull -> "?"         _ -> ""       where p = if pad then " " else "" 
src/mysql/Connect.hs view
@@ -14,7 +14,7 @@ --------------------------------------------------------------------------------------}  -module Connect where+module Connect (Connection,connectionDriver,connect) where  import Database.HDBC(handleSqlError) import Database.HDBC.ODBC
src/noDB/Text/XML/HXQ/OptionalDB.hs view
@@ -24,13 +24,9 @@ type Statement = String type Table = String -class IConnection conn- data Connection = Connection String -instance IConnection Connection - noDBerror = error "This version of HXQ does not provide database connectivity"  @@ -42,7 +38,7 @@ executeSQL stmt args = noDBerror  -prepareSQL :: (IConnection conn) => conn -> String -> IO Statement+prepareSQL :: Connection -> String -> IO Statement prepareSQL db sql = noDBerror  @@ -55,18 +51,26 @@ disconnect db = noDBerror  +commit :: conn -> IO ()+commit db = noDBerror+++rollback :: conn -> IO ()+rollback db = noDBerror++ -- | Print the relational schema of the XML document stored in the database under the given name-printSchema :: (IConnection conn) => conn -> String -> IO ()+printSchema :: Connection -> String -> IO () printSchema db name = noDBerror   -- | Create a schema for an XML document into the database under the given name.-genSchema :: (IConnection conn) => conn -> String -> String -> IO Table+genSchema :: Connection -> String -> String -> IO Table genSchema db file name = noDBerror   -- | Store an XML document into the database under the given name.-shred :: (IConnection conn) => conn -> String -> String -> IO ()+shred :: Connection -> String -> String -> IO () shred db file name = noDBerror  @@ -76,5 +80,17 @@   -- | Create a secondary index on tagname for the shredded document under the given name..-createIndex :: (IConnection conn) => conn -> String -> String -> IO ()+createIndex :: Connection -> String -> String -> IO () createIndex db name tagname = noDBerror+++insertDB :: Connection -> XSeq -> XSeq -> IO XSeq+insertDB db from into = noDBerror+++deleteDB :: Connection -> XSeq -> IO XSeq+deleteDB db from = noDBerror+++replaceDB :: Connection -> XSeq -> XSeq -> IO XSeq+replaceDB db dest with = noDBerror
src/sqlite/Connect.hs view
@@ -14,8 +14,7 @@ --------------------------------------------------------------------------------------}  -module Connect where-+module Connect (Connection,connectionDriver,connect) where  import Database.HDBC.Sqlite3 
src/withDB/Text/XML/HXQ/DB.hs view
@@ -4,7 +4,7 @@ - Programmer: Leonidas Fegaras - Email: fegaras@cse.uta.edu - Web: http://lambda.uta.edu/-- Creation: 05/12/08, last update: 10/25/08+- Creation: 05/12/08, last update: 11/23/08 -  - Copyright (c) 2008 by Leonidas Fegaras, the University of Texas at Arlington. All rights reserved. - This material is provided as is, with absolutely no warranty expressed or implied.@@ -13,24 +13,24 @@ - --------------------------------------------------------------------------------------} --{-# OPTIONS_GHC -fth -funbox-strict-fields #-}+{-# LANGUAGE TemplateHaskell #-}+{-# OPTIONS_GHC -funbox-strict-fields #-}   module Text.XML.HXQ.DB where  import System.IO.Unsafe-import Char(isSpace,toLower)-import List(union,zip)+import Char(isSpace,isDigit,toLower)+import List(zip) import Data.List(foldl')-import Language.Haskell.TH import Database.HDBC import Text.XML.HXQ.XTree+import Text.XML.HXQ.Functions(child_step) import XMLParse(XMLEvent(..),parseDocument) import HXML(AttList) import Text.XML.HXQ.Parser import Connect-+import Language.Haskell.TH   sql2xml :: SqlValue -> XTree@@ -49,7 +49,7 @@       SqlRational n -> XText (show n)       SqlEpochTime n -> XText (show n)       SqlTimeDiff n -> XText (show n)-      SqlNull -> XText ""+      SqlNull -> XNull   xml2sql :: XTree -> SqlValue@@ -60,10 +60,10 @@       XFloat n -> SqlString (show n)       XBool n -> SqlBool n       XElem n _ _ _ [x] -> xml2sql x-      _ -> error ("Cannot convert "++show e++" into sql")+      _ -> error ("*** Cannot convert "++show e++" into sql")  -perror = error "constructed elements have no parent"+perror = error "Constructed elements do not have a parent"   executeSQL :: Statement -> XSeq -> IO XSeq@@ -71,15 +71,15 @@     = do n <- handleSqlError (execute stmt (map xml2sql args))          result <- handleSqlError (fetchAllRowsAL stmt)          return (map (\x -> XElem "row" [] 0 perror (map (\(s,v) -> XElem (column s) [] 0 perror [sql2xml v]) x)) result)-    where column s = if elem '.' s then tail(dropWhile (/= '.') s) else s+    where column s = if elem '.' s then tail (dropWhile (/= '.') s) else s  -prepareSQL :: (IConnection conn) => conn -> String -> IO Statement+prepareSQL :: Connection -> String -> IO Statement prepareSQL db sql = handleSqlError (prepare db sql)   {------------------------------------------------------------------------------------------ extract the structural summary and statistics from an XML file+-- Extract the structural summary and statistics from an XML file ----------------------------------------------------------------------------------------}  @@ -105,24 +105,31 @@       in (c,t:s)  -getSS :: [XMLEvent] -> Int -> [SSnode] -> [SSnode]-getSS ((EmptyEvent n atts):xs) count rs-    = (getSS ((StartEvent n atts):(EndEvent n):xs) $! count) $! rs-getSS ((StartEvent n atts):xs) count ((SSnode m i j l b len ns):rs)+getSS :: [XMLEvent] -> Int -> [String] -> [SSnode] -> [SSnode]+getSS ((EmptyEvent n atts):xs) count ignored rs+    = ((getSS ((StartEvent n atts):(EndEvent n):xs) $! count) $! ignored) $! rs+getSS ((StartEvent n atts):xs) count ignored rs+    | elem n ignored+    = ((getSS xs $! count) $! ignored) $! rs+getSS ((EndEvent n):xs) count ignored rs+    | elem n ignored+    = ((getSS xs $! count) $! ignored) $! rs+getSS ((StartEvent n atts):xs) count ignored ((SSnode m i j l b len ns):rs)     = let (c,SSnode m' i' j' l' b' len' ks,ts) = (insertSS n $! count) 0 $! ns           (nc,as) = foldr (\(a,v) (i,s) -> ((insSS ('@':a) $! i) $! (length v)) $! s) (c,ks) atts           r (SSnode m i j _ b len ts) = SSnode m i j 0 b len ts           reset (SSnode m i j l b len ts) = SSnode m i j l b len (map r ts)-      in (getSS xs $! nc) $! (reset (SSnode m' i' j' l' b' len' as):(SSnode m i j l b len ts):rs)-getSS ((EndEvent n):xs) count (t:(SSnode m i j l b len ns):rs)+      in ((getSS xs $! nc) $! ignored) $! (reset (SSnode m' i' j' l' b' len' as):(SSnode m i j l b len ts):rs)+getSS ((EndEvent n):xs) count ignored (t:(SSnode m i j l b len ns):rs)     = let s (SSnode m i j l b len ts) = SSnode m i (max j l) 0 b len ts           set (SSnode m i j l b len ts) = SSnode m i j l b len (map s ts)-      in (getSS xs $! count) $! ((SSnode m i j l b len (set t:ns):rs))-getSS ((TextEvent t):xs) count ((SSnode m i j l _ len ns):rs)+      in ((getSS xs $! count) $! ignored) $! ((SSnode m i j l b len (set t:ns):rs))+getSS ((TextEvent t):xs) count ignored ((SSnode m i j l _ len ns):rs)     | any (not . isSpace) t-    = (getSS xs $! count) $! ((SSnode m i j l True (max len (length t)) ns):rs)-getSS (_:xs) count rs = (getSS xs $! count) $! rs-getSS [] _ rs = rs+    = ((getSS xs $! count) $! ignored) $! ((SSnode m i j l True (max len (length t)) ns):rs)+getSS (_:xs) count ignored rs+    = ((getSS xs $! count) $! ignored) $! rs+getSS [] _ _ rs = rs   {---------------------------------------------------------------------------------------@@ -133,8 +140,8 @@ type Path = [Tag]  -data Table = Table String Path Bool [Table]-           | Column String Path Int+data Table = Table String Path Bool [Table]  -- table-name relative-path mixed-content? components+           | Column String Path Int          -- column-name relative-path max-byte-size            deriving (Show,Read)  @@ -149,44 +156,54 @@  schema :: SSnode -> String -> [String] -> [Table] schema (SSnode n i _ (-1) _ len ts) prefix path-    = [ Table (prefix++show i) (pathCons n path) True+    = [ Table (prefix++"_"++show i) (pathCons n path) True               ((reverse (concatMap (\t -> schema t prefix []) ts))                ++[ Column "value" [] len ]) ]-schema (SSnode n i j _ _ len []) prefix path-    | j == 1 || head n == '@'-    = [ Column (prefix++show i) (pathCons n path) len ]+schema (SSnode ('@':n) i j _ _ len []) prefix path+    = [ Column (prefix++"_"++show i) (pathCons ('@':n) path) len ]+schema (SSnode n i 1 _ _ len []) prefix path+    = [ Column (prefix++"_"++show i) (pathCons n path) len ] schema (SSnode n i 1 _ _ _ ts) prefix path-    = concatMap (\t -> schema t prefix (pathCons n path)) ts-schema (SSnode n i _ _ b len ts) prefix path-    = [ Table (prefix++show i) (pathCons n path) False+    = concatMap (\t -> schema t prefix (n:path)) ts+schema (t@(SSnode n i _ _ b len ts)) prefix path+    = [ Table (prefix++"_"++show i) (pathCons n path) False               ((reverse (concatMap (\t -> schema t prefix []) ts))+              ++concatMap (getContent []) ts               ++(if b && all (\(SSnode x _ _ _ _ _ _)-> head x == '@') ts                  then [ Column "value" [] len ] else [])) ]+      where getContent _ (SSnode _ _ _ (-1) _ _ ts) = []+            getContent ps (SSnode n i _ _ True len (_:_))+                = [Column (prefix++"_"++show i) (n:ps) len]+            getContent ps (SSnode n _ 1 _ _ _ ts)+                = concatMap (getContent (n:ps)) ts+            getContent _ _ = []  +-- if an element has both text content and subelements, then it must be mixed content; fixSS :: SSnode -> SSnode fixSS (SSnode n i j l True len ts)     | any (\(SSnode x _ _ _ _ _ _)-> head x /= '@') ts-    = SSnode n i j (-1) True len (filter (\(SSnode x _ _ _ _ _ _)-> head x == '@') ts)+    = SSnode n i j (-1) True len (map fixSS ts) fixSS (SSnode n i j l b len ts)     = SSnode n i j l b len (map fixSS ts)  -deriveSchema :: String -> String -> IO Table-deriveSchema file prefix+deriveSchema :: String -> String -> [String] -> IO Table+deriveSchema file prefix ignored     = do doc <- readFile file          let ts = parseDocument doc-             [SSnode _ _ _ _ _ _ [t]] = getSS ts 0 [SSnode "root" 1 1 1 False 0 []]+             [SSnode _ _ _ _ _ _ [t]] = getSS ts 0 ignored [SSnode "root" 1 1 1 False 0 []]              nt@(SSnode m i j l b len s) = fixSS t-         return $! (Table prefix [] False (reverse (schema (SSnode m i 2 l b len s) prefix [])))+         -- putStrLn (show nt)+         return $! (head (schema (SSnode m i 2 l b len s) prefix []))   relationalSchema :: Table -> String -> [String] relationalSchema (Table n path b ts) parent-    = ("create table "++n++" (      /* "++printPath path+    = ("\ncreate table "++n++" (      /* "++printPath path        ++(if b then " (mixed content)" else "")++" */\n"        ++n++"_id integer primary key not null"-       ++(if parent /= "" then (",\n"++n++"_parent integer references "++parent++"("++parent++"_id)") else "")+       ++",\n"++n++"_parent integer"++(if parent /= "" then (" references "++parent++"("++parent++"_id)") else "")        ++(concat [ ",\n"++m++" varchar("++show size++")    /* "++printPath p++" */" | Column m p size <- ts ])        ++")\n")       :[ s | t@(Table _ _ _ _) <- ts, s <- relationalSchema t n ]@@ -197,7 +214,7 @@ getTableNames _ = []  -initializeDB :: (IConnection conn) => conn -> IO ()+initializeDB :: Connection -> IO () initializeDB db     = do tbs <- getTables db        -- mySql always returns []          desc <- if null tbs && connectionDriver /= "sqlite"@@ -212,8 +229,8 @@             else return ()  -createSchema :: (IConnection conn) => conn -> String -> String -> IO Table-createSchema db file name+createSchema :: Connection -> String -> String -> [String] -> IO Table+createSchema db file name ignored     = do initializeDB db          stmt <- handleSqlError (prepare db "select summary from HXQCatalog where name = ?")          _ <- handleSqlError (execute stmt  [SqlString name])@@ -227,7 +244,7 @@                     _ <- handleSqlError (run db "delete from HXQCatalog where name = ?" [SqlString name])                     commit db             else return ()-         t <- deriveSchema file name+         t <- deriveSchema file name ignored          let schema = relationalSchema t ""          _ <- handleSqlError (run db "insert into HXQCatalog values (?,?,?,?,?)"                                       [SqlString name, SqlInteger 0, SqlString file,@@ -237,7 +254,14 @@          return $! t  -findSchema :: (IConnection conn) => conn -> String -> IO Table+-- | Create a schema for an XML document into the database under the given name.+-- The excluded tags are HTML tags to be ignored+genSchema :: Connection -> String -> String -> [String] -> IO Table+genSchema db file name excludedTags+    = createSchema db file (map toLower name) excludedTags+++findSchema :: Connection -> String -> IO Table findSchema db name     = do initializeDB db          stmt <- handleSqlError (prepare db "select summary from HXQCatalog where name = ?")@@ -246,11 +270,11 @@          if length result == 1             then let [[(_,SqlString s)]] = result                  in return $! ((read s)::Table)-            else error ("Schema "++name++" doesn't exist")+            else error ("*** Schema "++name++" doesn't exist")   -- | Print the relational schema of the XML document stored in the database under the given name-printSchema :: (IConnection conn) => conn -> String -> IO ()+printSchema :: Connection -> String -> IO () printSchema db name     = do initializeDB db          stmt <- handleSqlError (prepare db "select relational_schema from HXQCatalog where name = ?")@@ -259,7 +283,7 @@          if length result == 1             then let [[(_,SqlString s)]] = result                  in putStrLn s-            else error ("Schema "++name++" doesn't exist")+            else error ("*** Schema "++name++" doesn't exist")   {---------------------------------------------------------------------------------------@@ -268,10 +292,18 @@   findPath :: [Table] -> [String] -> Int -> Maybe (Int,Table)-findPath (t@(Table _ p _ s):ts) path _ | p == path = Just ((length s)-1,t)-findPath (t@(Column _ p _):ts) path n | p == path = Just (n,t)-findPath ((Table _ _ _ _):ts) path n = findPath ts path n-findPath (_:ts) path n = findPath ts path (n+1)+findPath (t@(Table _ p _ s):ts) path _+    | p == path+    = Just (length[ 1 | Column _ _ _ <- s]-1,t)+findPath (t@(Column _ p _):ts) path n+    | p == path+    = Just (n,t)+findPath ((Table _ _ _ s):ts) path n+    = let xs = findPath s path n+          xt = findPath ts path n+      in case xs of Nothing -> xt; _ -> xs+findPath (_:ts) path n+    = findPath ts path (n+1) findPath [] _ _ = Nothing  @@ -280,21 +312,13 @@     = populate ((StartEvent tag atts):(EndEvent tag):xs) ts n ps populate (x@(StartEvent tag atts):xs) ((t@(Table n path _ s)):ts) _ (p:ps)     = case findPath s (tag:p) 0 of-        Just (n,nt@(Table m _ True as))-            -> (-1,m):(popAtts atts as ++ showXTree xs 1 "")-               where showXTree ((EmptyEvent tag atts):xs) i s-                         = showXTree xs i (s++"<"++tag++showAL atts++"/>")-                     showXTree ((StartEvent tag atts):xs) i s-                         = showXTree xs (i+1) (s++"<"++tag++showAL atts++">")-                     showXTree ((EndEvent tag):xs) i s-                         = if i==1 then (n,s):(-2,m):(populate xs (t:ts) n (p:ps))-                           else showXTree xs (i-1) (s++"</"++tag++">")-                     showXTree ((TextEvent text):xs) i s = showXTree xs i (s++text)-                     showXTree (_:xs) i s = showXTree xs i s         Just (n,nt@(Table m _ _ as))             -> (-1,m):((popAtts atts as)++(populate xs (nt:t:ts) n ([]:p:ps)))         Just (n,nt)-            -> populate xs (nt:t:ts) n ((tag:p):ps)+            -> map (\(a,v) -> case findPath ts (('@':a):tag:p) 0 of+                                Just (n,_) -> (n,v)+                                Nothing -> error ("*** Unrecognized attribute: "++a)) atts+               ++ populate xs (nt:t:ts) n ((tag:p):ps)         Nothing -> populate xs (t:ts) 0 ((tag:p):ps)       where popAtts ((a,v):as) ks                 = let Just(m,_) = findPath ks ['@':a] 0@@ -314,11 +338,17 @@ populate [] ts n ps = []  -insert :: (IConnection conn) => conn -> [(Int,String)] -> Integer -> [(String,Int,Statement)] -> IO Integer-insert db xs id stmts = let (s,_,_,_) = m xs id 0 in s+insert :: [(Int,String)] -> Integer -> Integer -> [(String,Int,Statement)] -> IO (Integer,[(Int,String)])+insert xs id parent stmts = let (s,binds,rest,_) = m xs id parent+                            in if null rest+                               then do n <- s; return (n,binds)+                               else do n <- s+                                       (m,mb) <- insert rest n parent stmts+                                       return (m,mb++binds)     where m ((-1,m):xs) i p = let (s,el,xs',i') = ml xs (i+1) i                               in ((insertTuple m el i p) >> s,[],xs',i')           m ((k,m):xs) i p = (return i,[(k,m)],xs,i)+          m [] i p = (return i,[],[],i)           ml [] i p = (return i,[],[],i)           ml ((-2,m):xs) i p = (return i,[],xs,i)           ml xs i p = let (s,el,xs',i') = m xs i p@@ -329,42 +359,35 @@               = let (len,stmt) = foldr (\(a,l,s) r -> if m==a then (l,s) else r) (error "*** sql stmt not found") stmts                     tuple = map (\c -> find c e) [0..len]                     lift x = if x=="\NUL" then SqlNull else SqlString x-                in do _ <- handleSqlError (execute stmt-                                           (if i==id-                                            then SqlInteger i:(map lift tuple)-                                            else SqlInteger i:SqlInteger p:(map lift tuple)))+                in do -- putStrLn (m++show(show i:show p:tuple))+                      _ <- handleSqlError (execute stmt (SqlInteger i:SqlInteger p:(map lift tuple)))                       return i  --- | Create a schema for an XML document into the database under the given name.-genSchema :: (IConnection conn) => conn -> String -> String -> IO Table-genSchema db file name-    = createSchema db file (map toLower name)+tableStmt db root (Table n _ _ ts)+    = do let len = length[ 1 | Column _ _ _ <- ts ]-1+         stmt <- handleSqlError (prepare db ("insert into "++n++" values (?,?"+                                             ++(concatMap (\_ -> ",?") [0..len])++")"))+         l <- mapM (tableStmt db root) ts+         return $! ((n,len,stmt):(concat l))+tableStmt _ _ _ = return []   -- | Store an XML document into the database under the given name.-shred :: (IConnection conn) => conn -> String -> String -> IO ()+shred :: Connection -> String -> String -> IO () shred db file name     = do let prefix = map toLower name-         t <- findSchema db prefix-         --putStrLn (show t)-         let tableStmt (Table n _ _ ts)-                 = do let len = length[ 1 | Column _ _ _ <- ts ]-1-                      stmt <- handleSqlError (prepare db ("insert into "++n++" values ("-                                                          ++(if n==prefix then "" else "?,")++"?"-                                                          ++(concatMap (\_ -> ",?") [0..len])++")"))-                      l <- mapM tableStmt ts-                      return $! ((n,len,stmt):(concat l))-             tableStmt _ = return []-         stmts <- tableStmt t+         t@(Table root _ _ _) <- findSchema db prefix+         stmts <- tableStmt db root t          stmt1 <- prepare db "select next_id from HXQCatalog where name = ?"          _ <- execute stmt1 [SqlString prefix]          [[(_,SqlString ids)]] <- fetchAllRowsAL stmt1          doc <- readFile file-         let id = read ids+         let id = (read ids)+1              ts = parseDocument doc-             ic = (-1,prefix):(populate ts [t] 0 [[]] ++ [(-2,prefix)])-         new_id <- insert db ic id stmts+             ic = populate ts [Table prefix [] True [t]] 0 [[]]+         -- putStrLn (show ic)+         (new_id,_) <- insert ic id 0 stmts          stmt2 <- prepare db "update HXQCatalog set next_id = ? where name = ?"          execute stmt2 [SqlInteger new_id,SqlString prefix]          commit db@@ -372,13 +395,13 @@   -- | Create a secondary index on tagname for the shredded document under the given name..-createIndex :: (IConnection conn) => conn -> String -> String -> IO ()+createIndex :: Connection -> String -> String -> IO () createIndex db name tagname     = do let prefix = map toLower name          table <- findSchema db name          let indexes = getIndexes "" table          _ <- if null indexes-              then error ("there is no tagname: "++tagname)+              then error ("*** Tthere is no tagname: "++tagname)               else mapM (\(t,c) -> do -- putStrLn (t++" "++c)                                       stmt <- handleSqlError (prepare db ("create index "++t++"_"++c++" on "++t++" ("++c++")"))                                       handleSqlError (execute stmt [])) indexes@@ -396,7 +419,7 @@   {-# NOINLINE insertTuple #-}-insertTuple :: (IConnection conn) => conn -> Statement -> String -> Int+insertTuple :: Connection -> Statement -> String -> Int             -> [Integer] -> [[(Int,String)]] -> [[(Int,String)]] insertTuple db stmt nm len (id:parent:_) (c:cs)          = let find x xs = foldr (\(a,v) r -> if x==a then v else r) "\NUL" xs@@ -406,9 +429,7 @@                p = toInteger parent                query = unsafePerformIO                        (do -- putStrLn (nm++show(show i:show p:tuple))-                           catchSql (do execute stmt (if id==0-                                                      then SqlInteger i:(map lift tuple)-                                                      else SqlInteger i:SqlInteger p:(map lift tuple))+                           catchSql (do execute stmt (SqlInteger i:SqlInteger p:(map lift tuple))                                         return ())                                     (\ e -> putStrLn (show e++show cs))                            if mod id 10000 == 9999@@ -418,15 +439,16 @@            in query `seq` cs  -pushTuple :: (Int,String) -> [[(Int,String)]] -> [[(Int,String)]]-pushTuple a (x:xs) = (a:x):xs+pushColumn :: (Int,String) -> [[(Int,String)]] -> [[(Int,String)]]+pushColumn a (x:xs) = (a:x):xs   pushAttributes :: [(String,String)] -> [(Int,String)] -> [[(Int,String)]] -> [[(Int,String)]] pushAttributes atts ps (x:xs)     = ((map (\(a,v) -> findColumn a v ps) atts)++x):xs       where findColumn name value ps-                = foldr (\(i,a) r -> if a==name then (i,value) else r) (error ("column "++name++" not found")) ps+                = foldr (\(i,a) r -> if a==name then (i,value) else r)+                        (error ("*** Column "++name++" not found")) ps   dfa state stream values i ancs c@@ -442,63 +464,93 @@ shredC dbname file name   = unsafePerformIO (       do let prefix = map toLower name+             rev (Table n path b ts) = Table n (reverse path) b (map rev ts)+             rev (Column tag path len) = Column tag (reverse path) len          dbc <- connect dbname-         table <- findSchema dbc prefix-         let intE = litE . integerL . toInteger+         tbl <- findSchema dbc prefix+         let table = rev tbl+             intE = litE . integerL . toInteger              intP = litP . integerL . toInteger-             genCase table cols state pats c-                 = case table of-                     Column _ ['@':_] _-                         -> c state pats-                     Column nm path _-                         -> let col = findTag nm cols-                            in genPath (reverse path) state pats-                                   (\m ps -> (match (tupP [intP m,infixP (conP (mkName "TextEvent") [dp]) (mkName ":") rp])-                                              (normalB [| ($(intE m),pushTuple ($(intE col),$d) $cs,-                                                            $current,$ancestors,$r) |]) []):(c m ps))-                     Table nm path mixed ts-                         -> let cols = zip [2..] [ a | Column a _ _ <- ts ]-                                atts = [ (i,a) | (i,['@':a]) <- zip [2..] [ p | Column _ p _ <- ts ] ]-                            in genTuple (reverse path) nm atts state pats cols-                                   (\m -> foldr (\t r _ ps -> genCase t cols m ps r) c ts m)+             pathHead (Table _ (tag:_:_) _ _) = Just tag+             pathHead (Column _ (tag:_:_) _) = Just tag+             pathHead _ = Nothing+             filter _ [] = ([],[])+             filter tag ((Table n (p:ps) b s):ts)+                 | p == tag+                 = let (s1,s2) = filter tag ts+                   in ((Table n ps b s):s1,s2)+             filter tag ((Column n (p:ps) len):ts)+                 | p == tag+                 = let (s1,s2) = filter tag ts+                   in ((Column n ps len):s1,s2)+             filter tag (t:ts)+                 = let (s1,s2) = filter tag ts+                   in (s1,t:s2)              findTag tag = foldr (\(n,t) r -> if t==tag then n else r) (error "tag not found")-             findState state tag = foldr (\(b,t,a) r -> if t==tag && b==state then a else r) (-1)-             genTuple [] _ _ state pats _ c = c state pats-             genTuple (p:path) nm atts state pats cols c-                 = let after = findState state p pats-                   in if after >= 0-                      then genPath path after pats c-                      else let next = (length pats)+2-                               ncs = [| [] : $cs |]-                               ae xs = if null atts-                                       then [| $xs |]-                                       else [| pushAttributes $al $(listE (map (\(i,a) -> tupE [intE i,litE (stringL a)]) atts)) $xs |]-                           in [match (tupP [intP state,infixP (conP (mkName "StartEvent") [litP (stringL p),alp]) (mkName ":") rp])+             getColumns nm ts = zip [2..] [ a | Column a _ _ <- ts ]+             getAttributes nm ts = [ (i,a) | (i,['@':a]) <- zip [2..] [ p | Column _ p _ <- ts ] ]+             genCodeL [] state avail _+                 = (avail,[])+             genCodeL (x@(t:ts)) state avail cols+                 = case pathHead t of+                     Nothing+                         -> let (i1,c1) = genCode t state avail cols+                                (i2,c2) = genCodeL ts state i1 cols+                            in (i2,c1++c2)+                     Just tag -> let (s1,s2) = filter tag x+                                     (i1,c1) = genCodeL s1 avail (avail+1) cols+                                     (i2,c2) = if null s2 then (i1,[]) else genCodeL s2 state i1 cols+                                     atts = [ (findTag m cols,a) | Column m ['@':a] _ <- s1++s2  ]+                                 in (i2,skipTag tag state avail atts ++ c1 ++ c2)+             skipTag tag state avail atts+                 = let next = avail+                       ae xs = if null atts+                               then [| $xs |]+                               else [| pushAttributes $al $(listE (map (\(i,a) -> tupE [intE i,litE (stringL a)]) atts)) $xs |]+                   in [ match (tupP [intP state,infixP (conP (mkName "StartEvent") [litP (stringL tag),alp]) (mkName ":") rp])+                              (normalB [| ($(intE next),$(ae cs),$current,$ancestors,$r) |]) [],+                        match (tupP [intP next,infixP (conP (mkName "EndEvent") [litP (stringL tag)]) (mkName ":") rp])+                              (normalB [| ($(intE state),$cs,$current,$ancestors,$r) |]) [],+                        match (tupP [intP state,infixP (conP (mkName "EmptyEvent") [litP (stringL tag),alp]) (mkName ":") rp])+                              (normalB [| ($(intE state),$(ae cs),$current,$ancestors,$r) |]) []]+             genCode (Column "value" [] _) state avail cols+                 = (avail,[ match (tupP [intP state,infixP (conP (mkName "TextEvent") [dp]) (mkName ":") rp])+                                  (normalB [| ($(intE state),pushColumn ($(intE (findTag "value" cols)),$d) $cs,+                                               $current,$ancestors,$r) |]) [] ])+             genCode (Column nm ['@':tag] _) state avail _+                 = (avail,[])+             genCode (Column nm [] _) state avail cols+                 = (avail,[ match (tupP [intP state,infixP (conP (mkName "TextEvent") [dp]) (mkName ":") rp])+                                  (normalB [| ($(intE state),pushColumn ($(intE (findTag nm cols)),$d) $cs,+                                               $current,$ancestors,$r) |]) [] ])+             genCode (Table nm [tag] mixed ts) state avail _+                 = let next = avail+                       ncs = [| [] : $cs |]+                       cols = getColumns nm ts+                       atts = getAttributes nm ts+                       ae xs = if null atts+                               then [| $xs |]+                               else [| pushAttributes $al $(listE (map (\(i,a) -> tupE [intE i,litE (stringL a)]) atts)) $xs |]+                       (i,c) = genCodeL ts next (avail+1) cols+                   in (i,[ match (tupP [intP state,infixP (conP (mkName "StartEvent") [litP (stringL tag),alp]) (mkName ":") rp])                                          (normalB [| ($(intE next),$(ae ncs),$current+1,($current+1) : $ancestors,$r) |]) [],-                               match (tupP [intP next,infixP (conP (mkName "EndEvent") [litP (stringL p)]) (mkName ":") rp])+                           match (tupP [intP next,infixP (conP (mkName "EndEvent") [litP (stringL tag)]) (mkName ":") rp])                                          (normalB [| ($(intE state),-                                                       insertTuple $db $(varE (mkName (nm++"_stmt"))) $(litE (stringL p))+                                                       insertTuple $db $(varE (mkName (nm++"_stmt"))) $(litE (stringL nm))                                                                        $(intE ((length cols)+1)) $ancestors $cs,                                                       $current,tail $ancestors,$r) |]) [],-                               match (tupP [intP state,infixP (conP (mkName "EmptyEvent") [litP (stringL p),alp]) (mkName ":") rp])+                           match (tupP [intP state,infixP (conP (mkName "EmptyEvent") [litP (stringL tag),alp]) (mkName ":") rp])                                          (normalB [| ($(intE state),-                                                       insertTuple $db $(varE (mkName (nm++"_stmt"))) $(litE (stringL p))+                                                       insertTuple $db $(varE (mkName (nm++"_stmt"))) $(litE (stringL nm))                                                                        $(intE ((length cols)+1)) (($current+1) : $ancestors) $(ae ncs),-                                                      $current+1,$ancestors,$r) |]) []]-                                 ++(genPath path next ((state,p,next):pats) c)-             genPath [] state pats c = c state pats-             genPath (p:path) state pats c-                 = let after = findState state p pats-                   in if after >= 0-                      then genPath path after pats c-                      else let next = (length pats)+2-                           in [match (tupP [intP state,infixP (conP (mkName "StartEvent") [litP (stringL p),alp]) (mkName ":") rp])-                                         (normalB [| ($(intE next),$cs,$current,$ancestors,$r) |]) [],-                               match (tupP [intP next,infixP (conP (mkName "EndEvent") [litP (stringL p)]) (mkName ":") rp])-                                         (normalB [| ($(intE state),$cs,$current,$ancestors,$r) |]) [],-                               match (tupP [intP state,infixP (conP (mkName "EmptyEvent") [litP (stringL p),alp]) (mkName ":") rp])-                                         (normalB [| ($(intE state),$cs,$current,$ancestors,$r) |]) []]-                                 ++(genPath path next ((state,p,next):pats) c)+                                                      $current+1,$ancestors,$r) |]) [] ]+                           ++ c)+             genCode (Column nm (tag:path) k) state avail cols+                 = let (i,s) = genCode (Column nm path k) avail (avail+1) cols+                   in (i,skipTag tag state avail []++s)+             genCode (Table nm (tag:path) mixed ts) state avail cols+                 = let (i,s) = genCode (Table nm path mixed ts) avail (avail+1) cols+                   in (i,skipTag tag state avail []++s)              s = varE (mkName "s")              r = varE (mkName "r")              current = varE (mkName "i")@@ -512,26 +564,24 @@              rp = varP (mkName "r")              dp = varP (mkName "d")              alp = varP (mkName "al")+             (_,caseCode) = genCode table 1 2 []              code = lamE [sp,varP (mkName "i"),varP (mkName "ancs"),varP (mkName "cs")]                     (caseE (varE (mkName "s"))-                               ((genCase table [] 1 [] (\_ _ -> []))-                                ++[match (tupP [sp,infixP wildP (mkName ":") rp])-                                         (normalB [| ($s,$cs,$current,$ancestors,$r) |]) [],-                                   match wildP (normalB [| (0,[],1,[],[]) |]) []]))+                           (caseCode++[match (tupP [sp,infixP wildP (mkName ":") rp])+                                             (normalB [| ($s,$cs,$current,$ancestors,$r) |]) [],+                                       match wildP (normalB [| (0,[],1,[],[]) |]) []]))              tableStmt (Table n _ _ ts)                  = let len = length[ 1 | Column _ _ _ <- ts ]-1-                       ins = "insert into "++n++" values ("-                             ++(if n==prefix then "" else "?,")++"?"+                       ins = "insert into "++n++" values (?,?"                              ++(concatMap (\_ -> ",?") [0..len])++")"-                       stmt = [| handleSqlError (prepare $db $(litE (stringL ins))) |]+                       stmt = [| prepare $db $(litE (stringL ins)) |]                    in (n++"_stmt",stmt):concatMap tableStmt ts              tableStmt _ = []              mseq a v b = infixE (Just a) (varE (mkName ">>=")) (Just (lamE [varP (mkName v)] b))              ret = foldr (\(n,s) r -> mseq s n r)-                         [| do execute $(varE (mkName (prefix++"_stmt"))) [SqlInteger $id]-                               return $! dfa 1 $(varE (mkName "doc")) [[]] $id [0] $code |]+                         [| return $! dfa 1 $(varE (mkName "doc")) [[]] $id [0] $code |]                          (tableStmt table)-         -- runQ ret >>= putStrLn.pprint+         -- runQ code >>= putStrLn.pprint          return $! [| do d <- readFile $(litE (stringL file))                          let doc = parseDocument d                          db <- connect $(litE (stringL dbname))@@ -553,33 +603,35 @@   -- construct an XQuery (in string form) that extracts a shredded XML document-publishTable :: Table -> Bool -> String-publishTable table needsParent-    = "<root>{" ++ pubS (rev table) "()" id ++ "}</root>"-      where rev (Table n path b ts) = Table n (reverse path) b (map rev ts)-            rev (Column tag path len) = Column tag (reverse path) len-            pubS (Table n [] _ ts) _ _-                = "for $"++n++" in SQL(select(),from($"++n++"),true()) return " ++ pubLS ts n "()" id-            pubS (Table n (p:_) _ ts) parent c-                = c ("{for $"++n++" in SQL(select(),from($"++n++"),$"++n++"/"++n++"_parent eq $"-                     ++parent++"/"++parent++"_id) return "-                     ++"<"++p++">"-                     -- "{attribute {'_id'} {$"++n++"/"++n++"_id/text()}}"-                     -- ++",attribute {'_parent'} {"++(if needsParent then "$"++parent else "()")++"}}"-                     ++ pubLS ts n parent id ++ "</"++p++">}")+publishTable :: Table -> String -> Bool -> String+publishTable (table@(Table n _ _ _)) schema needsParent+    = "<root>{attribute {'_id'} {'0'},attribute {'_parent'} {()}"+      ++",attribute {'_table'} {'"++schema++" "++n++" "++n++"'}}"+      ++ pubS table "()" id ++ "</root>"+      where pubS (Table n (p:_) _ ts) parent c+                = c ("{for $"++n++" in SQL(select(),tables($"++n++"),"+                     ++(if parent == "()"+                        then "true()"+                        else "$"++n++"/"++n++"_parent eq $"++parent++"/"++parent++"_id")+                     ++") return <"++p++">"++header n n False++"}"++ pubLS ts n parent id ++ "</"++p++">}")             pubS (Column tag (('@':p):_) _) parent c-                = c ("attribute "++p++" {$"++parent++"/"++tag++"/text()}")+                = c ("{attribute "++p++" {$"++parent++"/"++tag++"/text()}}")             pubS (Column tag (p:_) _) parent c-                = c ("<"++p++">{$"++parent++"/"++tag++"/text()}</"++p++">")-            pubS (Column "value" [] _) parent c-                = c ("{$"++parent++"/value/text()}")+                = c ("<"++p++">"++header tag parent False++",$"++parent++"/"++tag++"/text()}</"++p++">")+            pubS (Column tag [] _) parent c+                = c ("{$"++parent++"/"++tag++"/text()}")+            header tag parent composite+                = "{attribute {'_id'} {$"++parent++"/"++parent++"_id/text()}"+                  ++",attribute {'_parent'} {"++(if needsParent && parent /= "()/()_id" then "$"++parent else "()")++"}"+                  ++",attribute {'_table'} {'"++schema++" "++parent++(if composite then " +" else " ")++tag++"'}"             pubLS [] _ _ c = c ""             pubLS (x@(t:ts)) n parent c                 = case head t of                     Nothing -> (pubS t n c)++(pubLS ts n parent c)                     Just tag -> let (s1,s2) = filter tag (reverse x)-                                in (mkE tag s1 c)++(if null s2 then "" else (","++pubLS s2 n parent id))-                  where mkE tag s c = "<"++tag++">"++pubLS s n parent c++"</"++tag++">"+                                in (mkE tag s1 c)++(if null s2 then "" else pubLS s2 n parent id)+                  where mkE tag s c+                            = "<"++tag++">"++header tag n True++"}"++pubLS s n parent c++"</"++tag++">"                         head (Table _ (p:_:_) _ _) = Just p                         head (Column _ (p:_:_) _) = Just p                         head _ = Nothing@@ -604,11 +656,170 @@     = let query = unsafePerformIO (publishWrapper filepath name)           [ast] = parse (scan query)       in ast-    where publishWrapper filepath name+    where rev (Table n path b ts) = Table n (reverse path) b (map rev ts)+          rev (Column tag path len) = Column tag (reverse path) len+          publishWrapper filepath name               = do let prefix = map toLower name                    db <- connect filepath                    table <- findSchema db prefix                    -- putStrLn (show table)-                   let query = publishTable table needsParent+                   let query = publishTable (rev table) prefix needsParent                    -- putStrLn query                    return $! query+++{----------------------------------------------------------------------------------------------------+--  Database updates+----------------------------------------------------------------------------------------------------}+++dbError :: Connection -> String -> IO a+dbError db msg = rollback db >> error ("*** "++msg)+++toStream :: XSeq -> [XMLEvent]+toStream ((XElem tag al _ _ ts):xs)+    = (StartEvent tag al):(toStream ts++((EndEvent tag):toStream xs))+toStream (x:xs) = (TextEvent (show x)):toStream xs+toStream [] = []+++insertChildren :: Connection -> String -> Table -> XSeq -> Int -> IO [(Int,String)]+insertChildren db schema table children parent+    = do stmts <- tableStmt db schema table+         stmt1 <- prepare db "select next_id from HXQCatalog where name = ?"+         execute stmt1 [SqlString schema]+         [[(_,SqlString ids)]] <- fetchAllRowsAL stmt1+         let id = (read ids)+1+             Table tag _ _ ts = table+             ic = populate (toStream children) [table,table] 0 [[],[]]+         (new_id,binds) <- insert ic id (toInteger parent) stmts+         stmt2 <- prepare db "update HXQCatalog set next_id = ? where name = ?"+         execute stmt2 [SqlInteger new_id,SqlString schema]+         return binds+++getDestinationTable :: Table -> String -> [Table]+getDestinationTable (x@(Table t _ _ ts)) tname+    | t == tname+    = [x]+getDestinationTable (Table t _ _ ts) tname+    = concatMap (\t -> getDestinationTable t tname) ts+getDestinationTable _ _ = []+++insertDB :: Connection -> XSeq -> XSeq -> IO XSeq+insertDB db from into+    = case into of+        [d@(XElem tag (("_table",tnm):_) id parent cs)]+            -> do let [schema,tableName,attrName] = words tnm+                  table <- findSchema db schema+                  let [dest@(Table _ _ _ tbs)] = getDestinationTable table tableName+                  if attrName == tableName+                     then insertChildren db schema dest from id+                     else do mapM (\x -> case x of+                                           XElem t _ _ _ ts+                                               -> if head attrName == '+'+                                                  then case [ z | z@(Table _ (tn:_) _ _) <- tbs, t==tn ] of+                                                         [Table tx (tn:_) tb s]+                                                             -> insertChildren db schema (Table tableName [] False [Table tx [tn] tb s]) from id+                                                         _ -> case child_step t d of+                                                                c@[XElem _ _ _ _ [XNull]]+                                                                    -> replaceDB db c ts >> return []+                                                                [] -> dbError db ("You cannot insert this element at this position: "++show x)+                                                                _ -> dbError db ("There is already an inserted element "+                                                                                 ++"at this position; use replace instead: "++show x)+                                                  else case child_step t d of+                                                         c@[XElem _ _ _ _ [XNull]]+                                                             -> replaceDB db c ts >> return []+                                                         [] -> dbError db ("You cannot insert this element at this position: "++show x)+                                                         _ -> dbError db ("There is already an inserted element "+                                                                          ++"at this position; use replace instead: "++show x)+                                           _ -> dbError db ("Incompatible insertion source: "++show x)+                                  ) from+                             return []+                  return from+        _ -> dbError db ("The insert destination must be a single persistent XML element: "++show into)+++removeTuples :: Connection -> String -> Table -> Integer -> IO ()+removeTuples db schema (Table n _ _ ts) parent+    = do stmt <- handleSqlError (prepare db ("select "++n++"_id from "++n++" where "++n++"_parent = ?"))+         handleSqlError (execute stmt [SqlInteger parent])+         result <- fetchAllRowsAL stmt+         case result of+           [[(_,SqlString ids)]]+               -> do let id = read ids+                     handleSqlError (run db ("delete from "++n++" where "++n++"_id = ?") [SqlInteger id])+                     mapM (\t -> removeTuples db schema t id) ts+                     return ()+           _ -> return ()+removeTuples _ _ _ _  = return ()+++getColumns (XElem tag (("_table",tnm):_) id parent cs)+    = let [schema,tableName,attrName] = words tnm+      in if head attrName == '+'+         then concatMap getColumns cs+         else [attrName]+getColumns _ = []+++deleteDB :: Connection -> XSeq -> IO XSeq+deleteDB db (x@(XElem tag (("_table",tnm):_) id parent cs):xs)+    = do let [schema,tableName,attrName] = words tnm+         if tableName /= attrName+            then mapM (\c -> handleSqlError (run db ("update "++tableName++" set "++c+                                                     ++" = NULL where "++tableName++"_id = ?")+                                                    [SqlInteger (toInteger id)]))+                      (getColumns x)+            else do table <- findSchema db schema+                    let [Table n _ _ ts] = getDestinationTable table tableName+                    handleSqlError (run db ("delete from "++n++" where "++n++"_id = ?")+                                           [SqlInteger (toInteger id)])+                    mapM (\t -> removeTuples db schema t (toInteger id)) ts+                    return [0]+         deleteDB db xs+deleteDB db (x:_) = dbError db ("You may only delete persistent XML elements: "++show x)+deleteDB _ [] = return []+++replaceDB :: Connection -> XSeq -> XSeq -> IO XSeq+replaceDB db dest with+    = case dest of+        [d@(XElem tag (("_table",tnm):_) id parent cs)]+            -> do let [schema,tableName,attrName] = words tnm+                      update x = do handleSqlError (run db ("update "++tableName++" set "++attrName+                                                            ++" = ? where "++tableName++"_id = ?")+                                                    [SqlString (show x),SqlInteger (toInteger id)])+                                    return []+                  table <- findSchema db schema+                  if tableName == attrName+                     then let [dest@(Table _ _ _ ts)] = getDestinationTable table tableName+                          in do handleSqlError (run db ("delete from "++tableName++" where "++tableName++"_id = ?")+                                                [SqlInteger (toInteger id)])+                                mapM (\t -> removeTuples db schema t (toInteger id)) ts+                                insertChildren db schema dest with id+                                return []+                     else case with of+                            [XElem t _ _ _ ts]+                                -> if t == tag+                                   then mapM (\w -> case w of+                                                      XNoPad -> return []+                                                      XElem t' _ _ _ _ +                                                          -> case child_step t' d of+                                                               [z] -> replaceDB db [z] [w]+                                                               _ -> dbError db ("The replace destination element tagged '"+                                                                                ++tag++"' does not have a child tagged '"++t'++"'")+                                                      _ -> if head attrName == '+'+                                                           then dbError db ("The destination element tagged '"+                                                                            ++tag++"' can only be replaced with another element")+                                                           else update w+                                             ) ts+                                   else dbError db ("The destination element tagged '"+                                                    ++tag++"' cannot be replaced with an element tagged '"++t++"'")+                            [x] | head attrName /= '+' -> update x+                            [] -> return []+                            _ -> dbError db ("The replace source must be a singleton value: "++show with)+                  return with+        _ -> dbError db ("The replace destination must be a single persistent XML element: "++show dest)
src/withDB/Text/XML/HXQ/OptionalDB.hs view
@@ -15,8 +15,8 @@   module Text.XML.HXQ.OptionalDB-    ( IConnection, Statement, publishXmlDoc, executeSQL, prepareSQL, connect, disconnect,-      genSchema, shred, shredC, printSchema, createIndex+    ( IConnection, Statement, Connection, publishXmlDoc, executeSQL, prepareSQL, connect, disconnect, commit, rollback,+      genSchema, shred, shredC, printSchema, createIndex, insertDB, deleteDB, replaceDB     ) where