cnc-spec-compiler (empty) → 0.2.0.0
raw patch · 32 files changed
+9817/−0 lines, 32 filesdep +Graphalyzedep +HUnitdep +HaXmlsetup-changed
Dependencies added: Graphalyze, HUnit, HaXml, ansi-terminal, array, base, binary, bytestring, containers, directory, fgl, filepath, haxr, hscurses, hubigraph, mtl, parsec, pretty, prettyclass, process, split, stringtable-atom, unix, zlib
Files
- Intel/Cnc/BenchSynth.hs +483/−0
- Intel/Cnc/EasyEmit.hs +531/−0
- Intel/Cnc/Spec/AST.hs +296/−0
- Intel/Cnc/Spec/CncGrammar.y +369/−0
- Intel/Cnc/Spec/CncGraph.hs +177/−0
- Intel/Cnc/Spec/CncLexer.x +217/−0
- Intel/Cnc/Spec/CncViz.hs +535/−0
- Intel/Cnc/Spec/Codegen/CodegenShared.hs +53/−0
- Intel/Cnc/Spec/Codegen/CppOld.hs +863/−0
- Intel/Cnc/Spec/Codegen/Haskell.hs +179/−0
- Intel/Cnc/Spec/Codegen/Plugins.hs +448/−0
- Intel/Cnc/Spec/Codegen/Plugins/Depends.hs +120/−0
- Intel/Cnc/Spec/Codegen/Plugins/ReductionDone.hs +31/−0
- Intel/Cnc/Spec/Codegen/Plugins/TagFunCorrectness.hs +104/−0
- Intel/Cnc/Spec/Curses.hs +412/−0
- Intel/Cnc/Spec/GatherGraph.hs +263/−0
- Intel/Cnc/Spec/Globals.hs +12/−0
- Intel/Cnc/Spec/GraphAnalysis.hs +185/−0
- Intel/Cnc/Spec/Main.hs +11/−0
- Intel/Cnc/Spec/MainExecutable.hs +711/−0
- Intel/Cnc/Spec/Passes/ReadHarch.hs +352/−0
- Intel/Cnc/Spec/Passes/TypeDef.hs +123/−0
- Intel/Cnc/Spec/SrcLoc.hs +379/−0
- Intel/Cnc/Spec/TagFun.hs +149/−0
- Intel/Cnc/Spec/TraceVacuum.hs +416/−0
- Intel/Cnc/Spec/Util.hs +240/−0
- Intel/Cnc/Spec/Version.hs +4/−0
- LICENSE +31/−0
- Setup.hs +42/−0
- cnc-spec-compiler.cabal +98/−0
- dist/build/cnc/cnc-tmp/Intel/Cnc/Spec/CncGrammar.hs +1440/−0
- dist/build/cnc/cnc-tmp/Intel/Cnc/Spec/CncLexer.hs +543/−0
+ Intel/Cnc/BenchSynth.hs view
@@ -0,0 +1,483 @@+{-# LANGUAGE OverloadedStrings, ScopedTypeVariables #-}++-- UNFINISHED!!! ++{- HOWTO RUN (current as of [2011.01.23]):+ ---------------------------------------+ For now this is an executable entrypoint itself (Main).++ runhaskell Intel/Cnc/BenchSynth.hs++ The resulting file can be built with:++ g++ -ltbb -ltbbmalloc test.cpp -o test.exe++ Assuming you've got the environment set up right for tbb....+ + -} +----------------------------------------------------------------------------------------------------+++-- module Intel.Cnc.BenchSynth where+module Main where++{- + The goal of this utility is to generate graph benchmarks with a certain set of features.++ This encompasses both kernel generation and graph generation.+ -}++import Intel.Cnc.Spec.AST+import Intel.Cnc.Spec.Util hiding (app)+import Intel.Cnc.Spec.MainExecutable as Comp+import Intel.Cnc.Spec.Codegen.CodegenShared+import Intel.Cnc.Spec.Codegen.CppOld++import Control.Monad+-- import Data.ByteString.Char8 hiding (putStrLn)+import Text.PrettyPrint.HughesPJ+import Text.PrettyPrint.HughesPJClass +import StringTable.Atom++--import GHC.Exts -- For IsString++-- FGL graphs:+import qualified Data.Graph.Inductive as G+import qualified Intel.Cnc.EasyEmit as EE+-- import Intel.Cnc.EasyEmit hiding (app, not, (&&), (==), (||))+import Intel.Cnc.EasyEmit hiding (not, (&&), (==), (||))++import Prelude hiding ((<), (>=))++-- type StringT = ByteString+type StringT = String++----------------------------------------------------------------------------------------------------++-- Rough draft #1:++-- A kernel takes an argument as input and produces a body given +data Kernel = Krn { arg :: Doc+ , body :: Emitter -> Doc+ }++-- Could make these safer if desired:+type NodeName = Atom+type CommandSnip = Doc+type ExprSnip = Doc++-- For each backend, the Emitter produces output to a given stream.+-- Given a destination, a expression codesnippet (argument), it+-- produces a command codesnippet.+type Emitter = NodeName -> ExprSnip -> CommandSnip++data GraphNode = ComputeNode Kernel+ | SharedMemNode++-- A graph consists of compute nodes and shared memory nodes+-- (e.g. steps and item collections).+type BenchGraph = G.Gr NodeName GraphNode++----------------------------------------------------------------------------------------------------+-- Rough draft #2++-- Doing chains of reductions first, then we'll try to generalize from there.++-- The end goal is a convenient set of combinators that allow the+-- description of arbitrary benchmark generators. Then on top of that+-- will be randomized/automatic benchmark generation.+++data TBBBenchConfig = TBBBenchConfig+ { freeReduces :: Bool + }+ deriving Show++default_tbb_bench_config = + TBBBenchConfig+ { freeReduces = False+ }+++debug_benchsynth = True++----------------------------------------------------------------------------------------------------+-- Reusable infrastructure -- not backend-specific.+----------------------------------------------------------------------------------------------------++type VarName = Syntax++-- A numeric computation on a single scalar.+-- Takes the name of a variable. +-- Emits a block of code and returns the name of a variable that contains the result.+-- data ScalarKernel = ScalarKernel (Syntax -> EasyEmit Syntax)+type ScalarKernel = (VarName -> EasyEmit VarName)+type ScalarKernel2 = (VarName -> VarName -> EasyEmit VarName)++-- Perform approximately n flops (where n is an expression returning int).+simpleFlops :: Type -> Syntax -> ScalarKernel+simpleFlops ty n = + -- ScalarKernel $ + \ inp -> do + tmp <- tmpvarinit ty inp+ comm$ " Simple "++ synToStr n ++" FLOPs kernel, input "++ + synToStr inp ++" output "++ synToStr tmp+-- forLoopSimple (0, fromInt (n `quot` 2)) $ \ ind -> do+ forLoopSimple (0, n/2) $ \ ind -> do+ set tmp ("2.0000001" * tmp)+ set tmp (tmp - inp)+ return tmp++-- A version with two arguments:+simpleFlops2 :: Type -> Syntax -> ScalarKernel2+-- simpleFlops2 ty n = +-- \ x y -> +-- do comm$ "Simple TWO argument "++ synToStr n ++" FLOPs kernel (combining two separate kernels):"+-- x1 <- simpleFlops ty (n/2) x+-- y1 <- simpleFlops ty (n/2) y+-- comm$ "END TWO argument kernel, output = " ++ synToStr (x1 + y1)+-- return (x1 + y1)++-- This one is associative and commutative:+simpleFlops2 ty flps = + \ x y -> + do comm$ "Simple TWO argument "++ synToStr flps ++" FLOPs kernel, inputs: "+++ synToStr x ++" "++ synToStr y+ tmp <- tmpvarinit ty (x + y)+ forLoopSimple (0, flps) $ \ _ -> set tmp ("0.0000001" + tmp)+ comm$ "END TWO argument kernel, output: " ++ synToStr tmp+ return tmp+++-- funappKern f x = function f [x]+-- funappKern2 f x y = function f [x,y]++noopKern :: ScalarKernel+noopKern x = return x++-- Use a for loop to go over a blocked range:+iteratorFor range = forLoopSimple (range `dot` "begin()", range `dot` "end()") ++-- | Put together a complete benchmark .cpp file. +-- The interface is a bit weird, taking in a function to produce+-- top-level code and another to produce code inside the main+-- method, BUT with a value communicated between these two pieces of+-- code.+makeBenchFile :: StringT -> (Int,Int,Int) -- length, width flops+ -> ((Syntax, Syntax, Syntax) -> EasyEmit a)+ -> ((Syntax, Syntax, Syntax, Syntax) -> a -> EasyEmit ())+ -> EasyEmit ObjFun+makeBenchFile header (_numstages, _width, _flops) restfile mainbody =+ do + putS header+ comm "Create global variables for benchmark dimensions/parameters:"+ threads <- var TInt "threads"+ length <- var TInt "length"+ width <- var TInt "width"+ flops <- var TInt "flops"+ pkg <- restfile (length, width, flops)++ putS ""+ funDef TInt "main" [TInt, TPtr$ TPtr TChar] $ \ (argc :: Syntax, argv :: Syntax) -> do+ comm "Parse command line arguments:"+ if_ (argc >= 5)+ (do app (function "printf") [stringconst "Reading command line arguments: threads, length, width, op flops\n"]+ set threads$ function "strtol" [argv `arrsub` 1, 0, 10]+ set length $ function "strtol" [argv `arrsub` 2, 0, 10]+ set width $ function "strtol" [argv `arrsub` 3, 0, 10]+ set flops $ function "strtol" [argv `arrsub` 4, 0, 10])+ (do app (function "printf") [stringconst "No command line arguments: using default benchmark params.\n"]+ set threads $ 1+ set length $ fromInt _numstages+ set width $ fromInt _width+ set flops $ fromInt _flops)++ mainbody (threads, length, width, flops) pkg++++----------------------------------------------------------------------------------------------------+-- TBB backend, generate code to construct a TBB graph and TBB execute methods.+----------------------------------------------------------------------------------------------------++-- Emit an entire graph as the complete text of a .cpp file.+tbbEmitGraph :: GraphNode -> Doc +tbbEmitGraph = + undefined+++-- Create code for a single kernel+tbbEmitKernel :: Kernel -> Doc +tbbEmitKernel = + undefined++--------------------------------------------------------------------------------++-- rTy = TFloat+rTy = TDouble -- TODO: generalize+vTy = tyConstructor "concurrent_vector" rTy+tname_reduce = "Reducer"+tname_produce = "Producer"+++rangeTy = tyConstructor "blocked_range" TInt++tbb_parProduceStruct :: Syntax -> ScalarKernel2 -> EasyEmit ()+tbb_parProduceStruct tname kernel = do + cppStruct tname "" $ do+ prev <- var rTy "prev"+ outbuf <- var (TPtr vTy) "outbuf"++ constFunDef voidTy "operator()" [TConst$ TRef rangeTy] $ \ range -> do+ iteratorFor range $ \ i -> do+ result <- kernel i prev+ arrset (dereference outbuf) i result++ return ()++tbb_parProduceFun :: Syntax -> EasyEmit ObjFun+tbb_parProduceFun tname_produce = do+ comm "This stage expands the single reduced scalar from the previous reduce "+ comm "stage back into an array of values."+ funDef rTy "ParProduceStage" [TInt, TRef rTy, TRef vTy] $ \ (size, inp, outp) -> do+ app (function$ outp `dot` "grow_to_at_least") [size]+ producer <- tmpvar (litType tname_produce)+ fieldset producer "prev" inp+ fieldset producer "outbuf" (addressOf outp)+ app (function "parallel_for")+ [function "blocked_range<int>" [0, methcall outp "size" []],+ producer]++----------------------------------------++-- Create the struct encapsulating the reduction operator for use with parallel_reduce:+tbb_parReduceStruct :: Syntax -> ScalarKernel2 -> EasyEmit ()+tbb_parReduceStruct tname kernel = + do {+ cppStruct tname "" $ do+ val <- var rTy "value"+ inp <- var (TPtr vTy) "input_vals"+ outp <- var (TPtr vTy) "output_vals"+ + cppConstructor tname [] [("value",0)] $ return ()+ cppConstructor tname [(TRef$ litType tname, "s"),+ (TSym "split", "_")] -- Ignored+ [("value",0)] $ + do set val 0+ set inp $ "s" `dot` inp+ set outp$ "s" `dot` outp++ funDef voidTy "operator()" [TConst$ TRef rangeTy] $ \ range -> do+ tmp <- tmpvar rTy+ set tmp val+ forLoopSimple (range `dot` "begin()", range `dot` "end()") $ \ i -> do + result <- kernel tmp (dereference inp `arrsub` i)+ set tmp result+ set val tmp++ funDef voidTy "join" [TRef$ litType tname] $ \ arg -> do+ result <- kernel val (arg `dot` val)+ set val result+ return ()+ }++-- Create the function that calls parallel_reduce+--parReduceFun :: Syntax -> EasyEmit ((Syntax,Syntax) -> EasyEmit Syntax)+tbb_parReduceFun :: Syntax -> EasyEmit ObjFun+tbb_parReduceFun tname = + funDef voidTy "ParReduceStage" [TRef vTy, TRef rTy] $ \ (inp, outp) -> + do + total <- tmpvar (litType tname)+ set (total `dot` "input_vals") (addressOf inp)+ let size = inp `dot` "size()"+ app (function "parallel_reduce")+ [function (Syn$ pPrint rangeTy) [0,size] , total]++ final <- tmpvarinit rTy$ total `dot` "value" / size+ set outp final++tbb_header :: StringT+tbb_header = "\+ \ #include <stdio.h> \n\+ \ #include <iostream> \n\+ \ #include \"tbb/task_scheduler_init.h\" \n\+ \ #include \"tbb/parallel_reduce.h\" \n\+ \ #include \"tbb/parallel_for.h\" \n\+ \ #include \"tbb/blocked_range.h\" \n\+ \ #include \"tbb/concurrent_vector.h\" \n\+ \ using namespace tbb; \n\+ \ \n"++-- Execute a linear chain of reductions:+tbb_produceReduceChain dofree (length, width, flops) + prodFun redFun =+ do + let printf = function "printf"+ app printf [stringconst "Running pipe of length %d, width %d, op flops %d\n", + length, width, flops]+ app printf [stringconst "------------------------------------------------------------\n"]+ + comm "Create a series of reduction steps, separated by buffers, as well"+ comm "as 'spreader' production steps that fan the reduced values back out."++ val0 <- varinit (rTy) "val0" 1 + forLoopSimple (0, length) $ \i -> do+ when debug_benchsynth $ + app printf [stringconst "Round %d, initial value = %lf\n", i, val0]+ intmdt <- varinit (TPtr vTy) "intermediate_buf" (new vTy [])+ app prodFun [width, val0, dereference intmdt]++ when debug_benchsynth $ + do app printf [stringconst "Round %d, buf: [ ", i]+ forLoopSimple (0, width) $ \j -> do + app printf [stringconst "%lf ", (dereference intmdt) `arrsub` j]+ app printf [stringconst "]\n"]++ val1 <- var (rTy) "val1" + app redFun [dereference intmdt, val1]+ when dofree $ app (function "delete") [intmdt]+ set val0 val1++ putS$ "printf(\"Final spot check sum: %lf\\n\", "++ synToStr val0 ++");"+ ret 0++++-- Temp: run everything and generate one benchmark config to a file:+genTbbFile filename = + Prelude.writeFile filename $+ render$+ execEasyEmit$+ makeBenchFile tbb_header (10,10,10) -- Defaults if no command line options are provided.+ (\ (length, width, flops) -> + do + putS ""; comm "This function is used to do the actual FLOPs: "+ cnc_reduceOp "simpleFlops2" flops++ --funDef rTy "simpleFlops2" [TInt, rTy,rTy] $ \ (flops, x,y) -> do+ -- funDef rTy "simpleFlops2" [rTy,rTy] $ \ (x,y) -> do+ -- x <- simpleFlops2 rTy flops x y+ -- ret x+ putS ""+-- let kern x y = return (function "simpleFlops2" ["flops",x,y])+ let kern x y = return (function "simpleFlops2" [x,y])+ tbb_parReduceStruct tname_reduce kern; putS ""+ redfn <- tbb_parReduceFun tname_reduce; putS ""+ tbb_parProduceStruct tname_produce kern; putS ""+ prodfn <- tbb_parProduceFun tname_produce; putS ""+ return (prodfn,redfn)+ )+ (\ (threads, length, width, flops) (prodfn,redfn) -> do+ tmpclassvar (TSym "task_scheduler_init") [threads]+ app (function "printf") [stringconst "Initialized num threads to %d\n", threads]+ tbb_produceReduceChain False (length, width, flops) prodfn redfn+ )++-- Temporary entrypoint:+main = + do putStrLn$ "Generating files"+ genTbbFile "test_tbb.cpp"+ genCnCFile "test_cnc.cpp"+ putStrLn$ "Finished generating"+++----------------------------------------------------------------------------------------------------+-- CnC backend+----------------------------------------------------------------------------------------------------+-- UNFINISHED:++-- Here we would like to reuse the main spec compiler code to do some of the work for us.++genCnCFile filename = do + cnc_header <- readFile "./Intel/Cnc/BenchSynth/cnc_reduce_header.cpp"+ spec <- cnc_spec+ Prelude.writeFile filename $+ render$+ execEasyEmit$ do + comm "DO NOT MODIFY -- GENERATED CnC code\n"+ makeBenchFile (cnc_header)+ (10,10,10) -- Defaults if no command line options are provided.+ (\ (length, width, flops) -> + do + comm ""+ comm "First declare some types/functions that are needed *before* the spec:"+ cnc_reduceOp "reduce_op" flops+ comm ""+ comm "And here's an unfortunate (hopefully temporary) global variable:" + var rTy "prev"+ comm ""+ comm "Next emit code for the CnC spec in the usual way:"+ comm "(But inline it right into this merged benchmark file.)"+ comm "================================================================================"+ emitCpp default_codegen_config spec+ comm ""+ comm "================================================================================"+ comm "Next add the step implementations."+ let kern x y = return (function "reduce_op" [x,y])+ cnc_parProduceReduceStep kern+ return ()+ )+ (\ (threads, length, width, flops) () -> + -- tbb_produceReduceChain False (length, width, flops) prodfn redfn+ + return ()+ )++-- cnc_parProduceReduceStep :: Syntax -> EasyEmit ObjFun+-- cnc_parProduceReduceStep tname_produce = do+cnc_parProduceReduceStep kernel = do + putS ""+-- cppStruct "S1" "" $ do + putS "template< typename ctxt >"+ constFunDef TInt "S1::execute" [TConst$ TRef$ TInt, TRef$ TSym "ctxt"] $ + \ (ind :: Syntax, ctxt :: Syntax) -> + do + result <- kernel ind "prev" + -- reduc_scalar_t result = simpleFlops2(n, n, c.prev);++ -- CONUNDRUM: How do test the strategy of NOT using the inefficient reduction collection?+-- app (function$ ctxt `dot` "reducer" `arrow` "put") [result]+ app (function$ ctxt `dot` "R1" `dot` "put") [0, result]++ putS "return CnC::CNC_Success;"+ return ()++cnc_reduceOp name flops = do+ putS ""+ funDef rTy name [rTy,rTy] $ \ (x,y) -> do+ new <- simpleFlops2 rTy flops x y+ app (function "printf") [stringconst "Computed %lf from %lf and %lf, flops %d\n", new,x,y, flops]+ ret new++-- Emit the CnC context definition.+-- Ideally we would use the translator itself to generate this!+--+-- However, right now we want to be able to use individual reducers,+-- which is not efficent currently.+cnc_produceReduceContext :: EasyEmit() +cnc_produceReduceContext = + undefined+++-- This is one of those incomplete specs that doesn't include the+-- produce/consume edges.+cnc_spec = + readCnCFromStr (-1) "benchsynth_reduce.cnc"+ " tags<int> T1; \n\+ \ steps S1; \n\+ \ reductions<int, double> R1(reduce_op, 0 ); \n\+ \ T1 :: S1; \n\+ \ env -> T1; \n\+ \ "++++++++--------------------------------------------------------------------------------+-- Cilk/Nabbit? +++--------------------------------------------------------------------------------
+ Intel/Cnc/EasyEmit.hs view
@@ -0,0 +1,531 @@+{-# LANGUAGE DeriveDataTypeable, OverloadedStrings, FlexibleInstances, ScopedTypeVariables, MultiParamTypeClasses, FunctionalDependencies, TypeSynonymInstances #-}++{-|+ This module provides a simple way to use HOAS (higher order abstract syntax) to emit C++ code.++ This is an AST-free method! It doesn't define a complete model for+ C++ code, just an easier way of emitting concretes syntax than+ using strings.+ + -}++module Intel.Cnc.EasyEmit where+++import Intel.Cnc.Spec.Util hiding (app, commasep)+import Intel.Cnc.Spec.AST ++import Control.Monad +import qualified Control.Monad.State.Strict as S ++import Data.Data+import Data.List+import GHC.Exts -- For IsString++import StringTable.Atom+import Text.PrettyPrint.HughesPJ+import Text.PrettyPrint.HughesPJClass +import Test.HUnit++import qualified Prelude as P+import Prelude hiding ((&&), (||), (==), (/=), not, Eq+ , Ord, (<), (<=), (>), (>=), max, min -- , compare+ )+++----------------------------------------------------------------------------------------------------+-- Monad plus HOAS for C+++----------------------------------------------------------------------------------------------------++-- | A monad for generating syntax:+-- The state consists of an accumulator for lines of syntax, plus a counter for temporary variables.+newtype EasyEmit a = EE (S.State EEState a)+type EEState = ([Doc],Int)++-- | Run a syntax-emitting computation and render it to a document.+++runEasyEmit :: EasyEmit a -> (a,Doc)+runEasyEmit m = (a,b)+ where (a,_,b) = rawRunEasyEmit 0 m++-- This full version includes the counter:+rawRunEasyEmit :: Int -> EasyEmit a -> (a, Int, Doc)+rawRunEasyEmit start (EE m) = (a, cnt, vcat (reverse ls))+ where + (a,(ls,cnt)) = S.runState m ([], start)++execEasyEmit :: EasyEmit a -> Doc+execEasyEmit = snd . runEasyEmit++evalEasyEmit :: EasyEmit a -> a+evalEasyEmit = fst . runEasyEmit +++-- This runs a subcomputation only for value -- discards its emission side effects.+forValueOnly :: EasyEmit a -> EasyEmit a+forValueOnly (EE m) =+ do (ls,c) <- S.get + let (val,(_,c2)) = S.runState m ([], c)+ S.put (ls,c2)+ return val++-- BOILERPLATE, because of newtype rather than type synonym for EasyEmit:+instance Monad EasyEmit where+ -- Whew, need to verify that this has no perfermance overhead:+ (EE ma) >>= fn = EE (ma >>= (\x -> case fn x of EE m -> m))+ return x = EE (return x)+instance S.MonadState EEState EasyEmit where+ get = EE S.get+ put x = EE (S.put x)++instance StringBuilder EasyEmit where +--instance StringBuilder (S.State ([Doc], Int)) where + putS s = S.modify (\ (ls,cnt) -> (text s:ls, cnt) )+ runSB (EE m) = + let (res, (ls,cnt)) = S.runState m ([],0) + in (render$ vcat$ reverse ls, res)++instance ToAtom Syntax where+ toAtom d = toAtom$ deSyn d+++--------------------------------------------------------------------------------+-- First, simple helpers / utilities:+--------------------------------------------------------------------------------++instance P.Eq Doc where+ -- Would be nice to memoize this!+ a == b = render a P.== render b++-- | The EasyEmit monad uses this Syntax type internally:+data Syntax = Syn Doc+ deriving (Show, P.Eq)++deSyn (Syn s) = s+synToStr = render . deSyn ++fromInt = Syn . int ++atomToSyn = Syn . text . fromAtom+strToSyn = Syn . text ++(Syn a) +++ (Syn b) = Syn (a <> b)++(Syn a) `dot` (Syn b) = Syn (a <> text "." <> b)+(Syn a) `arrow` (Syn b) = Syn (a <> text "->" <> b)++dereference (Syn a) = Syn$ parens (text "*" <> a)+addressOf (Syn a) = Syn$ parens (text "&" <> a)++-- Array subscript operator:+arrsub (Syn a) (Syn b) = Syn$ (a <> text "[" <> b <> text "]")++-- Adds implicit newline at the end:+addChunk :: Syntax -> EasyEmit ()+addChunk (Syn doc) = + do (ls,c) <- S.get+ S.put (doc : ls, c)++-- A bit ugly, this adds the chunk to the end of the previous line.+addChunkPrevLine (Syn doc) = + do (ls,c) <- S.get+ S.put $ case ls of + [] -> (doc : ls, c)+ (hd:tl) -> (hd <> doc : tl, c)++-- Adds the semi-colon at the end also:+addLine (Syn doc) = addChunk (Syn$ doc <> semi)++-- Also, overloading the string constants themselves is nice:+instance IsString Syntax where+ fromString s = Syn (text s)++-- instance IsString Doc where+-- fromString s = (text s)+++-- Comma separate Docs either horizontally or vertically:+-- TEMP: MAKING THIS HCAT FOR NOW UNTIL I CAN FIGURE OUT SOME OF THE INDENTATION PROBELMS:+commasep ls = hcat$ intersperse (text", ") ls++-- (This version includes parens)+--pcommasep = parens . commasep+pcommasep ls = parens$ fcat$ intersperse (text", ") ls +++--------------------------------------------------------------------------------+-- C++ Expressions+--------------------------------------------------------------------------------++(Syn a) ? (Syn b) = Syn ("(" <> a <> " ? " <> b )+-- Hack, these must always be used together to get balanced parens:+(Syn a) .: (Syn b) = Syn ( a <> " : " <> b <> ")")++-- The most important class of expressions are generated by overloaded+-- standard operators, as follows:++instance Num Syntax where + (Syn a) + (Syn b) = Syn (parens $ a <> " + " <> b )+ (Syn a) * (Syn b) = Syn (parens $ a <> " * " <> b )+ (Syn a) - (Syn b) = Syn (parens $ a <> " - " <> b )+ abs (Syn a) = Syn ("abs" <> parens a )+ negate (Syn a) = Syn (parens ("-" <> parens a))+ fromInteger n = Syn (text $ show n)+ -- Could implement this I suppose...+ signum _ = "__ERROR__"++instance Fractional Syntax where + (Syn a) / (Syn b) = Syn (parens $ a <> " / " <> b )+ recip (Syn a) = Syn (parens $ "1 / " <> a )+ fromRational rat = Syn ( text$ show rat )++instance Boolean Syntax where+ (Syn a) && (Syn b) = Syn (parens $ a <> " && " <> b )+ (Syn a) || (Syn b) = Syn (parens $ a <> " || " <> b )+ not (Syn a) = Syn ("!" <> parens a )+ false = Syn "false"+ true = Syn "true"++instance Ord Syntax Syntax where+ (Syn a) < (Syn b) = Syn (parens $ a <> " < " <> b )+ (Syn a) > (Syn b) = Syn (parens $ a <> " > " <> b )+ (Syn a) <= (Syn b) = Syn (parens $ a <> " <= " <> b )+ (Syn a) >= (Syn b) = Syn (parens $ a <> " >= " <> b )+ max (Syn a) (Syn b) = Syn ("max" <> pcommasep [a,b] )+ min (Syn a) (Syn b) = Syn ("min" <> pcommasep [a,b] )++-- conditional (Syn a) b c = Syn (parens $ a <> " ? " <> b <> ":" <> c )++instance Eq Syntax Syntax where+ (Syn a) == (Syn b) = Syn (parens $ a <> " == " <> b ) ++-- Use a C++ constant +constant :: String -> Syntax+constant = fromString++stringconst :: String -> Syntax+stringconst str = Syn$ dubquotes$ escapeString str++-- new :: Syntax -> [Syntax] -> Syntax+new :: Type -> [Syntax] -> Syntax+new ty args = Syn$ "new" <+> (deSyn$ function (Syn$ pPrint ty) args)+++--------------------------------------------------------------------------------+-- Declaring variables+--------------------------------------------------------------------------------++-- With names:+var :: Type -> Syntax -> EasyEmit Syntax+var ty (Syn name) = do addLine (Syn (cppType ty <+> name ))+ return (Syn name)++-- With initialization expression:+varinit :: Type -> Syntax -> Syntax -> EasyEmit Syntax+varinit ty (Syn name) (Syn rhs) = + do addLine (Syn (cppType ty <+> name <+> "=" <+> rhs))+ return (Syn name)++-- A var declaration with a constructor invocation.+classvar :: Type -> Syntax -> [Syntax] -> EasyEmit Syntax+classvar ty (Syn name) args =+ do addLine (Syn (cppType ty <+> name <+> pcommasep (map deSyn args)))+ return (Syn name)++-- Without names:+----------------------------------------+gensym root = + do (ls,cnt) <- S.get+ S.put (ls,cnt+1)+ return$ Syn$ root <> int cnt++tmpvar :: Type -> EasyEmit Syntax+tmpvar ty = do name <- gensym "tmp"+ var ty name++tmpvarinit :: Type -> Syntax -> EasyEmit Syntax+tmpvarinit ty rhs = + do name <- gensym "tmp"+ varinit ty name rhs+ +-- A var declaration with a constructor invocation.+tmpclassvar :: Type -> [Syntax] -> EasyEmit Syntax+tmpclassvar ty args =+ do name <- gensym "obj"+ classvar ty name args+++------------------------------------------------------------+-- C++ Statements +------------------------------------------------------------++-- This is a function in the meta language that represents a function+-- in the object language.+type ObjFun = ([Syntax] -> Syntax)++-- Variable Assignment:+set :: Syntax -> Syntax -> EasyEmit ()+set (Syn x) (Syn v) = addLine$ Syn$ x <+> "=" <+> v ++-- Assignment for array locations:+arrset :: Syntax -> Syntax -> Syntax -> EasyEmit ()+arrset arr i rhs = set (arr `arrsub` i) rhs++-- Assignment for a field R.x.+fieldset :: Syntax -> Syntax -> Syntax -> EasyEmit ()+fieldset arr x rhs = set (arr `dot` x) rhs++-- Function application (command context):+app :: ObjFun -> [Syntax] -> EasyEmit ()+app fn ls = addLine$ fn ls+++-- A shorthand that looks C-ish:+(Syn x) += (Syn n) = addLine$ Syn$ x <+> "+=" <+> n+(Syn x) -= (Syn n) = addLine$ Syn$ x <+> "-=" <+> n++-- Comments:+--comm :: Doc -> EasyEmit ()+comm :: String -> EasyEmit ()+comm x = addChunk$ Syn$ txt+ where + txt = text$ maybeInit$ unlines lns -- init strips the last newline+ maybeInit [] = []+ maybeInit ls = init ls+ lns = map fn $ lines x --(render x)+ fn "" = ""+ fn other = "// " ++ other++if_ (Syn a) m1 m2 = + do let bod1 = execEasyEmit m1+ bod2 = execEasyEmit m2+ addChunk$ Syn$ hangbraces ("if " <> parens a) indent bod1+ addChunk$ Syn$ "else"+ addChunk$ Syn$ hangbraces (empty) indent bod2++ret (Syn x) = addLine$ Syn$ "return " <> x++assert (Syn exp) = + do addLine$ Syn ("assert" <> pcommasep [exp])+++------------------------------------------------------------+-- C++ Definitions & Declarations+------------------------------------------------------------++-- The funDef function creates a function definition as well as+-- returning a Haskell function that can be used to construct+-- applications of that function.+class FunDefable args where+ -- This is VERY painful, but need to expose separate keywords for pre- and post- the function name/args.+ funDefAttr :: String -> String -> Type -> Syntax -> [Type] -> (args -> EasyEmit ()) -> EasyEmit ObjFun++instance FunDefable () where funDefAttr pre post r n ts fn = funDefShared pre post r n ts fn (\ [] -> ())+instance FunDefable Syntax where funDefAttr pre post r n ts fn = funDefShared pre post r n ts fn (\ [a] -> a) +instance FunDefable (Syntax,Syntax) where funDefAttr pre post r n ts fn = funDefShared pre post r n ts fn (\ [a,b] -> (a,b)) +instance FunDefable (Syntax,Syntax,Syntax) where funDefAttr pre post r n ts fn = funDefShared pre post r n ts fn (\ [a,b,c] -> (a,b,c)) +instance FunDefable (Syntax,Syntax,Syntax,Syntax) where funDefAttr pre post r n ts fn = funDefShared pre post r n ts fn (\ [a,b,c,d] -> (a,b,c,d)) +instance FunDefable [Syntax] where funDefAttr pre post r n ts fn = funDefShared pre post r n ts fn id+++-- Terrible ugliness just to deal with those darn const qualifiers:+funDef :: FunDefable args => Type -> Syntax -> [Type] -> (args -> EasyEmit ()) -> EasyEmit ObjFun+constFunDef :: FunDefable args => Type -> Syntax -> [Type] -> (args -> EasyEmit ()) -> EasyEmit ObjFun+inlineFunDef :: FunDefable args => Type -> Syntax -> [Type] -> (args -> EasyEmit ()) -> EasyEmit ObjFun++funDef = funDefAttr "" ""+constFunDef = funDefAttr "" "const"+inlineFunDef = funDefAttr "inline" ""+++-- Internal helper function used above:+funDefShared pre postqualifiers retty (Syn name) tyls fn formTup = + do (ls,c) <- S.get + --args <- mapM (forValueOnly . tmpvar) tyls -- Generate temp names only (emit nothing).+ args <- sequence$ take (length tyls) (repeat$ gensym "arg") -- Generate temp names only (emit nothing).+ let body = execEasyEmit (fn$ formTup args)+ formals = map (\ (t,a) -> cppType t <+> deSyn a) (zip tyls args)+ addChunk$ Syn$ + hangbraces ((if pre P.== "" then empty else text (pre++" ")) <> + cppType retty <+> name <> pcommasep formals <+> (text postqualifiers)) + indent body+-- addChunk$ "\n"+ return (\ args -> Syn$ name <> (pcommasep (map deSyn args)))+++-- This applies a C++ function referred to by name (defined elsewhere):+function :: Syntax -> ObjFun+function (Syn name) = + \ args -> Syn$ name <> (pcommasep$ map deSyn args)++-- Shortcut for applying a method given an object or object reference.+methcall :: Syntax -> Syntax -> ObjFun+methcall obj meth args = obj `dot` (function meth args)+++-- Common case: for loop over a range with integer index:+------------------------------------------------------------+-- Input is [Inclusive,Exclusive) range.+forLoopSimple :: (Syntax,Syntax) -> (Syntax -> EasyEmit ()) -> EasyEmit ()+forLoopSimple (start,end) fn = + do + Syn var <- gensym "i"+ (ls,oldcnt) <- S.get++ let (_,newcnt,body) = rawRunEasyEmit oldcnt $ fn (Syn var)++ -- To maintain uniqueness we take the counter mods from the body.+ -- TODO: A cleaner way to do this would be to include the indent level in the state monad and NOT LEAVE IT.+ S.put (ls, newcnt)++ addChunk$ Syn$ hangbraces ("for " <> parens ( cppType TInt <+> var <+> "=" <+> deSyn start <> semi <+>+ var <+> "<" <+> deSyn end <> semi <+>+ var <> "++"+ )) indent $+ body++-- Helper used below:+a <++> b | a P.== "" = b+a <++> b | b P.== "" = a+a <++> b = a <+> b++-- This creates a class-decl-like pattern with a ':'+-- It is parameterized by a little prefix which could be "class" or "struct" or anything else.+-- Similarly, there's a postfix which is usually ";".+classLike :: String -> String -> Syntax -> Syntax -> EasyEmit () -> EasyEmit ()+classLike prefix postfix (Syn name) (Syn inherits) m = + do + putD$ t prefix <++> + hsep (if inherits P.== empty+ then [name]+ else [name <+> colon, inherits])+ block m+ addChunkPrevLine$ strToSyn postfix ++-- | Takes: name, inheritance expression, and a body.+cppClass :: Syntax -> Syntax -> EasyEmit () -> EasyEmit ()+cppClass = classLike "class" ";"++-- | Takes: name, inheritance expression, and a body.+cppStruct :: Syntax -> Syntax -> EasyEmit () -> EasyEmit ()+cppStruct = classLike "struct" ";"++-- Arg list is (type,argname) and init list is (name,expression/value)+cppConstructor :: Syntax -> [(Type,Syntax)] -> [(Syntax,Syntax)] -> EasyEmit () -> EasyEmit ()+cppConstructor (Syn name) args inits body = + let fn (t,x) = pPrint t <+> deSyn x in+ classLike "" "" (Syn$ name <> parens (commasep$ map fn args)) + (Syn$ commasep$ map (\ (a,b) -> deSyn a <> parens (deSyn b)) inits)+ body++-- Constructor method prototypes just look like applications+constructorPrototype :: Syntax -> [Syntax] -> EasyEmit ()+constructorPrototype name args = + app (function name) args++-- Curly-brace delimited, indented block:+-- POSSIBLY INEFFICIENT!+-- TODO: Implement this by tracking the indent level in the monad:+block :: EasyEmit () -> EasyEmit ()+block m = + do let body = execEasyEmit m+ addChunk "{"+ addChunk$ Syn$ nest indent body+ addChunk "}"++++----------------------------------------------------------------------------------------------------+-- Overloaded booleans and predicates from Lennart Augustsson:+----------------------------------------------------------------------------------------------------++-- | Generalization of the 'Bool' type. Used by the generalized 'Eq' and 'Ord'.+class Boolean bool where+ (&&) :: bool -> bool -> bool -- ^Logical conjunction.+ (||) :: bool -> bool -> bool -- ^Logical disjunction.+ not :: bool -> bool -- ^Locical negation.+ false :: bool -- ^Truth.+ true :: bool -- ^Falsity.+ fromBool :: Bool -> bool -- ^Convert a 'Bool' to the generalized Boolean type.+ fromBool b = if b then true else false++-- Why not just make this part of the above class?+-- | Generalization of the @if@ construct.+--class (Boolean bool) => Conditional bool a where -- orig+--class (Boolean bool) => Conditional bool where+-- conditional :: bool -> a -> a -> a -- ^Pick the first argument if the 'Boolean' value is true, otherwise the second argument.+++--class (Boolean bool) => Eq a bool {- x | a -> bool -} where+class (Boolean bool) => Eq a bool | a -> bool where+ (==) :: a -> a -> bool+ (/=) :: a -> a -> bool++ x /= y = not (x == y)+ x == y = not (x /= y)+++--class (Conditional bool Ordering, Eq a bool) => Ord a bool | a -> bool where+--class (Conditional bool, Eq a bool) => Ord a bool | a -> bool where+class (Boolean bool, Eq a bool) => Ord a bool | a -> bool where+ (<), (<=), (>), (>=) :: a -> a -> bool+ max, min :: a -> a -> a++-- Need to define precedence because these new operations really have nothing to do with the originals:+infix 4 ==, /=, <, <=, >=, >+infixr 3 &&+infixr 2 ||+++----------------------------------------------------------------------------------------------------+-- Internal helpers:+----------------------------------------------------------------------------------------------------+++----------------------------------------------------------------------------------------------------+-- Testing:+----------------------------------------------------------------------------------------------------++t1 = cppClass "foo" "bar" $ comm "body"++t2 = execEasyEmit$ funDef TInt "foo" [TInt] $ \(Syn y) -> + do comm "Body"+ funDef TInt "nested" [] $ \ () -> comm "Inner body"+ return ()+++ee_example :: EasyEmit ()+ee_example = + do + comm "\nFirst some global vars:\n "+ y <- tmpvar TInt+ x <- var TInt "x"++ bar <- funDef (TSym "void") "bar" [TInt, TInt] $ \ (z,q) -> do+ set y (z + q)++ comm "\nA function declaration:"+ foo <- funDef TInt "foo" [TInt] $ \y -> do+ x += (x + y * 3)+ x -= 4+ ret x++ let baz = function "baz"+ quux = fromString "quux"++ app baz [quux, quux]++ forLoopSimple (0,10) $ \i -> do+ if_ (i == 10 || i > 100)+ (app foo [foo [i / 10]])+ (app foo [i ? 3 .: 4])++ -- cppClass "blah" $ do + -- if_ (app f x) x x + -- -- funDef "method" [TInt, TFloat] $ \(y,z) -> y + z++ee_test1 = testCase "" "Code emission example"$ + 391 ~=? (length$ render$ execEasyEmit ee_example)++tests_easyemit = testSet "EasyEmit" [ee_test1]
+ Intel/Cnc/Spec/AST.hs view
@@ -0,0 +1,296 @@+{-# LANGUAGE DeriveDataTypeable, ScopedTypeVariables #-}+{-# OPTIONS_GHC -fwarn-incomplete-patterns #-}++module Intel.Cnc.Spec.AST where ++import StringTable.Atom+import Data.Data+import Data.Char+import Text.PrettyPrint.HughesPJClass+--import Data.Generics.Serialization.SExp+--import Data.Generics.Serialization.Streams+import Intel.Cnc.Spec.Util+import Intel.Cnc.Spec.SrcLoc++-- For now there is exactly one predefined step collection:+isBuiltin e | e == special_environment_name = True+isBuiltin _ = False++-- Oops, I don't know how to compose type constructors in a "curried" way:+--instance Decorated t => Decorated ([] . t) where +-- stripDecor = map stripDecor+-- getDecor = ++--------------------------------------------------------------------------------+-- Expressions and Literals+--------------------------------------------------------------------------------++-- Expressions are the code used inside step skeletons.++data Lit = + LitInt Int + | LitFloat Float+ deriving (Eq, Ord, Show, Data, Typeable)++-- Expressions are decorated with values of an arbitrary type:+data Exp dec = + Lit dec Lit+ | Var dec Atom+ | App dec (Exp dec) [Exp dec]+ | If dec (Exp dec) (Exp dec) (Exp dec) + deriving (Eq, Ord, Show, Data, Typeable)+++instance Pretty Lit where + pPrint (LitInt i) = pPrint i+ pPrint (LitFloat f) = pPrint f++instance Pretty (Exp dec) where + pPrint (Lit _ l) = pPrint l+ pPrint (Var _ s) = text (fromAtom s)+ pPrint (App _ rator rands) = + case (rator,rands) of + -- If it's a binop we should print appropriately.+ (Var _ name, [left,right]) | (not $ isAlpha (head (fromAtom name))) -> + -- Sep can actually yield some very wierd behavior:+-- pPrint left `sep2` text name `sep2` pPrint right+ parens (pp left <+> text (fromAtom name) <+> pp right)+ _ -> pPrint rator <> (parens $ commasep rands)++ pPrint (If _ a b c) = + sep [text "if (" <> pPrint a <> text ")",+ nest 5 $ pPrint b, + text "else " <> pPrint c]++instance Decorated Exp where + mapDecor f e = + case e of + Lit s l -> Lit (f s) l+ Var s v -> Var (f s) v+ App s r d -> App (f s) (mapDecor f r) (map (mapDecor f) d)+ If s a b c -> If (f s) (mapDecor f a) (mapDecor f b) (mapDecor f c)++ -- This is the price of tagging the source locations (and other+ -- decorations) right on the Exprs rather than the even/odd+ -- alternating expression/decoration types.+ getDecor e = + case e of + Lit s _ -> s+ Var s _ -> s+ App s _ _ -> s+ If s _ _ _ -> s++--------------------------------------------------------------------------------+-- Types+--------------------------------------------------------------------------------++data Type =+ TInt+ | TFloat | TDouble+ | TChar+ -- An abstract type not intpreted by CnC:+ | TSym Atom+ | TPtr Type+ | TRef Type -- quite annoying, used for C+++ | TConst Type -- quite annoying, used for C+++ | TDense Type -- Density annotations.+ | TTuple [Type]+ deriving (Eq,Ord,Show,Data,Typeable)++instance Pretty (Type) where+ pPrint = cppType+ -- pPrint (TInt) = text "int"+ -- pPrint (TFloat) = text "float"+ -- pPrint (TDouble) = text "double"+ -- pPrint (TSym str) = text (fromAtom str)+ -- pPrint (TPtr ty) = pPrint ty <> text "*"+ -- pPrint (TRef ty) = pPrint ty <> text "&"+ -- pPrint (TDense ty) = text "dense" <+> pPrint ty + -- pPrint (TConst ty) = text "const" <+> pPrint ty + -- pPrint (TTuple ty) = text "(" <> commacat ty <> text ")"++-- A literal text description of a type. +litType x = TSym (toAtom x)++-- For now I'm not exposing type constructors as a separate variant:+tyConstructor :: Doc -> Type -> Type+tyConstructor doc ty = + TSym (toAtom$ doc <> angles (pPrint ty))++voidTy = TSym (toAtom "void")++-- Converting types to C++ concrete syntax.+cppType :: Type -> Doc+cppType ty = case ty of + TInt -> t "int"+ TFloat -> t "float"+ TDouble -> t "double"+ TChar -> t "char"+ TSym s -> textAtom s+ TPtr ty -> cppType ty <> t "*"+ TRef ty -> cppType ty <> t " &"+ TConst ty -> t"const" <+> cppType ty ++ -- This doesn't affect the C-type, any influence has already taken place.+ TDense ty -> cppType ty ++-- Here is the convention for representing tuples in C++.+ --TTuple [a,b] -> t "Pair" <> angles (hcat$ punctuate commspc (map cppType [a,b]))+ --TTuple [a,b,c] -> t "Triple" <> angles (hcat$ punctuate commspc (map cppType [a,b,c]))+ TTuple ls -> t "cnctup::tuple" <> angles (hcat$ punctuate commspc$ map cppType ls)+ --TTuple ls -> error$ "CppOld codegen: Tuple types of length "++ show (length ls) ++" not standardized yet!"+++----------------------------------------------------------------------------------------------------+-- Abstract Syntax for Top level Statements in a .cnc file:+----------------------------------------------------------------------------------------------------++-- These are the statements produced by parsing (hence 'P')+-- They get converted to a different format post-parsing+data PStatement dec = + -- When we parse a file we allow statements to be arbitrarily long chains of relations:+ -- We represent this as a starting instance(s) followed by an arbitrary number of links.+ Chain [CollectionInstance dec] [RelLink dec]+ | DeclareTags dec Atom (Maybe Type)+ | DeclareItems dec Atom (Maybe (Type, Type))+ | DeclareReductions dec Atom Atom (Exp dec) (Maybe (Type, Type))+ | DeclareSteps dec Atom ++ -- Type synonyms are of kind * for now...+ | TypeDef dec Atom Type++ | Function+ | DeclareExtern+ | Constraints dec (CollectionInstance dec) [Exp dec]++ deriving (Eq,Ord,Show,Data,Typeable)++instance Pretty (PStatement dec) where + pPrint (Chain first rest) = + commacat first <+>+ hsep (map pPrint rest) <> text ";\n"+ pPrint (DeclareTags _ name Nothing) = text "tags " <> text (fromAtom name) <> text ";\n"+ pPrint (DeclareTags _ name (Just ty)) = text "tags<" <> pPrint ty <> text "> " <> text (fromAtom name) <> t";\n"+ pPrint (DeclareItems _ name Nothing) = text "items" <+> text (fromAtom name) <> t";\n"+ pPrint (DeclareItems _ name (Just (ty1,ty2))) = + t"items<" <> pp ty1 <> comma <+> pp ty2 <> t"> " <> toDoc name <> t";\n"++ pPrint (DeclareReductions _ name op exp Nothing) = + t"reductions" <+> (toDoc name) <> parens (toDoc op <> t", " <> pPrint exp) <> t";\n"+-- pPrint (DeclareReductions _ name op (Just (ty1,ty2))) = + pPrint (DeclareReductions _ name op exp (Just ty1)) = + t"reductions<" <> pp ty1 <> t"> " <> toDoc name <> parens (toDoc op <> t", " <> pPrint exp) <> t";\n"++ pPrint (DeclareSteps _ name) = text "steps " <> text (fromAtom name) <> text ";\n"+ pPrint (Constraints _ inst exps) = text "constrain " <> pp inst <+> + hcat (punctuate (text ", ") $ map pp exps) <> text ";\n"++ pPrint (TypeDef _ nm ty) = text "type"<+> pPrint nm <+> char '=' <+> pPrint ty <> text ";\n"++ pPrint (Function ) = text "FUNCTION NOT WORKING YET"+ pPrint (DeclareExtern) = text "DECLARE EXTERN NOT WORKING YET"+++--instance Pretty [PStatement dec] where +-- pPrint ls = vcat (map pPrint ls)++instance Decorated PStatement where + mapDecor f stmt = + case stmt of + Chain insts links -> Chain (map (mapDecor f) insts) (map (mapDecor f) links)+ DeclareTags s name ty -> DeclareTags (f s) name ty+ DeclareItems s name ty -> DeclareItems (f s) name ty+ DeclareReductions s name op exp ty -> DeclareReductions (f s) name op (mapDecor f exp) ty+-- DeclareReductions s name op exp ty -> DeclareReductions (f s) name op exp ty+ DeclareSteps s name -> DeclareSteps (f s) name+ Constraints s inst ls -> Constraints (f s) (mapDecor f inst) (map (mapDecor f) ls)++ Function -> Function + DeclareExtern -> DeclareExtern + TypeDef s name ty -> TypeDef (f s) name ty+++ getDecor stmt = + case stmt of + Chain (hd:_) _ -> getDecor hd+ Chain [] (hd:_) -> getDecor hd+ Chain [] [] -> error "getDecor: cannot get decoration from an empty 'Chain'. Shouldn't have such a thing anyway."+ DeclareTags s _ _ -> s+ DeclareItems s _ _ -> s+ DeclareReductions s _ _ _ _ -> s+ DeclareSteps s _ -> s+ Constraints s _ _ -> s+ TypeDef s _ _ -> s+ Function -> error "getDecor: not implemented yet"+ DeclareExtern -> error "getDecor: not implemented yet"+++------------------------------------------------------------+data RelLink dec = + ProduceLink dec [CollectionInstance dec]+ | PrescribeLink dec [CollectionInstance dec]+ | RevProduceLink dec [CollectionInstance dec]+ deriving (Eq,Ord,Show,Data,Typeable)++instance Pretty (RelLink dec) where+ pPrint (ProduceLink _ ls) = text "->" <+> commacat ls + pPrint (PrescribeLink _ ls) = text "::" <+> commacat ls + pPrint (RevProduceLink _ ls) = text "<-" <+> commacat ls ++instance Decorated RelLink where + mapDecor f link = + case link of + ProduceLink s ls -> ProduceLink (f s) (map (mapDecor f) ls)+ PrescribeLink s ls -> PrescribeLink (f s) (map (mapDecor f) ls)+ RevProduceLink s ls -> RevProduceLink (f s) (map (mapDecor f) ls) + getDecor link = + case link of + ProduceLink s _ -> s+ PrescribeLink s _ -> s+ RevProduceLink s _ -> s++------------------------------------------------------------++-- These are references to collections in the+-- prescribe/produce/consume constructions of the .cnc file.+data CollectionInstance dec = + InstName dec String+ -- TEMP: until the syntax has been figured out we sometimes know+ -- that an instance is a Step OR a Tag collection, but not which.+ | InstStepOrTags dec String [Exp dec]+ | InstTagCol dec String [Exp dec]+ | InstItemCol dec String [Exp dec]+ | InstReductionCol dec String [Exp dec]+ | InstStepCol dec String [Exp dec]++ deriving (Eq,Ord,Show,Data,Typeable)++instance Pretty (CollectionInstance dec) where + pPrint (InstName _ s) = text s+-- pPrint (InstItemCol s exps) = text s <> pPrint exps -- WEIRD indent behaviour, commasep is ALSO weird+ pPrint (InstStepOrTags _ s exps) = text s <> parens (commacat exps)+ pPrint (InstItemCol _ s exps) = text s <> brackets (commacat exps)+ pPrint (InstStepCol _ s exps) = text s <> parens (commacat exps)+ pPrint (InstTagCol _ s exps) = text s <> angles (commacat exps)+++instance Decorated CollectionInstance where + mapDecor f inst = + case inst of + InstName s n -> InstName (f s) n + InstStepOrTags s n ls -> InstStepOrTags (f s) n (map (mapDecor f) ls)+ InstItemCol s n ls -> InstItemCol (f s) n (map (mapDecor f) ls)+ InstStepCol s n ls -> InstStepCol (f s) n (map (mapDecor f) ls)+ InstTagCol s n ls -> InstTagCol (f s) n (map (mapDecor f) ls)+ -- We follow a "left hand rule" for data structures that are not decorated but have decorated children.+ -- That is, pick the left-most child that has a decoration.+ getDecor inst = + case inst of + InstName s _ -> s+ InstStepOrTags s _ _ -> s+ InstItemCol s _ _ -> s+ InstStepCol s _ _ -> s+ InstTagCol s _ _ -> s+++----------------------------------------------------------------------------------------------------
+ Intel/Cnc/Spec/CncGrammar.y view
@@ -0,0 +1,369 @@+{+{-# LANGUAGE DeriveDataTypeable #-}+module Intel.Cnc.Spec.CncGrammar where++import Intel.Cnc.Spec.CncLexer hiding (main)+import Intel.Cnc.Spec.AST+import Intel.Cnc.Spec.SrcLoc++--import Data.Char+import StringTable.Atom+--import Data.Data+import Text.PrettyPrint.HughesPJClass+import Debug.Trace++}+-- (Based on example from Simon Marlow.)++-- These are similar macros to those used by the GHC parser:+-- define L0 L noSrcSpan+-- define L1 sL (getLoc $1)++-- Both arguments are Lexemes:++-- One or both arguments can be Decorated instead:+++++-- Here is a praticularly painful special case where we have a possibly+-- empty list on the right end. We take any source info that is there+-- and fall back to the second to last token otherwise.+++-- For now we enable BOTH the new syntax and the legacy one:+++-- First thing to declare is the name of your parser,+-- and the type of the tokens the parser reads.++%name parse_cnc+%tokentype { Lexeme }++-- The parser will be of type [Token] -> ?, where ? is determined by the+-- production rules. Now we declare all the possible tokens:++%token++ tuple { L _ LVarId "tuple" }++ var { L _ LVarId _ }+ qvar { L _ LQVarId _ }+ int { L _ LInteger _ }++ "->" { L _ LReservedOp "->" }+ "<-" { L _ LReservedOp "<-" }+ "::" { L _ LReservedOp "::" }++-- ':' { L _ LReservedOp ":" }+ ':' { L _ LSpecial ":" }++ '(' { L _ LSpecial "(" }+ ')' { L _ LSpecial ")" }+ '[' { L _ LSpecial "[" }+ ']' { L _ LSpecial "]" }+ ';' { L _ LSpecial ";" }+ ',' { L _ LSpecial "," }+ '<' { L _ LReservedOp "<" }+ '>' { L _ LReservedOp ">" }++ '=' { L _ LVarOp "=" }+ '+' { L _ LVarOp "+" }+ '-' { L _ LVarOp "-" }+-- '*' { L _ LVarOp "*" }+ '*' { L _ LSpecial "*" }+ '/' { L _ LVarOp "/" }+ op { L _ LVarOp _ }++-- step { L _ LReservedId "step" }+ mod { L _ LReservedId "module" }++ tags { L _ LReservedId "tags" }+ items { L _ LReservedId "items" }+ steps { L _ LReservedId "steps" }+ reductions { L _ LReservedId "reductions" }+ dense { L _ LReservedId "dense" }+ prescribes { L _ LReservedId "prescribes" }++ type { L _ LReservedId "type" }++-- FUTURE WORK: Reserving space in the grammar for presently+-- unimplemented features [2011.04.12]:+ constrain { L _ LReservedId "constrain" }++ eof { L _ LEOF _ }++-- comment { L _ LComment _ }+++-- The left hand side are the names of the terminals or tokens,+-- and the right hand side is how to pattern match them.++%nonassoc '<' '>' '<=' '>=' '==' '='+%left '+' '-'+%left '*' '/'++-- Like yacc, we include %% here, for no real reason.+%%++-- Now the production rules.+----------------------------------------------------------------------------------------------------+++File :: { [PStatement SrcSpan] }+File : Statements { $1 }++Statements : Statement Statements { $1 ++ $2 }+ | Statement { $1 }+ | eof { [] }++-- Statement : Terminated_Relation { [$1] }+-- | Terminated_Decl { $1 }+-- Terminated_Relation : Relation ';' { $1 }+-- Terminated_Decl : Decl ';' { $1 }++Statement : Relation ';' { [$1] }+ | Decl ';' { $1 }++ | type var '=' Type ';' { [TypeDef (lexPointSpan $2) (tAL $2) $4] }+-- | type var Type ';' { [TypeDef (lexPointSpan $2) (tAL $2) $3] }++ -- These are just for better errors:+ | Relation eof { parseErrorSDoc (getDecor $1) $ text "Premature end of file, possible missing semi-colon." }+ | Decl eof { parseErrorSDoc (getDecorLs $1) $ text "Premature end of file, possible missing semi-colon." }++-- reduce/reduce conflict+-- | Relation Instance { parseErrorSDoc (getDecor $2) $ text "Possible missing semi-colon." }++Decl :: { [PStatement SrcSpan] }+Decl+ : steps VarLs { map (\x -> DeclareSteps (lexSpan $1) (tAL x)) $2 }++ -- Here we try particularly hard to get good source location info:+ | constrain Instance ':' TagExps { [Constraints (cLLS $1 (lexSpan $3) $4) $2 $4] }+ -- One additional shift/reduce conflict if we do not use a separator:+ | constrain Instance TagExps { [Constraints (cLLS $1 (getDecor $2) $3) $2 $3] }+ --| constrain TagExps { [Constraints (lexSpan $1) (InstName "foo") []] }+ --| constrain Instance { [Constraints (lexSpan $1) (InstName "foo") []] }+ --| constrain var { [Constraints (lexSpan $1) (InstName "foo") []] }++{- #if 0 -}+ | Mods tags var { [DeclareTags (cLL $2 $3) (tAL $3) Nothing] }+ -- [2010.07.20] I am having a strange problem making Mods optional:+-- | Mods tags '<' Type '>' var { [DeclareTags (lexSpan $2) (lexStr $6) (Just $4)] }+ | Mod Mods tags '<' Type '>' var { [DeclareTags (cLL $3 $7) (tAL $7) (Just $5)] }+ | tags '<' Type '>' var { [DeclareTags (combineSrcSpans (lexSpan $1) (lexSpan $>)) (tAL $5) (Just $3)] }++-- TODO: Rearrange this so that the arbitrary numbers of template args+-- are accepted and an error is thrown if the wrong number are present:++ | Mods items var { [DeclareItems (cLL $2 $3) (tAL $3) Nothing] }+ | Mods items '<' Type ',' Type '>' var { [DeclareItems (cLL $2 $8) (tAL $8) (Just ($4, $6))] }++ -- Reductions are similar to item collections except they are parameterized by a reduction op.+ -- | Mods reductions var '(' var ')' { [DeclareReductions (cLL $2 $3) (tAL $3) (tAL $5) Nothing] }+ -- | Mods reductions '<' Type ',' Type '>' var '(' var ')'+ -- { [DeclareReductions (cLL $2 $8) (tAL $8) (tAL $10) (Just ($4, $6))] }++ | Mods reductions var '(' var ',' Exp ')' { [DeclareReductions (cLL $2 $3) (tAL $3) (tAL $5) $7 Nothing] }+ | Mods reductions '<' Type ',' Type '>' var '(' var ',' Exp ')'+ { [DeclareReductions (cLL $2 $10) (tAL $8) (tAL $10) $12 (Just ($4, $6))] }++++ | '<' Type var '>' { [DeclareTags (combineSrcSpans (lexSpan $1) (lexSpan $>)) (tAL $3) (Just $2)] }+ -- Inexplicable problem with this TagExps version, maybe because of '>' not being special...+ --| '<' Type var ':' TagExps '>' { [DeclareTags (lexSpan $3) (tAL $3) (Just $2)] }+ | '<' Type var ':' VarsOnlyHack '>' { [DeclareTags (combineSrcSpans (lexSpan $1) (lexSpan $>)) (tAL $3) (Just $2)] }++ | '[' Type var '<' Type '>' ':' TagExps ']' { [DeclareItems (combineSrcSpans (lexSpan $1) (lexSpan $>)) (tAL $3) (Just ($5, $2))] }+ | '[' Type var '<' Type '>' ']' { [DeclareItems (combineSrcSpans (lexSpan $1) (lexSpan $>)) (tAL $3) (Just ($5, $2))] }++++VarLs : var { [$1] }+ | var ',' VarLs { $1 : $3 }++-- Modifier keywords can precede declarations.+Mods : {- empty -} { [] }+ | Mod Mods { $1 : $2 }+Mod : dense { "dense" }++Relation :: { PStatement SrcSpan }+Relation : Instances Chain { Chain $1 $2 }++Chain :: { [RelLink SrcSpan] }+Chain : { [] }+-- | Link { [$1] }+ | Link Chain { $1 : $2 }+Link : "->" Instances { ProduceLink (lexSpan $1) $2 }+ | "<-" Instances { RevProduceLink (lexSpan $1) $2 }+ | "::" Instances { PrescribeLink (lexSpan $1) $2 }+ | prescribes Instances { PrescribeLink (lexSpan $1) $2 }++Instances :: { [CollectionInstance SrcSpan] }+Instances+ : { [] }+ | Instance { [$1] }+ | Instance ',' Instances { $1 : $3 }++Instance+ : var { InstName (lexSpan $1) (lexStr $1) }+ | var '[' TagExps ']' { InstItemCol (combineSrcSpans (lexSpan $1) (lexSpan $>)) (lexStr $1) $3 }+-- | var '<' TagExps '>' { InstStepOrTags (combineSrcSpans (lexSpan $1) (lexSpan $>)) (lexStr $1) $3 }+ | var '(' TagExps ')' { InstStepOrTags (combineSrcSpans (lexSpan $1) (lexSpan $>)) (lexStr $1) $3 }++ | '<' Var '>' { InstTagCol (combineSrcSpans (lexSpan $1) (lexSpan $>)) (lexStr $2) [] }+ | '(' Var ')' { InstStepCol (combineSrcSpans (lexSpan $1) (lexSpan $>)) (lexStr $2) [] }+ | '[' Var ']' { InstItemCol (combineSrcSpans (lexSpan $1) (lexSpan $>)) (lexStr $2) [] }+ -- TEMP FIXME: Again, problem here with full tag exps:+ | '<' Var ':' VarsOnlyHack '>' { InstTagCol (combineSrcSpans (lexSpan $1) (lexSpan $>)) (lexStr $2) $4 }+ | '(' Var ':' TagExps ')' { InstStepCol (combineSrcSpans (lexSpan $1) (lexSpan $>)) (lexStr $2) $4 }+ | '[' Var ':' TagExps ']' { InstItemCol (combineSrcSpans (lexSpan $1) (lexSpan $>)) (lexStr $2) $4 }+++TagExps :: { [Exp SrcSpan] }+TagExps : { [] }+ | Exp { [$1] }+ | Exp ',' TagExps { $1 : $3 }++-- TEMP, HACK:+VarsOnlyHack : { [] }+ | var { [Var (lexSpan $1) (tAL $1)] }+ | var ',' VarsOnlyHack { Var (lexSpan $1) (tAL $1) : $3 }+++-- This is just for catching errors:+Var : var { $1 }+ -- This error checking must be introduced CAREFULLY or it can yield errors. Not every position can be checked.++ -- Sadly, this error checking should go EVERYWHERE:+ | tags { parseErrorSDoc (lexSpan $1) $ text "Keyword 'tags' used incorrectly." }+ | items { parseErrorSDoc (lexSpan $1) $ text "Keyword 'items' used incorrectly." }+ | reductions { parseErrorSDoc (lexSpan $1) $ text "Keyword 'reductions' used incorrectly." }+ | steps { parseErrorSDoc (lexSpan $1) $ text "Keyword 'steps' used incorrectly." }+ | dense { parseErrorSDoc (lexSpan $1) $ text "Keyword 'dense' used incorrectly." }+ | prescribes { parseErrorSDoc (lexSpan $1) $ text "Keyword 'prescribes' used incorrectly." }+ | constrain { parseErrorSDoc (lexSpan $1) $ text "Keyword 'constrain' used incorrectly." }+ | mod { parseErrorSDoc (lexSpan $1) $ text "Keyword 'module' used incorrectly." }+-- | step { parseErrorSDoc (lexSpan $1) $ text "Keyword 'step' used incorrectly." }+++Exp :: { Exp SrcSpan } -- The haskell type of the result of parsing this syntax class.++Exp : var { Var (lexSpan $1) (tAL $1) }+ | qvar { Var (lexSpan $1) (tAL $1) }+ | int { Lit (lexSpan $1) (LitInt $ read (lexStr $1)) }+ | '(' Exp ')' { $2 }++ -- Function application:+ | var '(' TagExps ')' { App (combineSrcSpans (lexSpan $1) (getDecor (last $3)))+ (Var (lexSpan $1) (tAL $1)) $3 }++ -- Tuples? *** TODO ***.+++ -- Including explicit productions for arithmetic just to handle precedence/associativity:+ | Exp '+' Exp { App (combExpSpans $1 $3) (Var (combineSrcSpans (getDecor $1) (getDecor $>)) (toAtom "+")) [$1, $3] }+ | Exp '-' Exp { App (combExpSpans $1 $3) (Var (combineSrcSpans (getDecor $1) (getDecor $>)) (toAtom "-")) [$1, $3] }+ | Exp '*' Exp { App (combExpSpans $1 $3) (Var (combineSrcSpans (getDecor $1) (getDecor $>)) (toAtom "*")) [$1, $3] }+ | Exp '/' Exp { App (combExpSpans $1 $3) (Var (combineSrcSpans (getDecor $1) (getDecor $>)) (toAtom "/")) [$1, $3] }++ -- These need to be handled because they are lexed differently, being reserved characters:+ | Exp '<' Exp { App (combExpSpans $1 $3) (Var (combineSrcSpans (getDecor $1) (getDecor $>)) (toAtom "<")) [$1, $3] }+ | Exp '>' Exp { App (combExpSpans $1 $3) (Var (combineSrcSpans (getDecor $1) (getDecor $>)) (toAtom ">")) [$1, $3] }++ | Exp op Exp { App (combExpSpans $1 $3) (Var (combineSrcSpans (getDecor $1) (getDecor $>)) (tAL $2)) [$1, $3] }++Type+ : var { TSym (toAtom $ lexStr $1) }+ | dense Type { TDense $2 }+ | Type '*' { TPtr $1 }+ | '(' Types ')' { TTuple $2 }+ | tuple '<' Types '>' { TTuple $3 }++Types : { [] }+ | Type { [$1] }+ | Type ',' Types { $1 : $3 }+++-- We are simply returning the parsed data structure! Now we need+-- some extra code, to support this parser, and make in complete:++----------------------------------------------------------------------------------------------------+{++-- Combine two lexical tokens for a source span:+cLL a b = (lexSpan a) `combineSrcSpans` (lexSpan b)+-- more obscure, combine two tokens and the first (if it exists) of a list:+cLLS a b c = combineSrcSpans (lexSpan a) $ combineSrcSpans b (getDecorLs c)++getDecorLs [] = srcLocSpan noSrcLoc+getDecorLs (h:t) = getDecor h+++-- All parsers must declair this function, which is called when an error+-- is detected. Note that currently we do no error recovery.+happyError :: [Lexeme] -> a++happyError [] = error "Parse error. Strange - it's not before any token that I know of..."+happyError ls =+ let loc = lexLoc $ head ls in+ error$ "Parse error before token at location : \n " +++ show (pPrint loc) +++ (if srcColumn loc <= 1+ then "\n(An error at the beginning of the line like this could be a missing semi-colon on the previous line.)\n"+ else "")++parseErrorSDoc span doc =+ error $ show $ text "\n\nPARSE ERROR!\n " <> doc $$+ text "At location: " <> pPrint span++-- Now we declare the datastructure that we are parsing.++runCncParser :: String -> String -> [PStatement SrcSpan]+runCncParser file str =+ let notcomment = filter (not . is_comment) $ scan_to_list str in++ -- FIXME:+ -- Here's a hack that's a bit ineffecient. We POST-FACTO put the right filename in the+ -- sourceloc decorations. It would be better to do it right the first time.+ --+ -- NOTE [2010.07.23] This has another problem. Parse errors will say "unknown file".+ -- I guess I need to thread through a reader monad.+ map (mapDecor (srcSpanSetFileName file)) $+ -- For now filter out comments before parsing:+ if null notcomment+ then error "ERROR: Specification file contains no CnC statements!"+ else parse_cnc $ notcomment++is_comment ( L _ LComment _ ) = True+is_comment _ = False++lexStr :: Lexeme -> String+lexStr (L _ _ str) = str++tAL = toAtom . lexStr++lexLoc :: Lexeme -> SrcLoc+lexLoc (L (AlexPn n l c) _ _) = (SrcLoc "" l c)++lexSpan :: Lexeme -> SrcSpan+-- [2010.07.23] We can do a little better by looking at the length of+-- the string and stretching the src location to include all of it.+-- DANGER, we assume that Lexemes stay on one line!! (not true of multiline comments)+lexSpan (L (AlexPn n l c) _ str) =+ let start = mkSrcLoc "" l c+ end = mkSrcLoc "" l (c + length str)+ in srcLocSpan start `combineSrcSpans` srcLocSpan end++-- Not a span, just a single point:+--lexPointSpan (L (AlexPn n l c) _ _) = srcLocSpan (SrcLoc "unknownfile" l c)+lexPointSpan = srcLocSpan . lexLoc++-- Combine the spans in two expressions.+combExpSpans e1 e2 = combineSrcSpans (getDecor e1) (getDecor e2)++quit = print "runCnc failed\n"++}
+ Intel/Cnc/Spec/CncGraph.hs view
@@ -0,0 +1,177 @@+{-# LANGUAGE RecordWildCards, ScopedTypeVariables #-}+{-# OPTIONS_GHC -fwarn-incomplete-patterns #-}+----------------------------------------------------------------------------------------------------+-- Data types and utilities for working with CnC Specifications (Graphs)+-- Original Author: Ryan Newton+----------------------------------------------------------------------------------------------------+module Intel.Cnc.Spec.CncGraph ( + CncSpec (..), CncGraph, + CncGraphNode (..), ColName, graphNodeName, isStepC, isReductionC, isTagC, isItemC,+ + upstreamNbrs, downstreamNbrs, builtinSteps,+ getStepPrescriber+ + ) where++import Intel.Cnc.Spec.Util +import Intel.Cnc.Spec.AST+import Intel.Cnc.Spec.TagFun+import Data.List as L+import Data.Maybe+import Data.Map+import StringTable.Atom +import StringTable.AtomMap as AM+import StringTable.AtomSet as AS+import Text.PrettyPrint.HughesPJClass hiding (Style)+import Data.Graph.Inductive as G++-- | The total "Spec" includes the graph and other metadata.+data CncSpec = CncSpec {+ -- | steps, tags, items include all top-level collections in the graph.+ steps :: AtomSet,+ tags :: AtomMap (Maybe Type),+ items :: AtomMap (Maybe (Type,Type)),+ reductions :: AtomMap (Atom, Exp (), Maybe (Type,Type)), -- Contains 'op' and type.++ graph :: CncGraph,++ -- | appname is metadata, usually corresponding to the name of the .cnc file.+ appname :: String,+ -- Might as well cache this after it is extracted, used by FGL calls:+ nodemap :: NodeMap CncGraphNode,+ -- Annoyingly, FGL nodemaps are essentially unreadable and useless, hence this:+ realmap :: Map CncGraphNode Node,++ -- We store the graph in a "flat" form and separately keep a tree of partitions:+ harchtree :: ()+}+-- deriving (Eq, Ord)++-- | The CnCGraph is a raw graph object without additional metadata and indexes.+-- +-- NOTE: If a step peforms multiple gets/puts those are treated as+-- SEPARATE EDGES in the graph currently. (There is no notion of a+-- TagFun returning a set of tags, but that may change.)+type CncGraph = (Gr CncGraphNode (Maybe TagFun))++type ColName = Atom++builtinSteps = [toAtom special_environment_name]++-- | The name of a collection, together with the type of collection (step/item/etc).+data CncGraphNode = + CGSteps ColName + | CGTags ColName + | CGItems ColName + | CGReductions ColName + deriving (Eq, Ord, Show)++graphNodeName (CGSteps n) = fromAtom n+graphNodeName (CGTags n) = fromAtom n+graphNodeName (CGItems n) = fromAtom n+graphNodeName (CGReductions n) = fromAtom n++instance Pretty CncGraphNode where+ pPrint = text . show ++instance Show CncSpec where+ show = show . pPrint++instance Pretty CncSpec where+ pPrint (CncSpec{..}) = + text "CncSpec{\n ------------- All Steps ----------------------" $$ + hcat (intersperse (text ", ") $ L.map (text . fromAtom) $ AS.toList steps) $$+ text "\n ------------- Tag Types ----------------------" $$ + sep (L.map (\(x,y) -> pp((fromAtom x)::String,y)) $ AM.toList tags) $$+ text "\n ------------- Item Types ---------------------" $$ + sep (L.map (\(x,y) -> pp((fromAtom x)::String,y)) $ AM.toList items) $$++ text "\n ----------- Reduction Ops/Types --------------" $$ + sep (L.map (\(x,y) -> pp((fromAtom x)::String,y)) $ AM.toList reductions) $$++ text "\n ----------------- FGL Graph ------------------" $$ + text (show graph) $$+ text "}"+++----------------------------------------------------------------------------------------------------++-- TODO: Perform basic checks here.+--verifySpec :: CncSpec -> CncSpec+verifySpec spec = + spec+ -- All steps are prescribed.+ -- All tags/items have types (for now, for C++)+ -- ++----------------------------------------------------------------------------------------------------+++-- | Go over all the edges from a step collection and collect their+-- contributions to getcounts of neighboring item collections.+stepGetCountContributions :: CncSpec -> ColName -> Map ColName Int+-- For now getcounts are simple (static) numbers. Dynamically+-- valued getcounts may be a useful feature in the future.+stepGetCountContributions spec stepC =+ let + nbrs = L.filter isItemC $ + upstreamNbrs spec (CGSteps stepC)+ in + undefined+++-- Get the name of the tag collection that prescribes a given step.+getStepPrescriber :: CncSpec -> ColName -> ColName+getStepPrescriber (CncSpec{..}) atom = + case L.filter isTagC labs of + [CGTags t] -> t+ ls -> error$ "getStepPrescriber step "++ (fromAtom atom) ++ + " should have exactly one prescribing tag collection, not "++ show (length ls)+ where + (nd,_) = mkNode_ nodemap (CGSteps atom)+ preds = pre graph nd+ labs = catMaybes$ L.map (lab graph) preds++isTagC (CGTags _) = True+isTagC _ = False+isItemC (CGItems _) = True+isItemC _ = False+isStepC (CGSteps _) = True+isStepC _ = False+isReductionC (CGReductions _) = True+isReductionC _ = False+++----------------------------------------------------------------------------------------------------++-- | Get upstream neighbors in the CnC graph.+-- This routine sees *through* tag collections.+-- Returns a list of STEP and ITEM collections.+upstreamNbrs :: CncSpec -> CncGraphNode -> [CncGraphNode]+upstreamNbrs = nbrHelper pre++-- | Get downstream neighbors in the CnC graph.+-- This routine sees *through* tag collections.+-- Returns a list of STEP and ITEM collections.+downstreamNbrs :: CncSpec -> CncGraphNode -> [CncGraphNode]+downstreamNbrs = nbrHelper suc++nbrHelper adjacent (spec@CncSpec{..}) nodelab = + if gelem nd graph + then L.concat$ L.map process labs+ else error$ "upstream/downstream: cannot find neighbors because node is not in graph: "++ show nodelab+ where + (nd,_) = mkNode_ nodemap nodelab+ labs = catMaybes$ L.map (lab graph) (adjacent graph nd)+ process x@(CGSteps _) = [x]+ process x@(CGItems _) = [x]+ process x@(CGReductions _) = [x]+ process x@(CGTags _) = nbrHelper adjacent spec x+++-- | Extract a subgraph of the full CnC graph that only contains step collections (including 'env').+stepOnlyGraph :: CncGraph -> Gr ColName ()+stepOnlyGraph = error "stepOnlyGraph: TODO: implement me"+++----------------------------------------------------------------------------------------------------
+ Intel/Cnc/Spec/CncLexer.x view
@@ -0,0 +1,217 @@++{+module Intel.Cnc.Spec.CncLexer where+-- import Debug.Trace+}++%wrapper "monad"++-- Based on example from Happy distribution.++-- First some useful macros:+----------------------------------------------------------------------------------------------------+$whitechar = [ \t\n\r\f\v]+-- RRN [2010.07.19] Moving asterisk to special category:+-- This may be a bad idea wrt extensibility.+-- Moving colon to the special category too.+$special = [\(\)\,\;\[\]\`\{\}\*\:]++$digit = 0-9+$large = [A-Z \xc0-\xd6 \xd8-\xde]+$small = [a-z \xdf-\xf6 \xf8-\xff \_]+$alpha = [$small $large]++$ascsymbol = [\!\#\$\%\&\+\.\/\<\=\>\?\@\\\^\|\-\~]+$symbol = [$ascsymbol] # [$special \_\:\"\']++-- Almost everything:+$graphic = [$small $large $symbol $digit $special \:\"\']++$idchar = [$alpha $digit \']+--$symchar = [$symbol \:]+$symchar = [$symbol ]++-- These are the KEYWORDS for the language:+@reservedid = + module|fun|tags|items|reductions|steps|dense|constrain|prescribes|type+--step++@reservedop =+ "::" | "|" | "<-" | "->" | "{" | "}" | "<" | ">" +-- | "[" | "]" + -- | "*" | "+"++@varid = $idchar++@capid = $large $idchar*++-- So called "ops" are usually infix and start with punctuation:+@varop = $symbol $symchar*+--@consym = \: $symchar*++@decimal = $digit++@exponent = [eE] [\-\+] @decimal++$cntrl = [$large \@\[\\\]\^\_]+@ascii = \^ $cntrl | NUL | SOH | STX | ETX | EOT | ENQ | ACK+ | BEL | BS | HT | LF | VT | FF | CR | SO | SI | DLE+ | DC1 | DC2 | DC3 | DC4 | NAK | SYN | ETB | CAN | EM+ | SUB | ESC | FS | GS | RS | US | SP | DEL+$charesc = [abfnrtv\\\"\'\&]+@escape = \\ ($charesc | @ascii | @decimal )+@gap = \\ $whitechar+ \\+@string = $graphic # [\"\\] | " " | @escape | @gap++++-- Here are the productions themselves:+----------------------------------------------------------------------------------------------------+haskell :-++<0> $white+ { skip }++-- <0> "//"\-*[^$symbol].* { mkL LComment }+<0> "//".* { mkL LComment }+"/*" { nested_comment }++<0> $special { mkL LSpecial }++<0> @reservedid { mkL LReservedId }+<0> ( @capid \. )+ @varid { mkL LQVarId }+<0> @varid { mkL LVarId }+<0> @capid { mkL LCapid }++<0> @reservedop { mkL LReservedOp }+<0> ( @capid \. )+ @varop { mkL LVarOp }+--<0> @capid \. @consym { mkL LConSym }+<0> @varop { mkL LVarOp }+--<0> @consym { mkL LConSym }++<0> @decimal \. @decimal + | @decimal \. @decimal @exponent ?+ | @decimal @exponent { mkL LFloat }++<0> @decimal { mkL LInteger }++<0> \' ($graphic # [\'\\] | " " | @escape) \'+ { mkL LChar }+<0> \" @string* \" { mkL LString }++++----------------------------------------------------------------------------------------------------+{ -- Begin Haskell code block to include in output:++-- The type of tokens:+data Lexeme = L AlexPosn LexemeClass String+ deriving Show++data LexemeClass+ = LInteger+ | LFloat+ | LChar+ | LString+ + | LComment++ | LSpecial+ | LReservedId+ | LReservedOp+ | LVarId+ | LQVarId+ | LCapid+ | LQCapid+ | LVarOp+ | LQVarOp+-- | LConSym+-- | LQConSym+ | LEOF+ deriving (Eq, Show)+ +-- Handle a common case: create one token +mkL :: LexemeClass -> AlexInput -> Int -> Alex Lexeme+mkL c (p,_,str) len = return (L p c (take len str))+++-- This handles arbitrarily nested comments:+nested_comment :: AlexInput -> Int -> Alex Lexeme+nested_comment (apos, chr, str) int = do+ input <- alexGetInput+ go 1 input "*/"+ -- When finished, set the position to after the comment ('input')+-- where go 0 input acc = do alexSetInput input; alexMonadScan+ where go 0 input acc = do alexSetInput input; (mkL LComment (apos,chr, reverse acc) (length acc))+ go n input acc = do+ -- The 'n' parameter here keepstrack of the nesting.+ let prev = alexInputPrevChar input + case alexGetChar input of+ Nothing -> err input+ Just (c,input) -> do+ case c of++ -- We've got a potential comment ENDING:+ '/' -> do+ case prev of+ ('*') -> go (n-1) input ('/':acc) -- CLOSE a level.+ (c) -> go n input ('/':acc)+ + -- Here we've got another comment BEGINNING:+ '*' -> do+ case prev of+ ('/') -> go (n+1) input ('*':acc) -- OPEN a level+ (c) -> go n input ('*':acc)++ -- Other characters: add to the pile and keep going:+ c -> go n input (c:acc)++ err input = do alexSetInput input; lexError "error in nested comment" +++lexError :: String -> Alex b +lexError s = do+ (p,c,input) <- alexGetInput+ alexError (showPosn p ++ ": " ++ s ++ + (if (not (null input))+ then " before " ++ show (head input)+ else " at end of file"))++-- Returns either a list of tokens or an error:+scan_to_list :: String -> [Lexeme]+scan_to_list str = + case result of + Left err -> error$ "Error in lexing stage:\n" ++ err+ Right ls -> ls+ where + result = runAlex str $ do+{-+-- TODO: get line number for lex error:+ let loop i = do tok@(L _ cl _) <- alexMonadScan; +-} +-- Maybe we can hack the monad here by replacing bind with our own version.+ let loop i = do tok@(L _ cl _) <- alexMonadScan; + if cl == LEOF+ then return [tok]+ else do ls <- loop $! (i+1)+ return (tok:ls)+ loop 0+++--alexEOF = return (L (error "EOF has no position") LEOF "")+alexEOF = return (L (AlexPn (-1) (-1) (-1)) LEOF "")+--alexEOF = return (L (noSrcLoc) LEOF "")++showPosn (AlexPn _ line col) = "line " ++ show line ++ ", col " ++ show col++main = do+ putStrLn "HEllo!\n"+ s <- getContents+ --s <- getLine+ --print (scanner s)+ sequence_ (map print $ scan_to_list s)+ -- case scan_to_list s of + -- Left err -> print err+ -- Right ls -> sequence_ (map print ls)++} -- End final code block:+++
+ Intel/Cnc/Spec/CncViz.hs view
@@ -0,0 +1,535 @@+{-# LANGUAGE RecordWildCards, NamedFieldPuns, ScopedTypeVariables #-}++----------------------------------------------------------------------------------------------------+-- This module includes visualization code which has numerous extra+-- dependencies compared to the rest of the spec tool's code.+----------------------------------------------------------------------------------------------------+module Intel.Cnc.Spec.CncViz where++import Intel.Cnc.Spec.TraceVacuum+import Intel.Cnc.Spec.CncGraph+import Intel.Cnc.Spec.Curses+import Intel.Cnc.Spec.Util+import qualified Intel.Cnc.Spec.Passes.ReadHarch as H++import qualified Data.Graph.Inductive as G+import Data.Graph.Inductive.Query.DFS+import Data.Maybe+import Data.Char+import qualified Data.ByteString.Char8 as B+import qualified Data.Map as M+import qualified Data.IntMap as IM+import qualified Data.Set as S+import qualified Data.List as L++import qualified StringTable.AtomSet as AS+import qualified StringTable.AtomMap as AM+import StringTable.Atom ++import Control.Monad+import qualified Control.Monad.Reader as R++import Graphics.Ubigraph as Ub+import qualified Data.GraphViz as Gv++import System.Posix.Unistd+import System.Posix.Env++-- There are various options for trying to improve the stringmaps used in this program:+--+--import qualified Data.Map.StringMap as SM -- from TernaryTrees+--import qualified Data.Map.TernaryMap as TM -- from TernaryTrees++--import qualified Data.ListTrie.Patricia.Map as PM++import qualified Data.Map as SM -- Data.Map serves as StringMap for now.++import Debug.Trace++default_server_url = "http://127.0.0.1:20738/RPC2"++----------------------------------------------------------------------------------------------------+-- Graph Visualization++-- Draw a cnc spec through graphviz:+cncGraphviz = + -- This is easy because the graphviz wrapper uses fgl.+ error "TODO: IMPLEMENT ME"+++--------------------------------------------------------------------------------+-- Display a cncgraph through ubigraph:+++cncUbigraph :: Bool -> CncGraph -> IO ()+cncUbigraph interactive gr = + do server_url <- getEnvDefault "UBIGRAPH_SERVER" default_server_url+ putStrLn$ "DRAWING UBIGRAPH, total nodes "++ show (length sorted)+ initHubigraph server_url >>= runHubigraph go+ --r $ mkRing 10+ where + r x = initHubigraph default_server_url >>= runHubigraph x++ sorted = topsort gr+ contexts = map (G.context gr) sorted++ go = do + clear+ stepstyle <- newVStyle 0+ itemstyle <- newVStyle 0+ tagstyle <- newVStyle 0+ mapM_ (flip setVStyleAttr stepstyle) (defaultStepAttr)+ mapM_ (flip setVStyleAttr itemstyle) (defaultItemAttr)+ mapM_ (flip setVStyleAttr tagstyle) (defaultTagAttr)++ --let eshared = [EOriented True, ESpline True, EStrength 1.0]+ --let eshared = [EOriented True, ESpline True, EStrength 0.001]+ let eshared = [EOriented True]+ -- EArrow True++ baseEstyle <- newEStyle 0+ mapM_ (flip setEStyleAttr baseEstyle) eshared++ producestyle <- newEStyle baseEstyle+ consumestyle <- newEStyle baseEstyle+ prescribestyle <- newEStyle baseEstyle++ mapM_ (flip setEStyleAttr producestyle)$ [EColor "#ff4444", EWidth 2.5] + mapM_ (flip setEStyleAttr consumestyle)$ [EColor "#44ff44", EWidth 2.5] + mapM_ (flip setEStyleAttr prescribestyle)$ [EColor "#666666"] ++ eshared++ -- Currently doing a two-phased add, but I don't actually like this:+ -- (I want to see it appear with the dataflow.)++ forM_ contexts $ \ (prev, id, label, _) -> + do newVertexWithID id + case label of + CGSteps atom -> + do changeVStyle stepstyle id + setVAttr (VLabel$ fromAtom atom) id + if fromAtom atom == special_environment_name+ then do setVAttr (VColor "#ffff00") id + setVAttr (VLabel "env IN") id + newVertexWithID (-1)+ changeVStyle stepstyle (-1)+ setVAttr (VLabel "env OUT") (-1)+ setVAttr (VColor "#ffff00") (-1)+ else return False++ CGItems atom -> + do changeVStyle itemstyle id + setVAttr (VLabel$ fromAtom atom) id ++ CGTags atom -> + do changeVStyle tagstyle id + setVAttr (VLabel$ fromAtom atom) id +++-- FIXME!!! DOUBLE CHECK.. do GET edges flow from the ITEM to the STEP? (re: gravity)+ forM_ contexts $ \ (prev, id, label, _) -> + forM_ prev $ \ (_,p) -> + case label of + CGSteps a | fromAtom a == special_environment_name -> + do edge <- newEdge (p,-1)+ changeEStyle consumestyle edge+ _ ->+ do edge <- newEdge (p,id)+ (flip changeEStyle edge) + (case fromJust$ G.lab gr p of + (CGSteps _) -> producestyle+ (CGItems _) -> consumestyle+ (CGTags _) -> prescribestyle)++ -- ABSTRACTION VIOLATION? Is the hubigraph monad supposed to be opaque?+ -- In interactive mode we bring up a prompt... should do this with ncurses:+ R.lift$ putStrLn "Going into interactive CnC/Ubigraph visualization shell:"+ ++-- | Visualize any FGL graph in a window using GraphViz.+simple_graphviz :: (nd1 -> String) -> G.Gr nd1 edge -> IO Gv.RunResult+simple_graphviz lablNode gr = +-- runGraphvizCanvas Dot dot Gtk+ Gv.runGraphvizCanvas Gv.Dot dot Gv.Xlib+ where + dot = Gv.graphToDot params gr+ --params :: GraphvizParams String Int () String+ --params :: GraphvizParams String unknown () String+ --params :: GraphvizParams nd1 edge () nd1+ --params = defaultParams { fmtNode= nodeAttrs }+ params = Gv.nonClusteredParams { Gv.fmtNode= nodeAttrs }+ nodeAttrs (node, x) =+ [ Gv.Label $ Gv.StrLabel $ lablNode x+ , Gv.Shape Gv.Circle+ -- , Color [colors !! a]+ -- , FillColor $ colors !! a+ , Gv.Style [Gv.SItem Gv.Filled []]+ ]++-- | Using GraphViz, display a CnC graph with Harch partitioning info.+harch_graphviz :: (H.HarchNode -> String) -> H.HarchSpec -> IO Gv.RunResult+harch_graphviz lablNode (H.HarchSpec gr tree) = + Gv.runGraphvizCanvas Gv.Dot (Gv.graphToDot params gr) Gv.Xlib+ where + params :: Gv.GraphvizParams H.HarchNode () [Int] H.HarchNode+ params = Gv.defaultParams + { Gv.fmtNode= nodeAttrs+ , Gv.clusterBy = lookup_clusters+ , Gv.clusterID = \ ls -> Just$ Gv.Str (show ls)+ , Gv.fmtCluster = clusterAttrs+ }++ -- We must take care here... there are two different numbering+ -- schemes. The FGL graph has a node ID, an the HarchNode has the+ -- number from the original harch file. It would be nice to+ -- guarantee these are the same, or to make them disjoint so that+ -- confusion is impossible.+ lookup_clusters :: (G.LNode H.HarchNode) -> Gv.LNodeCluster [Int] H.HarchNode+ lookup_clusters (ind, nd) = + case IM.lookup (H.num nd) all_clusters of+ Nothing -> error$ "harch_graphviz: node that did not appear in the harch tree: "++ show nd+ Just set -> + -- Convert the set using the C/N constructors:+ S.fold (Gv.C) (Gv.N (ind,nd)) set++ all_clusters = walk_tree [] tree++ -- Walk over the tree to build a map from nodes -> partitions.+ -- Partitions are named by the tree-index.+ walk_tree :: [Int] -> H.HarchTreeOrdered -> IM.IntMap (S.Set [Int])+ walk_tree ind (H.HT part children) = + let + chldmaps = L.zipWith (\ i -> walk_tree (ind++[i]) ) + [0..] children+ combined = L.foldl' (IM.unionWith S.union) IM.empty chldmaps++ insert acc node = IM.insertWith S.union node (S.singleton ind) acc+ in L.foldl' insert combined part++ clusterAttrs intls = + [ Gv.GraphAttrs [Gv.Label$ Gv.StrLabel$ H.showTreePath intls ] ]++ nodeAttrs (node, x) =+ [ Gv.Label $ Gv.StrLabel $ lablNode x+ , Gv.Shape Gv.Circle+ -- , Color [colors !! a]+ -- , FillColor $ colors !! a+ , Gv.Style [Gv.SItem Gv.Filled []]+ ]++++----------------------------------------------------------------------------------------------------+-- Rewind/fast-forward support++-- What's the best way to create a reversible transaction log?+-- Should I create Data.Sequence of some kind of actions and interpret it?+++data GUIAction =+ ChangeV NameTag [VAttr]+ | ChangeE Atom Atom EAttr+ | AddV NameTag+ | AddE NameTag NameTag+ | WaitAction -- We don't sleep between ALL actions, let's make them explicit.+ deriving Show++-- This is a little more involved than I would like, but we may need+-- to track the whole state of the drawing at each point in time.+--+-- The GUI state also lets us know what's in the graph at any given point.+data GUIState = GS {+ nodes :: AM.AtomMap GUINodeState, + edges :: AM.AtomMap (AM.AtomMap GUIEdgeState),+ -- Map steps to the tag collections that prescribe them.+ prescribedBy :: AM.AtomMap Atom+ }+++-- The V/EAttr types are sum types that we wish to convert to a product type here...+{-+data GUINodeState = GNS {+ color :: String, + label :: String,+ shape :: Ub.Shape,+ size :: Float+ -- ...+ }+-}+-- We could get into SYB generic programming here, but easier is to+-- use the toPair function provided by the ubigraph library.+--type GUINodeState = SM.StringMap (String)+type StringMap a = M.Map String a +-- The following StringMaps map the name ("size", "label") of each attribute onto its value.+type GUIEdgeState = StringMap EAttr+-- I also add a "count" to nodes to track how many instances they contain.+data GUINodeState = GNS { count :: Int, props :: StringMap VAttr }+ deriving Show++--type LogEvent = (GUIAction, GUIState)++instance Show VAttr where +-- show vat = show (toPair vat)+ show vat = let (hd:tl,b) = toPair vat in "V"++ (toUpper hd : tl) ++" "++ b ++instance Show EAttr where + show eat = show (toPair eat)++--------------------------------------------------------------------------------++-- foo :: SM.StringMap Int+-- foo = SM.fromList [("foo",3), ("bar", 4)]+-- bar = TM.lookup "foo" foo+scale = 3.0+defaultStepMap = SM.fromList [("color", VColor "#3333ff"), ("shape", VShape Sphere), + ("size", VSize (1.0 * scale)), ("shapedetail", VShapedetail 10), ("visible", VVisible True)]+defaultItemMap = SM.fromList [("color", VColor "#008800"), ("shape", VShape Cube), ("size", VSize (0.75 * scale)), ("visible", VVisible True)]+defaultTagMap = SM.fromList [("color", VColor "#555555"), ("shape", VShape Octahedron), ("size", VSize (0.4 * scale)), ("visible", VVisible True)]++-- For convenience, here are the default attributes as lists:+defaultStepAttr = map snd$ SM.toList defaultStepMap+defaultItemAttr = map snd$ SM.toList defaultItemMap+defaultTagAttr = map snd$ SM.toList defaultTagMap++-- The environment appears as a tweaked step:+defaultEnvAttr = map snd $ SM.toList $ + SM.insert "color" (VColor "#ffff00") $ + SM.insert "label" (VLabel "env IN") $ + defaultStepMap++++named def nm = SM.insert "label" vlab $+ -- This is a property of my own that I add for future reference:+ --SM.insert "origname" vlab $ + def+ where vlab = VLabel$ fromAtom nm++namedStep = named defaultStepMap+++emptyGUIState = GS AM.empty AM.empty AM.empty++--pump_size = False+pump_size = True++--------------------------------------------------------------------------------+-- Convert a parsed trace into a series of GUI actions:+-- Two distinct behaviors.+--+-- Drawing collections ():+-- Steps are indexed with an empty ("") tag. Each additional+-- instance added to a collection may change its appearance but+-- will not add a new node.+-- +-- Drawing instances (full_dynamic_graph):++-- Draw the "dynamic graph" of step instances. Instances are+-- identified by a pair of their collection name and a string+-- representing a tag value.+++traceToGUI :: [CncTraceEvent] -> [GUIAction]+traceToGUI trace =+ AddV envpr : ChangeV envpr defaultEnvAttr :+ loop emptyGUIState trace+ where + envpr = (toAtom special_environment_name, B.pack "")+ loop _ [] = []+ loop state0@GS{..} (hd:tl) = + let -- When drawing step collections we may "pump them up" as we get more instances:+ -- (This function also continues the loop, so it's called as a continuation.)+ pump_up_instance (nm,tag) gns@GNS{..} = + if full_dynamic_graph+ then keep_going+ else ChangeV (nm,tag) [VLabel$ oldlab ++" #"++ show (count+1), newsize] : keep_going+ where + keep_going = loop state0{ nodes= newnodes } tl + newnodes = AM.insert nm gns{count=count+1, props=props'} nodes++ VLabel oldlab = props SM.! "label" + -- Experimenting with growing the size too:+ VSize oldsize = props SM.! "size"+ newsize = VSize$ oldsize + 0.1+ props' = if pump_size then SM.insert "size" newsize props else props++ newstate nm attrs = state0{ nodes = AM.insert nm (GNS 1 attrs) nodes }+ in+ case hd of + Prescribe tags step -> + let state1 = state0{ prescribedBy= AM.insert step tags prescribedBy } in+ -- When drawing+ if full_dynamic_graph+ then loop state1 tl+ else AddV (step, B.pack "") : loop state1 tl++ ------------------------------------------------------------+ StartStep pr@(nm,tg) -> + case AM.lookup nm prescribedBy of + Nothing -> error$ "traceToGUI: no Prescribe relation corresponding to step "++show nm+ Just tags -> + -- Add an edge connecting the tag [collection] to the step [collection]:+ let edge = AddE (tags,tg) pr+ vertedge = [AddV pr, edge, ChangeV pr defaultStepAttr, WaitAction] in+ (if full_dynamic_graph then vertedge else []) +++ case AM.lookup nm nodes of+ Nothing -> loop (newstate nm$ namedStep nm) tl+ Just gns -> pump_up_instance pr gns ++ ------------------------------------------------------------+ PutT (stepnm,stag) tpr@(tgnm,_) -> + let edge = AddE (stepnm,stag) tpr + vertedge = [AddV tpr, edge, ChangeV tpr defaultTagAttr, WaitAction] in+ case AM.lookup tgnm nodes of + Nothing -> vertedge ++ loop (newstate tgnm$ named defaultTagMap tgnm) tl+ Just gns -> (if full_dynamic_graph then vertedge else [])+ ++ pump_up_instance tpr gns+ + ------------------------------------------------------------+ PutI (stepnm,stag) ipr@(inm,_) -> + let edge = AddE (stepnm,stag) ipr + vertedge = [AddV ipr, edge, ChangeV ipr defaultItemAttr, WaitAction] in+ case AM.lookup inm nodes of + Nothing -> vertedge ++ loop (newstate inm$ named defaultItemMap inm) tl+ Just gns -> (if full_dynamic_graph then vertedge else [])+ ++ pump_up_instance ipr gns++ ------------------------------------------------------------+ GetI (stepnm,stag) ipr@(inm,_) -> + let edge = AddE (stepnm,stag) ipr in+ case AM.lookup inm nodes of + Nothing -> --AddV ipr : + --ChangeV ipr defaultItemAttr :+ edge : loop (newstate inm$ named defaultItemMap inm) tl+ _ -> edge : loop state0 tl+++ _ -> loop state0 tl+ -- EndStep NameTag + -- FAIL String+++++t29 = traceToGUI $ parseCncTrace sample_trace++t30 = playback emptyGUIState t29 ++----------------------------------------------------------------------------------------------------+-- Another way to do it would be to construct a reverse-log as we go,+-- for each attribute set, store a command which woud set it back to+-- the old attribute.+----------------------------------------------------------------------------------------------------++-- playback takes a forward and reverse sequence of actions. To play+-- forward it reads from one tape, and reverse the other. +-- It also must model the state of the GUI to be able to reverse actions.++--playback :: GUIState -> [GUIAction] -> [GUIAction] -> IO ()++playback :: GUIState -> [GUIAction] -> IO ()++-- Should we actually create a node for every dynamic instance?+full_dynamic_graph = False+++playback state fwd = + do server_url <- getEnvDefault "UBIGRAPH_SERVER" default_server_url+ putStrLn$ cnctag++"Visualizing trace using ubigraph."+ initHubigraph server_url >>= runHubigraph initialize+ where + r x = initHubigraph default_server_url >>= runHubigraph x++ initialize = do + clear++ setVStyleAttr (VVisible False) 0+ setVStyleAttr (VColor "#ff0000") 0++ stepstyle <- newVStyle 0+ itemstyle <- newVStyle 0+ tagstyle <- newVStyle 0++ mapM_ (flip setVStyleAttr stepstyle) (defaultStepAttr)+ mapM_ (flip setVStyleAttr itemstyle) (defaultItemAttr)+ mapM_ (flip setVStyleAttr tagstyle) (defaultTagAttr)++ --let eshared = [EOriented True, ESpline True, EStrength 0.001]+ let eshared = [EOriented True, ESpline True, EStrength 0.0]+ --let eshared = [EOriented True]+ baseEstyle <- newEStyle 0+ mapM_ (flip setEStyleAttr baseEstyle) eshared++ producestyle <- newEStyle baseEstyle+ consumestyle <- newEStyle baseEstyle+ prescribestyle <- newEStyle baseEstyle++ mapM_ (flip setEStyleAttr producestyle)$ [EColor "#ff4444", EWidth 2.5] + mapM_ (flip setEStyleAttr consumestyle)$ [EColor "#44ff44", EWidth 2.5] + mapM_ (flip setEStyleAttr prescribestyle)$ [EColor "#666666"] ++ eshared++ --------------------------------------------------------------------------------+ -- Main loop+ --------------------------------------------------------------------------------+ let step_forward idmap fwd = + case fwd of + [] -> do R.lift$ putStrLn "playback finished: no more actions!"+ return idmap+ hd:tl -> + case hd of + AddV pr@(atom, tag) -> + do id <- newVertex+-- setVAttr (VLabel$ B.concat [fromAtom atom, B.pack " ", tag]) id + setVAttr (VLabel$ fromAtom atom ++ " " ++ B.unpack tag) id + return$ M.insert pr id idmap++ ChangeV pr updates -> + do let id = idmap M.! pr+ mapM_ (flip setVAttr id) updates+ return idmap+++ AddE from to -> + do --R.lift$ putStrLn$ "ADDING EDGE "++ show from ++" "++ show to+ let from' = M.lookup from idmap + to' = M.lookup to idmap+ case (M.lookup from idmap, M.lookup to idmap) of + (Just from', Just to') -> do + id <- newEdge (from', to')+ changeEStyle producestyle id + return idmap+ (Nothing,_) -> do R.lift$ putStrLn$ ("Warning: Missing source of AddE edge! "++show from)+ return idmap+ (_,Nothing) -> do R.lift$ putStrLn$ ("Warning: Missing destination of AddE edge! "++show to)+ return idmap++ WaitAction -> do R.lift$ usleep (300 * 1000) -- 0.1 second sleep.+ return idmap+ _ -> return idmap+ --x -> error$ "playback: unhandled GUIAction: "++ show x++ -- For now just play forward, maximum speed:+ let loop idmap state rvrs fwd = + do newidmap <- step_forward idmap fwd + --R.lift$ usleep (100 * 1000)+ --Control.Concurrent.threadDelay+ loop newidmap+ (error "no state atm") --(updateState state hd) + (error "no rev action") --(buildRevAction state hd : rvrs) + (tail fwd)+ loop (M.fromList [((toAtom special_environment_name, B.pack ""), envID)])+ state [] fwd++-- This simply needs to not conflict with the auto-assigned Ubigraph ids:+envID = 1+++deJust msg Nothing = error msg+deJust _ (Just x) = x++updateState = error "updateState"+buildRevAction = error "buildRevAction"++ -- It also must model the state ++-- loop state +
@@ -0,0 +1,53 @@+{-# LANGUAGE ScopedTypeVariables, OverloadedStrings, NamedFieldPuns #-}++-- NOTES+-- It would be nice for plugins to be able to invoke methods of all other plugins...++-- TODO / FIXME:+-- whenDone hook can be removed now.++-- Environment will currently be decremented below zero because of+-- upstream reduction collections.. only active collections should+-- count for that.++--------------------------------------------------------------------------------++module Intel.Cnc.Spec.Codegen.CodegenShared +where++import Intel.Cnc.Spec.Codegen.Plugins++----------------------------------------------------------------------------------------------------+-- This datatype stores the configuration information for backend acode generation.+----------------------------------------------------------------------------------------------------++data CodeGenConfig = CodeGenConfig + { cgverbosity :: Bool + , old_05_api :: Bool+ , genstepdefs :: Bool+ , gentracing :: Bool+ , gendepends :: Bool+ , gendebug :: Bool+ , wrapall :: Bool -- wrap ALL collections no matter what+ , plugins :: [CodeGenPlugin]+ , done_plugins :: [DonePlugin]++ -- Debug flags:+ , debug_autodone :: Bool+ -- , debug_* :: Bool+ }+ deriving Show++default_codegen_config = + CodeGenConfig + { cgverbosity = False + , old_05_api = False+ , genstepdefs = True+ , gentracing = False+ , gendepends = False+ , gendebug = False+ , wrapall = False+ , done_plugins = []+ , plugins = []+ , debug_autodone = False + }
+ Intel/Cnc/Spec/Codegen/CppOld.hs view
@@ -0,0 +1,863 @@+{-# LANGUAGE RecordWildCards, QuasiQuotes, NamedFieldPuns, ScopedTypeVariables, CPP #-}+{-# OPTIONS_GHC -fwarn-incomplete-patterns #-}+-- OverloadedStrings -- TODO: currently causes ambiguities with toDoc+++----------------------------------------------------------------------------------------------------+-- This is the code generator for the original (CnC/C++ 0.1-0.5) "context"-based C++ API.+-- Original Author: Ryan Newton+----------------------------------------------------------------------------------------------------++-- This should eventually be based on some intermediate representation of C code. For a+-- first cut, however, it is easier to just generate syntax directly. (Especially with+-- the assistance of the pretty printing libary.)++module Intel.Cnc.Spec.Codegen.CppOld where++import Intel.Cnc.Spec.Codegen.CodegenShared+import Intel.Cnc.Spec.Codegen.Plugins+import Intel.Cnc.Spec.Codegen.Plugins.Depends++import Intel.Cnc.Spec.AST +import Intel.Cnc.Spec.TagFun+import Intel.Cnc.Spec.CncGraph+--import Intel.Cnc.Spec.GatherGraph+import Intel.Cnc.Spec.Util as U hiding (commacat)++import qualified Intel.Cnc.EasyEmit as EE+import Intel.Cnc.EasyEmit hiding (app, not, (&&), (==), (||))++import Control.Monad.State+import StringTable.Atom++import Text.PrettyPrint.HughesPJClass +import Text.Printf++-- QuasiQuoting is too expensive in final binary size:+-- import Text.InterpolatedString.QQ++import qualified Data.Map as M+import Data.List+import Data.Maybe+import Data.Graph.Inductive hiding (empty)++import qualified StringTable.AtomMap as AM+import qualified StringTable.AtomSet as AS++----------------------------------------------------------------------------------------------------++-- An annoying feature of our current API [2010.08.03] is that we+-- don't have explicit step_collection objects. We make sure to only+-- allocate one copy of the user's temporary Step() object and then+-- use its pointer as a key:+step_obj e | e == special_environment_name = e+step_obj str = "m_" ++ str ++--obj_ref a = t"*" <> (t$ step_obj$ fromAtom a)+obj_ref a = (t$ step_obj$ fromAtom a)+++-- [2010.11.14] TEMPTOGGLE: Disabling the one-argument version of get:+oldstyle_get_method = False++commacat ls = hcat (intersperse (text ", ") $ ls)++s = Syn . text +doc2Ty = TSym . toAtom . render++instance FromAtom Doc where+ fromAtom = text . fromAtom++-- If a block of text is nonempty, then preface it with a comment:+maybeCommentDoc ls txt = + if txt == t""+ then txt+ else vcat (map (\ cmnt -> if cmnt == t"" then cmnt else t"// "<> cmnt) ls) $$ + txt++maybeComment ls mnd = + -- FIXME FIXME:+ -- FIXME!! THIS EXECUTES IT TWICE!+ let doc = execEasyEmit mnd in+ if doc == t""+ then return ()+-- else putD$ maybeCommentDoc ls doc+ else do forM_ ls $ \ cmnt ->+ putD$ if cmnt == t"" then cmnt else t"// "<> cmnt+ mnd++----------------------------------------------------------------------------------------------------++-- Name for a private context:+privcontext stp = textAtom stp <> t"_context"++----------------------------------------------------------------------------------------------------++--emitCpp :: StringBuilder m => CodeGenConfig -> CncSpec -> m ()+emitCpp :: CodeGenConfig -> CncSpec -> EasyEmit ()++emitCpp (config@CodeGenConfig{..}) (spec @ CncSpec{appname, steps, tags, items, reductions, graph, realmap}) = do +-- HOWTO READ the below code:+-- This code emits a series of strings/docs to build up a file.+-- Some of the more complex looking bits are building up large lists of type [Doc].+--+-- [2010.11.15] NOTE: This will get more complex for a little while+-- because I am IN THE MIDDLE OF switching to use EasyEmit functionality.++ --------------------------------------------------------------------------------+ -- Prelude: set up some bindings for EasyEmit functions and other helpers:+ --------------------------------------------------------------------------------+ let + -- Don't include builtins (e.g. the environment):+ stepls = filter (\ x -> not$ x `elem` builtinSteps) $+ AS.toList steps+ stepls_with_types = zip stepls tagtys++ -- Call each plugin's "constructor" so it can analyze the spec.+ initialized_plugins = map (\pg -> pg spec) plugins+ + -- Then create a map of which plugins apply to which steps:+ plug_map = AM.fromList$+ filter (not . null . snd) $+ map (\stpC -> (stpC, + catMaybes$ map (\pg -> pg stpC) + initialized_plugins))+ (toAtom special_environment_name : stepls)++ -- This predicate determines whether there is any requirement to wrap a particular step collection:+ shouldWrapStep stpname = + wrapall || AM.member stpname plug_map+ --wrapall || any (\ cgh -> hooksPredicate cgh stpname ) plugins + ++ areAnyWrapped = wrapall || any shouldWrapStep stepls++ tractible_depends_steps = AS.fromList (filter (all_tagfuns_tractible graph) stepls)++ prescribers = map (getStepPrescriber spec) stepls+ tagtys = map (\ name -> case tags AM.! name of + Nothing -> error$ "Tag collection '"++ show name ++"' missing type, needed for C++ codegen!"+ Just ty -> ty)+ prescribers ++ privcontext_member stp = t"m_priv_" <> privcontext stp + tls_key stp = privcontext stp <> t"_tls_key"+++ --------------------------------------------------------------------------------+ -- First we produce the header of the file:+ --------------------------------------------------------------------------------+ -- TODO: Try quasiquoting for multiline-strings here again when they fix the binary bloating problem:+ putS$ "\n//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"+ putS$ "// This code was GENERATED from a CnC specification, DO NOT MODIFY.\n"+ putS$ "//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n\n"+ putS$ "#ifndef "++appname++"_H_ALREADY_INCLUDED\n"+ putS$ "#define "++appname++"_H_ALREADY_INCLUDED\n\n"++ -- Ideally this would only be included IF tuple types are used... complicated right now.+ -- putS "#include \"boost/tuple/tuple.hpp\"\n\n"+ putS "// For now we use C++ TR1 to provide tuples:\n"+ putS "#include <tr1/tuple>\n"+ putS "#define cnctup std::tr1\n\n"+++ putS "// This tells cnc.h to define certain things. TODO: should do this ONLY if tuples are needed!\n"+ putS "#define CNC_ASSUME_TR1 \n\n"++ putS "#include <cnc/cnc.h>\n"+ putS "#include <cnc/debug.h>\n"+ when areAnyWrapped$ putS "#include <cnc/internal/tls.h>\n"++ -- [2010.08.16] This is an INSUFFICIENT forward declaration:++ ------------------------------------------------------------+ -- Emit the step prototypes (two possibilities here):+ ------------------------------------------------------------+ when (genstepdefs)$ + putS "\n// Next this generated file contains prototypes for each step implementation:\n"+ when (not genstepdefs)$ do + putS "// The user's step types should be defined SEPARATELY from this header, and must \n"+ putS "// be in scope before this header is included.\n"+ putS "// As a hint, the below are valid example definitions:\n"+ putS "/*\n"+ + forM_ stepls_with_types $ \ (stp,ty) ->+ do emitStep appname (fromAtom stp) ty + putS "\n\n"+ when (not genstepdefs)$ putS "*/\n"+++ when (not old_05_api) $ do + maybeComment [t"", t"", t"Forward declarations for private contexts."] $+ forM_ stepls $ \stp -> + when (shouldWrapStep stp) $+ putD$ t"class " <> privcontext stp <> semi <> t"\n"+ putS$ "\n"++ ------------------------------------------------------------+ -- Prototype for user step wrappers+ ------------------------------------------------------------ + let+ usercontext = appname++"_context" -- The top-level context exposed to the user+ maincontext = if areAnyWrapped -- The top-level context (internal)+ then t$ appname++"_context_INTERNAL" + else t usercontext+ let stepwrapper stp = textAtom stp <> t"_step_wrapper"++ when (not old_05_api)$ do+ putS "// Forward declaration of the context class (representing the CnC graph)\n"+ putD$ t"class " <> maincontext <> t";"+ when areAnyWrapped$ putD$ t"class " <> t usercontext <> t";"++ maybeComment [t"", t"Type definitions for wrappers around steps."]+ (forM_ stepls_with_types $ \ (stp,ty) -> when (shouldWrapStep stp) $ do+ putD$ struct (stepwrapper stp) $ + textAtom stp <+> t"m_step" <> semi $$+ --stepwrapper stp <> parens empty <> semi+ t"int execute(" <+> constRefType ty <+> t "tag," <+> maincontext <> t" & c) const;"+ putS$ "\n")++ ------------------------------------------------------------+ -- Emit the main context class+ ------------------------------------------------------------ + putS$ "\n\n// Here is the definition for the main application context:\n" ++-- putD$ cppclass (maincontext <> t " : public CnC::context" <> angles (pad maincontext)) $ + cppClass (Syn maincontext) (Syn$ t "public CnC::context" <> angles (pad maincontext)) $ do ++ -- Discarded this API proposal already:+ -- t "\n private:" : + -- t "// Members to store instances of the users Step type:" : + -- ((flip map) stepls $ \ stp -> + -- textAtom stp <> t"* " <> (t$ step_obj$ fromAtom stp) <> semi) ++++ putS "\n public:"+ + when (not old_05_api) $ do+ comm "Step collection members:" + forM_ stepls $ \ stp -> + var (doc2Ty$ t "CnC::step_collection" <> angles (if shouldWrapStep stp then stepwrapper stp else textAtom stp))+ (strToSyn$ step_obj$ fromAtom stp) ++ comm ""+ comm "Tag collection members:" + forM_ (AM.toList tags) $ \ (tg,mty) -> + case mty of + Nothing -> error$ "CppOld.hs Codegen: tag collection without type: "++ (fromAtom tg)+ Just ty -> var (doc2Ty$ t"CnC::tag_collection" <> angles (cppType ty)) (atomToSyn tg)++ comm ""+ comm "Item collection members:"+ forM_ (AM.toList items) $ \ (itC,mty) -> + case mty of + Nothing -> error$ "CppOld Codegen: item collection without type: "++ (fromAtom itC)+ Just (ty1,ty2) -> + let extra = + case ty1 of + -- In the case where the tag type is dense in all dimensions, turn on CNC_VECTOR:+ TDense _ -> commspc<> t"CnC::cnc_tag_hash_compare" <> angles (cppType ty1) <>commspc<> t"CnC::CNC_VECTOR"+ _ -> empty+ in + var (doc2Ty$ t "CnC::item_collection" <> angles (cppType ty1 <>commspc<> cppType ty2 <> extra)) + (atomToSyn itC)++ comm ""+ comm "Reduction collection members:"+ forM_ (AM.toList reductions) $ \ (rdC, mty) -> + case mty of + (_, _, Nothing) -> error$ "CppOld.hs Codegen: reduction collection without type: "++ (fromAtom rdC)+ (op, exp, Just (ty1,ty2)) -> var (doc2Ty$ t "CnC::reduction_collection" <> angles (cppType ty1 <> t", " <> cppType ty2))+ (atomToSyn rdC)++ maybeComment [t"", t" Keys for thread local storage:"] $ + forM_ stepls $ \stp -> + when (shouldWrapStep stp) (putD$ t"int "<> tls_key stp <> semi)+++ maybeComment [t"",t"Next, global state used/generated by plugins:"] $+ forM_ (AM.toList plug_map) $ \ (stpC,hooks) ->+ sequence_ $ map (fst . addGlobalState) hooks++ comm ""+ comm "The context class constructor (prototype): "+ constructorPrototype (Syn maincontext) []++ return ()+{-+++ ++ + + ++ ++-}++ -- [2010.08.19] Don't need the destructor for now:+ -- [space, t "// The context class destructor: "] +++ -- [hangbraces + -- (t"~" <> maincontext <> parens empty )+ -- indent + -- -- Body of the constructor+ -- empty+ -- -- Destroy temporary step objects/collections:+ -- -- (vcat$ (flip map) stepls $ \ stp -> + -- -- t"delete " <> (t$ step_obj$ fromAtom stp) <> semi)+ -- ]+++ ------------------------------------------------------------+ -- Top level bindings (such as tuners):+ ------------------------------------------------------------ ++ maybeComment [t"", t"Plugin-generated top-level bindings:"]$+ forM_ (AM.toList plug_map) $ \ (stp, methodtables) -> do+ sequence_ $ + map (\fn -> fn (Syn$t usercontext, Syn maincontext) ()) $+ map addTopLevel methodtables++ --------------------------------------------------------------------------------+ -- Emit private contexts for each step. This means building wrappers.+ --------------------------------------------------------------------------------+ + -- INVARIANT! Due to error checking above, we can omit some error checking here:+ when (not old_05_api) $ do + maybeComment [t"", t"", t"Next we define 'private contexts'.",+ t"These allow steps to exist in their own little universes with special properties:"] $+ forM_ stepls_with_types $ \ (stp,stpty) -> when (shouldWrapStep stp) $ do+ generate_wrapper_context config spec stp stpty plug_map maincontext usercontext++ when areAnyWrapped $ do+ comm "Also, we generate a wrapper for the main context that is exposed to the user:"+ comm "================================================================================"+ generate_wrapper_context config spec (toAtom special_environment_name) TInt plug_map maincontext usercontext++ ------------------------------------------------------------+ -- Execute wrapper methods + ------------------------------------------------------------ ++ maybeComment [t"", t"", t"Execute method wrappers for each step that uses a private context:"] $+ forM_ stepls_with_types $ \ (stp,ty) -> when (shouldWrapStep stp) $ do+ putD$ hangbraces + (t"int "<> stepwrapper stp <> t"::execute(" <+> constRefType ty <+> t "tag," <+> maincontext <> t" & c) const")+ indent $+ t"// To access the (thread local) state we fetch a pointer to the private context object:"$$+ assignCast (mkPtr$ privcontext stp) (t"ptr") + (U.app "CnC::Internal::CnC_TlsGetValue" [deref (t"c") (tls_key stp)]) $$ ++ hangbraces (t"if " <> parens (t"!ptr")) indent+ (assign "ptr" (t"new " <> U.app (privcontext stp) ["c"]) $$+ U.app "CnC::Internal::CnC_TlsSetValue" [deref (t"c") (tls_key stp), t"ptr" ] + <> semi) $$++ t"ptr->tag = &tag;\n" $$+ -- t"printf(\"PTR %p\\n\", ptr);" $$++ (execEasyEmit$ + forM_ (AM.findWithDefault [] stp plug_map) $ \hks -> + beforeStepExecute hks (Syn$ t"ptr", Syn$t"c") (Syn$ t"tag", Syn$ t"ptr", Syn$t"c")) $$+ t"int result = " <+> U.app "m_step.execute" ["tag", "*ptr"] <> semi $$+ (execEasyEmit$ + forM_ (AM.findWithDefault [] stp plug_map) $ \hks -> + afterStepExecute hks (Syn$ t"ptr", Syn$t"c") (Syn$ t"tag", Syn$ t"ptr", Syn$t"c")) $$+ t"return result;"++ -- privcontext stp <> t"* ptr = ("<> privcontext stp + -- <> t"*) CnC::Internal::CnC_TlsGetValue" <> parens (t"c." <> tls_key stp) <> semi+++ ------------------------------------------------------------+ -- Main Context constructor+ ------------------------------------------------------------+ putS "\n\n"+ putS "// Finally, define the constructor for the main context:\n"+ --when (areAnyWrapped && not old_05_api) $ do + when (not old_05_api) $ do + putS "// (Note that this occurs AFTER the private contexts are defined.)\n"+ cppConstructor (Syn$ maincontext <> t"::" <> maincontext) [] -- Name, Args+ -- Initializer list:+ ((if old_05_api then [] else + -- t "// Initialize step collections" :+ ((flip map) stepls $ \ stp -> (Syn$ t$ step_obj$ fromAtom stp, s"this"))) ++++ -- t "// Initialize tag collections" :+ ((flip map) (AM.toList tags) $ \ (tg,Just ty) -> (atomToSyn tg, s"this, false")) ++ ++ -- t "// Initialize item collections" :+ ((flip map) (AM.toList items) $ \ (itC,Just (ty1,ty2)) -> (atomToSyn itC, s "this")) ++ ++ -- t "// Initialize reduction collections: "+ ((flip map) (AM.toList reductions) $ \ (rdC, (op, exp, Just ty)) -> (atomToSyn rdC, Syn(pPrint exp <> t", & "<> textAtom op <> t", this")))+ ) $++ -- Body of the constructor+ putD+ (nest 6 $ vcat $ + [-- Create objects for all step collections:+ -- This was an intermediate step in our API evolution:+ -- (vcat$ (flip map) stepls $ \ stp -> + -- (t$ step_obj$ fromAtom stp) <> t" = new " <> textAtom stp <> parens empty <> semi+ -- ), ++ t"CnC::step_collection< "<> textAtom (head stepls) <>t" > env(this);\n"+ ]++++ [t"", ++ -- Generate prescribe relations first [mandatory]:+ (vcat $ (flip map) (zip3 stepls prescribers tagtys) $ \ (stp,tg,ty) ->+ t"prescribe" <> parens (pad$ hcat $ punctuate commspc $ + [ textAtom tg+ , if old_05_api + then textAtom stp <> parens empty+ else obj_ref stp] + ++ if gendepends && AS.member stp tractible_depends_steps+ then [thunkapp (tuner_name stp)]+ else []+ -- [2010.08.19] Revamp: don't need tuner/private context here anymore:+ -- if old_05_api then [] else + -- [t"CnC::default_tuner< " <> cppType ty <>commspc<> privcontext stp <> t" >" <> parens empty+ -- , t"*" <> privcontext_member stp + -- --, privcontext stp <> parens (t"this")+ -- ]+ )+ <> semi),++ -- Next, consume relations:+ if old_05_api then empty else + (let egs = concat $ + map (\ (a,b,_) -> + case (lab graph a, lab graph b) of + (Just (CGItems i), Just (CGSteps s)) -> [(i,s)]+ _ -> []) $ + labEdges graph in + vcat $ (flip map) egs $ \ (a,b) ->+ t"consume" <> parens (obj_ref b <> commspc <> (t$ fromAtom a)) <> semi),+ -- Finally, produce relations:+ if old_05_api then empty else + (let egs = concat $ + map (\ (a,b,_) -> + case (lab graph a, lab graph b) of + (Just (CGSteps s), Just (CGItems i)) -> [(s,i)]+ (Just (CGSteps s), Just (CGTags t)) -> [(s,t)]+ _ -> []) $ + labEdges graph in + vcat $ (flip map) egs $ \ (a,b) ->+ t"produce" <> parens (obj_ref a <> commspc <> (t$ fromAtom b)) <> semi), ++ t"", + (vcat$ (flip map) stepls $ \ stp -> + if shouldWrapStep stp+ then assign (tls_key stp) (thunkapp "CnC::Internal::CnC_TlsAlloc")+ else empty)++ ] +++ --------------------------------------------------------------------------------+ -- FIXME:+ -- This should be completely obsoleted when the API catches up (e.g. trace_all works properly)+ [hangbraces (t"if " <> parens (if gentracing then t"1" else t"0")) indent (vcat $+ ((flip map) (zip3 stepls prescribers tagtys) $ \ (stp,tg,ty) ->+ U.app "CnC::debug::trace" [(text$ step_obj$ fromAtom stp), (dubquotes stp)] <> semi) +++ ((flip map) (AM.toList tags) $ \ (tg,_) -> + U.app "CnC::debug::trace" [textAtom tg, dubquotes tg] <> semi) +++ ((flip map) (AM.toList items) $ \ (itC,_) -> + U.app "CnC::debug::trace" [textAtom itC, dubquotes itC] <> semi) + )] +++ --------------------------------------------------------------------------------++ [nest 6$ execEasyEmit$+ (maybeComment [t"",t"Finally global state added by plugins is initalized:"] $+ forM_ (AM.toList plug_map) $ \ (stpC,hooks) ->+ sequence_ $ map (snd . addGlobalState) hooks )]+ )++ ------------------------------------------------------------+ -- Finish up+ ------------------------------------------------------------+ -- This is the "footer" for the document.+ putS$ "\n\n#endif // "++appname++"_H_ALREADY_INCLUDED\n"+ return ()+++++--------------------------------------------------------------------------------+-- Produce the prototype for a single step.+emitStep appname name ty = putD$ + struct (t name)+ (t ("template < class ctxt > ") $$+ t "int execute(" <+> constRefType ty <+> t "tag," <+> + t "ctxt & c) const;"+ --t appname <> t "_context & c) const;"+ )+++-- Make a type both const and a reference.+-- TODO: add some error checking here to see if it is already const or reference...+constRefType ty = t "const" <+> cppType ty <+> t "&"++++------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------++-- NOTE: This routine is multiplexed so that it can generate a wrapper+-- either for the top-level context (for use by the environment) or for individual step's contexts.+-- To call for the environment, simply call with name (stp) = special_environment_name+-- +--generate_wrapper_context :: Atom -> Type -> EasyEmit ()+generate_wrapper_context (CodeGenConfig{gendebug})+ (spec @ CncSpec{appname, steps, tags, items, reductions, graph, realmap}) + stp stpty plug_map maincontext usercontext = + let + is_top_context = (stp == toAtom special_environment_name)+ classname = if is_top_context then toDoc usercontext else privcontext stp++ fprintf = function$ Syn$t "fprintf"+ stderr = constant "stderr"+ abort = function$ Syn$t "abort" ++ in do cppClass (Syn classname) (Syn empty)+ (do + putS "\n public:\n"++ comm "First, state for the private context. Note one private context object is instantiated for EACH thread."+ when (not is_top_context) $ do+ comm "Cache the tag for each step instance:" + var (TConst$ TPtr stpty) (s "tag")++ -- Execute plugin hooks:+ maybeComment [t"",t"Next, collection/thread local state used/generated by plugins:"] $+ sequence_$ map (fst . addLocalState) (AM.findWithDefault [] stp plug_map)++ ------------------------------------------------------------ + -- Wrap tag collections:+ ------------------------------------------------------------ + comm ""+ comm "Wrappers for tag collections:" ++-- FIXME FIXME TODO TODO: Factor this to merge it with Item collections.+ forM_ (AM.toList tags) $ \ (tgC, Just ty) -> + --var (TRef TTemplate "CnC::tag_collection" ty) (atomToSyn tgC)++ -- Unwrapped option, just a reference:+ --putD$ text "CnC::tag_collection" <> angles (cppType ty) <> t" & " <> textAtom tgC <> semi+ let wrapper = textAtom tgC <> t"_wrapper"+ member = t"m_" <> textAtom tgC+ in+ cppClass (Syn wrapper) (s"")+ (do putS "public:" + var (TPtr$ doc2Ty$ classname) (s"m_context")+ var (TRef$ doc2Ty$ maincontext) (s"parent_context")++ putD$ t"CnC::tag_collection" <> angles (cppType ty) <> t" & " <> member <> semi $$ t"" + comm "The constructor here needs to grab a reference from the main context:"++ cppConstructor (Syn wrapper)+ [(TRef$ litType maincontext, s"p"),+ (TPtr$ litType classname, s"c")] -- Args.+ [(Syn$ member, Syn$ t"p." <> textAtom tgC),+ (s"parent_context", s"p"),+ (s"m_context", s"c")] -- Initialization.+ (do return ()+ -- set (s"m_context") (s"c") -- Body.+ -- set (s"parent_context") (s"&p")+ )++ inlineFunDef voidTy (strToSyn "put") [TConst$ TRef ty] $ \ tagArg -> + do let doplugs project = + forM_ (AM.findWithDefault [] stp plug_map) $ \ hooks ->+ project hooks (s"m_context", s"parent_context", tgC)+ tagArg+ doplugs beforeTagPut+ EE.app (function$ Syn$ t "m_"<> textAtom tgC <> t".put") [tagArg]+ doplugs afterTagPut+ + return ()+-- FIXME FIXME TODO TODO: Factor this to merge it with Item/Reduction collections.+ ) ++ comm ""+ comm "PUBLIC MEMBERS: Tag collections are all wrapped for now:" + forM_ (AM.toList tags) $ \ (tgC, Just ty1) -> + (putD$ textAtom tgC <> t"_wrapper" <+> textAtom tgC <> semi)++ ------------------------------------------------------------ + comm ""+ comm "Wrappers for reduction collections:" + ------------------------------------------------------------ + forM_ (AM.toList reductions) $ \ (redC, (op, init, Just (ty1,ty2))) -> do+ wrap_item_or_reduction_collection "reduction" redC ty1 ty2 classname stp plug_map fprintf stderr abort maincontext realmap gendebug graph+ comm ""+ comm "PUBLIC MEMBERS: Reduction collections are all wrapped for now:" + forM_ (AM.toList reductions) $ \ (redC, (op, init, Just (ty1,ty2))) -> + (putD$ textAtom redC <> t"_wrapper" <+> textAtom redC <> semi)++ ------------------------------------------------------------ + comm ""+ comm "Wrappers for item collections:" + ------------------------------------------------------------ + forM_ (AM.toList items) $ \ (itC,Just (ty1,ty2)) -> do+ wrap_item_or_reduction_collection "item" itC ty1 ty2 classname stp plug_map fprintf stderr abort maincontext realmap gendebug graph+ comm ""+ comm "PUBLIC MEMBERS: Item collections are all wrapped for now:" + forM_ (AM.toList items) $ \ (itC, Just (ty1,ty2)) -> + (putD$ textAtom itC <> t"_wrapper" <+> textAtom itC <> semi)++ ------------------------------------------------------------ ++ when is_top_context $ do + comm "This member variable holds the *real* context:"+ var (doc2Ty maincontext) (s"p")+ comm ""+ let env_hooks = AM.findWithDefault [] (toAtom special_environment_name) plug_map+ ctxt_field = s"p"+ inlineFunDef voidTy (s "wait") [] $ \ () -> do+ forM_ env_hooks $ \ hooks -> + beforeEnvWait hooks (MainCtxtRef$ ctxt_field)+ EE.app (function$ ctxt_field `dot` s"wait") []+ forM_ env_hooks $ \ hooks -> + afterEnvWait hooks (MainCtxtRef$ ctxt_field)+ return ()++ comm ""+ comm "Constructor for the private/custom context: "+ if False -- is_top_context+ then do return ()+ else + cppConstructor (Syn classname) -- Name.+ (if is_top_context -- Args.+ then []+ else [(TRef$ litType maincontext, s"p")]) + -- Lots of initializers:+ ((if is_top_context + -- In this case we initialize our own copy of the context rather than taking it as argument:+ then [(s"p", s"")]+ else []) +++ -- Item collections:+ ((flip map) (AM.toList items) $ \ (itC, Just (ty1,ty2)) -> + (atomToSyn itC, s"p, this")+ ) ++ ++ ((flip map) (AM.toList reductions) $ \ (redC, _) -> + (atomToSyn redC, s"p, this")+ ) ++ ++ ((flip map) (AM.toList tags) $ \ (tgC, Just ty) -> + --(atomToSyn tgC, s"p" `dot` atomToSyn tgC)+ (atomToSyn tgC, s"p, this") -- This is for the new, WRAPPED, tag collection.+ ))+ (maybeComment [t"",t"Next, collection/thread-local state is initalized:"] $+ sequence_$ map (snd . addLocalState) (AM.findWithDefault [] stp plug_map)+ )+ -- Have to wrap tag collections as well just to redirect references to the main context:+ )+ putS$ "\n"+ putS$ "\n"++++------------------------------------------------------------------------------------------------------------------------++-- HACK: TEMPORARY: This needs refactoring.+-- It has been factored out here, but clearly the interface is hugely complex:+++checkTagFun stp target getnbrs fprintf stderr abort tagty args realmap graph = + -- TODO INSERT CORRECTNESS CHECKING HERE:+ let stpnd = realmap M.! (CGSteps stp)+ itemnd = realmap M.! target+ gctxt = context graph itemnd+ lnhbrs = getnbrs gctxt-- lpre' gctxt ++ lsuc' gctxt+ ls = filter (\ (nd,lab) -> nd == stpnd) lnhbrs+ -- [(_,tf)] = filter (\ (nd,lab) -> nd == stpnd)$ lpre' gctxt + --[(_,tf)] = trace (" LENGTH "++ show (length ls) ++" "++ show stpnd ++" "++ show itemnd++" "++ show lnhbrs) ls+ in + execEasyEmit$+ case ls of + -- If we have no relationship to that collection its an error to access it:++ [] -> do let str = printf " [tagfun_check] CnC graph violation: should not access collection '%s' from '%s'" + (graphNodeName target :: String) (show stp) + EE.app fprintf [stderr, stringconst$ str]+ EE.app abort[]++ [(_,Nothing)] -> comm " [tagfun_check] No tag function to check..."++ --((_,Just (TF args exps)) : []) -> ++ ((_,Just (TF tfargs exps)) : tl) -> -- TEMPTOGGLE ... permissive, ignoring additional tag functions!+ case (tfargs,exps) of + ([arg], [exp]) -> + do comm (" [tagfun_check] Checking tag function "++ show arg ++" -> "++ show exp)+ -- TODO: use normal variable decl here:+ putD$ tagty <+> (fromAtom arg) <+> t"=" <+> t"* m_context->tag" <> semi+ when (not$ null args)$ assert (head args EE.== Syn (pPrint exp)) -- FIXME -- afer factoring fix this head args+ _ -> error "internal error: tag function correctness not fully implemented yet. Finish me."++ _ -> error$ "internal error: tag function correctness codegen: \n w"++show ls+++wrap_item_or_reduction_collection which colName ty1 ty2 classname stp plug_map fprintf stderr abort maincontext realmap gendebug graph = + (+ let + isReduction = case which of+ "reduction" -> True+ "item" -> False+ _ -> error "the helper function wrap_item_or_reduction_collection must take either 'reduction' or 'item'"+ tagty = cppType ty1++ -- A reused bit of syntax for wrapper get/put methods:+ -- (This is one of those things that you don't want to duplicate, + -- but it has too many arguments and is poorly abstracted.)+ wrapGP doret retty nm args isPut = + -- First let's put together the function's arguments:+ let + doplugs project = execEasyEmit$ + -- FIXME: HACK:+ when (length args Prelude.>= 2) $+ forM_ (AM.findWithDefault [] stp plug_map) $ \ hooks ->+ project hooks (Syn$ t$ snd$ head args, Syn$ t$ snd$ head$ tail args, colName)+ (Syn$ t$ snd$ head args, Syn$ t$ snd$ head$ tail args)+ in++ inlineFunDef retty (s nm) (map (doc2Ty . fst) args) $ \ (args::[Syntax]) -> + do +#if 1+ putD$ (if gendebug -- Optionally include debugging assertions.+ then checkTagFun stp ((if isReduction then CGReductions else CGItems) colName) + (if isPut then lpre' else lsuc') + fprintf stderr abort tagty args realmap graph+ else empty)+#endif+ -- Execute plugin hooks:+ putD$ (if isPut + then doplugs (if isReduction then beforeReducerPut else beforeItemPut)+ else doplugs (if isReduction then beforeReducerGet else beforeItemGet))+ --------------------------------------------------------------------------------+ putD$ (if doret then t"return " else t"") <>+ t "m_"<> textAtom colName <> t"." <> t nm <> parens (commacat$ map deSyn args) <> semi + --------------------------------------------------------------------------------+ putD$ (if isPut + then doplugs (if isReduction then afterReducerPut else afterItemPut)+ else doplugs (if isReduction then afterReducerGet else afterItemGet))++ -- Basic get or put:+ basicGP nm isPut = wrapGP False voidTy nm + [(mkConstRef tagty, "tag"), + ((if isPut then mkConstRef else mkRef) (cppType ty2) , "ref")] isPut++ wrapper = textAtom colName <> t"_wrapper"+ member = t"m_" <> textAtom colName+ in do + comm$ "The "++ which ++" collection wrapper: A 'NoOp' wrapper class that does nothing: "+ cppClass (Syn wrapper) (s"")+ (do putS "public:" + putD$ mkPtr classname <> t" m_context;" + putD$ mkPtr maincontext <> t" parent_context;\n" ++ putD$ t("CnC::"++ which ++"_collection") <> angles (cppType ty1 <>commspc<> cppType ty2) <> t" & " <> member <> semi $$ t"" + comm "The constructor here needs to grab a reference from the main context:"+ cppConstructor (Syn wrapper) -- Name.+ [(TRef$ litType maincontext, s"p"),+ (TPtr$ litType classname, s"c")]+ [(Syn$ member, Syn$ t"p." <> textAtom colName)]+ (do set (s"m_context") (s"c") + set (s"parent_context") (s"&p"))++ -- Just three methods: two variants of get and one put.+ basicGP "get" False + basicGP "put" True ++ -- Hackish: adding the done and done_all methods:+ when isReduction $ do + wrapGP False voidTy "done" [(mkConstRef (cppType ty1),"tag")] False+ wrapGP False voidTy "all_done" [] False+ return ()++ if oldstyle_get_method + then do wrapGP True ty2 "get" [(mkConstRef (cppType ty1),"tag")] False+ return ()+ else return ()+ ) + putS "")++++++------------------------------------------------------------------------------------------------------------------------+-- CODING HINTS GENERATION+------------------------------------------------------------------------------------------------------------------------++-- UNFINISHED++codingHints :: StringBuilder m => Bool -> CncSpec -> m ()++codingHints old_05_api (spec @ CncSpec{..}) =+ do putD $ + (hangbraces + (t"foo") 4 (t"baz")+ )+ ++--------------------------------------------------------------------------------+-- EXAMPLE: OLD CODING HINTS:++{-++++/****************************************************************************+/* The following code provides an example of what the user code that invokes+/* this graph might look, using the inputs and outputs defined for the +/* environment (ENV).+/***************************************************************************/+ #include "mandel.h"+ + // Create an instance of the context class which defines the graph+ mandel_context c;+ + // Debug trace can be enabled for a collection with the call:+ // CnC::debug::trace( c.position, "position" );+ + // For each item from the environment (ENV), put the item using the + // proper tag + c.data.put( data_Tag, ... );+ c.max_depth.put( max_depth_Tag, ... );+ + // For each tag value from the environment (ENV), put the tag into+ // the proper tag collection+ c.position.put( position_Tag );+ + // Wait for all steps to finish+ c.wait();+ + // For each output to the environment (ENV), get the item using the + // proper tag + int pixel_ENV;+ pixel.get( pair(...), pixel_ENV );++/*********************************************************************+/* The following code provides an example of what the user Step code +/* might look like for this Step, using the inputs and outputs defined+/* in the context.+/********************************************************************/+int compute::execute(const pair & t, mandel_context & c ) const+{+ + // For each input item for this step retrieve the item using the proper tag value+ complex data_instance;+ c.data.get( pair(...), data_instance );+ int max_depth_instance;+ c.max_depth.get( int(...), max_depth_instance );++ // Step implementation logic goes here+ ...++ // For each output item for this step, put the new item using the proper tag value + c.pixel.put( pair(...), ... );++ return CnC::CNC_Success;+}++-}
+ Intel/Cnc/Spec/Codegen/Haskell.hs view
@@ -0,0 +1,179 @@+{-# LANGUAGE RecordWildCards #-}+{-# OPTIONS_GHC -fwarn-incomplete-patterns #-}++----------------------------------------------------------------------------------------------------+-- This is the code generator for Haskell CnC itself.+-- Original Author: Ryan Newton+----------------------------------------------------------------------------------------------------++module Intel.Cnc.Spec.Codegen.Haskell where++--import Intel.Cnc.Spec.AST+import Intel.Cnc.Spec.CncGraph+--import Intel.Cnc.Spec.GatherGraph+import Intel.Cnc.Spec.Util +--import Control.Monad.State+--import StringTable.Atom+--import Data.Maybe+--import Text.PrettyPrint.HughesPJClass++--import qualified StringTable.AtomMap as AM+--import qualified StringTable.AtomSet as AS++emitHaskell :: StringBuilder m => CncSpec -> m ()+emitHaskell (spec @ CncSpec{..}) = do+ putS$ "\n-- This code was GENERATED from a CnC specification, do not modify.\n\n"+ ++{-++import Data.Complex+import Data.Int+import System.Environment+import Control.Monad++-- #define USE_GMAP+-- #define MEMOIZE+ #include <haskell_cnc.h>++type Pair = (Int16, Int16)++mandelProg :: Int -> Int -> Int -> GraphCode Int+mandelProg max_row max_col max_depth = + do dat :: ItemCol Pair (Complex Double) <- newItemCol+ pixel :: ItemCol Pair Int <- newItemCol+ + let mandelStep tag = + do tid <- stepUnsafeIO myThreadId+ --stepPutStr$ "["++ show tid ++"] Mandel Step executing: "++ show tag ++ "\n"+ cplx <- get dat tag+ put pixel tag (mandel max_depth cplx)++ position :: TagCol Pair <- prescribeNT [mandelStep] ++ initialize $ + forM_ [0..max_row-1] $ \i -> + forM_ [0..max_col-1] $ \j ->+ let (_i,_j) = (fromIntegral i, fromIntegral j)+ z = (r_scale * (fromIntegral j) + r_origin) :+ + (c_scale * (fromIntegral i) + c_origin) in+ do put dat (_i,_j) z+ putt position (_i,_j)++ -- Final result, count coordinates of the pixels with a certain value:+ finalize $ do + --stepPutStr$ "Finalize action begun...\n"+ foldM (\acc i -> + foldM (\acc j -> + do --stepPutStr$ " ... try get pixel "++ show (i,j) ++"\n "+ p <- get pixel (fromIntegral i, fromIntegral j)+ --stepPutStr$ " GET PIXEL SUCCESSFUL "++ show (i,j) ++"\n "+ if p == max_depth+ then return (acc + (i*max_col + j))+ else return acc)+ acc [0..max_col-1]+ ) 0 [0..max_row-1] + + where + r_origin = -2 :: Double+ r_scale = 4.0 / (fromIntegral max_row) :: Double+ c_origin = -2.0 :: Double+ c_scale = 4.0 / (fromIntegral max_col) :: Double+++runMandel a b c = + let check = runGraph $ mandelProg a b c in+ putStrLn ("Mandel check " ++ show check)++main = do args <- getArgs + case args of+ [] -> runMandel 1 1 3 -- Should output 57.+ [] -> runMandel 4 4 3 -- Should output 57.+ [a,b,c] -> runMandel (read a) (read b) (read c)+-}++++{-+-- Here's how it might look refactored:++module Mandel ++import MandelBase++mandelStep MandelContext{..} tag = + do tid <- stepUnsafeIO myThreadId+ cplx <- get dat tag+ put pixel tag (mandel max_depth cplx)++mandel :: Int -> Complex Double -> Int+mandel max_depth c = loop 0 0 0+ where + fn = magnitude+ loop i z count+ | i == max_depth = count+ | fn(z) >= 2.0 = count + | otherwise = loop (i+1) (z*z + c) (count+1)+++initStep MandelContext{..} =+ forM_ [0..max_row-1] $ \i -> + forM_ [0..max_col-1] $ \j ->+ let (_i,_j) = (fromIntegral i, fromIntegral j)+ z = (r_scale * (fromIntegral j) + r_origin) :+ + (c_scale * (fromIntegral i) + c_origin) in+ do put dat (_i,_j) z+ putt position (_i,_j)+ where+ r_origin = -2 :: Double+ r_scale = 4.0 / (fromIntegral max_row) :: Double+ c_origin = -2.0 :: Double+ c_scale = 4.0 / (fromIntegral max_col) :: Double+++finalizeStep MandelContext{..} =+ do foldM (\acc i -> + foldM (\acc j -> + do --stepPutStr$ " ... try get pixel "++ show (i,j) ++"\n "+ p <- get pixel (fromIntegral i, fromIntegral j)+ --stepPutStr$ " GET PIXEL SUCCESSFUL "++ show (i,j) ++"\n "+ if p == max_depth+ then return (acc + (i*max_col + j))+ else return acc)+ acc [0..max_col-1]+ ) 0 [0..max_row-1] ++runMandel a b c = + let check = runGraph $ mandelGraph a b c in+ putStrLn ("Mandel check " ++ show check)++main = do args <- getArgs + case args of+ [] -> runMandel 1 1 3 -- Should output 57.+ [] -> runMandel 4 4 3 -- Should output 57.+ [a,b,c] -> runMandel (read a) (read b) (read c)++++----------------------------------------------------------------------------------------------------++type Pair = (Int16, Int16)++-- +mandelStep+++mandelGraph max_row max_col max_depth = + do dat :: ItemCol Pair (Complex Double) <- newItemCol+ pixel :: ItemCol Pair Int <- newItemCol+ + position :: TagCol Pair <- prescribeNT [mandelStep] +++ -- Final result, count coordinates of the pixels with a certain value:+ + where ++++-}
+ Intel/Cnc/Spec/Codegen/Plugins.hs view
@@ -0,0 +1,448 @@+{-# LANGUAGE ScopedTypeVariables, OverloadedStrings, NamedFieldPuns #-}++module Intel.Cnc.Spec.Codegen.Plugins+ (+ CodeGenPlugin, HooksTable(..), MainCtxtRef(..), PrivCtxtPtr(..), DonePlugin(..),+ defaultHooksTable, testplugin,+ composeDonePlugins, convertDonePlugin,++ autodonePlugin+ )+where++-- import Intel.Cnc.Spec.Codegen.Plugins.ReductionDone++import Intel.Cnc.Spec.GraphAnalysis+import Intel.Cnc.Spec.AST +import Intel.Cnc.Spec.CncGraph+import qualified Intel.Cnc.EasyEmit as E+import Intel.Cnc.EasyEmit hiding (not, (||))+import Intel.Cnc.Spec.Util hiding (app)+++import StringTable.Atom+import qualified StringTable.AtomMap as AM+import Data.List as L+import Data.Maybe+import qualified Data.Set as S+import qualified Data.Map as M+import Control.Monad++import Prelude hiding ((&&), (==), (<=))+import qualified Prelude as P+++----------------------------------------------------------------------------------------------------+-- Here's a convenient Plugin architecture that uses EasyEmit+----------------------------------------------------------------------------------------------------++-- A "plugin" represents a collection of hooks that can be used by a+-- codegen backend to inject code before/after steps, puts, and gets.+-- This is an attempt to convert some of our different extensions into+-- modular plugins.+--+-- The "constructor" for each plugin object takes a spec and then the name of the step collection.+-- It returns a methodtable full of hooks IF the plugin applies to the given step, and Nothing otherwise.+type CodeGenPlugin = CncSpec -> ColName -> Maybe HooksTable++-- DESIGN NOTE: We could have created a type class for plugins and+-- used existential types to pass around "objects" with their method+-- tables. But the below record-based approach is more explicit and+-- doesn't complicate the types; so sticking with it for now.++-- Each hook takes two groups of argument:+-- (1) Graph context: names of relevant collections (other than the host step)+-- PLUS two bits of syntax that refer to the private/main contexts.+-- (2) Arguments: bits of syntax that refer to the relevant values.+type Hook grphCtxt args = grphCtxt -> args -> EasyEmit ()++-- It's very hard to keep all these pieces of "Syntax" straight. To+-- help a little we wrap them in new types.+-- UNFINISHED!!! Haven't applied these new types yet!+newtype PrivCtxtPtr = PrivCtxtPtr Syntax+newtype MainCtxtRef = MainCtxtRef Syntax ++-- Graph context aliases: What information does a hook need about the graph?+-- First two Syntax arguments are the names of the private/main context respectively+type GrCtxt1 = (Syntax, Syntax)+type GrCtxt2 = (Syntax, Syntax, ColName) -- Includes destination collection name.++data HooksTable = HooksTable+ {+ -- I vacillated on whether or not to put all of these hooks+ -- (functions) inside a Maybe. That would make it more clear+ -- what a plugin DOESN'T implement, but I think it makes the+ -- plugins more clunky to use, and makes the below combineHooks+ -- function harder to write. Besides, there is a sensible+ -- default hook -- it emits nothing.++ -- Add a top-level binding to the resulting header file:+ addTopLevel :: Hook GrCtxt1 (),++ -- Declare & initialize (respectively) global state for a collection, stored in global context.+ addGlobalState :: (EasyEmit (), EasyEmit ()),+ -- Declare & initialize (respectively) local state, stored for a given step collection in TLS.+ addLocalState :: (EasyEmit (), EasyEmit ()),++ -- Two arguments: reference to tag, reference to item.+ beforeItemPut :: Hook GrCtxt2 (Syntax,Syntax),+ afterItemPut :: Hook GrCtxt2 (Syntax,Syntax),+ beforeItemGet :: Hook GrCtxt2 (Syntax,Syntax),+ afterItemGet :: Hook GrCtxt2 (Syntax,Syntax),++ beforeReducerPut :: Hook GrCtxt2 (Syntax,Syntax),+ afterReducerPut :: Hook GrCtxt2 (Syntax,Syntax),+ beforeReducerGet :: Hook GrCtxt2 (Syntax,Syntax),+ afterReducerGet :: Hook GrCtxt2 (Syntax,Syntax),++ -- In contrast to the above, here we only need one piece of syntax (the tag):+ beforeTagPut :: Hook GrCtxt2 Syntax,+ afterTagPut :: Hook GrCtxt2 Syntax,++ -- Step hooks take three syntax arguments:+ -- (1) name of the step's tag as input+ -- (2) name of a variable holding a pointer to the private+ -- context -- a struct that has the state added by+ -- "addLocalState" before.+ -- (3) name of a variable holding a reference to the main+ -- context -- containing the state added by "addGlobalState"+ beforeStepExecute :: Hook GrCtxt1 (Syntax,Syntax,Syntax),+ afterStepExecute :: Hook GrCtxt1 (Syntax,Syntax,Syntax),++ -- These inject code around the context's wait() method:+ beforeEnvWait :: MainCtxtRef -> EasyEmit (),+ afterEnvWait :: MainCtxtRef -> EasyEmit (),++ -- Done happens per-set-of-collections (cycles cause grouping)+ -- This hook is used ONLY when the done plugins are enabled.+ whenDone :: S.Set CncGraphNode -> EasyEmit ()+-- whenDone :: S.Set ColName -> EasyEmit ()+ }+ deriving Show++--instance Show CodeGenPlugin where+instance Show (a -> b) where+ show _ = "<fun>"++instance Show (EasyEmit a) where+ show _ = "<easyemit_computation>"++--------------------------------------------------------------------------------+-- The default method table does nothing.++defaultHooksTable = + -- The default hooks just do nothing:+ let twoarg = const$ const$ return ()+ in HooksTable+ {+ addTopLevel = twoarg,+ addGlobalState = (return (), return ()),+ addLocalState = (return (), return ()),++ beforeItemPut = twoarg,+ afterItemPut = twoarg,+ beforeItemGet = twoarg,+ afterItemGet = twoarg,++ beforeReducerPut = twoarg,+ afterReducerPut = twoarg,+ beforeReducerGet = twoarg,+ afterReducerGet = twoarg,++ beforeTagPut = twoarg,+ afterTagPut = twoarg,+ beforeStepExecute = twoarg,+ afterStepExecute = twoarg,+ beforeEnvWait = const$ return (),+ afterEnvWait = const$ return (),++ whenDone = const$ return ()+ }+++----------------------------------------------------------------------------------------------------+-- A plugin simply to test the infrastruture:+----------------------------------------------------------------------------------------------------++testplugin spec stpC =+ let + boilerplate msg = + \ (_,_,to) (tag,val) -> + putS$ "// [testhooks] "++ show stpC ++ ": " ++ msg ++" "++ show to + ++", args: " ++ show (deSyn tag) ++" "++ show (deSyn val)++ in+ Just$ defaultHooksTable+ { + addLocalState = (comm "[testhooks] Local state declaration goes here.",+ comm "[testhooks] Local state initialization goes here.")+ , addGlobalState = (comm "[testhooks] Global state declaration goes here.",+ comm "[testhooks] Global state initialization goes here.")++ , beforeItemPut = boilerplate "before putting Item to"+ , afterItemPut = boilerplate "after putting Item to"+ , beforeItemGet = boilerplate "before getting Item from"+ , afterItemGet = boilerplate "after getting Item from"++ , beforeReducerPut = boilerplate "before putting Reducer to"+ , afterReducerPut = boilerplate "after putting Reducer to"+ , beforeReducerGet = boilerplate "before getting Reducer from"+ , afterReducerGet = boilerplate "after getting Reducer from"++ , beforeTagPut = \ (_,_,tgC) tag -> putS$ "// [testhooks] before putting Tag: " ++ show (deSyn tag)+ , afterTagPut = \ (_,_,tgC) tag -> putS$ "// [testhooks] after putting Tag: " ++ show (deSyn tag) ++ , beforeStepExecute = \ _ (tag,priv,main) -> + putS$ "// [testhooks] before step execute on tag reference: " ++ show (deSyn tag) ++" "++ show (deSyn priv) ++" "++ show (deSyn main)+ , afterStepExecute = \ _ (tag,priv,main) -> + putS$ "// [testhooks] after step execute on tag reference: " ++ show (deSyn tag) ++" "++ show (deSyn priv) ++" "++ show (deSyn main)++ , beforeEnvWait = \ (MainCtxtRef m) -> putS$ "// [testhooks] before environment wait, main ctxt ref "++ show (deSyn m)+ , afterEnvWait = \ (MainCtxtRef m) -> putS "// [testhooks] after environment wait"++ , whenDone = \ cols -> putS "// [testhooks] done"++ -- TODO add a "done" hook and introduce a "done" method alongside the step execute method inside the step wrapper.++ }+++++-- =================================================================================================+-- DONE propogation plugins:+-- -------------------------------------------------------------------------------------------------++-- Done-plugins are a second kind of plugin that attaches an action+-- when collections in the graph are all finished. Done plugins+-- essentially depend on a single, shared service of+-- in-flight-instance-tracking. Therefore, while more than one+-- done-plugin may be used, but they must all be *combined* into a+-- single regular plugin (together with the shared service).++-- 'Done' plugins are composable with one another.+-- A done plugin is both a predicate and a codegenerator that contributes to the "whenDone" method.+-- The additional bool argument is a debug-mode flag.+newtype DonePlugin = DonePlugin (Bool -> CncGraphNode -> Maybe (EasyEmit ()))+++-- All the DonePlugins used in a run of the translator should be+-- composed together before conversion into a regular plugin.+composeDonePlugins :: DonePlugin -> DonePlugin -> DonePlugin +convertDonePlugin :: Bool -> DonePlugin -> CodeGenPlugin+-- | The autodone plugin introduces counters for step collections and+-- | tracks when they are completely finished ("done").+autodonePlugin :: DonePlugin++instance Show DonePlugin where show _ = "DonePlugin"++-- Used in this file only:+countername :: Int -> Syntax+countername num = Syn$t$ "done_counter" ++ show num++--------------------------------------------------------------------------------+-- autodone: Most basic done-plugin.+--------------------------------------------------------------------------------++-- This is a basic plugin that tracks done-ness but doesn't actually DO anything.+-- See other files in the Plugins/ directory for more meaningful Done functionality.+autodonePlugin = DonePlugin $ + \ debug node -> + if isStepC node + then Just$ return ()+ else Nothing++--------------------------------------------------------------------------------+-- Composing and Converting done-plugins.+--------------------------------------------------------------------------------++composeDonePlugins (DonePlugin dp1) (DonePlugin dp2) = DonePlugin$ + \ debug cncnode -> + case catMaybes [dp1 debug cncnode, dp2 debug cncnode] of + [] -> Nothing+ ls -> Just$ sequence_ ls+++-- There's an important distinction here. Not all nodes that+-- have done *signaled* must also decrement their downstream.+-- Passive nodes NEEDNT be marked explicitly as done for active+-- downstream nodes to be done.+isActiveCollection = isStepC -- For now only step collections are ACTIVE.++-- Don't know why this isn't in the standard lib.+set_any pred = S.fold (\ a b -> b || pred a) False +++-- | Conversion from done plugin to a normal plugin. The first argument is a debug flag.+-- TODO: Currently debug mode is set for ALL done plugins. We may want finer grained control.+convertDonePlugin debug_autodone (DonePlugin dpgfun)+ (spec@CncSpec{graph, steps, items, reductions, nodemap}) + stpC + = + Just this+ where + BasicCycleAnalysis {index_map, rev_index_map, upstream_map, downstream_map} = basicCycleAnalysis spec+ + funname num = Syn$t$ "decr_done_counter" ++ show num++ -- The predicate for which nodes are tracked with done counters.+ -- ALL step collections must be tracked, and some subset of the+ -- "passive" collections may be tracked as well.+ -- (TODO: we could track only what is upstream of the collections of interest to dpgfun)+ hasDoneSignaled cncNode = isStepC cncNode || isJust (dpgfun debug_autodone cncNode)+ -- NOTE: this is in contrast with isActiveCollection above.++ -- This includes unique counters we need for the tracked subset of collections:+ numbered_nodesets :: [(Int, S.Set CncGraphNode)] = + -- This is a bit odd... but if ANY node within the set is of+ -- interest to us, we include that counter:+ L.filter (\ (i,set) -> set_any hasDoneSignaled set) $+ M.toList rev_index_map+ counter_lookup stp = case AM.lookup stp index_map of + Just x -> x+ Nothing -> error$ "autodonePlugin: Could not find counter corresponding to step: "++ show stp++ is_maincontext = (stpC P.== toAtom special_environment_name) + -- env_ind :: Int = fst $ G.mkNode_ nodemap $ CGSteps $ toAtom special_environment_name+ -- The index of the counter associated with the environment:+ env_ind :: Int = index_map AM.! (toAtom special_environment_name)+ + -- Find up or downstream *graph nodes* (chunking cycles together).+ nbr_set filt updown_map set = + S.filter filt $ + S.unions $ + map (\nd -> AM.findWithDefault S.empty (graphNodeName nd) updown_map) $+ S.toList set+ -- Convert nodes to counters:+ nbr_set_to_counters set = + -- Compute a set consisting of all downstream *counters* (step groups), not steps:+ S.toList $ + S.map ((index_map AM.!) . graphNodeName) $+ set++ stpind = counter_lookup stpC++ -- Bind the "methodtable" to 'this' so it can be recursively referenced:+ this = defaultHooksTable+ {+ whenDone = \ thisset -> do+ let + -- CAREFUL: we signal to ALL relevant downstream, but upstream we care only about Active.+ downcounters = nbr_set_to_counters$ + nbr_set hasDoneSignaled downstream_map thisset+ upstream = nbr_set isActiveCollection upstream_map thisset++ when debug_autodone$ + app (function$ "printf") [stringconst$ " [autodone] Node(s) done "+ ++ show ((map graphNodeName $ S.toList thisset) :: [Atom])+ ++", upstream deps met: " ++ + show ((map graphNodeName $ + filter isActiveCollection$ S.toList upstream)+ :: [Atom]) ++"\n"]++ -- Here we do the real decrementing, but ONLY if we OURSELVES are an "active" collection:+ if set_any isActiveCollection$ thisset+ then do comm "[autodone] As we become done, we decrement our downstream counters."+ forM_ downcounters $ \ cntr -> app (function$ funname cntr) []+ else comm "[autodone] NOT decrementing downstream because this node(set) does not create control instances!"+ -- Finally, inject code from all the DonePlugins that are active:+ sequence_ (catMaybes$ map (dpgfun debug_autodone) $ S.toList thisset)++ , addGlobalState = + let names_str ndset = concat (intersperse " "$ map graphNodeName (S.toList ndset)) in+ -- This only happens ONCE, not per step-collection, and it declares ALL the counters:+ if is_maincontext+ then (do comm "[autodone] Maintain a piece of state for each tracked subgraph: the done counter"+ forM_ numbered_nodesets $ \ (ind, ndset) -> do + comm$ "Counter "++ show ind ++ ": Serves node(s): " ++ names_str ndset+ + var (TSym "tbb::atomic<int>") (countername ind)+ -- "We also introduce a procedure that transitions a group of nodes into a done state:"+ funDef voidTy (funname ind) [] $ \() -> do + x <- tmpvar TInt+ let name = countername ind+ set x (function (name `dot` "fetch_and_decrement") [])+ when debug_autodone$ + app (function "printf") [stringconst$ " [autodone] Decremented ("+++ names_str ndset ++ ") to %d\n", + x-1]+ if_ (x == 1)+ (whenDone this ndset)+ (when debug_autodone $+ app (function "printf") [stringconst$ " [autodone] "++show stpC++" NOT DONE\n"])+ comm ""++ return ()++ , do comm "[autodone] Initialize done counters based on number of upstream deps:"+ when debug_autodone$ do + app (function "printf") [stringconst$ " [autodone] Initializing done counters...\n"]+ forM_ numbered_nodesets $ \ (ind, ndset) -> do+ let nbrs = nbr_set isActiveCollection upstream_map ndset+ counters = nbr_set_to_counters nbrs+ numcounters = length counters+ if ind P.== env_ind then + alwaysAssertEq "Env should not have upstream" [] counters $ do+ comm$ " Counter "++ show ind ++ " represents the environment and is initialized to one."+ set (countername ind) 1+ else do+ comm$ " Counter "++ show ind ++ " (representing "++ names_str ndset+ ++") initalized to "++ show numcounters + ++" for upstream deps "++ names_str nbrs+ -- show ((map graphNodeName $ S.toList nbrs)::[Atom])+ set (countername ind) (fromIntegral numcounters)+ )+ else (return (), return ())++ , afterStepExecute = \ _ (tag,priv,main) -> + do comm "[autodone] Decrement the counter that tracks these instances:"+ app (function $ main `dot` (funname stpind)) []++ , beforeTagPut = \ (priv,main, tgC) tag -> + do comm "[autodone] Increment the counter that tracks downstream step instances:"+ let downstream = map graphNodeName $ filter isActiveCollection $ + downstreamNbrs spec (CGTags tgC)+ forM_ downstream $ \ destC -> do+ let counter = main `dot` countername (counter_lookup destC)+ when debug_autodone$ + app (function "printf") [stringconst$ " [autodone] "++show stpC+++ ": Incrementing "++show destC++" refcount to %d\n", + "1 + (int)" +++ counter]+ app (function (counter `dot` "fetch_and_increment")) []++ , beforeEnvWait = \ (MainCtxtRef main) ->+ do comm "[autodone] We consider the environment 'done' at this point:"+ when debug_autodone$+ app (function "printf") [stringconst$ " [autodone] Environment waiting, considered done.\n"]+ app (function$ main `dot` (funname stpind)) [] + }+++++-- OTHER PLUGINS TO CONSIDER WRITING:++----------------------------------------------------------------------------------------------------+-- Dead-Item-Collection plugin:+----------------------------------------------------------------------------------------------------++-- This one will extend the autodonePlugin and add counters for+-- item collections. When all the steps consuming from an item+-- collection are 'done' then the item collection can be freed.+++---------------------------------------------------------------------------------------------------- +-- Fusion plugin:+---------------------------------------------------------------------------------------------------- ++-- Idea: this is a kind of interesting way to do fusion.+-- We can fuse producer/consumer A and B by:+-- (1) Call B directly from A's put method. Use "return" to avoid the REAL put.+-- (2) Use "return" in B's beforeStepExecute to disable it.++-- Actually, (2) is not necessary, beforeStepExecute should really+-- throw an exception, because B's execute should never be called in+-- this framework.+++
+ Intel/Cnc/Spec/Codegen/Plugins/Depends.hs view
@@ -0,0 +1,120 @@+{-# LANGUAGE CPP, NamedFieldPuns, ScopedTypeVariables #-}++module Intel.Cnc.Spec.Codegen.Plugins.Depends+ (+ dependsPlugin,+ all_tagfuns_tractible,+ tuner_name + )+where++import Control.Monad+import qualified Data.Map as M+import Data.Graph.Inductive hiding (empty)+import Data.Maybe++import Intel.Cnc.Spec.TagFun+import Intel.Cnc.Spec.Codegen.Plugins+import Intel.Cnc.Spec.CncGraph++import Text.PrettyPrint.HughesPJClass +-- import Intel.Cnc.EasyEmit hiding (not, (||))+import qualified Intel.Cnc.EasyEmit as EE+import Intel.Cnc.EasyEmit hiding (app, not, (&&), (==), (||), (/=))++import Intel.Cnc.Spec.Util +import Intel.Cnc.Spec.AST+import StringTable.Atom+import qualified StringTable.AtomMap as AM++dependsPlugin :: CodeGenPlugin+dependsPlugin (spec @ CncSpec{appname, steps, tags, items, reductions, graph, realmap})+ stpname = + if all_tagfuns_tractible graph stpname && + stpname /= toAtom special_environment_name+ then + Just$ defaultHooksTable + { + addTopLevel = \ (privCtx, Syn mainCtx) () -> do+ comm "[depends] Generate tuner with depends() function:"+ cppStruct (Syn$ tuner_name stpname)+ (Syn$ t"public CnC::default_tuner< " <>+ cppType tagty <> t", "<> + mainCtx <> t" >") $+ (do putS "bool preschedule() const { return false; }"+ putS "template< class dependency_consumer >" + constFunDef voidTy (s"depends") + [TConst$ TRef$ tagty, + TRef$ TSym$ toAtom$ render mainCtx, + TRef$ TSym$ toAtom$ "dependency_consumer"] $ + \ (Syn tag, contextref, deps) -> do+ let dep = function$ Syn$t$ synToStr$ deps `dot` s"depends"+ -- Now iterate through all data collections connected to the step collection:+ forM_ (lpre graph$ realmap M.! (CGSteps stpname)) $ \ (nd, tgfn) -> + case lab graph nd of + Just (CGItems itC) -> do+ comm$ "Dependency on collection "++ (graphNodeName$ fromJust$ lab graph nd) ++", tagfun " ++ show tgfn+ case tgfn of + Just fn -> forM_ (applyTagFun fn tag) $ \ resulttag -> + EE.app dep [contextref `dot` Syn (toDoc itC), Syn resulttag]+ Nothing -> comm "Ack.. tag function not available..."+ _ -> return ()+ return ()+ )+ return ()+ }+ else Nothing+ where+ tagC = getStepPrescriber spec stpname+ tagty = case tags AM.! tagC of+ Nothing -> error ""+ Just ty -> ty ++-- shorthands: +s = Syn . text ++-- This predicate determines whether we can successfully determine all+-- the data dependencies of a step, for example to generate a depends function.+all_tagfuns_tractible :: CncGraph -> Atom -> Bool+all_tagfuns_tractible graph step =+ True+ -- FIXME -- TODO -- FINISH THIS!!!+++tuner_name stp = toDoc stp <> t"_tuner"+++++#if 0+ maybeComment [t"", t"Automatically generated tuners, where possible."]$+ when gendepends $ + forM_ stepls_with_types $ \ (stp,ty) -> + when (AS.member stp tractible_depends_steps) $++ cppStruct (Syn$ tuner_name stp)+ (Syn$ t"public CnC::default_tuner< " <>+ cppType ty <> t", "<> + maincontext <> t" >")+ (do putS "bool preschedule() const { return false; }"+ putS "template< class dependency_consumer >" + constFunDef voidTy (s"depends") + [TConst$ TRef$ ty, + TRef$ TSym$ toAtom$ render maincontext, + TRef$ TSym$ toAtom$ "dependency_consumer"] $ + \ (Syn tag, contextref, deps) -> do+ let dep = function$ Syn$t$ synToStr$ deps `dot` s"depends"+ -- Now iterate through all data collections connected to the step collection:+ forM_ (lpre graph$ realmap M.! (CGSteps stp)) $ \ (nd, tgfn) -> + case lab graph nd of + Just (CGItems itC) -> do+ comm$ "Dependency on collection "++ (graphNodeName$ fromJust$ lab graph nd) ++", tagfun " ++ show tgfn+ case tgfn of + Just fn -> forM_ (applyTagFun fn tag) $ \ resulttag -> + EE.app dep [contextref `dot` Syn (toDoc itC), Syn resulttag]+ Nothing -> comm "Ack.. tag function not available..."+ _ -> return ()+ return ()+ )++#endif
+ Intel/Cnc/Spec/Codegen/Plugins/ReductionDone.hs view
@@ -0,0 +1,31 @@+{-# LANGUAGE ScopedTypeVariables, OverloadedStrings, NamedFieldPuns #-}+{- ++ The reduction-done plugin extends autodone by introducing counters+ for reduction collections and signalling all_done().++ -}+module Intel.Cnc.Spec.Codegen.Plugins.ReductionDone+ (+ reductionDonePlugin+ )+where+import Intel.Cnc.Spec.Codegen.Plugins+import Intel.Cnc.Spec.CncGraph+import Intel.Cnc.EasyEmit hiding (not, (||))+import Control.Monad+++reductionDonePlugin :: DonePlugin+reductionDonePlugin = DonePlugin $ + \ debug_autodone node -> + if isReductionC node then Just$ + do let redC = graphNodeName node++ comm "[reduction_done] When the dependencies of a reduction collection are done, signal all_done() on it"+ when debug_autodone$+ app (function "printf") [stringconst$ " [reduction_done] Signaling all_done() for "++ show redC ++".\n"]+ app (function (atomToSyn redC `dot` "all_done")) []++ else Nothing+
+ Intel/Cnc/Spec/Codegen/Plugins/TagFunCorrectness.hs view
@@ -0,0 +1,104 @@+{-# LANGUAGE CPP, NamedFieldPuns, ScopedTypeVariables #-}++module Intel.Cnc.Spec.Codegen.Plugins.TagFunCorrectness+ (+ tagfunCorrectnessPlugin+ )+where++import Control.Monad+import qualified Data.Map as M+import Data.Graph.Inductive hiding (empty)++import Intel.Cnc.Spec.TagFun+import Intel.Cnc.Spec.Codegen.Plugins+import Intel.Cnc.Spec.CncGraph++import Text.PrettyPrint.HughesPJClass +-- import Intel.Cnc.EasyEmit hiding (not, (||))+import qualified Intel.Cnc.EasyEmit as EE+import Intel.Cnc.EasyEmit hiding (app, not, (&&), (==), (||))++tagfunCorrectnessPlugin :: CodeGenPlugin+tagfunCorrectnessPlugin (spec @ CncSpec{appname, steps, tags, items, reductions, graph, realmap})+ stpname = + Just$ defaultHooksTable + {+ beforeItemPut = boilerplate CGItems lpre' "Item Put",+ beforeItemGet = boilerplate CGItems lsuc' "Item Get",+ beforeReducerPut = boilerplate CGReductions lpre' "Reducer Put",+ beforeReducerGet = boilerplate CGReductions lsuc' "Reducer Get"+ }+ where + fprintf = function$ Syn$t "fprintf"+ stderr = constant "stderr"+ abort = function$ Syn$t "abort" + + boilerplate constructor getnbrs msg (privC, mainC, to) (tag,val) = do+ let + target = constructor to+ stpnd = CGSteps stpname+ itemnd = realmap M.! target+ gctxt = context graph itemnd+ lnhbrs :: [(Node, Maybe TagFun)] = getnbrs gctxt+-- access_edges = filter (\ (nd,lab) -> nd == stpname) lnhbrs++ return ()+++-- shorthands: +s = Syn . text +t = text++#if 0 ++ doplugs project = execEasyEmit$ + -- FIXME: HACK:+ when (length args Prelude.>= 2) $+ forM_ (AM.findWithDefault [] stp plug_map) $ \ hooks ->+ project hooks (Syn$ t$ snd$ head args, Syn$ t$ snd$ head$ tail args, colName)+ (Syn$ t$ snd$ head args, Syn$ t$ snd$ head$ tail args)+++checkTagFun stp target getnbrs fprintf stderr abort tagty args realmap graph = + -- TODO INSERT CORRECTNESS CHECKING HERE:+ stpnd = realmap M.! (CGSteps stp)+ itemnd = realmap M.! target+ gctxt = context graph itemnd+ lnhbrs = getnbrs gctxt-- lpre' gctxt ++ lsuc' gctxt+ ls = filter (\ (nd,lab) -> nd == stpnd) lnhbrs+ -- [(_,tf)] = filter (\ (nd,lab) -> nd == stpnd)$ lpre' gctxt + --[(_,tf)] = trace (" LENGTH "++ show (length ls) ++" "++ show stpnd ++" "++ show itemnd++" "++ show lnhbrs) ls+ in + execEasyEmit$+ case ls of + -- If we have no relationship to that collection its an error to access it:++ [] -> do let str = printf " [tagfun_check] CnC graph violation: should not access collection '%s' from '%s'" + (graphNodeName target :: String) (show stp) + EE.app fprintf [stderr, stringconst$ str]+ EE.app abort[]++ [(_,Nothing)] -> comm " [tagfun_check] No tag function to check..."++ --((_,Just (TF args exps)) : []) -> ++ ((_,Just (TF tfargs exps)) : tl) -> -- TEMPTOGGLE ... permissive, ignoring additional tag functions!+ case (tfargs,exps) of + ([arg], [exp]) -> + do comm (" [tagfun_check] Checking tag function "++ show arg ++" -> "++ show exp)+ -- TODO: use normal variable decl here:+ putD$ tagty <+> (fromAtom arg) <+> t"=" <+> t"* m_context->tag" <> semi+ when (not$ null args)$ assert (head args EE.== Syn (pPrint exp)) -- FIXME -- afer factoring fix this head args+ _ -> error "internal error: tag function correctness not fully implemented yet. Finish me."++ _ -> error$ "internal error: tag function correctness codegen: \n w"++show ls++++ putD$ (if gendebug -- Optionally include debugging assertions.+ then checkTagFun stp ((if isReduction then CGReductions else CGItems) colName) + (if isPut then lpre' else lsuc') + fprintf stderr abort tagty args realmap graph+ else empty)+#endif
+ Intel/Cnc/Spec/Curses.hs view
@@ -0,0 +1,412 @@+{-# LANGUAGE RecordWildCards #-}++{-| + A Curses-based user interface. + -}++module Intel.Cnc.Spec.Curses where++--import System.IO+--import System.Environment+import System.Exit+import UI.HSCurses.Curses+import UI.HSCurses.CursesHelper as Help+import UI.HSCurses.Widgets++import Control.Monad+import System.Posix.Unistd+import Data.Sequence as Seq +import Data.IORef+++centeredLine win row str = + do let len = Prelude.length str + (height,width) <- scrSize+ move row ((width - len) `quot` 2)+ wAddStr win str++-- Hmm... I absolutely shouldn't have to write this:+-- It creates a bounding border (box)+box (y,x) (h,w) = + do let horiz = "+"++ (Prelude.take (w-2) $ repeat '-') ++"+"+ mvWAddStr stdScr y x horiz+ mvWAddStr stdScr (y + h - 1) x horiz+ forM_ [1..h-2] $ \r -> mvWAddStr stdScr (y + r) x "|"+ forM_ [1..h-2] $ \r -> mvWAddStr stdScr (y + r) (x + w - 1) "|"+ ++------------------------------------------------------------------------------------------------------------------------+-- Scrolling Text Windows (Buffers)+------------------------------------------------------------------------------------------------------------------------+-- I shouldn't have to write this either.+-- The hscurses textwidget is written in a profoundly inefficient way.++data ScrollBufRec = SB { + --Int+ bottom :: Bool, -- Are we following the bottom or have we "paged up" to the history?+ offscreen :: Seq.Seq String, -- The lines that have scrolled off+ visible :: Seq.Seq String, -- The lines we can see.+ pos :: Pos,+ size :: Size+}++type ScrollBuf = IORef ScrollBufRec++--mkScrollBuf :: Int -> ScrollBuf+--mkScrollBuf n = SB n Seq.empty+--emptyScrollBuf pos size = SB True Seq.empty Seq.empty pos size++--mkScrollBuf :: Pos -> Size -> IO (IORef ScrollBuf)+mkScrollBuf :: Pos -> Size -> IO ScrollBuf+mkScrollBuf pos size = newIORef $ SB True Seq.empty Seq.empty pos size ++scrollBufAddLine :: ScrollBuf -> String -> IO ()+scrollBufAddLine ref str = + do orig <- readIORef ref+ let (y,x) = pos orig+ (h,w) = size orig+ newvis = visible orig |> str+ extra = Seq.length newvis - h+ sb = if bottom orig && extra > 0+ then orig{ offscreen= offscreen orig >< Seq.take extra newvis,+ visible= Seq.drop extra newvis+ }+ else orig{ visible= newvis }+ writeIORef ref sb+ drawScrollBuf sb++-- Adds to the end of the last line:+--scrollBufAddStr ++drawScrollBuf sb = + do let lns = viewLtoList $ viewl $ visible sb+ tw = newTextWidget defaultTWOptions $ unlines lns+ drawTextWidget (pos sb) (size sb) DHNormal tw++scrollBufToTop ref = + do sb <- readIORef ref+ scrollBufUp ref (Seq.length $ offscreen sb)++scrollBufToBottom ref = + do sb <- readIORef ref+ scrollBufDown ref (Seq.length $ visible sb)++scrollBufUp ref n = + do sb <- readIORef ref+ let loop 0 sb = sb+ loop n sb = + loop (n-1) $ + case viewr$ offscreen sb of+ EmptyR -> sb + rest :> r -> sb { bottom = False, + offscreen= rest,+ visible= r <| visible sb }+ new = loop n sb+ writeIORef ref new+ drawScrollBuf new+++scrollBufDown ref n = + do sb <- readIORef ref+ if bottom sb + then return ()+ else do + let (h,w) = size sb + --loop n vis+ extra = Seq.length (visible sb) - h+ scroll = min extra n+ loop 0 sb = sb+ loop n sb = + loop (n-1) $+ case viewl$ visible sb of+ EmptyL -> sb { bottom = True }+ l :< rest -> sb { --bottom = False, + bottom = (Seq.length rest <= h) || bottom sb,+ offscreen= offscreen sb |> l, + visible= rest }+ new = if scroll <= 0 then sb + else loop scroll sb+ writeIORef ref new+ drawScrollBuf new++scrollBufSet :: ScrollBuf -> [String] -> IO ()+scrollBufSet ref lines = + do sb <- readIORef ref+ let new = sb{ bottom=True, offscreen= Seq.empty, visible= Seq.fromList lines }+ writeIORef ref new+ drawScrollBuf new++viewLtoList EmptyL = []+viewLtoList (a :< rest) = a : viewLtoList (viewl rest)++----------------------------------------------------------------------------------------------------+-- Labeled text fields.+-- These are something simpler... just a single-line text field that is updated.+----------------------------------------------------------------------------------------------------++-- These are drawn with wAddStr directly rather than the "textWidget"++data TextFieldRec a = TF {+-- contents :: String, + contents :: a, + tfpos :: Pos,+ width :: Int+-- hookOn :: [IO ()],+-- hookOff :: [IO ()]+}++--type TextField a = IORef (TextFieldRec a)+type TextField = IORef (TextFieldRec String)++mkTextField :: String -> Pos -> Int -> IO TextField+mkTextField label (y,x) width {-onhk offhk-} = + do mvWAddStr stdScr y x label+ newIORef $ TF "" (y, x + Prelude.length label) (width - Prelude.length label) -- onhk offhk++setTextField :: TextField -> String -> IO ()+setTextField ref str = + do tf <- readIORef ref+ let (y,x) = tfpos tf+ -- Crop the right end of the string:+ mvWAddStr stdScr y x (Prelude.take (width tf) str)+ wAddStr stdScr (Prelude.take (width tf - Prelude.length str) $ repeat ' ')+ writeIORef ref tf{ contents = str }++-- Add text to a field rather than overwriting. Allows building up contents with different styles.+appendTextField ref str = + do tf <- readIORef ref+ let (y,x) = tfpos tf+ len = Prelude.length $ contents tf+ mvWAddStr stdScr y (x + len) (Prelude.take (width tf - len) str)+ writeIORef ref tf{ contents = contents tf ++ str }++-- If appending bits of text, cap when finished to blank the remainder of the text field.+capTextField ref = + do tf <- readIORef ref+ let (y,x) = tfpos tf+ len = Prelude.length $ contents tf+ mvWAddStr stdScr y (x + len) (Prelude.take (width tf - len) $ repeat ' ')++-- Multiple text fields across a line:+textFieldsLine :: Int -> [String] -> IO [TextField]+textFieldsLine row labels = + do size@(height,width) <- scrSize+ let len = Prelude.length labels+ portion = width `quot` len+ forM (Prelude.zip [0 .. len-1] labels) $ \ (i,lab) -> do+ mkTextField lab (row, i * portion) portion --[] []+ +----------------------------------------------------------------------------------------------------+-- A "DisplayCell" is a wrapper around a TextField that stores any Showable type of data.+-- When the contents of the cell is updated, so is the display.+----------------------------------------------------------------------------------------------------++type DisplayCell a = (IORef a, [(a -> String, TextField)])++{-+mkDisplayCell x pos wid = + do tf <- mkTextField stdScr (show x) pos wid+ ref <- newIORef x+ return (ref, tf)+-}++-- This takes a list of displays to update and printer procedures to do the updates.+mkDisplayCell x ls = + do ref <- newIORef x+ forM_ ls $ \ (printer,tf) -> setTextField tf (printer x)+ return (ref, ls)++setDisplayCell (ref,ls) x = + do writeIORef ref x+ forM_ ls $ \ (printer,tf) -> + setTextField tf (printer x)+ +getDisplayCell (ref,_) = readIORef ref+++ +----------------------------------------------------------------------------------------------------++widget pos size = + do putStrLn$ "foo"+ let lns = map ((" "++) . show) [1..100]+ tw = newTextWidget defaultTWOptions $ unlines lns+ drawTextWidget pos size DHNormal $ + --drawTextWidget (6,2) (20,20) DHActive $+ --drawTextWidget pos size DHFocus $ + --textWidgetScrollUp (10,10) tw+ textWidgetScrollDown (15,0) tw -- problems+ --textWidgetScrollLeft (1,1) tw+ --textWidgetScrollRight (0,0) tw -- problems+ --tw++ refresh + --usleep (900 * 1000) -- 0.1 second sleep.+ --drawTextWidget pos size DHNormal $ textWidgetSetText tw $ unlines (drop 10 lns)+ refresh ++ return ()++main = runCursesUI undefined undefined (\c -> putStrLn$ "CALLBACK "++show c)++----------------------------------------------------------------------------------------------------++-- When the visualization layer instantiates this keyboard interface it provides two callbacks.++-- Each callback scrolls either backwards or forwards, updates the+-- visualization and allows a "peak" at the timestamp of the NEXT+-- event if the user keeps going in that direction.+type Callback a b = a -> IO b+type PeekEventCallback = Callback () Double++data PlayMode = Realtime Double | Const Double | Paused+ deriving (Show, Eq, Ord)++disp_mode Paused = "Paused"+disp_mode (Realtime coef) = "Realtime"+disp_mode (Const wait) = "Const"+disp_rate Paused = ""+disp_rate (Realtime coef) = show coef ++ " X"+disp_rate (Const wait) = show (round wait) ++ " ms/event"++--runCurses :: [(Double, String)] -> Callback () -> Callback () -> Callback Key -> IO ()+--runCurses timed_log fwd_callback rev_callback key_callback = +runCursesUI :: PeekEventCallback -> PeekEventCallback -> Callback Key () -> IO ()+runCursesUI fwd_callback rev_callback key_callback = + do Help.start+ initScr+ colors <- hasColors + if not colors then error "COLORS not available on this terminal" else return() + startColor ++ numPairs <- colorPairs++ initColor (Color 90) (0,0,0)+ initColor (Color 91) (500,0,0)+ initColor (Color 92) (1000,1000,1000)+ initPair (Pair 17) (Color 91) (Color 90)+ initPair (Pair 18) (Color 92) (Color 90)++ size@(height,width) <- scrSize++ move 1 0+ [redstyle, yellow, grey, green] <- + convertStyles [Style DarkRedF BlackB, Style YellowF BlackB, + Style GreyF BlackB, Style DarkGreenF BlackB ]+ withStyle redstyle $ drawLine width (repeat '=')+ withStyle redstyle $ centeredLine stdScr 0 "CnC Interactive Trace Visualizer"++ let sb_start = 9 -- Where the scrollbuffer starts on the screen.+ sb_size = (height - sb_start - 3, width - 7)++ sb <- mkScrollBuf (sb_start+2,3) sb_size+ withStyle green$ mvWAddStr stdScr sb_start 2 $ "Trace Event History:" + box (sb_start+1,1) (height-sb_start-1,width-4)+ refresh++ --------------------------------------------------------------------------------+ -- Model state+ --------------------------------------------------------------------------------+ let ln1 = ["Total elapsed time: ", "Playback mode: ", " Trace events: "]+ ln2 = [" Current time: ", "Playback rate: ", "Current event: "]+ [totaltime, play_mode, numevents] <- withStyle grey$ textFieldsLine 2 ln1+ [current_time, play_rate, current_event] <- withStyle grey$ textFieldsLine 3 ln2++ attrBoldOn+ setTextField totaltime "00:44.55"+ -- Wrap some of these text fields to store non-string datatypes.+ numevents_cell <- mkDisplayCell 0 [(show, numevents)]+ current_event_cell <- mkDisplayCell 0 [(show, current_event)]++ play_mode_cell <- mkDisplayCell Paused [(disp_mode, play_mode), (disp_rate, play_rate)]++ setDisplayCell play_mode_cell (Realtime 2.0)+ setDisplayCell play_mode_cell (Const 100.0)++ attrBoldOff+ --------------------------------------------------------------------------------++ mvWAddStr stdScr 5 0 $ "Enter keyboard input (? or 'h' for help):" ++ let cursor_pos = (6,2)+ withStyle yellow$ mvWAddStr stdScr (fst cursor_pos) 0 $ "> " ++ --gotoTop + mapM_ (scrollBufAddLine sb) $ map show [1..200]+ refresh+++ ----------------------------------------+ move (20) 40+ colors <- hasColors + refresh+ size@(height,width) <- scrSize+ [user_input, cursor_field] <- withStyle green$ textFieldsLine (fst cursor_pos) ["> ", ""]+ event_counter <- newIORef 0 ++ --------------------------------------------------------------------------------+ -- Begin main event loop+ --------------------------------------------------------------------------------+ let event_loop row 0 = return ()+ event_loop row n = do+ withStyle green$ box (sb_start+1,1) (height-sb_start-1,width-4)+ uncurry move cursor_pos+ refresh++ c <- Help.getKey refresh+ setTextField cursor_field $ "You pressed: "++ attrBoldOn+ --attrSet attr0 (Pair 17)+ withStyle green $ appendTextField cursor_field $ show c+ capTextField cursor_field + attrBoldOff+ --attrSet attr0 (Pair 18)+ --useDefaultColors+ + case c of + --KeyUp -> scrollBufUp sb 1+ --KeyDown -> scrollBufDown sb 1++ KeyUp -> do c <- readIORef event_counter + if c == 0 + then setTextField current_event "0"+ else do writeIORef event_counter (c-1)+ setTextField current_event (show$ c-1)+ KeyDown -> do c <- readIORef event_counter + if c == 999999 + then setTextField current_event (show c)+ else do writeIORef event_counter (c+1)+ setTextField current_event (show$ c+1)++ KeyPPage -> scrollBufUp sb (fst sb_size)+ KeyNPage -> scrollBufDown sb (fst sb_size)++ KeyHome -> scrollBufToTop sb+ KeyEnd -> scrollBufToBottom sb++ KeyDC -> scrollBufSet sb ["DELETED"]++ KeyChar ' ' -> do setTextField user_input " Playback started."+++ --KeyChar c -> scrollBufAddLine sb [c]++ _ -> key_callback c++ refresh+ if c == KeyChar '\ETX' + then return() + else event_loop (row+1) (n-1)+ --------------------------------------------------------------------------------+ -- End event_loop definition+ --------------------------------------------------------------------------------+ event_loop 22 999999999999++ endWin + Help.end+ --update++ putStrLn$ "Exited ncurses"+ return ()+
+ Intel/Cnc/Spec/GatherGraph.hs view
@@ -0,0 +1,263 @@+{-# LANGUAGE RecordWildCards, ScopedTypeVariables #-}+{-# OPTIONS_GHC -fwarn-incomplete-patterns #-}+----------------------------------------------------------------------------------------------------+-- This module implements a pass over the parser output that coalesces+-- all the relations in a .cnc file into a more manageable graph type.+--+-- The main entrypoint is "assembleSpec".+----------------------------------------------------------------------------------------------------++module Intel.Cnc.Spec.GatherGraph ( coalesceGraph,+ exampleGraph, tests_gathergraph+ ) where+import Intel.Cnc.Spec.AST+import Intel.Cnc.Spec.TagFun+import Intel.Cnc.Spec.CncGraph+import Intel.Cnc.Spec.SrcLoc+import Intel.Cnc.Spec.Util++import Data.Map as Map+import Data.List as L+import Data.Maybe+import StringTable.Atom +import StringTable.AtomMap as AM+import StringTable.AtomSet as AS+import Control.Monad+import Data.Graph.Inductive as G+--import Data.Graph.Inductive.NodeMap as NM++import Test.HUnit++----------------------------------------------------------------------------------------------------++-- Transform the not-directly-useful list of parsed statements into a real graph datatype.+coalesceGraph :: String -> [PStatement SrcSpan] -> CncSpec+coalesceGraph name parsed = + -- trace ("Got ALL nodes "++ show (L.map fst$ AM.toList$ tags allnodes) ++"\nsteps "++ + -- show (AS.toList$ steps allnodes) ++"\nitems "++ show (L.map fst$ AM.toList$ items allnodes)) $ + allnodes { graph=g2, appname=name, nodemap=nm, realmap= rm }+ where + g1 :: CncGraph = run_ G.empty $ + -- First add all the nodes to the graph+ do --mapM_ declare parsed + --mapM_ (insMapNodeM . CGSteps) builtinSteps + mapM_ (insMapNodeM . CGSteps) (AS.toList$ steps allnodes)+ mapM_ (insMapNodeM . CGTags) (L.map fst$ AM.toList$ tags allnodes)+ mapM_ (insMapNodeM . CGItems) (L.map fst$ AM.toList$ items allnodes)+ mapM_ (insMapNodeM . CGReductions) (L.map fst$ AM.toList$ reductions allnodes)++ (_,(nm,g2)) = --trace ("Done collecting declares.. all nodes: " ++ show g1) $ + run g1 $ forM_ parsed collect -- Then add the edges.++ rm = Map.fromList$ Prelude.map (\ (a,b) -> (b,a)) $ labNodes g2++ allnodes = collectInsts parsed $ collectDecls parsed+ collect stmt = + case stmt of + Chain start links -> coalesceChain allnodes start links+ Function -> return ()+ Constraints _ _ _ -> return ()+ DeclareExtern -> return ()+ DeclareTags _ _ _ -> return ()+ DeclareSteps _ _ -> return ()+ DeclareItems _ _ _ -> return ()+ DeclareReductions _ _ _ _ _ -> return ()+ TypeDef _ _ _ -> return ()+++-- This is tedious, but here we simply go over the big list of statements that come out of+-- the parser and collect the declarations for items, steps, and tags.+collectDecls :: [PStatement dec] -> CncSpec+collectDecls [] = seedWorld+collectDecls (DeclareTags s name ty : tl) = extendTags name ty $ (checkDup name$ collectDecls tl)+collectDecls (DeclareItems s name ty : tl) = extendItems name ty $ (checkDup name$ collectDecls tl)+collectDecls (DeclareSteps s name : tl) = extendSteps name $ (checkDup name$ collectDecls tl)+collectDecls (DeclareReductions s name op exp tys : tl) = + extendReductions name (op, mapDecor (const ()) exp, tys)+ $ (checkDup name$ collectDecls tl)+collectDecls (_ : tl) = collectDecls tl++-- A lot of other miscellaneous contortion here to the end of supporting legacy syntax:+--extendItems name ty (a@(CncSpec{..})) = a { items= AM.insert name (mergeTy name ty a) items }+extendItems name ty (a@(CncSpec{..})) = a { items= AM.insert name (mergeTy name ty items) items }+extendTags name ty (a@(CncSpec{..})) = a { tags = AM.insert name (mergeTy name ty tags) tags }+extendSteps name (a@(CncSpec{..})) = a { steps= AS.insert name steps }+extendReductions name opty (a@(CncSpec{..})) = a { reductions= AM.insert name opty reductions }+-- a { reductions= AM.insert name (op, mergeTy name ty reductions) items }++checkDup atom all = + if cncSpecMember atom all+ then error$ "Duplicate declaration of name: '"++ (fromAtom atom) ++"'"+ else all+cncSpecMember atom (CncSpec{..}) =+ AM.member atom tags ||+ AS.member atom steps ||+ AM.member atom reductions ||+ AM.member atom items++------------------------------------------------------------+-- TEMP: For the benefit of the legacy syntax we harvest from instances as well as decls:+collectInsts (Chain hds links : tl) root = + let acc = foldl extendWithInstance (collectInsts tl root) hds in+ foldl extendWithLink acc links+collectInsts (_ : tl) root = collectInsts tl root+collectInsts [] root = root++extendWithInstance acc inst =+ case inst of + InstStepCol _ name ls -> extendSteps (toAtom name) acc+ InstItemCol _ name ls -> extendItems (toAtom name) Nothing acc+ InstTagCol _ name ls -> extendTags (toAtom name) Nothing acc+-- _ -> acc+-- InstReductionCol _ name ls -> extendReductions (toAtom name) Nothing acc++-- These forms are ambiguous, so there is no extra information here:+ InstName _ _ -> acc+ InstStepOrTags _ _ _ -> acc+-- InstStepOrTags _ _ _ -> error$ "extendWithInstance: InstStepOrTags should have been desugared by now:\n " ++ show inst++extendWithLink acc link = + case link of + ProduceLink _ insts -> foldl extendWithInstance acc insts+ RevProduceLink _ insts -> foldl extendWithInstance acc insts+ PrescribeLink _ insts -> foldl extendWithInstance acc insts++-- Merge type info if there's already an entry:+mergeTy name ty amap = + case (maybeToList ty ++ + maybeToList (collapseMaybe (AM.lookup name amap))) of + [] -> Nothing+ [ty2] -> Just ty2+ [ty1,ty2] -> if ty1 == ty2 -- Types are nominal at the moment, no unification:+ then Just ty1+ else error$ "mergeTy: different types for "++fromAtom name++" "++ show(pp ty1) ++" and "++ show(pp ty2)+ _ -> error "mergTy, internal error"++----------------------------------------------------------------------------------------------------+ +-- Continue extending a graph with nodes from a parsed chain.+coalesceChain :: CncSpec -> [CollectionInstance SrcSpan] -> [RelLink SrcSpan] + -> NodeMapM CncGraphNode (Maybe TagFun) Gr ()+coalesceChain allnodes start ls = loop (process start) ls + where + process = L.map (\x -> (instToNode allnodes x, instToExps x)) + loop prevs [] = return ()+ loop prevs (hd:tl) = + -- FIXME: inefficent redundant classifications+ let produce prevs insts next = + forM_ insts $ \ (node,exps) -> + forM_ prevs $ \ (pnode,pexps) -> + let + insert = insMapEdgeM (pnode, node, mkTagFun (show (node,pnode)) exps pexps) + insert_flipped = insMapEdgeM (pnode, node, mkTagFun (show (pnode,node)) pexps exps) + in+ do case (pnode, node) of + -- Valid combinations for a producer relation:+ -- This is tricky because depending on whether the left or the right+ -- hand side is the step collection the tag expressions are interpreted+ -- differently.+ (CGSteps _, CGItems _) -> insert_flipped+ (CGSteps _, CGReductions _) -> insert_flipped+ (CGSteps _, CGTags _) -> insert_flipped++ -- NOTE: Tag functions always relative to the step collection.+ -- Flip the tag components for generating the tag function:+ (CGItems _, CGSteps _) -> insert+ (CGReductions _, CGSteps _) -> insert++ (l,r) -> error$ "coalesceChain: invalid put/get relation from '"++graphNodeName l++"' to '"++graphNodeName r++"'"+ loop next tl+ in+ case hd of + -- Connect the previous node to this one using a forward edge:+ ProduceLink _ insts -> let pi = process insts in produce prevs pi pi+ -- These mean the same thing but are written backwards:+ RevProduceLink s insts -> let pi = process insts in produce pi prevs pi+ PrescribeLink _ insts -> + let processed = process insts in+ forM_ (process insts) $ \ (node,exps) -> + forM_ prevs $ \ (pnode,pexps) -> + -- This is a bit simpler because there is only one valid prescribe:+ do case (pnode, node) of + (CGTags _, CGSteps _) -> + insMapEdgeM (pnode, node, mkTagFun (show (node,exps)) exps pexps)+ (l,r) -> error$ "coalesceChain: invalid prescribe relation from '"++graphNodeName l++"' to '"++graphNodeName r++"'"+ loop processed tl+++-- FIXME: classification should happen as a previous pass that pays more attention to context:+--+-- Based on global sets of nodes/items/tags classify collection references.+-- That is, turn "Instances" in the parse into real graph nodes.+instToNode :: CncSpec -> CollectionInstance t -> CncGraphNode +instToNode (CncSpec { .. }) inst = + let classify name | AS.member name steps = CGSteps name+ | AM.member name tags = CGTags name+ | AM.member name items = CGItems name + | AM.member name reductions = CGReductions name +-- | isBuiltin (fromAtom name) = CGSteps name+ | True = error$ "Collection was not declared: " ++ show name+ in case inst of + InstName _ name -> classify $ toAtom name+ InstItemCol _ name _ -> + case classify $ toAtom name of + x@(CGItems _) -> x+ _ -> error$ "instToNode: collection indexed with [] but was not an item collection: "++ show name++-- FIXME: these are currently only for the LEGACY syntax:+ InstStepCol _ name _ -> CGSteps$ toAtom name+ InstTagCol _ name _ -> CGTags$ toAtom name++-- InstReductionCol _ _ _ -> TODO++ InstStepOrTags _ name _ -> + case classify $ toAtom name of + x@(CGTags _) -> x+ x@(CGSteps _) -> x+ _ -> error$ "instToNode: Error, collection is an item collection but is indexed with (), not [] : "++ show name+++instToExps :: CollectionInstance t -> [Exp t]+instToExps inst =+ case inst of + InstName _ _ -> []+ InstStepOrTags _ _ exps -> exps+ InstStepCol _ _ exps -> exps+ InstItemCol _ _ exps -> exps+ InstTagCol _ _ exps -> exps+ +----------------------------------------------------------------------------------------------------++seedWorld =+ CncSpec { steps= AS.fromList builtinSteps+ , tags= AM.empty+ , items= AM.empty+ , reductions= AM.empty+ , graph = error "CncSpec: graph uninitialized"+ , nodemap = error "CncSpec: nodemap uninitialized"+ , appname = error "CncSpec: appname uninitialized"+ , realmap = error "CncSpec: realmap uninitialized"+ , harchtree= error "CncSpec: harchtree uninitialized"+ }++-- A very simple graph for testing:+exampleGraph = + coalesceGraph "foo" $+ L.map (mapDecor (\_ -> UnhelpfulSpan "")) $+ [ DeclareTags () (toAtom "T") (Just (TSym (toAtom "int")))+ , DeclareSteps () (toAtom "S")+ , DeclareItems () (toAtom "I") Nothing+ , Chain [InstName () "T"] [PrescribeLink () [InstName () "S"]]+ , Chain [InstName () "S"] [ProduceLink () [InstName () "I"]]+ ]+++tests_gathergraph = + testSet "GatherGraph" + [ testCase "" "getStepPrescriber: T should be the prescriber to S "$ + (toAtom "T") ~=? getStepPrescriber exampleGraph (toAtom "S") + ]+++----------------------------------------------------------------------------------------------------+
+ Intel/Cnc/Spec/Globals.hs view
@@ -0,0 +1,12 @@+-- A file with some global constants.++module Intel.Cnc.Spec.Globals where+++-- "Official" output from our process should be tagged in the following way:+cnctag = "[CnC] "++--hcnc_name = "hcnc"+hcnc_name = "cnc"++special_environment_name = "env"
+ Intel/Cnc/Spec/GraphAnalysis.hs view
@@ -0,0 +1,185 @@+{-# LANGUAGE ScopedTypeVariables, OverloadedStrings, NamedFieldPuns #-}++module Intel.Cnc.Spec.GraphAnalysis + (BasicCycleAnalysis(..), + basicCycleAnalysis,+ tests_graphanalysis)+where++import StringTable.Atom+import qualified StringTable.AtomMap as AM+import Data.List as L+import Data.Maybe+import qualified Data.Set as S+import qualified Data.Map as M+import Intel.Cnc.Spec.CncGraph+import Intel.Cnc.Spec.Util hiding (app)+import Prelude hiding ((&&), (==), (<=))+import qualified Prelude as P++import Test.HUnit+import qualified Data.Graph.Inductive as G+import Data.Graph.Analysis.Algorithms.Common++import Intel.Cnc.Spec.GatherGraph (exampleGraph)+import Text.PrettyPrint.HughesPJClass+++----------------------------------------------------------------------------------------------------+-- Type definitions and functions for graph analyses.+----------------------------------------------------------------------------------------------------++-- | This represents the result of a basic graph analysis to determine+-- cycles. The nodes are re-indexed according to a scheme that+-- assigns the same number to nodes within a cycle (e.g. they are+-- "grouped").+data BasicCycleAnalysis = BasicCycleAnalysis + {+ -- Map node names onto their new "collapsed" indices.+ index_map :: AM.AtomMap Int,+ -- The same in reverse:+ rev_index_map :: M.Map Int (S.Set CncGraphNode),+ -- Map nodes onto their up/downstream taking into account the+ -- grouping (e.g. a dependency on a node implies dependencies on+ -- all other nodes sharing the same group.+ downstream_map :: AM.AtomMap (S.Set CncGraphNode),+ upstream_map :: AM.AtomMap (S.Set CncGraphNode)+ }+ deriving Show++-- Would be nice to DERIVE this:+instance Pretty BasicCycleAnalysis where + pPrint BasicCycleAnalysis{index_map, rev_index_map, upstream_map, downstream_map} =+ text "BasicCycleAnalysis {" $$+ nest 4 (+ text "index_map = " <> pPrint index_map <> text ", " $$+ text "rev_index_map = " <> pPrint rev_index_map <> text ", " $$+ text "upstream_map = " <> pPrint upstream_map <> text ", " $$+ text "downstream_map = " <> pPrint downstream_map+ ) $$+ text "}"+++-- | Performs an analysis to produce a BasicCycleAnalysis+-- For efficiency we would expect that this analysis is performed+-- once and shared between multiple plugins.+--+-- NOTE: Currently only step collections are included in the counter map!+basicCycleAnalysis :: CncSpec -> BasicCycleAnalysis+basicCycleAnalysis (spec@CncSpec{graph, steps, items, reductions, nodemap, realmap}) = + BasicCycleAnalysis {index_map=counter_map, rev_index_map=rev_counter_map, upstream_map, downstream_map}+ where + indexToNamed nd = case G.lab graph nd of + Nothing -> error$ "basicCycleAnalysis: Node not found in graph: "++ show nd+ Just x -> x+ namedToIndex = fst . (G.mkNode_ nodemap)++ -- NOTE: Only "active" collections which can put new instances into+ -- other parts of the graph (currently only step collections) are+ -- considered for the purposes of cycle calculation.++ -- Thus remove reduction/item collections before computing cycles (interested in control only):+ pruned_graph = G.delNodes (map (namedToIndex . CGItems) $ AM.keys items) $+ G.delNodes (map (namedToIndex . CGReductions) $ AM.keys reductions) $+ graph + -- TODO: ALTERNATIVELY: Rebuild the graph with only step collections.+ --step_only_graph = stepOnlyGraph graph++ -- NOTE: This includes special_environment_name:+-- all_step_nds = S.fromList$ map (namedToIndex . CGSteps) (AS.toList steps)++ cycsets = joinCycles$ cyclesIn' pruned_graph+ + -- Remove all nodes that are in cycles to find those that remain:+-- non_cycle_nodes = S.toList $ foldl' S.difference all_step_nds cycsets++ all_names :: S.Set G.Node+ all_names = S.fromList$ map namedToIndex $ M.keys realmap+ non_cycle_nodes = S.toList$ foldl' S.difference all_names cycsets++ -- Combine the nodes in and out of cycles:+ allnodesets :: [S.Set G.Node] = cycsets ++ (map S.singleton $ non_cycle_nodes) ++ -- Map every node onto exactly one counter. Nodes in a cycle must have the same counter.+ counter_map :: AM.AtomMap Int = fromSetList $ nodesets_counters+ nodesets_counters = zip (map (S.map (graphNodeName . indexToNamed)) allnodesets) [0..] + --num_counters = length allnodesets+ -- For convenience, we store a map in the other direction as well, from counter -> nodeset:+ rev_counter_map = M.fromList $ + zip [0..] (map (S.map (fromJust . G.lab graph)) allnodesets)++ -- Next we compute the upstream dependencies of entire cycles taken together:+ cycs_wname = L.map getSteps cycsets+ -- getSteps: convert a set of FGL Nodes to a set of CGSteps+ getSteps = S.fromList . filter isStepC . map (fromJust . G.lab graph) . S.toList + + -- For each node we store its up/down-stream dependencies. If the node is part of a+ -- cycles, its up/down-stream deps are those of the entire cycle:+ upstream_map :: AM.AtomMap (S.Set CncGraphNode) = make_map upstreamNbrs + downstream_map :: AM.AtomMap (S.Set CncGraphNode) = make_map downstreamNbrs + + make_map getnbrs =+ let+ cycnbrs = L.map (\ set -> S.difference (setNbrs set) set) cycs_wname+ -- setNbrs: take the combined upstreams of a set of nodes:+ setNbrs = S.fromList . concat . map (getnbrs spec) . S.toList + in + fromSetList $ + (map (dosingle getnbrs) non_cycle_nodes +++ zip (map (S.map (graphNodeName . indexToNamed)) cycsets) cycnbrs)++ dosingle getnbrs nd = + let name = indexToNamed nd in + (S.singleton (graphNodeName name), + S.fromList$ getnbrs spec name)+++----------------------------------------------------------------------------------------------------+-- Helpers/Utilities:+----------------------------------------------------------------------------------------------------++--fromSetList :: P.Ord a => [(S.Set a, b)] -> M.Map a b+fromSetList ::[(S.Set Atom, b)] -> AM.AtomMap b+fromSetList = + foldl' (\ map (set,val) -> + S.fold (\ nd mp -> AM.insert nd val mp)+ map set)+ AM.empty+++-- Join together nodes that participate in overlapping cycles:+-- FIXME!!! Inefficient quadratic algorithm:+joinCycles :: (P.Ord a) => [[a]] -> [S.Set a]+joinCycles cycs = foldl' foldin [] (map S.fromList cycs)+ where + foldin [] cyc = [cyc]+ foldin (hd:tl) cyc = if S.null (S.intersection hd cyc)+ then hd : foldin tl cyc + else (S.union cyc hd) : tl+++---------------------------------------------------------------------------------------------------- +-- Unit Tests:+---------------------------------------------------------------------------------------------------- ++testg :: G.Gr () String+testg = G.mkGraph (zip [1..7] (repeat ())) + [(1,2,""), (2,3,""), (3,4,""), (4,5,""), (5,6,""), (6,7,""),+ -- Close some cycles.+ (4,2,""), (7,6,""), (7,3,"")+ ]+testc = cyclesIn' testg++tests_graphanalysis = + testSet "CodegenShared" + [ testCase "" "joinCycles connected1"$ [S.fromList [2,3,4,5,6,7]] ~=? joinCycles testc+ , testCase "" "joinCycles connected2"$ [S.fromList [2,3,4,5,6,7]] ~=? joinCycles [[4,5,6,7,3], [4,2,3], [6,7]]+ , testCase "" "joinCycles connected3"$ [S.fromList [2,3,4,5,6,7]] ~=? joinCycles [[4,5,6,7,3], [4,2,3]]+ , testCase "" "joinCycles split"$ [S.fromList [2,3,4], S.fromList [6,7]] ~=? joinCycles [[4,2,3], [6,7]]+ + , testCase "" "basic graph analysis"$ test$ do+ putStrLn "Printing result of basic cycle analysis:"+ print$ pPrint (basicCycleAnalysis exampleGraph)+ + ]+
+ Intel/Cnc/Spec/Main.hs view
@@ -0,0 +1,11 @@++-- For GHC's benefit, we need a module called "Main" in order to compile an executable.++-- We just import the library version of the same and package it appropriately.++module Main where++import Intel.Cnc.Spec.MainExecutable++main = mainExecutableCommand+
+ Intel/Cnc/Spec/MainExecutable.hs view
@@ -0,0 +1,711 @@+{-# LANGUAGE CPP, NamedFieldPuns #-}+{-# OPTIONS_GHC -fwarn-incomplete-patterns #-}++-- This file puts the pieces together and defines the main entyrpoints into the CnC tool.++module Intel.Cnc.Spec.MainExecutable+ ( readCnCFile, readCnCFromStr,+ mainExecutableCommand )+ where++import Intel.Cnc.Spec.CncLexer hiding (main)+import Intel.Cnc.Spec.CncGrammar+import Intel.Cnc.Spec.SrcLoc+import Intel.Cnc.Spec.CncGraph+import Intel.Cnc.Spec.GatherGraph+import Intel.Cnc.Spec.Util hiding(t)+import Intel.Cnc.Spec.TraceVacuum++import Intel.Cnc.Spec.GraphAnalysis+import Intel.Cnc.Spec.Codegen.CppOld+import Intel.Cnc.Spec.Codegen.CodegenShared+import Intel.Cnc.Spec.Codegen.Plugins+import Intel.Cnc.Spec.Codegen.Plugins.ReductionDone+import Intel.Cnc.Spec.Codegen.Plugins.TagFunCorrectness+import Intel.Cnc.Spec.Codegen.Plugins.Depends++import qualified Intel.Cnc.EasyEmit as EE -- TEMPTOGGLE++import Intel.Cnc.Spec.Codegen.Haskell+import Intel.Cnc.Spec.Passes.TypeDef+import Intel.Cnc.Spec.Passes.ReadHarch+import Intel.Cnc.Spec.Version++import Data.Maybe ( fromJust )+import qualified Data.Map as M+import qualified Data.Set as S+import Data.List++import qualified Data.ByteString.Char8 as B+import qualified Data.ByteString.Lazy.Char8 as BL++import Codec.Compression.GZip (decompress)+import Control.Monad hiding (when)+import Control.Exception ++import System.Environment+import System.Console.GetOpt+import System.Console.ANSI+import System.FilePath.Posix+import System.IO+import System.IO.Unsafe+import System.Exit+import qualified System.Directory as Dir++import Text.Printf+import Text.PrettyPrint.HughesPJClass+import Test.HUnit+-- import Debug.Trace++-- These expand the file size quite a bit. Not committing to include right now:+-- #define CNCVIZ+#ifdef CNCVIZ +import Intel.Cnc.Spec.CncViz as Viz+import Control.Concurrent+#endif++----------------------------------------------------------------------------------------------------486++data Flag + = Verbose Int | Version | Help | Debug + | GenTracing | GenDepends | NoStepDefs | SelfTest+ | AutoDone | AutoDoneDbg+ | Cpp | CppOld | Haskell+ -- | Input String | LibDir String+ | Output String + | HarchPart String+ | HarchViz String+ | NullOpt+ | DotOpt+ | VizOpt+ | UbigraphOpt+ -- Trace mode:+ | Pack String + | VacuumViz | Vacuum+ | SynthSpec String + deriving (Show, Eq, Ord)+ ++run_modes :: [(String, [OptDescr Flag], String)]+run_modes = + [ ("translate", translate_options, "Translates .cnc specification files to host language code")+ , ("trace" , trace_options, "Works with Traces, e.g. the output of CnC::debug::trace.\n"+++ " (Reads a trace from an input file, if provided, or stdin.)")+ , ("harchpart", harchpart_options, "Uses Harch, the hierarchical graph partitioner for CnC.\n"+++-- " (This mode expects one .harch as input and produces a .part.harch)")+ " (This mode enriches a .harch file with partition info.)")+ ]++common_options :: [OptDescr Flag]+common_options = + [ Option ['V'] ["version"] (NoArg Version) "show version number"+ , Option ['v'] ["verbose"] (OptArg (\x -> case x of Just n -> Verbose (read n); + Nothing -> Verbose (-1)) "N") + "verbosity level {0,1,2} default 1 (-v with no arg increments)"+ , Option [] ["selftest"] (NoArg SelfTest) "run internal unit tests"+ , Option [] ["help"] (NoArg Help) "print this help information"+ ]++translate_options :: [OptDescr Flag]+translate_options = + [ + Option [] ["cpp"] (NoArg Cpp) "translate spec to C++ code [default]"+ , Option ['c'] ["cppold"] (NoArg CppOld) "translate spec to C++ code (legacy 0.5 API)"+ , Option ['h'] ["haskell"] (NoArg Haskell) "translate spec to Haskell code"+ , Option ['o'] ["output"] (ReqArg Output "FILE") "use FILE as a prefix for output header/codinghints"+ , Option [] ["harch"] (ReqArg HarchPart "FILE") "read Harch graph metadata from FILE (used for translation)"+ , Option [] ["debug"] (NoArg Debug) "generate extra code for correctness checking"+ , Option [] ["tracing"] (NoArg GenTracing) "generate code in which tracing is on by default"+ , Option [] ["depends"] (NoArg GenDepends) "generate depends functions from spec where possible"+ , Option [] ["autodone"] (NoArg AutoDone) "track collection completion and signal reduction-completion automatically"+ , Option [] ["autodonedbg"] (NoArg AutoDoneDbg) "print additional messages for debugging autodone facility"++ -- , Option [] ["autodone"] (OptArg + -- (\ arg -> case arg of + -- Just str -> trace str $ AutoDone+ -- Nothing -> AutoDone)+ -- "mode")+ -- "track collection completion and signal reduction-completion automatically"++-- , Option [] ["defsteps"] (NoArg GenTracing)$ "[c++] rather than the user defining custom types for each step,\n"+++-- " emit default versions within the generated header"+-- " create a standard definition in the generate header"++ -- , Option [] ["defsteps"] (NoArg GenStepDefs)$ "[c++] define default step structs in the generated header \n"+++ -- " (rather than custom, user-defined type definitions)"++ , Option [] ["customsteps"] (NoArg NoStepDefs)$ "[c++] Don't define default step structs in the generated header \n"+++ " (Instead the user provides custom type definitions.)"+++#ifdef CNCVIZ+ , Option [] [] (NoArg NullOpt) ""+ , Option [] ["dot"] (NoArg DotOpt) "output CnC graph in graphviz .dot format instead of translating"+ , Option [] ["viz"] (NoArg VizOpt) "similar to --dot, a shortcut to visualize a CnC graph in a X11 window"+ , Option [] ["ubigraph"] (NoArg UbigraphOpt) "like --viz, but visualize on a local Ubigraph server"+#endif++ ]++trace_options :: [OptDescr Flag]+trace_options = + [ + Option ['p'] ["pack"] (ReqArg Pack "FILE") "write the captured trace to FILE in compressed binary format"+#ifdef CNCVIZ+ , Option [] ["viz"] (NoArg VacuumViz) "use trace to visualize graph execution using ubigraph"+#endif+++-- TEMPTOGGLE: This feature is not implemented yet:+#if 0+ , Option [] ["synth"] (ReqArg SynthSpec "FILE") "use trace to synthesize a draft .cnc Spec for the program"+#endif+ , Option [] ["debug"] (NoArg Debug) "print parsed trace to validate parsing"+ ]+++harchpart_options :: [OptDescr Flag]+harchpart_options = + [ + Option ['o'] ["output"] (ReqArg Output "FILE") "output the graph-partitioned harchfile to FILE"+#ifdef CNCVIZ+ , Option [] ["viz"] (ReqArg HarchViz "FILE") "visualize the graph stored in FILE with Harch clustering"+#endif+ ]++++printHeader = do+-- putStrLn$ "Intel(R) Concurrent Collections Specification Tool, version "++ version+ putStrLn$ "The fabulous, multi-purpose CnC Specification Tool, version "++ version+ putStrLn$ "Part of the Intel(R) Concurrent Collections (CnC) Project"+ putStrLn$ "Built on: " ++ builddate+ putStrLn$ "Copyright 2011 Intel Corporation."++when b action = if b then action else return ()+++------------------------------------------------------------------------------------------------------------------------+-- The translator front-end: parse a file, convert to graph:+------------------------------------------------------------------------------------------------------------------------++++-- This is a primary entrypoint.+-- It invokes the parser and creates the graph coelescence.+readCnCFile :: Int -> String -> IO CncSpec+readCnCFile verbosity file = do + handle <- openFile file ReadMode+ str <- hGetContents handle++-- let appname = takeBaseName file+ final <- readCnCFromStr verbosity file str+ hClose handle -- Cleaner to do this than to wait for garbage collection.+ return final++-- This works on strings... it take an file argument that is just+-- metadata, which file did the string come from and what should the+-- spec be named.+readCnCFromStr :: Int -> String -> String -> IO CncSpec+readCnCFromStr verbosity file str = do+ when (verbosity > 2)$ putStrLn "\n All Lexed Tokens "+ when (verbosity > 2)$ putStrLn "================================================================================"++ --when verbose$ print $ hcat $ intersperse (text ", ") $ map (\ (L _ cl str) -> text (show cl) <+> pp str) $ scan_to_list str+ when (verbosity > 2)$ print $ sep $ map (\ (L _ cl str) -> text (show cl) <+> pp str) $ scan_to_list str+ --filter (not . is_comment) $ scan_to_list str -- Even filtering the long lines still doesn't `sep` to do the right thing.++ let parsed = runCncParser file str++ parsed' = if null parsed + then error "ERROR: CnC file contained no statements!\n Empty spec not considered valid."+ else parsed+ ----------------------------------------+ -- Pass 1: desugar type+ p1 = desugarTypeDefs parsed'++ ----------------------------------------+ final_statements = p1++ ----------------------------------------+ when (verbosity > 2)$ putStrLn "\n Parsed AST (detailed)"+ when (verbosity > 2)$ putStrLn "================================================================================"+ when (verbosity > 2)$ sequence_ $ map (print . stripDecor) parsed++ -- when verbose$ putStrLn "\nParsed AST rendered as a SExp:"+ -- when verbose$ putStrLn "================================================================================"+ -- when verbose$ sequence_ $ map (\stmt -> putStrLn $ buildList $ sexpSerialize stmt) parsed++ when (verbosity > 1)$ putStrLn "\n Pretty printed parsed AST"+ when (verbosity > 1)$ putStrLn "================================================================================"+ when (verbosity > 1)$ putStrLn$ renderStyle style $ hcat $ map pPrint parsed++ -- [2010.07.23] Lazy parsing complicates this, it must happen after IO that touches the parse:+ evaluate (length str)++ when (verbosity > 1)$ putStrLn " Coalesced CnC Graph"+ when (verbosity > 1)$ putStrLn "================================================================================"+ -- The name of the module is derived from the file name: + let appname = takeBaseName file+ let graph = coalesceGraph appname final_statements++ when (verbosity > 1)$ putStrLn ""+ when (verbosity > 1)$ print $ pp graph++ when (verbosity > 1)$ putStrLn "================================================================================"+ return graph+++ +------------------------------------------------------------------------------------------------------------------------++-- If this module is used as an executable, this handles arguments and does the appropriate thing.+mainExecutableCommand = + do + argv <- getArgs+ mainWithArgStrings argv++baseline = [SetColor Background Dull Black]+withCol viv col act = + do setSGR [SetColor Foreground viv col]+ act + setSGR []+ --setSGR baseline++simpleErr "" msg = error$ "ERROR!\n " ++ msg+simpleErr mode msg = error$ "ERROR! ("++hcnc_name++" "++ mode ++" mode)\n " ++ msg+++mainWithArgStrings argv = do + let ++ print_usage_common = + do withCol Vivid Black$ putStr$ "Common Options (all modes):"+ putStr$ usageInfo "" common_options ++ mode_usage (mode, opts, help) = do + withCol Dull Green$ putStr$ "\n '"++ mode ++"' mode:\n "+ --withCol Dull Cyan $ putStr$ help ++":\n"+ withCol Vivid Black $ putStr$ help ++":\n"+ withCol Dull Red $ putStr$ take 80$ repeat '-'+ putStr$ usageInfo "" opts+ setSGR []++ print_usage_all = + do withCol Dull Green$ putStr$ "Usage: "++hcnc_name++" mode [OPTION...] files..." + putStr$ "\n\n"+ print_usage_common+ forM_ run_modes mode_usage++ defaultErr mode errs = + do + --setSGR baseline+ withCol Vivid Red$ putStr$ "ERROR! " ++ (if null mode then "" else "("++hcnc_name++" "++mode++" mode) ") ++errs++"\n"+ print_usage_all+ putStrLn ""+ error $ "ERROR! "++ -- simpleErr mode msg = do + -- withCol Vivid Red$ + -- case mode of + -- "" -> ++ ----------------------------------------------------------------------------------------------------+ -- Read and process option flags:+ ----------------------------------------------------------------------------------------------------++ -- Do a little pre-processing of the opts so we can catch --version:+ -- On first look we just look at the common options. Later on we include the mode options as well.+ let (common_opts,_,_) = getOpt Permute common_options argv++ when (Version `elem` common_opts) $ do printHeader; exitSuccess+ when (SelfTest `elem` common_opts) $ + do (Counts{errors,failures},_) <- cncRunAllTests+ if errors+failures == 0 + then exitSuccess+ else exitWith (ExitFailure (errors+failures))++ when (null argv) $ defaultErr ""$ "First argument to "++hcnc_name++" must specify a mode!\n"+ + let helpmode = Help `elem` common_opts+ (first:__rest) = argv+ (__mode, __mode_opts, _) = case filter (isPrefixOf first . fst3) run_modes of + [] | helpmode -> unsafePerformIO$ do { print_usage_all; exitSuccess }+ [] -> simpleErr ""$ first ++ " does not correspond to any "++hcnc_name++" mode\n"+ [m] -> m+ ls -> simpleErr ""$ "Prefix '"++first++"' could refer to multiple modes: "+ ++ concat (intersperse ", "$ map fst3 ls)+ verbosity = foldl (\ lvl opt -> case opt of Verbose (-1) -> lvl+1; Verbose n -> n; _ -> lvl) 1 common_opts++ -- uncommon: filter out options that get special treatment first:+ -- This is annoying but I can't think of a systematic way: + uncommmon (Verbose _) = False+ uncommmon (Version ) = False+ uncommmon (Help ) = False+ uncommmon (SelfTest ) = False+ uncommmon _ = True++ -- HACKish SHORTCUT to make things easy for people. A ".cnc" file is allowed as the first argument.+ (mode, mode_opts, rest) = + if takeExtension first == ".cnc" + -- Switch us implicitly into translate mode:+ then let Just (a,b,_) = find ((== "translate") . fst3) run_modes in + (a,b, argv)+ else (__mode, __mode_opts, __rest)++ evaluate mode -- Force the above unsafePerformIO ++ -- For now none of the command line flags attach any meaning to+ -- DUPLICATES, and some of the configuration actions need to only+ -- take place once. (For example, it would be disasterous to enable+ -- DonePlugins more than once.) Thus we treat 'opts' as a set:+ (opts_set,files) <- + case getOpt' Permute (common_options ++ mode_opts) rest of + (o,n,[], [] ) -> return (S.fromList$ filter uncommmon o, n)+ (o,n,bad,[] ) -> simpleErr ""$ "Unrecognized options in "++mode++" mode: "++ concat (intersperse " " bad)+ (_,_,_,errs) -> simpleErr mode$ concat errs + let opts = S.toList opts_set++ when helpmode $ + do --putStrLn "Mode specific options:"+ let do_mode = mode_usage$ fromJust$ find ((== mode) . fst3) run_modes + case mode of + "harchpart" -> do_mode+ "trace" -> do_mode+ "translate" -> do_mode+ _ -> error "Really egregious internal error"+ putStrLn ""+ print_usage_common+ exitSuccess++ ----------------------------------------------------------------------------------------------------+ -- Now begins the per-mode behavior:+ ----------------------------------------------------------------------------------------------------+ case mode of ++ "harchpart" -> harchpartCommand opts++ ------------------------------------------------------------ + "trace" -> do+ handle <- if null files + then do putStrLn$ cnctag++"Reading trace from stdin."+ return stdin + else do putStrLn$ cnctag++"Reading trace from file "++ show(head files)+ (openFile (head files) ReadMode)+ str <- BL.hGetContents handle+ let is_packed = isPackedTrace str+ is_gzipped = isGZipped str+ when is_packed $ putStrLn$ cnctag++"Trace is in packed (binary) format."+ when is_gzipped $ putStrLn$ cnctag++"Trace is GZipped, decompressing."+ let thetrace = if is_packed+ then unpackCncTrace str+-- else parseCncTrace$ lines$ BL.unpack str+ else parseCncTrace$ + -- TODO: We need to examine the efficiency of this:+ -- Currently the parser works in terms of a list of lines, with lines being STRICT bytestrings.+ -- But the extra conversion may make this pointless. Perhaps the parser should use lazy bytestrings directly.+ map (B.concat . BL.toChunks) $ + BL.lines$ + (if is_gzipped then decompress str else str)+ debug = foldl fn False opts+ fn deb opt = + case opt of + VacuumViz -> deb+ Debug -> True+ SynthSpec file -> error "Internal error, spec synthesis not implemented yet"+ Pack file -> deb+ _ -> error$ "Internal error, not handled in this mode: "++ show opt++ ispack (Pack _) = True+ ispack _ = False+ alldone = do let len = length thetrace+ evaluate len + putStrLn$ cnctag++"Reached end of trace (length "++ show len++"). Exiting."+ exitSuccess++ --------------------------------------------------------------------------------+ -- PROOF OF CONCEPT:+ -- TEMPTOGGLE -- GETCOUNT SUMMARIZATION PRINTOUTS : this is just for testing:+ -- Disabling for now [2011.01.25], bring back later:+ when (False && debug) $ do+ let + -- Here we need to collect all get events and take statistics:+ fn (GetI _ (_,tag)) = map fst (reads (B.unpack tag) :: [((Int,Int,Int), String)])+ fn _ = [] + -- TEMP: TODO: GENERALIZE+ getname (GetI _ (nm,_)) = [nm]+ getname _ = []+ names = concat$ map getname thetrace+ tags = concat$ map fn thetrace++ collected = foldl (\ acc tup -> M.insertWith (+) tup 1 acc) M.empty tags+ keys = M.keys collected+ bounds keys = ( foldl1 min $ map fst3 keys+ , foldl1 min $ map snd3 keys+ , foldl1 min $ map thd3 keys+ , foldl1 max $ map fst3 keys+ , foldl1 max $ map snd3 keys+ , foldl1 max $ map thd3 keys)+ -- Text formatting details:+ (l1,l2,l3,u1,u2,u3) = bounds keys+ biggest = foldl1 max $ M.elems collected+ -- Amount of space needed for biggest number:+ size = 1 + (ceiling$ log (fromIntegral biggest) / log 10.0)+ padtail size str = str ++ take (size - length str) (repeat ' ') ++ print collected+ putStrLn$ "LOWER BOUNDS: " ++ show (l1,l2,l3)+ putStrLn$ "UPPER BOUNDS: " ++ show (u1,u2,u3)++ putStrLn$ "\n\nTags for collection " ++ show (names !! 3) ++ " have schema (Int,Int,Int)."+ putStrLn$ "Observed getcounts were:"+ forM_ [l3..u3] $ \k -> do+ let (i1,i2,_,j1,j2,_) = bounds $ filter ((== k) . thd3) keys+ --putStrLn$ "\n i/j getcounts grid for k = " ++ show k ++ " i in ["++ show l1 ++","++ show u1 ++"], j in ["++ show l2 ++","++ show u2 ++"]:"+ printf "\n i/j getcounts grid for k = %d, i in [%d,%d], j in [%d,%d]:\n" k i1 i2 j1 j2+ putStr$ "+-------------------"+ forM_ [l1..u1] $ \i -> do+ putStr$ "\n|"+ forM_ [l2..u2] $ \j -> do+ case M.lookup (i,j,k) collected of + Nothing -> putStr$ take size (repeat ' ')+ Just n -> putStr$ padtail size (show n)+ putStrLn$ ""+ putStrLn$ "\n"++ --mapM_ print tags+ --mapM_ print (sortBy (compare `on` snd) $ M.toList collected)++ alldone++ -- END PROOF OF CONCEPT+ --------------------------------------------------------------------------------++-- case sort $ filter ispack opts of + case filter ispack opts of + [] -> return ()+ [Pack file] -> do putStrLn$ cnctag++"Packing trace to file "++ show file+ BL.writeFile file (packCncTrace thetrace)+ alldone + ls -> error$ "ERROR: bad combination of pack/unpack options: "++ show ls++ -- In debugging mode we just print the parsed trace:+ when (debug) $ do+ mapM_ print thetrace+ alldone++#ifdef CNCVIZ+ when (VacuumViz `S.member` opts_set) $ do+ let guiactions = traceToGUI thetrace++ -- This prints it out ASAP so it doesn't follow the actual playback unfortunately...+ -- TODO: Push this functionality down into "playback".+ when (verbosity>1) $ do (forkIO $ mapM_ print guiactions); return ()+ when (verbosity>1) $ do (forkIO $ mapM_ print thetrace); return ()++ playback emptyGUIState guiactions+ alldone+#endif++ -- Well, with nothing else to do might as well read to the end and then exit:+ alldone++ ------------------------------------------------------------------- + -- The most important mode of all: translate .cnc files to headers.+ ------------------------------------------------------------------- + "translate" -> translateCommand verbosity opts_set files++ _ -> error "Really egregious internal error"++ --------------------------------------------------------------------------------+ -- Finished with mode dispatch+ --------------------------------------------------------------------------------+ when (verbosity>0)$ putStrLn$ cnctag++"Done."+++----------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------++harchpartCommand opts = do + forM_ opts $ \ opt -> + case opt of +#ifdef CNCVIZ+ HarchViz file -> + do putStrLn$ "Reading (and visualizing) harch file from: "++ file+ spec@(HarchSpec g _) <- readHarchFile file+-- simple_graphviz name g+ harch_graphviz name spec+ putStrLn$ "Done with visualization, exiting without performing any .cnc spec translation."+ exitSuccess+#endif+ Output file -> error "Internal error, trace output not implemented yet"+ _ -> error$ "Internal error, not handled: "++ show opt++ -- HarchPart file -> + error "harchpart not implemented yet"+ return ()+++----------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------+++----------------------------------------------------------------------------------------------------+-- Implementation of translate mode.+----------------------------------------------------------------------------------------------------++translateCommand verbosity opts_set files = + do + let + opts = S.toList opts_set+ mode = "translate"++ codegenmode_option o = o `elem` [Cpp, CppOld, Haskell] + codegenmode = case filter codegenmode_option opts of+ [] -> Cpp+ [o] -> o + ls -> simpleErr mode ("\nAsked to generate output in more than one format! Not allowed presently. "++show ls++"\n")+ file = case files of + [file] -> file+ [] -> simpleErr mode$ "\nNo files provided!\n"+ ls -> simpleErr mode$ "\nCurrently the translator expects exactly one input file, got "+ ++show (length ls)++":\n " ++ concat (intersperse ", " ls) ++ "\n"++ -- Force evaluation to make sure we hit the error:+ case codegenmode of + Cpp -> return ()+ _ -> return ()++ -- Sanity check on mode flags:+ when (AutoDone `S.member` opts_set && AutoDoneDbg `S.member` opts_set) $+ error$ "translate: cannot activate --autodone and --autodonedbg at the same time"++ -- Process options for this mode:+ protoconfig <- foldM (\ cfg opt -> do + case opt of + Help -> return cfg+#ifdef CNCVIZ+ UbigraphOpt -> + do CncSpec{graph} <- readCnCFile verbosity file+ cncUbigraph True graph+ putStrLn$ "Done with visualization, exiting without performing any .cnc spec translation."+ exitSuccess+#endif+ Debug -> return cfg{ gendebug=True, wrapall=True }+ GenTracing -> return cfg{ gentracing=True } + GenDepends -> return cfg{ gendepends=True+ , plugins = dependsPlugin : plugins cfg } ++ AutoDone -> return cfg{ done_plugins= reductionDonePlugin : done_plugins cfg }+ AutoDoneDbg -> return cfg{ done_plugins= reductionDonePlugin : done_plugins cfg+ , debug_autodone = True } + NoStepDefs -> return cfg{ genstepdefs=False } ++ m | codegenmode_option m -> return cfg+ o -> simpleErr mode ("Internal error: Currently unhandled option: "++ show o ++"\n")+ ) default_codegen_config opts++ -- Finally, squish all done plugins into one and add them into the main plugin list:+ let config = case done_plugins protoconfig of + [] -> protoconfig+ ls -> protoconfig + { done_plugins = [],+ plugins = let all_dones = foldl1 composeDonePlugins ls in + convertDonePlugin (debug_autodone protoconfig) all_dones + : plugins protoconfig+ }++ -- Now do the actual translation (if we get to here):+ ------------------------------------------------------------++ graph <- readCnCFile verbosity file ++ -- For clarity of error messages, let's force this before begin "emitCpp" below:+ evaluate graph++ let appname = takeBaseName file + base = takeDirectory file </> appname + toFile outname msg str = + do x <- try + (do outhand <- openFile outname WriteMode+ when (verbosity>0)$ putStrLn$ cnctag++"Generating "++msg++", output to: " ++ outname+ writeSB outhand $ str+ hClose outhand)+ case x of + Left (ex) -> + do let err = outname ++ ".ERR"+ putStrLn$ cnctag++"Spec "++ verb ++" failed, moving partially written file to " ++ err+ putStrLn$ cnctag++"Rethrowing error, see below: "+ Dir.renameFile outname err+ throw (ex :: SomeException)+ Right _ -> return ()++ case codegenmode of+ CppOld -> + toFile (base ++ ".h") "header (legacy CnC 0.5 API)"+ (emitCpp config graph :: EE.EasyEmit ())+--True (GenStepDefs `elem` opts)+ Cpp -> + toFile (base ++ ".h") "header"+ (emitCpp config graph :: EE.EasyEmit ())+--False (GenStepDefs `elem` opts)++ Haskell -> + toFile (base ++ "_heaader.hs") "header"+ (emitHaskell graph :: EE.EasyEmit ())++ _ -> error$ "Not a codegen mode: "++ show codegenmode++++verb = "translation" +-- verb = "compilation" ++------------------------------------------------------------------------------------------------------------------------+-- Testing +------------------------------------------------------------------------------------------------------------------------++-- Aggregate the unit tests from all the modules that provide them:+all_unit_tests = + --test $ + TestLabel "All cnc tool unit tests" $ TestList $+ [ test_desugarTypeDefs+ , test_traceVacuum+ , EE.tests_easyemit+ , test_readharch+ , tests_graphanalysis+ , tests_gathergraph+ ]++cncRunAllTests :: IO (Counts, ())+cncRunAllTests = + -- runTestText (putTextToHandle stdout True) all_unit_tests+ runTestText (PutText myPut ()) all_unit_tests+ where myPut msg True () = do putStrLn ""; putStrLn$ msg+ myPut msg False () = return ()++t = cncRunAllTests -- Lazy shorthand++{-++testread = +-- do file <- openFile "/Users/newton/cnc/experimental/graphPartitioner/test.harch" ReadMode + do file <- openFile "/Users/newton/cnc/experimental/graphPartitioner/test2.harch" ReadMode +-- do file <- openFile "/Users/newton/cnc/experimental/graphPartitioner/outputs/pipes.harch.partitioned" ReadMode + txt <- hGetContents file+ let ls = run harchfile txt+ --sequence_$ map print ls++ putStrLn "\n Now partitions: \n"+ let part = extractPartitions ls+ --print part+ + let gr = convertHarchGraph ls++ print gr+ simple_graphviz name gr++ --sequence_$ map print ppaths+ return part++-}
+ Intel/Cnc/Spec/Passes/ReadHarch.hs view
@@ -0,0 +1,352 @@+{-# LANGUAGE RecordWildCards, TupleSections, ScopedTypeVariables, DeriveFunctor #-}++----------------------------------------------------------------------------------------------------+-- Read .harch profiled/partitioned graph files.+--+-- Original Author: Ryan Newton+----------------------------------------------------------------------------------------------------++module Intel.Cnc.Spec.Passes.ReadHarch + -- (+ -- readHarchFile, parseHarchFile,+ -- HarchNode (..), showTreePath, + -- test_readharch+ -- ) + where++import Intel.Cnc.Spec.CncGraph+import Intel.Cnc.Spec.Util++import Test.HUnit +import Text.Parsec+import Text.Parsec.Char+import Text.Parsec.Combinator+import Text.Parsec.String+import System.IO+import Data.List+--import Data.Set as S hiding (map, filter, partition)+import Data.Set (Set, member)+import qualified Data.Set as Set+import Data.List.Split (splitOn) -- from 'split' package +import Data.Graph+import Debug.Trace+import Data.Function+import qualified Control.Exception as CE++import qualified Data.Graph.Inductive as G+import qualified Data.Graph.Inductive.Query.DFS as DFS+import Data.Graph.Inductive.Query.Monad (mapFst, mapSnd)++----------------------------------------------------------------------------------------------------++-- A graph from a Harch file is currently not quite the same datatype as a CncGraph.+-- The HarchGraph has only step collections currently. It has no edge labels.+data HarchSpec = HarchSpec {+ hgraph :: HarchGraph, + htree :: HarchTreeOrdered+}++type HarchGraph = G.Gr HarchNode ()++-- An individual node within the graph:+data HarchNode = HarchNode {+ name :: String, -- A mandatory field.+ properties :: [(String, String)], -- + num :: Int, -- Using numeric idenifiers for now+ nodecomments :: [String] -- User comments or documentation.+ }+ deriving Show++-- | A datatype for Harch trees, e.g. for hierarchical decompositions.+-- Parameterized by the type of the partitions themselves.+-- +-- This is sometimes a redundant representation because not all of the+-- intermediate nodes need to be labeled with the full contents. In+-- fact, for HarchTreeUnordered only leaves need be labeled. But+-- HarchTreeOrdered encodes extra information at all the intermediate+-- nodes (namely, potentially unique orderings).+data HarchTree a = HT a [HarchTree a] + deriving (Show, Eq, Ord, Functor)++-- A simple representation to start with is a set of Ints for each partition:+type HarchTreeUnordered = HarchTree (Set Int)++-- After topological sorting the partitions are ordered.+type HarchTreeOrdered = HarchTree [Int]++-- | Read a Harch file from disk.+readHarchFile :: String -> IO HarchSpec+readHarchFile path = + do file <- openFile path ReadMode + txt <- hGetContents file+ return (parseHarchFile txt)++-- | Parse the contents of a Harch file stored in a string.+--parseHarchFile :: String -> (HarchGraph, HarchTreeUnordered)+parseHarchFile :: String -> HarchSpec+parseHarchFile txt = HarchSpec gr ordered+ where + ls = run harchfile txt+ gr = convertHarchGraph ls+ sorted = DFS.topsort gr+ part = extractPartitions ls+ ordered = fmap (\set -> filter (flip member set) sorted) part++++----------------------------------------------------------------------------------------------------+-- Temporary datatypes used in parsing:+----------------------------------------------------------------------------------------------------++-- A simple datatype for parsed Harch Nodes:+data HarchNodeParse = HNP {+ hnode :: HarchNode,+ in_edges :: [Int],+ out_edges :: [Int]+ }+ deriving Show++----------------------------------------------------------------------------------------------------+-- Parsec parser for .harch syntax:++-- We use METIS comment lines for two purposes. Normal comments, and the reserved HARCHNODE lines.+-- Maybe we should have used a different delimiter, like %% for harch nodes to avoid this backtracking.+commentline :: Parser String+commentline = try $+ do whitespc; char '%'; whitespc+ notFollowedBy (string "HARCHNODE")+ str <- many (noneOf "\n")+ newline+ return str++harchfile :: Parser [HarchNodeParse]+harchfile = + do global_comments <- many commentline+ numbers; newline -- Skip the first line+ nodes <- many harchnode+ return$ map (\ (n, rec) -> + let h = hnode rec in rec { hnode= h{ num= n } })+ (zip [1..] nodes)++-- Remove one property from a property list and return the remainder.+popProp :: String -> [(String, String)] -> (String, [(String, String)])+popProp name pls = + case partition ((== name) . fst) pls of+ ([(_,nm)], rest) -> (nm, rest)+ (ls,_) -> error$ "Currently, exactly one '"++ show name ++"' property is required for each graph node, not "+ ++ show (length ls)++ ": "++ show ls++-- Remove a property that may occur multiple times:+popMultiProp name pls = + error "TODO, popMultiProp: implement me"++harchnode :: Parser HarchNodeParse+harchnode = + do+ node_comments1 <- many commentline+ whitespc; char '%'; whitespc; string "HARCHNODE"; whitespc+ node_comments2 <- many commentline+ ps <- props; newline; + (wght:edges) <- numbers; whitespc; newline;++ -- Parse out all the special fields:+ let (nm, rest) = popProp "name" ps ++ -- Are the edges mentioned inbound or outbound?+ let (dirs,rest2) = popProp "directions" rest+ let (ins,outs) = + if not (length dirs == length edges) + then error$ "\nNumber of 'directions' incorrect, "++ show (length dirs) ++" "+++ show dirs ++ " expected "++ show (length edges) ++ " for edges " ++ show edges+ else (map snd $ filter ((== '0') . fst) $ zip dirs edges,+ map snd $ filter ((== '1') . fst) $ zip dirs edges)++ return HNP {+ hnode = HarchNode { name= nm, properties= rest2, num=0, + nodecomments = node_comments1 ++ node_comments2 },+ in_edges= ins, out_edges= outs+ }++spc = oneOf " \t"+whitespc = many spc++-- Parse one property in the property list:+prop :: Parser (String,String)+prop = do w <- many1 letter+ char '=';+ -- The property may be the empty string:+ p <- many (noneOf ";")+ char ';';+ return (w,p)++-- Having problems with sepBy:+props :: Parser [(String,String)]+props = prop `sepEndBy` (many1 spc)++numbers :: Parser [Int]+numbers = do whitespc+ strs <- (many1 digit) `sepEndBy` (many1 spc)+ return$ map read strs++------------------------------------------------------------+-- Generic harness for running a parser:+run :: Show a => Parser a -> String -> a+run p input+ = case (parse p "" input) of+ Left err -> error ("parse error at "++ show err)+ Right x -> x+++----------------------------------------------------------------------------------------------------+-- Conversion to partitioned format:++showTreePath :: [Int] -> String+showTreePath intls = concat$ intersperse ":" $ map show intls++-- Parse the partition information packed into each vertices' metadata+extractPartitions :: [HarchNodeParse] -> HarchTreeUnordered+extractPartitions parsednodes = + --trace ("Allnums: "++ show allnums)$ + build (allnums, sorted)+ where+ nodes = map hnode parsednodes+ allnums :: Set Int+ allnums = Set.fromList$ map num nodes++ sorted :: [([Int], HarchNode)]+ sorted = sortBy (\ a b -> fst a `compare` fst b) $+ map extract nodes++ -- This pulls out the tree index (e.g. "0:1:3:0") as an int list:+ extract :: HarchNode -> ([Int], HarchNode) + extract (nd@HarchNode{..}) = + let (partstr, rest) = popProp "partitions" properties in+ (map read $ filter (not . null) $ splitOn ":" partstr :: [Int],+ nd { properties= rest})++ -- Build a tree recursively:+ build :: (Set Int, [([Int], HarchNode)]) -> HarchTreeUnordered+-- build (set, paths) | Set.null set = + build (set, paths) = + -- Each group is a child partition+ let + still_here = filter (not . null . fst) paths -- remove those that ran out+ sorted = sortBy (compare `on` (head . fst)) still_here+ + -- Group by the head-index and then chop it off.+ grouped = groupBy ((==) `on` (head . fst)) sorted+ clipped = map (map (mapFst tail)) grouped+ + -- For each sub-partition cut down the node set.+ restricted = map (Set.intersection set) $ + map (Set.fromList . map (num . snd)) clipped++ tree_children = map build $ zip restricted clipped++ -- Also sanity check those head-indexes.+ heads = map (head . fst . head) grouped++ shownpaths = + "heads " ++ show heads ++ " of paths "++ + concat (intersperse " "$ map showTreePath$ map fst paths)+ checked = + (if length heads == 1+ then trace ("WARNING: Degenerate sub-partition is equal to parent partition: "+++ shownpaths)+ else id) $ + -- FIXME: expensive way of checking:+ (if null heads || (minimum heads == 0 && heads == [0..maximum heads])+ then tree_children+ else trace ("WARNING: Tree-indices of sub-partitions are irregular; should be consecutive range [0,N).\n"+++ " Instead received "++ shownpaths)+ tree_children)++ in HT set checked+ +-- Convert parsed adjacency list info into a real graph.+convertHarchGraph :: [HarchNodeParse] -> HarchGraph+convertHarchGraph parsednodes = + -- Quick sanity check, catch things before the HORRIBLE fgl errors do.+ if Set.null diff + then G.mkGraph vertices edges+ --trace (" Vertices "++ show (map fst vertices) ++"\n Edges "++ show edges) $+ else error$ "Edges to connect to nonexistent nodes! " ++ show (Set.toList diff)+ + where+ nodes = map hnode parsednodes+ vertices = zip nums nodes+ edges = concat (map (\ nd -> map (num (hnode nd), , ()) $ out_edges nd)+ parsednodes)+ nums = map num nodes+ all_edges = Set.fromList$ concat$ map (\ (a,b,_) -> [a,b]) edges+ diff = Set.difference all_edges (Set.fromList nums)++++----------------------------------------------------------------------------------------------------+-- Testing: Or at least some miscellaneous unit tests.+----------------------------------------------------------------------------------------------------++runPr prs str = print (run prs str)++t1 = run prop$ "name=foo;"+t2 = run props$ "name=foo; direction=01;" -- No spcs at start end+t3 = run props$ "name=foo;" +t4 = run props$ "name=foo; blah=baz; " +t5 = run props$ "name=; blah=; " -- Blank properties+++l1 = "% HARCHNODE name=blah; direction=01;\n"++l2 = " 0 1 2 "+t6 = run numbers$ l2+foo = do whitespc; newline+bar = do char '\n'+t7 = run foo " \n"+t8 = run foo "\n"+t9 = run bar "\n"+t11 = runPr harchnode$ l1 ++ l2 ++ "\n"++testfile = unlines $+ ["4 3 10",+ "% graph with 4 verts 3 edges",+ "% HARCHNODE name=foo; directions=11; partitions=1; index=1;",+ "1 2 3",+ "% HARCHNODE name=bar; directions=; partitions=1:0; index=2;",+ "1",+ "% HARCHNODE name=baz1; directions=1; partitions=1:1; index=3;",+ "1 4",+ "% HARCHNODE name=baz2; directions=; partitions=1:1; index=4;",+ "1"]++t12 = runPr harchfile testfile++test_readharch = + testSet "ReadHarch" $+ [+ testCase "" "simple parse test 1"$ ("name","foo") ~=? t1+ , testCase "" "simple parse test 2"$ [("name","foo"),("direction","01")] ~=? t2+ , testCase "" "simple parse test 3"$ [("name","foo")] ~=? t3 + , testCase "" "simple parse test 4"$ [("name","foo"),("blah","baz")] ~=? t4 + , testCase "" "simple parse test: blank props"$ [("name",""),("blah","")] ~=? t5 + , testCase "" "parse numbers"$ [0,1,2] ~=? t6+ , testCase "" "whitespace newline 1"$ '\n' ~=? t7+ , testCase "" "whitespace newline 2"$ '\n' ~=? t8+ , testCase "" "whitespace newline 3"$ '\n' ~=? t9+ , testCase "" "expected parse error"$ TestCase $ do+ CE.catch (do t11; assertFailure "Parse of incorrect syntax must return an error")+ (\ (e :: CE.SomeException) -> return ())++ , testCase "" "commentline 1"$ "blah blah blah" ~=? run commentline " % blah blah blah\n"+ , testCase "" "commentline 2"$ "HARCHNO blah" ~=? run commentline " % HARCHNO blah\n"+ , testCase "" "commentline 3, expect fail"$ TestCase $ do+ CE.catch (do runPr commentline " % HARCHNODE foo \n"+ assertFailure "Parse of HARCHNODE line must not satisfy commentline.")+ (\ (e :: CE.SomeException) -> return ())++ , testCase "" "parse complete file, and print to stdout"$ TestCase t12+ + ]+++----------------------------------------------------------------------------------------------------
+ Intel/Cnc/Spec/Passes/TypeDef.hs view
@@ -0,0 +1,123 @@+{-# OPTIONS_GHC -fwarn-incomplete-patterns #-}++-- This module contains the simple spec transformation pass that desugars type synonyms (TypeDefs)++-- Certainly this is a candidate for Scrap-your-boilerplate generic programming.++module Intel.Cnc.Spec.Passes.TypeDef where++import Intel.Cnc.Spec.Util+import StringTable.Atom+import qualified StringTable.AtomMap as AM++import Intel.Cnc.Spec.AST+import Test.HUnit+--import Debug.Trace+++desugarTypeDefs :: [PStatement dec] -> [PStatement dec]+desugarTypeDefs input = + mapTypes desugarTy everything_else + where + synonyms = AM.fromList$ map (\ (TypeDef _ nm ty) -> (nm,ty)) $+ filter isdef input+ everything_else = filter (not . isdef) input+ isdef (TypeDef _ _ _) = True+ isdef _ = False++ desugarTy ty = + case ty of + TInt -> TInt+ TFloat -> TFloat+ TDouble -> TDouble+ TSym atom -> case AM.lookup atom synonyms of + Nothing -> TSym atom+ Just ty -> ty -- Easy, no constructor application+ TPtr ty -> TPtr $ desugarTy ty+ TRef ty -> TRef $ desugarTy ty+ TDense ty -> TDense $ desugarTy ty+ TConst ty -> TConst $ desugarTy ty+ TTuple ls -> TTuple $ map desugarTy ls++ ----------------------------------------------------------------------------------------------------+ -- Everything below this line is total boilerplate just to traverse the data-types.+ ----------------------------------------------------------------------------------------------------++-- Process all the types, SYB eligible. +class MapTypes a where+ mapTypes :: (Type -> Type) -> a -> a++instance MapTypes (PStatement dec) where + mapTypes fn stmnt = case stmnt of + DeclareTags s nm mty -> DeclareTags s nm $ fmap fn mty + DeclareItems s nm Nothing -> stmnt+ DeclareItems s nm (Just (ty1,ty2)) -> DeclareItems s nm $ Just (fn ty1, fn ty2)+ DeclareReductions s nm op exp Nothing -> DeclareReductions s nm op (mapTypes fn exp) Nothing+ DeclareReductions s nm op exp (Just (ty1,ty2)) -> DeclareReductions s nm op (mapTypes fn exp) (Just (fn ty1, fn ty2))+ DeclareSteps _ _ -> stmnt+ Function -> stmnt+ DeclareExtern -> stmnt+ Chain insts links -> Chain (mapTypes fn insts) (mapTypes fn links)+ Constraints s inst els -> Constraints s (mapTypes fn inst) (mapTypes fn els)+ TypeDef _ _ _ -> error "serious internal implementation error"++instance MapTypes (CollectionInstance dec) where + mapTypes fn inst = case inst of + InstName dec str -> inst+ InstStepOrTags dec str els -> InstStepOrTags dec str $ mapTypes fn els+ InstTagCol dec str els -> InstTagCol dec str $ mapTypes fn els+ InstItemCol dec str els -> InstItemCol dec str $ mapTypes fn els+ InstStepCol dec str els -> InstStepCol dec str $ mapTypes fn els++instance MapTypes (RelLink dec) where + mapTypes fn lnk = case lnk of + ProduceLink dec insts -> ProduceLink dec $ mapTypes fn insts+ PrescribeLink dec insts -> PrescribeLink dec $ mapTypes fn insts+ RevProduceLink dec insts -> RevProduceLink dec $ mapTypes fn insts++-- Expressions don't YET have any type info but we do a meaningless traversal here+-- just so we will catch future expressions added...+instance MapTypes (Exp dec) where + mapTypes fn e = case e of+ Lit _ _ -> e+ Var _ _ -> e+ App s rat rands -> App s (mapTypes fn rat) (mapTypes fn rands)+ If s a b c -> If s (mapTypes fn a) (mapTypes fn b) (mapTypes fn c)++instance MapTypes a => MapTypes [a] where+ mapTypes fn = map (mapTypes fn)++instance (MapTypes a, MapTypes b) => MapTypes (a,b) where+ mapTypes fn (a,b) = (mapTypes fn a, mapTypes fn b)+++----------------------------------------------------------------------------------------------------++mty = Just (TSym (toAtom "triple"), TPtr (TPtr (TSym (toAtom "double"))))+-- This will, oddly, compile but only hit the second part of the tuple!+strange = fmap (fmap (const TInt)) mty+strange2 = fmap (fmap (+1)) (Just (0,0))+-- Oh it must depend on compiler parameters, in a fresh GHCI this DOES NOT work:+-- Does some module I imported define this instance?? Ouch, non-local effect in this module?+strange3 = fmap (+1) (0,0)+++test_desugarTypeDefs = + testSet "TypeDef"+ [testCase "" "basic desugarTypeDefs test"$ result ~=? desugarTypeDefs input]+ where + pair = toAtom "pair"+ triple = toAtom "triple"+ int = toAtom "int"+ double = toAtom "double"+ lkji = toAtom "Lkji"+ control_S2 = toAtom "control_S2"+ control_S3 = toAtom "control_S3"+ result = [DeclareItems () lkji (Just (TTuple [TSym int,TSym int,TSym int],TPtr (TPtr (TSym double)))),+ DeclareTags () control_S2 (Just (TTuple [TSym int,TSym int])),+ DeclareTags () control_S3 (Just (TTuple [TSym int,TSym int,TSym int]))]+ input = [TypeDef () pair (TTuple [TSym int, TSym int]),+ TypeDef () triple (TTuple [TSym int,TSym int,TSym int]),+ DeclareItems () lkji (Just (TSym triple, TPtr (TPtr (TSym double)))),+ DeclareTags () control_S2 (Just (TSym pair)),+ DeclareTags () control_S3 (Just (TSym triple))]
+ Intel/Cnc/Spec/SrcLoc.hs view
@@ -0,0 +1,379 @@+{-# LANGUAGE DeriveDataTypeable, RecordWildCards #-}++--------------------------------------------------------------------------------+-- This is an adaption of GHC's SrcLoc.lhs+--+-- Copyright 2004, The University Court of the University of Glasgow.+--+-- Redistribution and use in source and binary forms, with or without+-- modification, are permitted provided that the following conditions+-- are met:++-- * Redistributions of source code must retain the above+-- * copyright notice, this list of conditions and the following+-- * disclaimer.++-- * Redistributions in binary form must reproduce the above+-- * copyright notice, this list of conditions and the following+-- * disclaimer in the documentation and/or other materials+-- * provided with the distribution.++-- * Neither name of the University nor the names of its+-- * contributors may be used to endorse or promote products+-- * derived from this software without specific prior written+-- * permission.++-- THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY COURT OF THE UNIVERSITY+-- OF GLASGOW AND THE CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED+-- WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES+-- OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+-- DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY COURT OF THE+-- UNIVERSITY OF GLASGOW OR THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT,+-- INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES+-- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR+-- SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)+-- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,+-- STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)+-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED+-- OF THE POSSIBILITY OF SUCH DAMAGE.+--------------------------------------------------------------------------------++module Intel.Cnc.Spec.SrcLoc where+import Data.Data+import Data.Bits+import System.IO+import System.IO.Unsafe+import Text.PrettyPrint.HughesPJClass++ -- I don't actually see why we would need interned strings for+ -- filenames. How many unique files are they? They should be shared+ -- properly even as normal strings. And how often do they need to be+ -- compared?+--type FileNameString = Atom+type FileNameString = String+mkFileNameString = id++data SrcLoc = SrcLoc {+ srcFilename :: FileNameString,+ srcLine :: {-# UNPACK #-} !Int,+ srcColumn :: {-# UNPACK #-} !Int+ }+ | UnhelpfulLoc FileNameString -- Just a general indication+ deriving (Eq,Ord,Show,Typeable,Data)++-- data SrcLoc+-- -- = SrcLoc Atom -- A precise location (file name)+-- = SrcLoc String -- A precise location (file name)+-- {-# UNPACK #-} !Int -- line number, begins at 1+-- {-# UNPACK #-} !Int -- column number, begins at 1+-- deriving (Eq,Ord,Show,Data,Typeable)++--data Loc a = Loc SrcLoc a deriving (Eq,Ord,Show)++--unknownLoc = SrcLoc "<unknown file>" 0 0 ++mkSrcLoc :: FileNameString -> Int -> Int -> SrcLoc+mkSrcLoc x line col = SrcLoc x line col++-- | Built-in "bad" 'SrcLoc' values for particular locations+noSrcLoc, generatedSrcLoc :: SrcLoc -- interactiveSrcLoc +noSrcLoc = UnhelpfulLoc (mkFileNameString "<no location info>")+generatedSrcLoc = UnhelpfulLoc (mkFileNameString "<compiler-generated code>")+--interactiveSrcLoc = UnhelpfulLoc (mkFileNameString "<interactive session>")++-- | Creates a "bad" 'SrcLoc' that has no detailed information about its location+mkGeneralSrcLoc :: FileNameString -> SrcLoc+mkGeneralSrcLoc = UnhelpfulLoc +++++-- | Move the 'SrcLoc' down by one line if the character is a newline,+-- to the next 8-char tabstop if it is a tab, and across by one+-- character in any other case+advanceSrcLoc :: SrcLoc -> Char -> SrcLoc+advanceSrcLoc (SrcLoc f l _) '\n' = SrcLoc f (l + 1) 1+advanceSrcLoc (SrcLoc f l c) '\t' = SrcLoc f l (((((c - 1) `shiftR` 3) + 1)+ `shiftL` 3) + 1)+advanceSrcLoc (SrcLoc f l c) _ = SrcLoc f l (c + 1)+++{- |+A SrcSpan delimits a portion of a text file. It could be represented+by a pair of (line,column) coordinates, but in fact we optimise+slightly by using more compact representations for single-line and+zero-length spans, both of which are quite common.++The end position is defined to be the column /after/ the end of the+span. That is, a span of (1,1)-(1,2) is one character long, and a+span of (1,1)-(1,1) is zero characters long.+-}+data SrcSpan+ = SrcSpanOneLine -- a common case: a single line+ { srcSpanFile :: !FileNameString,+ srcSpanLine :: {-# UNPACK #-} !Int,+ srcSpanSCol :: {-# UNPACK #-} !Int,+ srcSpanECol :: {-# UNPACK #-} !Int+ }++ | SrcSpanMultiLine+ { srcSpanFile :: !FileNameString,+ srcSpanSLine :: {-# UNPACK #-} !Int,+ srcSpanSCol :: {-# UNPACK #-} !Int,+ srcSpanELine :: {-# UNPACK #-} !Int,+ srcSpanECol :: {-# UNPACK #-} !Int+ }++ | SrcSpanPoint+ { srcSpanFile :: !FileNameString,+ srcSpanLine :: {-# UNPACK #-} !Int,+ srcSpanCol :: {-# UNPACK #-} !Int+ }++ | UnhelpfulSpan !FileNameString -- Just a general indication+ -- also used to indicate an empty span+ deriving (Eq,Typeable,Data)+++-- | Create a 'SrcSpan' corresponding to a single point+srcLocSpan :: SrcLoc -> SrcSpan+srcLocSpan (UnhelpfulLoc str) = UnhelpfulSpan str+srcLocSpan (SrcLoc file line col) = SrcSpanPoint file line col+++-- | Create a 'SrcSpan' between two points in a file mkSrcSpan :: SrcLoc -> SrcLoc -> SrcSpan+mkSrcSpan (UnhelpfulLoc str) _ = UnhelpfulSpan str+mkSrcSpan _ (UnhelpfulLoc str) = UnhelpfulSpan str+mkSrcSpan loc1 loc2+ | line1 == line2 = if col1 == col2+ then SrcSpanPoint file line1 col1+ else SrcSpanOneLine file line1 col1 col2+ | otherwise = SrcSpanMultiLine file line1 col1 line2 col2+ where+ line1 = srcLine loc1+ line2 = srcLine loc2+ col1 = srcColumn loc1+ col2 = srcColumn loc2+ file = srcFilename loc1++-- | Combines two 'SrcSpan' into one that spans at least all the characters+-- within both spans. Assumes the "file" part is the same in both inputs+combineSrcSpans :: SrcSpan -> SrcSpan -> SrcSpan+combineSrcSpans (UnhelpfulSpan _) r = r -- this seems more useful+combineSrcSpans l (UnhelpfulSpan _) = l+combineSrcSpans start end + = case line1 `compare` line2 of+ EQ -> case col1 `compare` col2 of+ EQ -> SrcSpanPoint file line1 col1+ LT -> SrcSpanOneLine file line1 col1 col2+ GT -> SrcSpanOneLine file line1 col2 col1+ LT -> SrcSpanMultiLine file line1 col1 line2 col2+ GT -> SrcSpanMultiLine file line2 col2 line1 col1+ where+ line1 = srcSpanStartLine start+ col1 = srcSpanStartCol start+ line2 = srcSpanEndLine end+ col2 = srcSpanEndCol end+ file = srcSpanFile start++-- | Test if a 'SrcSpan' is "good", i.e. has precise location information+isGoodSrcSpan :: SrcSpan -> Bool+isGoodSrcSpan SrcSpanOneLine{} = True+isGoodSrcSpan SrcSpanMultiLine{} = True+isGoodSrcSpan SrcSpanPoint{} = True+isGoodSrcSpan _ = False++isOneLineSpan :: SrcSpan -> Bool+-- ^ True if the span is known to straddle only one line.+-- For "bad" 'SrcSpan', it returns False+isOneLineSpan s+ | isGoodSrcSpan s = srcSpanStartLine s == srcSpanEndLine s+ | otherwise = False +++-- | Raises an error when used on a "bad" 'SrcSpan'+srcSpanStartLine :: SrcSpan -> Int+-- | Raises an error when used on a "bad" 'SrcSpan'+srcSpanEndLine :: SrcSpan -> Int+-- | Raises an error when used on a "bad" 'SrcSpan'+srcSpanStartCol :: SrcSpan -> Int+-- | Raises an error when used on a "bad" 'SrcSpan'+srcSpanEndCol :: SrcSpan -> Int++panic = error++srcSpanStartLine SrcSpanOneLine{ srcSpanLine=l } = l+srcSpanStartLine SrcSpanMultiLine{ srcSpanSLine=l } = l+srcSpanStartLine SrcSpanPoint{ srcSpanLine=l } = l+srcSpanStartLine _ = panic "SrcLoc.srcSpanStartLine"++srcSpanEndLine SrcSpanOneLine{ srcSpanLine=l } = l+srcSpanEndLine SrcSpanMultiLine{ srcSpanELine=l } = l+srcSpanEndLine SrcSpanPoint{ srcSpanLine=l } = l+srcSpanEndLine _ = panic "SrcLoc.srcSpanEndLine"++srcSpanStartCol SrcSpanOneLine{ srcSpanSCol=l } = l+srcSpanStartCol SrcSpanMultiLine{ srcSpanSCol=l } = l+srcSpanStartCol SrcSpanPoint{ srcSpanCol=l } = l+srcSpanStartCol _ = panic "SrcLoc.srcSpanStartCol"++srcSpanEndCol SrcSpanOneLine{ srcSpanECol=c } = c+srcSpanEndCol SrcSpanMultiLine{ srcSpanECol=c } = c+srcSpanEndCol SrcSpanPoint{ srcSpanCol=c } = c+srcSpanEndCol _ = panic "SrcLoc.srcSpanEndCol"+++++-- | Returns the location at the start of the 'SrcSpan' or a "bad" 'SrcSpan' if that is unavailable+srcSpanStart :: SrcSpan -> SrcLoc+-- | Returns the location at the end of the 'SrcSpan' or a "bad" 'SrcSpan' if that is unavailable+srcSpanEnd :: SrcSpan -> SrcLoc++srcSpanStart (UnhelpfulSpan str) = UnhelpfulLoc str+srcSpanStart s = mkSrcLoc (srcSpanFile s) + (srcSpanStartLine s)+ (srcSpanStartCol s)++srcSpanEnd (UnhelpfulSpan str) = UnhelpfulLoc str+srcSpanEnd s = + mkSrcLoc (srcSpanFile s) + (srcSpanEndLine s)+ (srcSpanEndCol s)++-- | Obtains the filename for a 'SrcSpan' if it is "good"+srcSpanFileName_maybe :: SrcSpan -> Maybe FileNameString+srcSpanFileName_maybe (SrcSpanOneLine { srcSpanFile = nm }) = Just nm+srcSpanFileName_maybe (SrcSpanMultiLine { srcSpanFile = nm }) = Just nm+srcSpanFileName_maybe (SrcSpanPoint { srcSpanFile = nm}) = Just nm+-- [2010.07.23] Hmm... why was this written to ignore the file that's there?+srcSpanFileName_maybe _ = Nothing++-- [2010.07.23] Should replace it with this:+srcSpanFileName :: SrcSpan -> FileNameString+srcSpanFileName (SrcSpanOneLine { srcSpanFile = nm }) = nm+srcSpanFileName (SrcSpanMultiLine { srcSpanFile = nm }) = nm+srcSpanFileName (SrcSpanPoint { srcSpanFile = nm}) = nm+srcSpanFileName (UnhelpfulSpan file) = file+++srcSpanSetFileName :: FileNameString -> SrcSpan -> SrcSpan+srcSpanSetFileName file (s@SrcSpanOneLine{..}) = s { srcSpanFile = file }+srcSpanSetFileName file (s@SrcSpanMultiLine{..}) = s { srcSpanFile = file }+srcSpanSetFileName file (s@SrcSpanPoint{..}) = s { srcSpanFile = file }+srcSpanSetFileName file (UnhelpfulSpan _) = UnhelpfulSpan file+++-- We want to order SrcSpans first by the start point, then by the end point.+instance Ord SrcSpan where+ a `compare` b = + (srcSpanStart a `compare` srcSpanStart b) `thenCmp` + (srcSpanEnd a `compare` srcSpanEnd b)++-- | Determines whether a span encloses a given line and column index+spans :: SrcSpan -> (Int, Int) -> Bool+spans span (l,c) = srcSpanStart span <= loc && loc <= srcSpanEnd span+ where loc = mkSrcLoc (srcSpanFile span) l c++-- | Determines whether a span is enclosed by another one+isSubspanOf :: SrcSpan -- ^ The span that may be enclosed by the other+ -> SrcSpan -- ^ The span it may be enclosed by+ -> Bool+isSubspanOf src parent + | srcSpanFileName_maybe parent /= srcSpanFileName_maybe src = False+ | otherwise = srcSpanStart parent <= srcSpanStart src &&+ srcSpanEnd parent >= srcSpanEnd src++----------------------------------------------------------------------------------------------------++instance Pretty SrcLoc where+ pPrint (UnhelpfulLoc s) = pPrint s+ pPrint (SrcLoc f l c) = + (if null f then empty else pPrint f) <+>+ text "line " <> int l <> text ", column " <> int c++-- Eventually this should print a snippet of the file:+-- Hmm... I'm not sure about columns.+instance Pretty SrcSpan where+ pPrint span = + -- NOTE: I thought this was zero-indexed but it seems to be one-indexed. Good.+ let startL = srcLine$ srcSpanStart span+ startC = srcColumn$ srcSpanStart span+ endL = srcLine$ srcSpanEnd span+ endC = srcColumn$ srcSpanEnd span+ in+ sep [text ("file " ++ (srcFilename $ srcSpanStart span)),+ if (startL,startC) == (endL,endC)+ then text $ "at line:column " ++ (show startL) ++ ":" ++ (show startC)+ else text $ "between line:column " ++ (show startL) ++ ":" ++ (show startC)+ ++ " and " ++ (show endL) ++ ":" ++ (show endC)]++-- This gives a detailed (multiline) printout with a snippet of the original file.+showSpanDetailed :: SrcSpan -> String+showSpanDetailed span = + "\nLocation:\n" ++ (show$ nest 4$ pPrint span) ++ + "\n\nContext in original file:\n" ++ + "----------------------------------------\n" + ++ (indent_lines 4 $ unsafePerformIO (snippet span)) +++ "----------------------------------------\n"++-- A constant, how many lines of context do we want:+snippet_lines = 7++-- If we wanted to get all fancy we could use ascii codes to bold or+-- color the actual characters within this context:+snippet :: SrcSpan -> IO String+snippet span = + do let file = srcSpanFileName span+ line1 = srcLine$ srcSpanStart span+ line2 = srcLine$ srcSpanEnd span+ -- If the span is less than snippet_lines long we could provide context AROUND it... not currently though.+ numlines = min snippet_lines (line2 - line1 + 1) ++ handle <- openFile file ReadMode+ contents <- hGetContents handle+ let snip = take numlines $ drop (line1-1) $ lines contents+ + return$ unlines snip++indent_lines n str = + unlines $+ map ((take n $ repeat ' ')++) (lines str)+++-- pPrint (srcSpanStart span) <> text " : " <>+-- pPrint (srcSpanEnd span)++-- Might as well use the pretty version for plain show:+instance Show SrcSpan where+ show = show . pPrint ++-- An error with a location.+locErr span msg = + error$ msg ++ "\n Location: "++ (show span)++----------------------------------------------------------------------------------------------------++infixr 9 `thenCmp`++thenCmp :: Ordering -> Ordering -> Ordering+{-# INLINE thenCmp #-}+thenCmp EQ ordering = ordering+thenCmp ordering _ = ordering+++----------------------------------------------------------------------------------------------------+-- Type class for decorated things.+----------------------------------------------------------------------------------------------------++-- | Everything that is decorated with annotations (e.g. source+-- locations) should be able to provide them or strip them.+-- This replicates most of the benefit of using a "Located" type.+--+-- Some generic programming could probably provide this for free.+class Decorated t where + mapDecor :: (a -> b) -> t a -> t b+ getDecor :: t a -> a+ stripDecor :: t a -> t ()+ stripDecor = mapDecor (\_ -> ())+
+ Intel/Cnc/Spec/TagFun.hs view
@@ -0,0 +1,149 @@+{-# LANGUAGE DeriveDataTypeable, ScopedTypeVariables #-}+{-# OPTIONS_GHC -fwarn-incomplete-patterns #-}++-- This file should contain everything having to do with the structure+-- and analysis of tag functions.++----------------------------------------------------------------------------------------------------+module Intel.Cnc.Spec.TagFun where ++import StringTable.Atom+import Data.Data+import Data.Char+import Text.PrettyPrint.HughesPJClass+import Intel.Cnc.Spec.Util+import Intel.Cnc.Spec.SrcLoc+import Intel.Cnc.Spec.AST++------------------------------------------------------------+-- Type definition.+------------------------------------------------------------+-- Tag expressions are distinct from Exp (in AST.hs) and much more+-- restrictive. (For example, conditionals are not allowed.)++-- Tag expressions are parameterized by the type of variable references.+data TagExp var = + TEVar var+ | TEInt Int -- Is there any conceivable need for arbitrary precision here?+ | TEApp Atom [TagExp var]++-- TODO: Add optionality (maybe) to tag functions.+-- TODO: Possible adapt tag functions to return sets of tags.+ deriving (Eq,Ord,Show,Data,Typeable)++------------------------------------------------------------+-- Instances.+------------------------------------------------------------++instance Pretty var => Pretty (TagExp var) where + pPrint te = case te of+ TEVar v -> pPrint v+ TEInt n -> text (show n)+ TEApp rat rands -> + case rands of + [left,right] | not $ isAlpha (head (fromAtom rat)) -> + parens (pp left <+> text (fromAtom rat) <+> pp right)+ _ -> text (fromAtom rat) <> (parens $ commasep rands)++-- A tag function of dimension N has N formal parameters and N "bodies".+data TagFun = TF [Atom] [TagExp Atom]+ deriving (Eq, Ord)++instance Pretty TagFun where + pPrint (TF formals bods) =+ text "\\" <> hsep (map (text . fromAtom) formals) <+> text "->" <+> + commacat bods++-- Again, might as well use the pretty version+instance Show TagFun where + show = show . pp++instance Functor TagExp where+ fmap f (TEVar v) = TEVar (f v)+ fmap _ (TEInt i) = TEInt i + fmap f (TEApp op ls) = TEApp op $ map (fmap f) ls+++------------------------------------------------------------+-- API for tag functions.+------------------------------------------------------------++-- The left argument is the "formal parameter" and the right argument the "body".+-- But really it's just an equality.+-- Note, the reason these are Exp LISTS is because these are implicitly tuples.+-- The tag functions are multi-dimensional.+--+-- TODO: This function could solve simple equations to get the formal+-- parameters all to one side of the equation, allowing things like (2*i -> 3*i).++--mkTagFun :: (CncGraphNode, [Exp SrcSpan]) -> +-- (CncGraphNode, [Exp SrcSpan]) -> Maybe TagFun+--mkTagFun (node1,exps1) (node2,exps2) = +mkTagFun :: String -> [Exp SrcSpan] -> [Exp SrcSpan] -> Maybe TagFun+mkTagFun ctxtmsg exps1 exps2 = + let e1s = Prelude.map checkConvertTF exps1+ e2s = Prelude.map checkConvertTF exps2+ in if all isTEVar e1s+ then+ if not (Prelude.null exps1) && not (Prelude.null exps2)+ -- length exps1 == length exps2 + then Just (TF (Prelude.map unTEVar e1s) e2s)+ -- Otherwise there is a mismatch in the number of tag components:+ else if Prelude.null exps2 + then Nothing -- It's ok to simply leave off a tag function (but to have some var names on the step).+ else error$ "ERROR:\n It is not acceptable to use the following tag components without\n"+++ " tag components indexing the step: "+-- " the same number of corresponding tag components indexing the step: "+ ++ (show$ pp exps2) ++ + showSpanDetailed (foldl1 combineSrcSpans $ Prelude.map getDecor exps2)++ else error$ ctxtmsg ++ ": mkTagFun of "++ (show$ pp exps1) ++ " and "++ show (pp exps2)++ + " - Presently the tag expressions indexing step collections must be simple variables." +++-- Substititution on tag expression's variables.+substTagExp :: Eq a => a -> a -> TagExp a -> TagExp a+substTagExp old new exp = + case exp of + TEVar v | v == old -> TEVar new+ | otherwise -> TEVar v+ TEInt i -> TEInt i+ TEApp op ls -> TEApp op $ map (substTagExp old new) ls+++-- Create a C++ expression that represents the application of the tag function.+-- TODO: Generalize this.+applyTagFun :: TagFun -> Doc -> [Doc]+applyTagFun (TF [formal] [body]) arg =+ [pPrint$ substTagExp formal (toAtom$ render arg) body]++applyTagFun _ _ = error "TODO: applyTagFun implement multidimensional"++isTEVar (TEVar _) = True+isTEVar _ = False++-- Avoid exhaustiveness warnings here:+unTEVar (TEVar name) = name+unTEVar _ = error "unTEVar: not TEVar"++-- This is where we convert arbitrary Exps into more restricted tag expressions that+-- support symbolic manipulation.+checkConvertTF e = + case e of + Lit s l -> case l of + LitInt i -> TEInt i; + _ -> locErr s "Only integer literals supported in tag functions presently."+ Var s name -> TEVar name + App _ (Var _ name) rands -> TEApp name (Prelude.map checkConvertTF rands)+ App s _ _ -> locErr s "Only very simple function applications allowed in tag functions presently."+ If s _ _ _ -> locErr s "Conditionals disallowed in tag functions."++-- | Compute the getcount contribution of a single tag function.+getCountTF :: TagFun -> Maybe Int+getCountTF (TF formals body) = + case body of+ -- UNFINISHED+ _ -> Nothing+ where + +
+ Intel/Cnc/Spec/TraceVacuum.hs view
@@ -0,0 +1,416 @@+{-# LANGUAGE RecordWildCards, ScopedTypeVariables, DeriveDataTypeable, OverloadedStrings #-}+{-# OPTIONS_GHC -fwarn-incomplete-patterns #-}+----------------------------------------------------------------------------------------------------+-- "Vacuum" mode is for sucking up trace output and doing useful things with it.+--+-- The initial intentions are to use it to formulate a prototype .cnc+-- spec file and to use it for visualization of an execution (and possible debugging).+--+-- Original Author: Ryan Newton+----------------------------------------------------------------------------------------------------++module Intel.Cnc.Spec.TraceVacuum + ( + NameTag, CncTraceEvent (..), + parseCncTrace, + packCncTrace, unpackCncTrace, isPackedTrace, + isGZipped,+ sample_trace, test_traceVacuum+ )+ where++import Intel.Cnc.Spec.Util+import Intel.Cnc.Spec.Version ++import Debug.Trace+import Data.Maybe+import Data.Data+import Data.Binary+-- import Data.Binary.Generic++import qualified Data.ByteString.Lazy.Char8 as BL+import qualified Data.ByteString.Lazy as BLW+import qualified Data.ByteString.Char8 as B++import Codec.Compression.GZip+import Control.Monad++import Text.Parsec as P+import Text.Parsec.ByteString++import Test.HUnit+import StringTable.Atom++--------------------------------------------------------------------------------++--type NameTag = (String,String)+-- type NameTag = (Atom,String)+type NameTag = (Atom, B.ByteString)++data CncTraceEvent = + Prescribe Atom Atom+ | PutI NameTag NameTag+ | GetI NameTag NameTag+ | PutT NameTag NameTag+ | StartStep NameTag + | EndStep NameTag + | PARSEFAIL B.ByteString -- For debugging purposes record the failures.+ deriving (Show, Eq, Data, Typeable)++-- We should parse tags that we can make sense of, namely scalars and tuples.+data CncTraceTag = + TTUnknown String+ | TTInt Int+ | TTFloat Float++--------------------------------------------------------------------------------+-- Parsing and Encoding traces++-- spc :: ParsecT s u m Char+spc :: Parser Char+spc = oneOf (" \t" :: String)+whitespc = many spc++defaultStepContext :: NameTag+defaultStepContext = (toAtom special_environment_name,"")++-- | This converts the lines of a trace file into a parsed trace.+parseCncTrace :: [B.ByteString] -> [CncTraceEvent]+parseCncTrace lines = loop defaultStepContext lines+ where + loop enclosing [] = []+ loop enclosing (line:tl) = + let parsed = Just$ doParse (traceline enclosing) line+ rest = case parsed of + Just (StartStep nametag) -> loop nametag tl+ _ -> loop enclosing tl+ in case parsed of + Nothing -> rest+ Just x -> (x:rest)+++-- Test if a stream of bytes is GZip format.+-- This uses the magic bytes at the beginning of the file: 1f8b+isGZipped :: BL.ByteString -> Bool+-- An alternative would be to just TRY to uncompress it and catch an exception...+-- But that would be awful sloppy...+isGZipped bs = + -- Byte 1f = 31, and 8b = 139+ prefix == [31,139]+ -- I'm seeing 8b1f on hexdump... that's a bit weird.+ where + prefix = take 2 $ BLW.unpack bs++--------------------------------------------------------------------------------+-- Pack traces into a binary format:+--------------------------------------------------------------------------------++-- Convention: Our file format is simple. We have one line of plain+-- ASCII for identification, and then a gzipped BLOb containing the+-- marshalled haskell datatype.++preface = "Intel CnC binary trace file, version "+tagline = preface ++ version ++ "\n"++-- [2011.01.26] Switching this to a CUSTOM binary format rather than+-- using a default (Data.Binary.Generic) one.++-- FORMAT CHANGE LOG:+-- ------------------+-- Ver 0.1.3.107 -- using Data.Binary.Generic encoding+-- Ver 0.1.3.108 -- Wrote new Data.Binary instance.+-- This version uses compressed format inspite of stack/space problems [2011.01.26]++{-+-- For a first cut we use[d] a default binary encoding. We could+-- standardize this if it was going to be read by any other tools....+instance Binary CncTraceEvent where+ put = putGeneric+ get = getGeneric+-}+++do_compress = True++-- NOTE: Could strip the PARSEFAIL entries upon packing.+-- Something to think about...+packCncTrace :: [CncTraceEvent] -> BL.ByteString +packCncTrace trace =+ BL.append (BL.pack tagline)$+ (if do_compress then compress else id)+ (encode trace)++unpackCncTrace :: BL.ByteString -> [CncTraceEvent]+unpackCncTrace bstr = + -- tail chops off the '\n' character:+ decode$ + (if do_compress then decompress else id) $+ BL.tail rest + where + (fst,rest) = BL.break (=='\n') bstr+++-- Actually this is not YET a fully specified binary format because it+-- depends on the Data.Binary representation of LISTS. We should lock+-- this down if we want it to be read by non-haskell languages. (Of+-- course, the binary package itself is bound to never change this+-- format for compatibility.)++instance Binary CncTraceEvent where + put x = + -- This is pretty much a pile of boilerplate:+ case x of + Prescribe a b -> do putWord8 0; put a; put b + PutI a b -> do putWord8 1; put a; put b+ GetI a b -> do putWord8 2; put a; put b+ PutT a b -> do putWord8 3; put a; put b+ StartStep nm -> do putWord8 4; put nm+ EndStep nm -> do putWord8 5; put nm+ PARSEFAIL str -> do putWord8 6; put str++ get = do tag <- getWord8 + case tag of + 0 -> liftM2 Prescribe get get + 1 -> liftM2 PutI get get + 2 -> liftM2 GetI get get + 3 -> liftM2 PutT get get + 4 -> liftM StartStep get + 5 -> liftM EndStep get + 6 -> liftM PARSEFAIL get + _ -> error$ "Unmarshalling CncTraceEvent, got bad tag byte: "++ show tag++-- | Check the first bytes in the stream to tell if its a CnC trace:+isPackedTrace :: BL.ByteString -> Bool+isPackedTrace = BL.isPrefixOf (BL.pack preface)+ ++--------------------------------------------------------------------------------+-- Helpers:++-- doParse :: Parser CncTraceEvent -> String -> CncTraceEvent+doParse :: Parser CncTraceEvent -> B.ByteString -> CncTraceEvent+doParse p input+ = case (parse p "" input) of+ Left err -> PARSEFAIL input+ Right x -> x++cnc_identifier :: Parser Atom+cnc_identifier = + do name <- many1 (letter <|> digit <|> oneOf "_")+ return$ toAtom name++traceline :: NameTag -> Parser CncTraceEvent+traceline stepctxt = + let nametag :: Char -> Char -> Parser NameTag+ nametag open close = + do name <- cnc_identifier+ char ':'; whitespc+ -- Then we grab EVERYTHING up until the ">" that ends things+ --tag <- many1 (noneOf end)+ tag <- balanced_nest open close+ return (name, tag)++ ruletemplate (str :: B.ByteString) open close fn = +-- try (do string (str++" "++[open]); whitespc+ try (do + --string (str `B.append` B.pack [' ',open])+ string (B.unpack str ++ [' ',open])+ whitespc+ pr <- nametag open close+ return$ fn pr)+ in+ ruletemplate "Start step" '('')' StartStep <|> + ruletemplate "End step" '('')' EndStep <|> + ruletemplate "Put tag" '<''>' (PutT stepctxt) <|> + ruletemplate "Put item" '['']' (PutI stepctxt) <|> + ruletemplate "Get item" '['']' (GetI stepctxt) <|> + ruletemplate "GetX item" '['']' (GetI stepctxt) <|>+ do string "Prescribe" ; whitespc + tags <- cnc_identifier; whitespc+ step <- cnc_identifier+ return (Prescribe tags step)++-- This is any old text but it must be balanced in the delimeters of interest: e.g. () <> []+balanced_nest :: Char -> Char -> Parser B.ByteString+balanced_nest open close = loop [] 0+ -- This is pretty inefficent because it goes character by character...+ where + loop acc n = + do c<-noneOf [open,close]; loop (c:acc) n+ <|> do c<-char open; loop (c:acc) (n+1)+ <|> do c<-char close; + if n==0 then return (B.reverse$ B.pack acc)+ else loop (c:acc) (n-1)++++++------------------------------------------------------------------------------------------------------------------------+-- Testing+------------------------------------------------------------------------------------------------------------------------+++runPr prs str = print (run prs str)+run :: Show a => Parser a -> B.ByteString -> a+run p input+ = case (P.parse p "" input) of+ Left err -> error ("parse error at "++ show err)+ Right x -> x+++-- tryParse :: Parser a -> String -> Maybe a+tryParse :: Parser a -> B.ByteString -> Maybe a+tryParse p input+ = case (P.parse p "" input) of+ Left err -> Nothing+-- Left err -> Just (PARSEFAIL input)+ Right x -> Just x++stoA :: String -> Atom+stoA = toAtom ++test_traceVacuum = + testSet "TraceVacuum" $ + let tP = tryParse (traceline defaultStepContext) + sample = map (tryParse (traceline defaultStepContext)) sample_trace+ sample' = catMaybes sample+ isfail (Just (PARSEFAIL _)) = True+ isfail _ = False+ tC = testCase ""+ in+ [ tC "traceline1: parse one line"$ Just (StartStep (stoA "fib_step","0")) ~=? tP "Start step (fib_step: 0)"+ , tC "traceline2: parse one line"$ Just (PutT (stoA special_environment_name,"") + (stoA "tags","10")) ~=? tP "Put tag <tags: 10>"+ , tC "traceline3: parse one line"$ Nothing ~=? tP "__Put tag <tags: 10>"+ , tC "traceline4: parse one line"$ Just (Prescribe (stoA "control_S1") (stoA "kj_compute"))+ ~=? tP "Prescribe control_S1 kj_compute"++ , tC "sample trace: #fail" $ 0 ~=? length (filter isfail sample)+ , tC "sample trace: #success"$ 111 ~=? length (filter (not . isfail) sample)+ , tC "sample trace: #noparse"$ 16 ~=? length (filter (==Nothing) sample)++ , tC "balanced nesting" $ Just"foo (a) (b c) bar" ~=? tryParse (balanced_nest '(' ')') "foo (a) (b c) bar) baz" ++ , tC "encode . decode = id for NameTag" $ + let x = ("Hi"::Atom, BL.pack "There") in+ x ~=? decode (encode x)++ , tC "unpack . pack = id " $ sample' ~=? (unpackCncTrace$ packCncTrace sample')++ ]++sample_trace = + ["Prescribe tags fib_step",+ "Prescribe tags fibctrl",+ "Put tag <tags: 10>",+ "Start step (fibctrl: 10)",+ "Put tag <tags: 9>",+ "Put tag <tags: 8>",+ "End step (fibctrl: 10)",+ "Start step (fibctrl: 8)",+ "Put tag <tags: 7>",+ "Put tag <tags: 6>",+ "End step (fibctrl: 8)",+ "Start step (fibctrl: 6)",+ "Put tag <tags: 5>",+ "Put tag <tags: 4>",+ "End step (fibctrl: 6)",+ "Start step (fibctrl: 4)",+ "Put tag <tags: 3>",+ "Put tag <tags: 2>",+ "End step (fibctrl: 4)",+ "Start step (fibctrl: 2)",+ "Put tag <tags: 1>",+ "Put tag <tags: 0>",+ "End step (fibctrl: 2)",+ "Start step (fibctrl: 0)",+ "End step (fibctrl: 0)",+ "Start step (fib_step: 0)",+ "Put item [fibs: 0] -> 0",+ "End step (fib_step: 0)",+ "Start step (fibctrl: 1)",+ "End step (fibctrl: 1)",+ "Start step (fib_step: 1)",+ "Put item [fibs: 1] -> 1",+ "End step (fib_step: 1)",+ "Start step (fib_step: 2)",+ "GetX item [fibs: 1] -> 1",+ "GetX item [fibs: 0] -> 0",+ "Put item [fibs: 2] -> 1 getcount=2",+ "End step (fib_step: 2)",+ "Start step (fib_step: 3)",+ "GetX item [fibs: 2] -> 1",+ "GetX item [fibs: 1] -> 1",+ "Put item [fibs: 3] -> 2 getcount=2",+ "item [fibs: <2>] m_getCount decremented to 1",+ "End step (fib_step: 3)",+ "Start step (fib_step: 4)",+ "GetX item [fibs: 3] -> 2",+ "GetX item [fibs: 2] -> 1",+ "Put item [fibs: 4] -> 3 getcount=2",+ "item [fibs: <3>] m_getCount decremented to 1",+ "item [fibs: <2>] m_getCount decremented to 0",+ "End step (fib_step: 4)",+ "Start step (fib_step: 5)",+ "GetX item [fibs: 4] -> 3",+ "GetX item [fibs: 3] -> 2",+ "Put item [fibs: 5] -> 5 getcount=2",+ "item [fibs: <4>] m_getCount decremented to 1",+ "item [fibs: <3>] m_getCount decremented to 0",+ "End step (fib_step: 5)",+ "Start step (fib_step: 6)",+ "GetX item [fibs: 5] -> 5",+ "GetX item [fibs: 4] -> 3",+ "Put item [fibs: 6] -> 8 getcount=2",+ "item [fibs: <5>] m_getCount decremented to 1",+ "item [fibs: <4>] m_getCount decremented to 0",+ "End step (fib_step: 6)",+ "Start step (fib_step: 7)",+ "GetX item [fibs: 6] -> 8",+ "GetX item [fibs: 5] -> 5",+ "Put item [fibs: 7] -> 13 getcount=2",+ "item [fibs: <6>] m_getCount decremented to 1",+ "item [fibs: <5>] m_getCount decremented to 0",+ "End step (fib_step: 7)",+ "Start step (fib_step: 8)",+ "GetX item [fibs: 7] -> 13",+ "GetX item [fibs: 6] -> 8",+ "Put item [fibs: 8] -> 21 getcount=2",+ "item [fibs: <7>] m_getCount decremented to 1",+ "item [fibs: <6>] m_getCount decremented to 0",+ "End step (fib_step: 8)",+ "Start step (fib_step: 9)",+ "GetX item [fibs: 8] -> 21",+ "GetX item [fibs: 7] -> 13",+ "Put item [fibs: 9] -> 34 getcount=2",+ "item [fibs: <8>] m_getCount decremented to 1",+ "item [fibs: <7>] m_getCount decremented to 0",+ "End step (fib_step: 9)",+ "Start step (fib_step: 10)",+ "GetX item [fibs: 9] -> 34",+ "GetX item [fibs: 8] -> 21",+ "Put item [fibs: 10] -> 55 getcount=2",+ "item [fibs: <9>] m_getCount decremented to 1",+ "item [fibs: <8>] m_getCount decremented to 0",+ "End step (fib_step: 10)",+ "Start step (fibctrl: 3)",+ "Put tag <tags: 2>",+ "Put tag <tags: 1>",+ "End step (fibctrl: 3)",+ "Start step (fibctrl: 5)",+ "Put tag <tags: 4>",+ "Put tag <tags: 3>",+ "End step (fibctrl: 5)",+ "Start step (fibctrl: 7)",+ "Put tag <tags: 6>",+ "Put tag <tags: 5>",+ "End step (fibctrl: 7)",+ "Start step (fibctrl: 9)",+ "Put tag <tags: 8>",+ "Put tag <tags: 7>",+ "End step (fibctrl: 9)",+ "Get item [fibs: 10] -> 55",+ "CnC recursive (10): 55"]++
+ Intel/Cnc/Spec/Util.hs view
@@ -0,0 +1,240 @@+{-# LANGUAGE FlexibleInstances, TypeSynonymInstances, CPP #-}++----------------------------------------------------------------------------------------------------+-- A miscellaneous utility file used by the CnC Spec tool.+--+-- Original Author: Ryan Newton+----------------------------------------------------------------------------------------------------++module Intel.Cnc.Spec.Util + (+ -- Reexported globals:+ special_environment_name, cnctag, hcnc_name, ++ fst3, snd3, thd3,++ commasep, commspc, commacat, + t, pp, angles, textAtom, toDoc, app,+ dubquotes, escapeString, hangbraces, indent, putD, putS, runSB, writeSB,+ struct, pad, assignCast, mkPtr, deref, thunkapp, mkConstRef, mkPtr, mkRef, assign,+ StringBuilder, ++ collapseMaybe, ++ alwaysAssertEq, testSet, testCase+ )+where++import Intel.Cnc.Spec.Globals+import Text.PrettyPrint.HughesPJClass+import Control.Monad.State+import Control.Exception as CE+import System.IO.Unsafe+import System.IO+import StringTable.Atom++import Data.List+import Data.Char+import GHC.Exts -- For IsString++import qualified Test.HUnit as HU+import Debug.Trace++import qualified StringTable.AtomMap as AM+import qualified Data.Map as M+import qualified Data.Set as S++-- String Builder+----------------------------------------------------------------------------------------------------+-- We abstract the process of creating strings so that we can make our+-- code generation more efficient when we feel like it (later).+--+-- I couldn't find a nice simple version of this in hackage or the+-- standard libraries so here we roll our own (trivial) StringBuilder class.++-- NOTE: It would be nice to do all this with ByteString, but alas the+-- pretty printing infrastructure uses Strings.+class Monad m => StringBuilder m where + putS :: String -> m ()+ putD :: Doc -> m () + runSB :: m a -> (String, a)+ writeSB :: Handle -> m a -> IO a++ -- Default inefficient implementation:+ putS s = putD (text s)+ putD d = putS (show d)+ writeSB h m = let (s,a) = runSB m in -- This appends the whole string... it shouldn't.+ do hPutStr h s+ return a++type SimpleBuilder a = State [String] a++-- Here's something simple, not yet bothering with compact strings or file Handles, just+-- accumulating a list of strings.+--instance StringBuilder SimpleBuilder where +instance StringBuilder (State [String]) where + putS s = modify (s:)+ runSB m = let (res,ls) = runState m [] + in (concat$ reverse ls, res)+++----------------------------------------------------------------------------------------------------+-- Simple pretty printing helpers, and C/C++ codegen helpers.+----------------------------------------------------------------------------------------------------+-- These operate on and produce Doc types:++-- Export this friendly shortcut:+pp x = pPrint x -- Eta expand, due to monomorphism restriction.+commacat ls = hcat (intersperse (text ", ") $ map pPrint ls)+commasep ls = sep (intersperse (text ", ") $ map pPrint ls)++escapeString = foldr showLitChar ""++vbraces d = lbrace $+$ d $+$ rbrace+textAtom = text . fromAtom+angles t = text "<" <+> t <+> text ">"+commspc = text ", "+pad t = space <> t <> space++-- Braces-delimited as in C/C++/Java code.+hangbraces d1 n d2 = sep [d1, vbraces$ nest n d2]++-- Create C++ structs/classes+struct title body = (hangbraces (text "struct " <> title) indent body) <> semi+cppclass title body = (hangbraces (text "class " <> title) indent body) <> semi++-- Shorthand: I am very lazy.+t = text++-- This seems useful:+collapseMaybe :: Maybe (Maybe t) -> Maybe t+collapseMaybe Nothing = Nothing+collapseMaybe (Just Nothing) = Nothing+collapseMaybe (Just (Just x)) = Just x++instance Pretty Atom where+ pPrint atom = text (show atom)+++fst3 (a,_,_) = a+snd3 (_,b,_) = b+thd3 (_,_,c) = c++map_but_last fn [] = []+map_but_last fn [h] = [h]+map_but_last fn (h:t) = fn h : map_but_last fn t+++-- The probability of any of the below stuff being reusable is pretty low.+-- (It's very C++ specific. This whole *strategy* of private context generation is probably pretty C++ specific.)+-- But I thought I would begin to at least BEGIN to abstract the syntax-construction operations.++-- A few decorations on C++ types:+mkPtr d = d <> t"*" -- Make a type into a pointer+mkRef tyD = tyD <> t"&" -- Make a type into a reference+mkConstRef tyD = t"const" <+> mkRef tyD -- Make a type const++-- The dot operator:+deref x y = x <> t"." <> y+++-- Create a line of code encompassing assignment commands:+assignCast ty x y = ty <+> x <+> t"=" <+> parens ty <> y <> semi+assign x y = toDoc x <+> t"=" <+> toDoc y <> semi++-- Function application:+app fn ls = toDoc fn <> (parens$ hcat$ intersperse (t", ")$ map toDoc ls)+thunkapp fn = app fn ([] :: [Doc])++-- Create a C++ constructor with initializers:+--constructor :: Int -> Int -> Int -> Int -> Int++constructor :: (SynChunk a, SynChunk a1) =>+ a -> [a1] -> [(Doc, Doc)] -> Doc -> Doc+constructor name args inits body = + hangbraces (app name args <+> colon $$ + nest 10 (vcat$ map_but_last (<>t", ")$ map (\ (a,b) -> a <> parens b) inits)) + indent body++-- Parameters to a function... abstracting this for, say, untyped languages?+param ty name = ty <+> name++dubquotes :: SynChunk a => a -> Doc+dubquotes d = (t"\"") <> toDoc d <> (t"\"")++-- This overloading just supports my laziness:+class SynChunk a where + toDoc :: a -> Doc+instance SynChunk String where + toDoc = text+instance SynChunk Doc where + toDoc = id+instance SynChunk Atom where + toDoc = text . fromAtom+++-- Also, overloading the string constants themselves is nice:+#if __GLASGOW_HASKELL__ >= 701+instance IsString Doc where+ fromString s = text s+#endif+instance IsString Atom where+ fromString s = toAtom s++instance ToAtom Doc where+ toAtom d = toAtom$ render d++-- Constant: indentation used across all code generators.+indent = 4++--------------------------------------------------------------------------------+-- Misc pretty-printing assistance. Not exhaustive; whatever I happen to need:++instance Pretty a => Pretty (S.Set a) where+ pPrint x = pPrint (S.toList x)++instance Pretty a => Pretty (AM.AtomMap a) where+ pPrint x = pPrint (AM.toList x)++instance (Pretty k, Pretty v) => Pretty (M.Map k v) where+ pPrint x = pPrint (M.toList x)++--------------------------------------------------------------------------------+-- Testing and Assertion Utilities+--------------------------------------------------------------------------------++-- The standard Control.Exception.assert is turned off in optimize mode and does not assume Show.+-- This is a variant that assumes Show and is always on.+alwaysAssertEq :: (Eq a, Show a) => String -> a -> a -> a1 -> a1+alwaysAssertEq msg expect got final = + if (expect == got)+ then final+ else unsafePerformIO$+ do putStrLn$ "\n!!! Assertion failed."+ putStrLn$ msg+ putStrLn$ "Expected: " ++ show expect+ putStrLn$ "Received: " ++ show got+ putStrLn$ ""+ -- For the source location:+ CE.assert (expect == got) + (return final)++-- HUnit convenience function (used by other modules):+-- There's a problem with quickcheck where it doesn't+-- newline-terminate the "Cases: N" report message.+--testCase str io = HU.TestLabel str $ HU.TestCase$ do putStrLn$ "\n *** Running unit test: "++str; io; putStrLn ""++-- Tag a little bit more verbose output to the tests:+testCase prefix str tst = HU.TestLabel lab (trace (tag++ lab) tst)+ where lab = if prefix == ""+ then str+ else prefix ++ ": " ++ str+-- tag = " *** "+ tag = " [test] "++-- Likewise, identify the per-module sub-groups of tests+testSet name ls = + trace ("\n"++header ++"\n"++ spacer) (HU.TestList ls)+ where header = "Running tests for module " ++ show name + spacer = (take (length header) $ repeat '=')+
+ Intel/Cnc/Spec/Version.hs view
@@ -0,0 +1,4 @@+-- WARNING: This file is generated from the .cabal file.+module Intel.Cnc.Spec.Version where+version = "0.2"+builddate = "2011-08-11 20:36:57.60858 UTC"
+ LICENSE view
@@ -0,0 +1,31 @@+NOTE: This License applies to all files in the "Haskell CnC"+distribution, irrespective of whether the license is appended at the+top of each file.++ BSD STANDARD THREE CLAUSE LICENSE ("New BSD License")++Copyright (c) 2010, Intel Corporation.+All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:+ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.+ * Redistributions in binary form must reproduce the above copyright+ notice, this list of conditions and the following disclaimer in the+ documentation and/or other materials provided with the distribution.+ * Neither the name of the <organization> nor the+ names of its contributors may be used to endorse or promote products+ derived from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.+
+ Setup.hs view
@@ -0,0 +1,42 @@+#!/usr/bin/env runhaskell+++-- module Main where+-- import Distribution.Simple+-- main :: IO ()+-- main = defaultMain+++import Distribution.Simple+import Distribution.Simple.PreProcess+import Distribution.PackageDescription +import Distribution.Simple.LocalBuildInfo +import System.Cmd(system) +import System.Exit++--main = defaultMainWithHooks simpleUserHooks+-- --defaultUserHooks++main :: IO () +main = do putStrLn$ "Running Setup.hs ..."+ defaultMainWithHooks + simpleUserHooks + -- (simpleUserHooks {+ -- --, hookedPreProcessors= (mypp : hookedPreProcessors hooks) + -- }) ++-- mypp :: PPSuffixHandler+-- mypp = (".y.pp", \ _ _ -> ppTestHandler)++-- ppTestHandler :: PreProcessor+-- ppTestHandler =+-- PreProcessor {+-- platformIndependent = True,+-- runPreProcessor = mkSimplePreProcessor $ \inFile outFile verbosity ->+-- do putStrLn$ (inFile++" has been preprocessed to "++outFile)+-- stuff <- readFile inFile+-- writeFile outFile ("-- preprocessed as a test\n\n" ++ stuff)+-- return ()+-- }++
+ cnc-spec-compiler.cabal view
@@ -0,0 +1,98 @@+Name: cnc-spec-compiler++Version: 0.2.0.0+-- [2010.11.10] 0.1.3.100 Bumping slightly after change to CNC_ASSUME_TR1+-- [2010.11.10] 0.1.3.101 New scheme for extracting version from cabal file.+-- [2010.12.06] 0.1.3.102 Bumped for recent translator plugin rearchitecture.+-- [2010.12.06] 0.1.3.103 Bumped for completion of autodone facility.+-- [2010.12.06] 0.1.3.104 Bumped for fix of autodone to remove item collections re: cycles.+-- [2010.12.06] 0.1.3.105 Bumped for done-signalling for reductions.+-- [2011.01.25] 0.1.3.106 Bumped for signifcant work in various areas.+-- [2011.01.25] 0.1.3.107 Bumped for new binary trace recording.+-- [2011.01.25] 0.1.3.108 Bumped for new binary trace format.+-- [2011.08.10] 0.2.0.0 Bumped because the Spec Compiler has been factored+-- into its own repo.+++License: BSD3+License-file: LICENSE+Stability: Beta+Author: Ryan Newton <rrnewton@gmail.com>+Maintainer: Ryan Newton <rrnewton@gmail.com>+homepage: http://software.intel.com/en-us/articles/intel-concurrent-collections-for-cc/+Copyright: Copyright (c) 2009-2010 Intel Corporation+Synopsis: Compiler/Translator for CnC Specification Files.+Description: Intel (Concurrent Collections) CnC is a data-flow like+ deterministic parallel programming model, similar to+ stream-processing but in which nodes in the computation graph share data in tables.+ In CnC, the structure of the graph and metadata about data-access+ patterns are stored in a specification, which can be used by this+ tool to generate code which will orchestrate the execution of the graph.++Category: system, concurrent+Cabal-Version: >=1.6++build-type: Simple++source-repository head+ type: git+ location: git://github.com/rrnewton/CnC-Spec-Compiler.git+++Flag BasicBuild + Description: Minimize requirements to maximize build success.+ Default: False+++Executable cnc+ Main-is: Intel/Cnc/Spec/Main.hs+ Build-Depends: base >= 3 && < 5+ , directory, process, containers, unix, bytestring, array+ , prettyclass, pretty, HUnit, mtl+ , stringtable-atom, filepath, split+ , parsec >= 3.1.0+ , hscurses, ansi-terminal+ , fgl+ , zlib, binary+-- graphviz is needed for GraphAnalysis.hs (not just visualization):+ , Graphalyze +-- , graphviz+-- , haxr, HTTP, network+-- For visualization:+ , hubigraph+--+-- [2011.08.11] There are currently polyparse dependency problems.+-- hubigraph -> haxr -> HaXml -> polyparse+--+-- I am addressing this currently by pinning older versions:+ , HaXml == 1.20.2+ , haxr == 3000.8.2++ extensions: CPP+-- Disabling for now. We will make this optional:+-- if (! BasicBuild) +-- cpp-options: -DCNCVIZ+++ other-modules: + -- Intel.Cnc.Spec.AST Intel.Cnc.Spec.CncLexer Intel.Cnc.Spec.CncGrammar+ -- Intel.Cnc.Spec.SrcLoc Intel.Cnc.Spec.GatherGraph Intel.Cnc.Spec.Codegen.CppOld+ -- Intel.Cnc.Spec.MainExecutable Intel.Cnc.Spec.Version Intel.Cnc.Spec.Globals+ -- Intel.Cnc.Spec.Util Intel.Cnc.Spec.CncGraph Intel.Cnc.Spec.TagFun+ -- Intel.Cnc.Spec.TypeDef+ -- Intel.Cnc.Spec.Passes.ReadHarch + Intel.Cnc.BenchSynth Intel.Cnc.EasyEmit Intel.Cnc.Spec.GraphAnalysis+ Intel.Cnc.Spec.CncLexer Intel.Cnc.Spec.GatherGraph Intel.Cnc.Spec.Main+ Intel.Cnc.Spec.MainExecutable Intel.Cnc.Spec.Util+ Intel.Cnc.Spec.Codegen.Plugins Intel.Cnc.Spec.Codegen.CppOld+ Intel.Cnc.Spec.Codegen.CodegenShared Intel.Cnc.Spec.Codegen.Haskell+ Intel.Cnc.Spec.Codegen.Plugins.Depends+ Intel.Cnc.Spec.Codegen.Plugins.TagFunCorrectness+ Intel.Cnc.Spec.Codegen.Plugins.ReductionDone+ Intel.Cnc.Spec.Passes.TypeDef Intel.Cnc.Spec.Passes.ReadHarch+ Intel.Cnc.Spec.TraceVacuum Intel.Cnc.Spec.Globals Intel.Cnc.Spec.AST+ Intel.Cnc.Spec.CncViz Intel.Cnc.Spec.CncGraph+ Intel.Cnc.Spec.CncGrammar Intel.Cnc.Spec.TagFun Intel.Cnc.Spec.Curses+ Intel.Cnc.Spec.SrcLoc Intel.Cnc.Spec.Version++-- GHC-Options: -O2 -threaded
+ dist/build/cnc/cnc-tmp/Intel/Cnc/Spec/CncGrammar.hs view
@@ -0,0 +1,1440 @@+{-# OPTIONS_GHC -fno-warn-overlapping-patterns #-}+{-# OPTIONS -fglasgow-exts -cpp #-}+{-# LANGUAGE DeriveDataTypeable #-}+module Intel.Cnc.Spec.CncGrammar where++import Intel.Cnc.Spec.CncLexer hiding (main)+import Intel.Cnc.Spec.AST+import Intel.Cnc.Spec.SrcLoc++--import Data.Char+import StringTable.Atom+--import Data.Data+import Text.PrettyPrint.HughesPJClass+import Debug.Trace+import qualified Data.Array as Happy_Data_Array+import qualified GHC.Exts as Happy_GHC_Exts++-- parser produced by Happy Version 1.18.5++newtype HappyAbsSyn t5 t6 t8 t9 t10 t13 t15 t17 t18 t20 t21 = HappyAbsSyn HappyAny+#if __GLASGOW_HASKELL__ >= 607+type HappyAny = Happy_GHC_Exts.Any+#else+type HappyAny = forall a . a+#endif+happyIn4 :: ([PStatement SrcSpan]) -> (HappyAbsSyn t5 t6 t8 t9 t10 t13 t15 t17 t18 t20 t21)+happyIn4 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyIn4 #-}+happyOut4 :: (HappyAbsSyn t5 t6 t8 t9 t10 t13 t15 t17 t18 t20 t21) -> ([PStatement SrcSpan])+happyOut4 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyOut4 #-}+happyIn5 :: t5 -> (HappyAbsSyn t5 t6 t8 t9 t10 t13 t15 t17 t18 t20 t21)+happyIn5 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyIn5 #-}+happyOut5 :: (HappyAbsSyn t5 t6 t8 t9 t10 t13 t15 t17 t18 t20 t21) -> t5+happyOut5 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyOut5 #-}+happyIn6 :: t6 -> (HappyAbsSyn t5 t6 t8 t9 t10 t13 t15 t17 t18 t20 t21)+happyIn6 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyIn6 #-}+happyOut6 :: (HappyAbsSyn t5 t6 t8 t9 t10 t13 t15 t17 t18 t20 t21) -> t6+happyOut6 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyOut6 #-}+happyIn7 :: ([PStatement SrcSpan]) -> (HappyAbsSyn t5 t6 t8 t9 t10 t13 t15 t17 t18 t20 t21)+happyIn7 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyIn7 #-}+happyOut7 :: (HappyAbsSyn t5 t6 t8 t9 t10 t13 t15 t17 t18 t20 t21) -> ([PStatement SrcSpan])+happyOut7 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyOut7 #-}+happyIn8 :: t8 -> (HappyAbsSyn t5 t6 t8 t9 t10 t13 t15 t17 t18 t20 t21)+happyIn8 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyIn8 #-}+happyOut8 :: (HappyAbsSyn t5 t6 t8 t9 t10 t13 t15 t17 t18 t20 t21) -> t8+happyOut8 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyOut8 #-}+happyIn9 :: t9 -> (HappyAbsSyn t5 t6 t8 t9 t10 t13 t15 t17 t18 t20 t21)+happyIn9 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyIn9 #-}+happyOut9 :: (HappyAbsSyn t5 t6 t8 t9 t10 t13 t15 t17 t18 t20 t21) -> t9+happyOut9 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyOut9 #-}+happyIn10 :: t10 -> (HappyAbsSyn t5 t6 t8 t9 t10 t13 t15 t17 t18 t20 t21)+happyIn10 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyIn10 #-}+happyOut10 :: (HappyAbsSyn t5 t6 t8 t9 t10 t13 t15 t17 t18 t20 t21) -> t10+happyOut10 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyOut10 #-}+happyIn11 :: (PStatement SrcSpan) -> (HappyAbsSyn t5 t6 t8 t9 t10 t13 t15 t17 t18 t20 t21)+happyIn11 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyIn11 #-}+happyOut11 :: (HappyAbsSyn t5 t6 t8 t9 t10 t13 t15 t17 t18 t20 t21) -> (PStatement SrcSpan)+happyOut11 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyOut11 #-}+happyIn12 :: ([RelLink SrcSpan]) -> (HappyAbsSyn t5 t6 t8 t9 t10 t13 t15 t17 t18 t20 t21)+happyIn12 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyIn12 #-}+happyOut12 :: (HappyAbsSyn t5 t6 t8 t9 t10 t13 t15 t17 t18 t20 t21) -> ([RelLink SrcSpan])+happyOut12 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyOut12 #-}+happyIn13 :: t13 -> (HappyAbsSyn t5 t6 t8 t9 t10 t13 t15 t17 t18 t20 t21)+happyIn13 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyIn13 #-}+happyOut13 :: (HappyAbsSyn t5 t6 t8 t9 t10 t13 t15 t17 t18 t20 t21) -> t13+happyOut13 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyOut13 #-}+happyIn14 :: ([CollectionInstance SrcSpan]) -> (HappyAbsSyn t5 t6 t8 t9 t10 t13 t15 t17 t18 t20 t21)+happyIn14 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyIn14 #-}+happyOut14 :: (HappyAbsSyn t5 t6 t8 t9 t10 t13 t15 t17 t18 t20 t21) -> ([CollectionInstance SrcSpan])+happyOut14 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyOut14 #-}+happyIn15 :: t15 -> (HappyAbsSyn t5 t6 t8 t9 t10 t13 t15 t17 t18 t20 t21)+happyIn15 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyIn15 #-}+happyOut15 :: (HappyAbsSyn t5 t6 t8 t9 t10 t13 t15 t17 t18 t20 t21) -> t15+happyOut15 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyOut15 #-}+happyIn16 :: ([Exp SrcSpan]) -> (HappyAbsSyn t5 t6 t8 t9 t10 t13 t15 t17 t18 t20 t21)+happyIn16 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyIn16 #-}+happyOut16 :: (HappyAbsSyn t5 t6 t8 t9 t10 t13 t15 t17 t18 t20 t21) -> ([Exp SrcSpan])+happyOut16 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyOut16 #-}+happyIn17 :: t17 -> (HappyAbsSyn t5 t6 t8 t9 t10 t13 t15 t17 t18 t20 t21)+happyIn17 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyIn17 #-}+happyOut17 :: (HappyAbsSyn t5 t6 t8 t9 t10 t13 t15 t17 t18 t20 t21) -> t17+happyOut17 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyOut17 #-}+happyIn18 :: t18 -> (HappyAbsSyn t5 t6 t8 t9 t10 t13 t15 t17 t18 t20 t21)+happyIn18 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyIn18 #-}+happyOut18 :: (HappyAbsSyn t5 t6 t8 t9 t10 t13 t15 t17 t18 t20 t21) -> t18+happyOut18 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyOut18 #-}+happyIn19 :: (Exp SrcSpan) -> (HappyAbsSyn t5 t6 t8 t9 t10 t13 t15 t17 t18 t20 t21)+happyIn19 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyIn19 #-}+happyOut19 :: (HappyAbsSyn t5 t6 t8 t9 t10 t13 t15 t17 t18 t20 t21) -> (Exp SrcSpan)+happyOut19 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyOut19 #-}+happyIn20 :: t20 -> (HappyAbsSyn t5 t6 t8 t9 t10 t13 t15 t17 t18 t20 t21)+happyIn20 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyIn20 #-}+happyOut20 :: (HappyAbsSyn t5 t6 t8 t9 t10 t13 t15 t17 t18 t20 t21) -> t20+happyOut20 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyOut20 #-}+happyIn21 :: t21 -> (HappyAbsSyn t5 t6 t8 t9 t10 t13 t15 t17 t18 t20 t21)+happyIn21 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyIn21 #-}+happyOut21 :: (HappyAbsSyn t5 t6 t8 t9 t10 t13 t15 t17 t18 t20 t21) -> t21+happyOut21 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyOut21 #-}+happyInTok :: (Lexeme) -> (HappyAbsSyn t5 t6 t8 t9 t10 t13 t15 t17 t18 t20 t21)+happyInTok x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyInTok #-}+happyOutTok :: (HappyAbsSyn t5 t6 t8 t9 t10 t13 t15 t17 t18 t20 t21) -> (Lexeme)+happyOutTok x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyOutTok #-}+++happyActOffsets :: HappyAddr+happyActOffsets = HappyA# "\x1a\x00\x41\x00\x00\x00\xff\xff\xf6\xff\x2d\x00\x2f\x01\xf5\xff\x0b\x00\x2d\x01\xe1\x00\x4b\x00\x25\x00\x25\x00\x2e\x01\x31\x01\x00\x00\x30\x01\x22\x00\x00\x00\x0c\x01\xcb\x00\x4b\x00\x4b\x00\x2b\x01\x00\x00\x2c\x01\x4d\x00\x43\x00\x35\x00\x2a\x01\xfd\xff\x4d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x4d\x00\x00\x00\x00\x00\xd0\x00\x0d\x00\xdf\x00\x00\x00\x00\x00\xce\x00\xce\x00\x22\x00\x00\x00\x0b\x00\x22\x00\x22\x00\x22\x00\x22\x00\x00\x00\x00\x00\x0e\x01\x28\x01\x29\x01\x05\x00\x04\x00\x00\x00\x00\x00\x00\x00\x27\x01\x4d\x00\x00\x00\x4d\x00\x00\x00\x00\x00\x26\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x25\x01\xa6\x00\x20\x01\x00\x00\x00\x00\xce\x00\x24\x01\xce\x00\x00\x00\x1d\x01\x00\x00\xce\x00\x00\x00\x1b\x01\x00\x00\x4d\x00\x5e\x00\x1e\x01\x4d\x00\xfc\xff\x23\x01\x00\x00\xc5\x00\x22\x01\x4d\x00\x00\x00\xce\x00\x00\x00\x44\x00\x00\x00\x21\x01\x1a\x01\x19\x01\x1f\x01\x00\x00\x10\x01\x00\x00\x4d\x00\x13\x01\x4d\x00\x18\x01\x00\x00\x7b\x00\xce\x00\xce\x00\xce\x00\xce\x00\xce\x00\xce\x00\xce\x00\xce\x00\xce\x00\x00\x00\x4d\x00\x46\x00\x1c\x00\x1c\x01\x0f\x01\x4d\x00\x4d\x00\x9c\x00\xb6\x00\x05\x01\x05\x01\x59\x00\x59\x00\xae\x00\xae\x00\x00\x00\x12\x01\x00\x00\x00\x00\x91\x00\x00\x00\x00\x00\x00\x00\x0a\x01\x17\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8e\x00\x00\x00\x16\x01\x78\x00\x6b\x00\xce\x00\x6e\x00\x15\x01\x14\x01\x00\x00\xce\x00\x00\x00\x09\x01\x00\x00\x0b\x01\x00\x00\x11\x01\x00\x00\x04\x01\xce\x00\x61\x00\x00\x00\x00\x00"#++happyGotoOffsets :: HappyAddr+happyGotoOffsets = HappyA# "\x92\x00\xa8\x00\x00\x00\x9d\x00\x00\x00\x00\x00\x00\x01\x00\x00\xfb\x00\x00\x00\x00\x00\x03\x01\x4e\x00\x47\x00\x00\x00\x07\x01\x00\x00\x00\x00\xff\x00\x00\x00\x00\x00\xd9\x00\x02\x01\x01\x01\x00\x00\x00\x00\x00\x00\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfd\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd7\x00\xd5\x00\xf5\x00\x00\x00\xf4\x00\xf0\x00\xee\x00\xec\x00\xea\x00\x00\x00\x00\x00\x00\x00\xed\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfc\x00\x00\x00\xf9\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xef\x00\x00\x00\xd3\x00\x00\x00\x00\x00\x00\x00\xd1\x00\x00\x00\x00\x00\x00\x00\xf8\x00\x00\x00\x00\x00\xe0\x00\x00\x00\xfa\x00\x00\x00\x00\x00\xeb\x00\xca\x00\x00\x00\xcf\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaa\x00\x00\x00\x00\x00\x00\x00\xdd\x00\x00\x00\x77\x00\x00\x00\x00\x00\x00\x00\x7a\x00\x6d\x00\xdc\x00\xc7\x00\xb8\x00\xb0\x00\xa2\x00\x97\x00\x8c\x00\x00\x00\x6a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x42\x00\x37\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfe\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00"#++happyDefActions :: HappyAddr+happyDefActions = HappyA# "\xdb\xff\x00\x00\xfe\xff\xdb\xff\x00\x00\x00\x00\xe5\xff\x00\x00\xe1\xff\xda\xff\xd8\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe3\xff\x00\x00\x00\x00\xfb\xff\x00\x00\xcf\xff\x00\x00\x00\x00\x00\x00\xf5\xff\xe7\xff\x00\x00\x00\x00\x00\x00\x00\x00\xb4\xff\xaf\xff\xc1\xff\xc8\xff\xc7\xff\xc5\xff\xc6\xff\xc4\xff\xc3\xff\xc2\xff\x00\x00\x00\x00\x00\x00\xc9\xff\xc4\xff\xcf\xff\xcf\xff\xdb\xff\xe2\xff\xe1\xff\xdb\xff\xdb\xff\xdb\xff\xdb\xff\xfa\xff\xf7\xff\xe4\xff\xe5\xff\x00\x00\x00\x00\x00\x00\xf9\xff\xf6\xff\xfd\xff\x00\x00\x00\x00\xef\xff\x00\x00\xf2\xff\xe4\xff\x00\x00\xdc\xff\xdd\xff\xde\xff\xdf\xff\xe0\xff\xd9\xff\x00\x00\xce\xff\xc0\xff\xbf\xff\xbe\xff\x00\x00\x00\x00\xcf\xff\xd4\xff\x00\x00\xb2\xff\xcf\xff\xd3\xff\xb3\xff\xb4\xff\x00\x00\xae\xff\x00\x00\xaf\xff\x00\x00\xcc\xff\xd5\xff\x00\x00\x00\x00\x00\x00\xf3\xff\xcf\xff\xf4\xff\x00\x00\xe6\xff\x00\x00\x00\x00\xcb\xff\xcc\xff\xeb\xff\x00\x00\xb1\xff\xaf\xff\x00\x00\x00\x00\x00\x00\xd6\xff\x00\x00\xcf\xff\xcf\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd7\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb5\xff\xb8\xff\xb9\xff\xba\xff\xbb\xff\xb6\xff\xb7\xff\xcd\xff\x00\x00\xbd\xff\xd1\xff\x00\x00\xd0\xff\xad\xff\xb0\xff\x00\x00\xcc\xff\xd2\xff\xf0\xff\xf8\xff\xca\xff\xea\xff\x00\x00\xbc\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\xff\xcf\xff\xe8\xff\x00\x00\xee\xff\x00\x00\xed\xff\x00\x00\xe9\xff\x00\x00\x00\x00\x00\x00\xec\xff"#++happyCheck :: HappyAddr+happyCheck = HappyA# "\xff\xff\x02\x00\x0d\x00\x0d\x00\x08\x00\x08\x00\x02\x00\x02\x00\x09\x00\x0c\x00\x0b\x00\x0d\x00\x10\x00\x10\x00\x0f\x00\x02\x00\x05\x00\x06\x00\x07\x00\x0f\x00\x0f\x00\x20\x00\x20\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x02\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x14\x00\x0f\x00\x09\x00\x02\x00\x0b\x00\x01\x00\x02\x00\x1d\x00\x0f\x00\x0e\x00\x09\x00\x0c\x00\x0b\x00\x09\x00\x0f\x00\x14\x00\x0f\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x02\x00\x1e\x00\x1f\x00\x20\x00\x0f\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x02\x00\x1f\x00\x18\x00\x19\x00\x10\x00\x1b\x00\x14\x00\x09\x00\x08\x00\x0b\x00\x02\x00\x01\x00\x02\x00\x0f\x00\x0d\x00\x10\x00\x10\x00\x0e\x00\x0e\x00\x09\x00\x10\x00\x14\x00\x18\x00\x14\x00\x1a\x00\x0e\x00\x1c\x00\x10\x00\x1e\x00\x1f\x00\x20\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1c\x00\x1f\x00\x0a\x00\x0e\x00\x14\x00\x15\x00\x16\x00\x0f\x00\x10\x00\x14\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x0a\x00\x0c\x00\x10\x00\x10\x00\x0f\x00\x0f\x00\x10\x00\x14\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x0a\x00\x0c\x00\x10\x00\x10\x00\x0f\x00\x0f\x00\x10\x00\x14\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x00\x00\x01\x00\x02\x00\x03\x00\x08\x00\x05\x00\x06\x00\x07\x00\x0c\x00\x0f\x00\x0a\x00\x0b\x00\x01\x00\x02\x00\x03\x00\x10\x00\x05\x00\x06\x00\x07\x00\x14\x00\x0f\x00\x0a\x00\x0b\x00\x01\x00\x02\x00\x03\x00\x10\x00\x05\x00\x06\x00\x07\x00\x14\x00\x0f\x00\x0a\x00\x0b\x00\x0e\x00\x0f\x00\x10\x00\x0d\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x0f\x00\x10\x00\x0f\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x0f\x00\x10\x00\x0f\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x02\x00\x03\x00\x04\x00\x02\x00\x03\x00\x04\x00\x08\x00\x09\x00\x10\x00\x0f\x00\x09\x00\x08\x00\x14\x00\x10\x00\x0c\x00\x0c\x00\x0c\x00\x0f\x00\x0c\x00\x0f\x00\x0c\x00\x0f\x00\x0c\x00\x0f\x00\x0c\x00\x0f\x00\x08\x00\x0f\x00\x0a\x00\x09\x00\x0f\x00\x0b\x00\x10\x00\x11\x00\x04\x00\x10\x00\x11\x00\x05\x00\x06\x00\x0a\x00\x0b\x00\x0a\x00\x0b\x00\x0a\x00\x0b\x00\x0a\x00\x0b\x00\x08\x00\x09\x00\x0f\x00\x0a\x00\x0b\x00\x10\x00\x11\x00\x08\x00\x09\x00\x05\x00\x06\x00\x0d\x00\x10\x00\x10\x00\x0b\x00\x04\x00\x10\x00\x10\x00\x10\x00\x0e\x00\x0e\x00\x0e\x00\x0e\x00\x02\x00\x09\x00\x0c\x00\x02\x00\x02\x00\x02\x00\x02\x00\x10\x00\x16\x00\x0a\x00\x0e\x00\x02\x00\x0c\x00\x10\x00\x02\x00\x0a\x00\x02\x00\x02\x00\x02\x00\x18\x00\x0e\x00\x0a\x00\x09\x00\x10\x00\x02\x00\x0f\x00\x21\x00\x0a\x00\x14\x00\x09\x00\x0c\x00\x02\x00\x02\x00\xff\xff\x0f\x00\xff\xff\xff\xff\xff\xff\x0f\x00\x0e\x00\x0e\x00\x11\x00\x0f\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x1c\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x1c\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"#++happyTable :: HappyAddr+happyTable = HappyA# "\x00\x00\x0b\x00\x38\x00\x3f\x00\x70\x00\xc9\xff\x42\x00\x44\x00\x0c\x00\xc9\xff\x0d\x00\x9f\x00\x71\x00\xc9\xff\x0e\x00\x58\x00\x34\x00\x35\x00\x36\x00\x43\x00\x45\x00\x39\x00\x40\x00\x0f\x00\xe5\xff\x10\x00\xe5\xff\x11\x00\x0b\x00\x12\x00\x13\x00\x14\x00\xfc\xff\x59\x00\xb5\x00\x0c\x00\x0b\x00\x0d\x00\x1f\x00\x20\x00\x37\x00\x0e\x00\x89\x00\x0c\x00\xad\x00\x17\x00\x21\x00\x4f\x00\x59\x00\x18\x00\x0f\x00\xe5\xff\x10\x00\xe5\xff\x11\x00\x62\x00\x12\x00\x13\x00\x14\x00\xa7\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x0b\x00\x29\x00\x3c\x00\x3d\x00\xa4\x00\x3e\x00\x59\x00\x0c\x00\x63\x00\x0d\x00\x2d\x00\x1f\x00\x5d\x00\x0e\x00\x9f\x00\xa5\x00\x64\x00\x8a\x00\x1c\x00\x21\x00\x1d\x00\x59\x00\x0f\x00\x59\x00\x10\x00\x29\x00\x11\x00\x2a\x00\x12\x00\x13\x00\x14\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x2e\x00\x28\x00\x5e\x00\x29\x00\xb7\x00\x74\x00\x80\x00\x81\x00\x82\x00\x7c\x00\x7d\x00\x59\x00\x7e\x00\x7f\x00\x80\x00\x81\x00\x82\x00\xb1\x00\x92\x00\x8a\x00\xa9\x00\x4f\x00\x7c\x00\x7d\x00\x59\x00\x7e\x00\x7f\x00\x80\x00\x81\x00\x82\x00\x95\x00\x93\x00\x96\x00\xaa\x00\x4f\x00\x7c\x00\x7d\x00\x59\x00\x7e\x00\x7f\x00\x80\x00\x81\x00\x82\x00\x14\x00\x02\x00\x03\x00\x04\x00\xac\x00\x05\x00\x06\x00\x07\x00\xad\x00\x8b\x00\x08\x00\x09\x00\x40\x00\x03\x00\x04\x00\xa2\x00\x05\x00\x06\x00\x07\x00\x59\x00\x8c\x00\x08\x00\x09\x00\x02\x00\x03\x00\x04\x00\xa4\x00\x05\x00\x06\x00\x07\x00\x59\x00\x8d\x00\x08\x00\x09\x00\x7b\x00\x7c\x00\x7d\x00\x9a\x00\x7e\x00\x7f\x00\x80\x00\x81\x00\x82\x00\x00\x00\x00\x00\x8e\x00\x7e\x00\x7f\x00\x80\x00\x81\x00\x82\x00\x7c\x00\x7d\x00\x8f\x00\x7e\x00\x7f\x00\x80\x00\x81\x00\x82\x00\x51\x00\x52\x00\x53\x00\x51\x00\x52\x00\x53\x00\x69\x00\x54\x00\x6d\x00\x90\x00\x54\x00\x5a\x00\x59\x00\x6a\x00\x69\x00\x5b\x00\x74\x00\x4f\x00\x76\x00\x4f\x00\x4e\x00\x4f\x00\x54\x00\x4f\x00\x67\x00\x4f\x00\x56\x00\x4f\x00\x57\x00\x2f\x00\x91\x00\x30\x00\x5e\x00\x98\x00\x6b\x00\x5e\x00\x71\x00\x46\x00\x3a\x00\x48\x00\x09\x00\x49\x00\x09\x00\x4a\x00\x09\x00\x4b\x00\x09\x00\x4c\x00\x32\x00\x78\x00\x4d\x00\x09\x00\x5e\x00\x5f\x00\x31\x00\x32\x00\x39\x00\x3a\x00\x6d\x00\x5b\x00\x84\x00\x15\x00\x19\x00\x85\x00\x5b\x00\x64\x00\x1c\x00\x29\x00\x2b\x00\xb5\x00\xb4\x00\xb2\x00\xb3\x00\xaf\x00\xb0\x00\xab\x00\x6f\x00\xa1\x00\x82\x00\xa3\x00\xa7\x00\x88\x00\x98\x00\x9a\x00\x6f\x00\x96\x00\x9e\x00\x1b\x00\x6f\x00\x48\x00\x9c\x00\x73\x00\x7a\x00\x9d\x00\x46\x00\x76\x00\xff\xff\x78\x00\x59\x00\x87\x00\x83\x00\x19\x00\x1b\x00\x00\x00\x84\x00\x00\x00\x00\x00\x00\x00\x61\x00\x66\x00\x31\x00\x67\x00\x1c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"#++happyReduceArr = Happy_Data_Array.array (1, 82) [+ (1 , happyReduce_1),+ (2 , happyReduce_2),+ (3 , happyReduce_3),+ (4 , happyReduce_4),+ (5 , happyReduce_5),+ (6 , happyReduce_6),+ (7 , happyReduce_7),+ (8 , happyReduce_8),+ (9 , happyReduce_9),+ (10 , happyReduce_10),+ (11 , happyReduce_11),+ (12 , happyReduce_12),+ (13 , happyReduce_13),+ (14 , happyReduce_14),+ (15 , happyReduce_15),+ (16 , happyReduce_16),+ (17 , happyReduce_17),+ (18 , happyReduce_18),+ (19 , happyReduce_19),+ (20 , happyReduce_20),+ (21 , happyReduce_21),+ (22 , happyReduce_22),+ (23 , happyReduce_23),+ (24 , happyReduce_24),+ (25 , happyReduce_25),+ (26 , happyReduce_26),+ (27 , happyReduce_27),+ (28 , happyReduce_28),+ (29 , happyReduce_29),+ (30 , happyReduce_30),+ (31 , happyReduce_31),+ (32 , happyReduce_32),+ (33 , happyReduce_33),+ (34 , happyReduce_34),+ (35 , happyReduce_35),+ (36 , happyReduce_36),+ (37 , happyReduce_37),+ (38 , happyReduce_38),+ (39 , happyReduce_39),+ (40 , happyReduce_40),+ (41 , happyReduce_41),+ (42 , happyReduce_42),+ (43 , happyReduce_43),+ (44 , happyReduce_44),+ (45 , happyReduce_45),+ (46 , happyReduce_46),+ (47 , happyReduce_47),+ (48 , happyReduce_48),+ (49 , happyReduce_49),+ (50 , happyReduce_50),+ (51 , happyReduce_51),+ (52 , happyReduce_52),+ (53 , happyReduce_53),+ (54 , happyReduce_54),+ (55 , happyReduce_55),+ (56 , happyReduce_56),+ (57 , happyReduce_57),+ (58 , happyReduce_58),+ (59 , happyReduce_59),+ (60 , happyReduce_60),+ (61 , happyReduce_61),+ (62 , happyReduce_62),+ (63 , happyReduce_63),+ (64 , happyReduce_64),+ (65 , happyReduce_65),+ (66 , happyReduce_66),+ (67 , happyReduce_67),+ (68 , happyReduce_68),+ (69 , happyReduce_69),+ (70 , happyReduce_70),+ (71 , happyReduce_71),+ (72 , happyReduce_72),+ (73 , happyReduce_73),+ (74 , happyReduce_74),+ (75 , happyReduce_75),+ (76 , happyReduce_76),+ (77 , happyReduce_77),+ (78 , happyReduce_78),+ (79 , happyReduce_79),+ (80 , happyReduce_80),+ (81 , happyReduce_81),+ (82 , happyReduce_82)+ ]++happy_n_terms = 34 :: Int+happy_n_nonterms = 18 :: Int++happyReduce_1 = happySpecReduce_1 0# happyReduction_1+happyReduction_1 happy_x_1+ = case happyOut5 happy_x_1 of { happy_var_1 -> + happyIn4+ (happy_var_1+ )}++happyReduce_2 = happySpecReduce_2 1# happyReduction_2+happyReduction_2 happy_x_2+ happy_x_1+ = case happyOut6 happy_x_1 of { happy_var_1 -> + case happyOut5 happy_x_2 of { happy_var_2 -> + happyIn5+ (happy_var_1 ++ happy_var_2+ )}}++happyReduce_3 = happySpecReduce_1 1# happyReduction_3+happyReduction_3 happy_x_1+ = case happyOut6 happy_x_1 of { happy_var_1 -> + happyIn5+ (happy_var_1+ )}++happyReduce_4 = happySpecReduce_1 1# happyReduction_4+happyReduction_4 happy_x_1+ = happyIn5+ ([]+ )++happyReduce_5 = happySpecReduce_2 2# happyReduction_5+happyReduction_5 happy_x_2+ happy_x_1+ = case happyOut11 happy_x_1 of { happy_var_1 -> + happyIn6+ ([happy_var_1]+ )}++happyReduce_6 = happySpecReduce_2 2# happyReduction_6+happyReduction_6 happy_x_2+ happy_x_1+ = case happyOut7 happy_x_1 of { happy_var_1 -> + happyIn6+ (happy_var_1+ )}++happyReduce_7 = happyReduce 5# 2# happyReduction_7+happyReduction_7 (happy_x_5 `HappyStk`+ happy_x_4 `HappyStk`+ happy_x_3 `HappyStk`+ happy_x_2 `HappyStk`+ happy_x_1 `HappyStk`+ happyRest)+ = case happyOutTok happy_x_2 of { happy_var_2 -> + case happyOut20 happy_x_4 of { happy_var_4 -> + happyIn6+ ([TypeDef (lexPointSpan happy_var_2) (tAL happy_var_2) happy_var_4]+ ) `HappyStk` happyRest}}++happyReduce_8 = happySpecReduce_2 2# happyReduction_8+happyReduction_8 happy_x_2+ happy_x_1+ = case happyOut11 happy_x_1 of { happy_var_1 -> + happyIn6+ (parseErrorSDoc (getDecor happy_var_1) $ text "Premature end of file, possible missing semi-colon."+ )}++happyReduce_9 = happySpecReduce_2 2# happyReduction_9+happyReduction_9 happy_x_2+ happy_x_1+ = case happyOut7 happy_x_1 of { happy_var_1 -> + happyIn6+ (parseErrorSDoc (getDecorLs happy_var_1) $ text "Premature end of file, possible missing semi-colon."+ )}++happyReduce_10 = happySpecReduce_2 3# happyReduction_10+happyReduction_10 happy_x_2+ happy_x_1+ = case happyOutTok happy_x_1 of { happy_var_1 -> + case happyOut8 happy_x_2 of { happy_var_2 -> + happyIn7+ (map (\x -> DeclareSteps (lexSpan happy_var_1) (tAL x)) happy_var_2+ )}}++happyReduce_11 = happyReduce 4# 3# happyReduction_11+happyReduction_11 (happy_x_4 `HappyStk`+ happy_x_3 `HappyStk`+ happy_x_2 `HappyStk`+ happy_x_1 `HappyStk`+ happyRest)+ = case happyOutTok happy_x_1 of { happy_var_1 -> + case happyOut15 happy_x_2 of { happy_var_2 -> + case happyOutTok happy_x_3 of { happy_var_3 -> + case happyOut16 happy_x_4 of { happy_var_4 -> + happyIn7+ ([Constraints (cLLS happy_var_1 (lexSpan happy_var_3) happy_var_4) happy_var_2 happy_var_4]+ ) `HappyStk` happyRest}}}}++happyReduce_12 = happySpecReduce_3 3# happyReduction_12+happyReduction_12 happy_x_3+ happy_x_2+ happy_x_1+ = case happyOutTok happy_x_1 of { happy_var_1 -> + case happyOut15 happy_x_2 of { happy_var_2 -> + case happyOut16 happy_x_3 of { happy_var_3 -> + happyIn7+ ([Constraints (cLLS happy_var_1 (getDecor happy_var_2) happy_var_3) happy_var_2 happy_var_3]+ )}}}++happyReduce_13 = happySpecReduce_3 3# happyReduction_13+happyReduction_13 happy_x_3+ happy_x_2+ happy_x_1+ = case happyOutTok happy_x_2 of { happy_var_2 -> + case happyOutTok happy_x_3 of { happy_var_3 -> + happyIn7+ ([DeclareTags (cLL happy_var_2 happy_var_3) (tAL happy_var_3) Nothing]+ )}}++happyReduce_14 = happyReduce 7# 3# happyReduction_14+happyReduction_14 (happy_x_7 `HappyStk`+ happy_x_6 `HappyStk`+ happy_x_5 `HappyStk`+ happy_x_4 `HappyStk`+ happy_x_3 `HappyStk`+ happy_x_2 `HappyStk`+ happy_x_1 `HappyStk`+ happyRest)+ = case happyOutTok happy_x_3 of { happy_var_3 -> + case happyOut20 happy_x_5 of { happy_var_5 -> + case happyOutTok happy_x_7 of { happy_var_7 -> + happyIn7+ ([DeclareTags (cLL happy_var_3 happy_var_7) (tAL happy_var_7) (Just happy_var_5)]+ ) `HappyStk` happyRest}}}++happyReduce_15 = happyReduce 5# 3# happyReduction_15+happyReduction_15 (happy_x_5 `HappyStk`+ happy_x_4 `HappyStk`+ happy_x_3 `HappyStk`+ happy_x_2 `HappyStk`+ happy_x_1 `HappyStk`+ happyRest)+ = case happyOutTok happy_x_1 of { happy_var_1 -> + case happyOut20 happy_x_3 of { happy_var_3 -> + case happyOutTok happy_x_5 of { happy_var_5 -> + happyIn7+ ([DeclareTags (combineSrcSpans (lexSpan happy_var_1) (lexSpan happy_var_5)) (tAL happy_var_5) (Just happy_var_3)]+ ) `HappyStk` happyRest}}}++happyReduce_16 = happySpecReduce_3 3# happyReduction_16+happyReduction_16 happy_x_3+ happy_x_2+ happy_x_1+ = case happyOutTok happy_x_2 of { happy_var_2 -> + case happyOutTok happy_x_3 of { happy_var_3 -> + happyIn7+ ([DeclareItems (cLL happy_var_2 happy_var_3) (tAL happy_var_3) Nothing]+ )}}++happyReduce_17 = happyReduce 8# 3# happyReduction_17+happyReduction_17 (happy_x_8 `HappyStk`+ happy_x_7 `HappyStk`+ happy_x_6 `HappyStk`+ happy_x_5 `HappyStk`+ happy_x_4 `HappyStk`+ happy_x_3 `HappyStk`+ happy_x_2 `HappyStk`+ happy_x_1 `HappyStk`+ happyRest)+ = case happyOutTok happy_x_2 of { happy_var_2 -> + case happyOut20 happy_x_4 of { happy_var_4 -> + case happyOut20 happy_x_6 of { happy_var_6 -> + case happyOutTok happy_x_8 of { happy_var_8 -> + happyIn7+ ([DeclareItems (cLL happy_var_2 happy_var_8) (tAL happy_var_8) (Just (happy_var_4, happy_var_6))]+ ) `HappyStk` happyRest}}}}++happyReduce_18 = happyReduce 8# 3# happyReduction_18+happyReduction_18 (happy_x_8 `HappyStk`+ happy_x_7 `HappyStk`+ happy_x_6 `HappyStk`+ happy_x_5 `HappyStk`+ happy_x_4 `HappyStk`+ happy_x_3 `HappyStk`+ happy_x_2 `HappyStk`+ happy_x_1 `HappyStk`+ happyRest)+ = case happyOutTok happy_x_2 of { happy_var_2 -> + case happyOutTok happy_x_3 of { happy_var_3 -> + case happyOutTok happy_x_5 of { happy_var_5 -> + case happyOut19 happy_x_7 of { happy_var_7 -> + happyIn7+ ([DeclareReductions (cLL happy_var_2 happy_var_3) (tAL happy_var_3) (tAL happy_var_5) happy_var_7 Nothing]+ ) `HappyStk` happyRest}}}}++happyReduce_19 = happyReduce 13# 3# happyReduction_19+happyReduction_19 (happy_x_13 `HappyStk`+ happy_x_12 `HappyStk`+ happy_x_11 `HappyStk`+ happy_x_10 `HappyStk`+ happy_x_9 `HappyStk`+ happy_x_8 `HappyStk`+ happy_x_7 `HappyStk`+ happy_x_6 `HappyStk`+ happy_x_5 `HappyStk`+ happy_x_4 `HappyStk`+ happy_x_3 `HappyStk`+ happy_x_2 `HappyStk`+ happy_x_1 `HappyStk`+ happyRest)+ = case happyOutTok happy_x_2 of { happy_var_2 -> + case happyOut20 happy_x_4 of { happy_var_4 -> + case happyOut20 happy_x_6 of { happy_var_6 -> + case happyOutTok happy_x_8 of { happy_var_8 -> + case happyOutTok happy_x_10 of { happy_var_10 -> + case happyOut19 happy_x_12 of { happy_var_12 -> + happyIn7+ ([DeclareReductions (cLL happy_var_2 happy_var_10) (tAL happy_var_8) (tAL happy_var_10) happy_var_12 (Just (happy_var_4, happy_var_6))]+ ) `HappyStk` happyRest}}}}}}++happyReduce_20 = happyReduce 4# 3# happyReduction_20+happyReduction_20 (happy_x_4 `HappyStk`+ happy_x_3 `HappyStk`+ happy_x_2 `HappyStk`+ happy_x_1 `HappyStk`+ happyRest)+ = case happyOutTok happy_x_1 of { happy_var_1 -> + case happyOut20 happy_x_2 of { happy_var_2 -> + case happyOutTok happy_x_3 of { happy_var_3 -> + case happyOutTok happy_x_4 of { happy_var_4 -> + happyIn7+ ([DeclareTags (combineSrcSpans (lexSpan happy_var_1) (lexSpan happy_var_4)) (tAL happy_var_3) (Just happy_var_2)]+ ) `HappyStk` happyRest}}}}++happyReduce_21 = happyReduce 6# 3# happyReduction_21+happyReduction_21 (happy_x_6 `HappyStk`+ happy_x_5 `HappyStk`+ happy_x_4 `HappyStk`+ happy_x_3 `HappyStk`+ happy_x_2 `HappyStk`+ happy_x_1 `HappyStk`+ happyRest)+ = case happyOutTok happy_x_1 of { happy_var_1 -> + case happyOut20 happy_x_2 of { happy_var_2 -> + case happyOutTok happy_x_3 of { happy_var_3 -> + case happyOutTok happy_x_6 of { happy_var_6 -> + happyIn7+ ([DeclareTags (combineSrcSpans (lexSpan happy_var_1) (lexSpan happy_var_6)) (tAL happy_var_3) (Just happy_var_2)]+ ) `HappyStk` happyRest}}}}++happyReduce_22 = happyReduce 9# 3# happyReduction_22+happyReduction_22 (happy_x_9 `HappyStk`+ happy_x_8 `HappyStk`+ happy_x_7 `HappyStk`+ happy_x_6 `HappyStk`+ happy_x_5 `HappyStk`+ happy_x_4 `HappyStk`+ happy_x_3 `HappyStk`+ happy_x_2 `HappyStk`+ happy_x_1 `HappyStk`+ happyRest)+ = case happyOutTok happy_x_1 of { happy_var_1 -> + case happyOut20 happy_x_2 of { happy_var_2 -> + case happyOutTok happy_x_3 of { happy_var_3 -> + case happyOut20 happy_x_5 of { happy_var_5 -> + case happyOutTok happy_x_9 of { happy_var_9 -> + happyIn7+ ([DeclareItems (combineSrcSpans (lexSpan happy_var_1) (lexSpan happy_var_9)) (tAL happy_var_3) (Just (happy_var_5, happy_var_2))]+ ) `HappyStk` happyRest}}}}}++happyReduce_23 = happyReduce 7# 3# happyReduction_23+happyReduction_23 (happy_x_7 `HappyStk`+ happy_x_6 `HappyStk`+ happy_x_5 `HappyStk`+ happy_x_4 `HappyStk`+ happy_x_3 `HappyStk`+ happy_x_2 `HappyStk`+ happy_x_1 `HappyStk`+ happyRest)+ = case happyOutTok happy_x_1 of { happy_var_1 -> + case happyOut20 happy_x_2 of { happy_var_2 -> + case happyOutTok happy_x_3 of { happy_var_3 -> + case happyOut20 happy_x_5 of { happy_var_5 -> + case happyOutTok happy_x_7 of { happy_var_7 -> + happyIn7+ ([DeclareItems (combineSrcSpans (lexSpan happy_var_1) (lexSpan happy_var_7)) (tAL happy_var_3) (Just (happy_var_5, happy_var_2))]+ ) `HappyStk` happyRest}}}}}++happyReduce_24 = happySpecReduce_1 4# happyReduction_24+happyReduction_24 happy_x_1+ = case happyOutTok happy_x_1 of { happy_var_1 -> + happyIn8+ ([happy_var_1]+ )}++happyReduce_25 = happySpecReduce_3 4# happyReduction_25+happyReduction_25 happy_x_3+ happy_x_2+ happy_x_1+ = case happyOutTok happy_x_1 of { happy_var_1 -> + case happyOut8 happy_x_3 of { happy_var_3 -> + happyIn8+ (happy_var_1 : happy_var_3+ )}}++happyReduce_26 = happySpecReduce_0 5# happyReduction_26+happyReduction_26 = happyIn9+ ([]+ )++happyReduce_27 = happySpecReduce_2 5# happyReduction_27+happyReduction_27 happy_x_2+ happy_x_1+ = case happyOut10 happy_x_1 of { happy_var_1 -> + case happyOut9 happy_x_2 of { happy_var_2 -> + happyIn9+ (happy_var_1 : happy_var_2+ )}}++happyReduce_28 = happySpecReduce_1 6# happyReduction_28+happyReduction_28 happy_x_1+ = happyIn10+ ("dense"+ )++happyReduce_29 = happySpecReduce_2 7# happyReduction_29+happyReduction_29 happy_x_2+ happy_x_1+ = case happyOut14 happy_x_1 of { happy_var_1 -> + case happyOut12 happy_x_2 of { happy_var_2 -> + happyIn11+ (Chain happy_var_1 happy_var_2+ )}}++happyReduce_30 = happySpecReduce_0 8# happyReduction_30+happyReduction_30 = happyIn12+ ([]+ )++happyReduce_31 = happySpecReduce_2 8# happyReduction_31+happyReduction_31 happy_x_2+ happy_x_1+ = case happyOut13 happy_x_1 of { happy_var_1 -> + case happyOut12 happy_x_2 of { happy_var_2 -> + happyIn12+ (happy_var_1 : happy_var_2+ )}}++happyReduce_32 = happySpecReduce_2 9# happyReduction_32+happyReduction_32 happy_x_2+ happy_x_1+ = case happyOutTok happy_x_1 of { happy_var_1 -> + case happyOut14 happy_x_2 of { happy_var_2 -> + happyIn13+ (ProduceLink (lexSpan happy_var_1) happy_var_2+ )}}++happyReduce_33 = happySpecReduce_2 9# happyReduction_33+happyReduction_33 happy_x_2+ happy_x_1+ = case happyOutTok happy_x_1 of { happy_var_1 -> + case happyOut14 happy_x_2 of { happy_var_2 -> + happyIn13+ (RevProduceLink (lexSpan happy_var_1) happy_var_2+ )}}++happyReduce_34 = happySpecReduce_2 9# happyReduction_34+happyReduction_34 happy_x_2+ happy_x_1+ = case happyOutTok happy_x_1 of { happy_var_1 -> + case happyOut14 happy_x_2 of { happy_var_2 -> + happyIn13+ (PrescribeLink (lexSpan happy_var_1) happy_var_2+ )}}++happyReduce_35 = happySpecReduce_2 9# happyReduction_35+happyReduction_35 happy_x_2+ happy_x_1+ = case happyOutTok happy_x_1 of { happy_var_1 -> + case happyOut14 happy_x_2 of { happy_var_2 -> + happyIn13+ (PrescribeLink (lexSpan happy_var_1) happy_var_2+ )}}++happyReduce_36 = happySpecReduce_0 10# happyReduction_36+happyReduction_36 = happyIn14+ ([]+ )++happyReduce_37 = happySpecReduce_1 10# happyReduction_37+happyReduction_37 happy_x_1+ = case happyOut15 happy_x_1 of { happy_var_1 -> + happyIn14+ ([happy_var_1]+ )}++happyReduce_38 = happySpecReduce_3 10# happyReduction_38+happyReduction_38 happy_x_3+ happy_x_2+ happy_x_1+ = case happyOut15 happy_x_1 of { happy_var_1 -> + case happyOut14 happy_x_3 of { happy_var_3 -> + happyIn14+ (happy_var_1 : happy_var_3+ )}}++happyReduce_39 = happySpecReduce_1 11# happyReduction_39+happyReduction_39 happy_x_1+ = case happyOutTok happy_x_1 of { happy_var_1 -> + happyIn15+ (InstName (lexSpan happy_var_1) (lexStr happy_var_1)+ )}++happyReduce_40 = happyReduce 4# 11# happyReduction_40+happyReduction_40 (happy_x_4 `HappyStk`+ happy_x_3 `HappyStk`+ happy_x_2 `HappyStk`+ happy_x_1 `HappyStk`+ happyRest)+ = case happyOutTok happy_x_1 of { happy_var_1 -> + case happyOut16 happy_x_3 of { happy_var_3 -> + case happyOutTok happy_x_4 of { happy_var_4 -> + happyIn15+ (InstItemCol (combineSrcSpans (lexSpan happy_var_1) (lexSpan happy_var_4)) (lexStr happy_var_1) happy_var_3+ ) `HappyStk` happyRest}}}++happyReduce_41 = happyReduce 4# 11# happyReduction_41+happyReduction_41 (happy_x_4 `HappyStk`+ happy_x_3 `HappyStk`+ happy_x_2 `HappyStk`+ happy_x_1 `HappyStk`+ happyRest)+ = case happyOutTok happy_x_1 of { happy_var_1 -> + case happyOut16 happy_x_3 of { happy_var_3 -> + case happyOutTok happy_x_4 of { happy_var_4 -> + happyIn15+ (InstStepOrTags (combineSrcSpans (lexSpan happy_var_1) (lexSpan happy_var_4)) (lexStr happy_var_1) happy_var_3+ ) `HappyStk` happyRest}}}++happyReduce_42 = happySpecReduce_3 11# happyReduction_42+happyReduction_42 happy_x_3+ happy_x_2+ happy_x_1+ = case happyOutTok happy_x_1 of { happy_var_1 -> + case happyOut18 happy_x_2 of { happy_var_2 -> + case happyOutTok happy_x_3 of { happy_var_3 -> + happyIn15+ (InstTagCol (combineSrcSpans (lexSpan happy_var_1) (lexSpan happy_var_3)) (lexStr happy_var_2) []+ )}}}++happyReduce_43 = happySpecReduce_3 11# happyReduction_43+happyReduction_43 happy_x_3+ happy_x_2+ happy_x_1+ = case happyOutTok happy_x_1 of { happy_var_1 -> + case happyOut18 happy_x_2 of { happy_var_2 -> + case happyOutTok happy_x_3 of { happy_var_3 -> + happyIn15+ (InstStepCol (combineSrcSpans (lexSpan happy_var_1) (lexSpan happy_var_3)) (lexStr happy_var_2) []+ )}}}++happyReduce_44 = happySpecReduce_3 11# happyReduction_44+happyReduction_44 happy_x_3+ happy_x_2+ happy_x_1+ = case happyOutTok happy_x_1 of { happy_var_1 -> + case happyOut18 happy_x_2 of { happy_var_2 -> + case happyOutTok happy_x_3 of { happy_var_3 -> + happyIn15+ (InstItemCol (combineSrcSpans (lexSpan happy_var_1) (lexSpan happy_var_3)) (lexStr happy_var_2) []+ )}}}++happyReduce_45 = happyReduce 5# 11# happyReduction_45+happyReduction_45 (happy_x_5 `HappyStk`+ happy_x_4 `HappyStk`+ happy_x_3 `HappyStk`+ happy_x_2 `HappyStk`+ happy_x_1 `HappyStk`+ happyRest)+ = case happyOutTok happy_x_1 of { happy_var_1 -> + case happyOut18 happy_x_2 of { happy_var_2 -> + case happyOut17 happy_x_4 of { happy_var_4 -> + case happyOutTok happy_x_5 of { happy_var_5 -> + happyIn15+ (InstTagCol (combineSrcSpans (lexSpan happy_var_1) (lexSpan happy_var_5)) (lexStr happy_var_2) happy_var_4+ ) `HappyStk` happyRest}}}}++happyReduce_46 = happyReduce 5# 11# happyReduction_46+happyReduction_46 (happy_x_5 `HappyStk`+ happy_x_4 `HappyStk`+ happy_x_3 `HappyStk`+ happy_x_2 `HappyStk`+ happy_x_1 `HappyStk`+ happyRest)+ = case happyOutTok happy_x_1 of { happy_var_1 -> + case happyOut18 happy_x_2 of { happy_var_2 -> + case happyOut16 happy_x_4 of { happy_var_4 -> + case happyOutTok happy_x_5 of { happy_var_5 -> + happyIn15+ (InstStepCol (combineSrcSpans (lexSpan happy_var_1) (lexSpan happy_var_5)) (lexStr happy_var_2) happy_var_4+ ) `HappyStk` happyRest}}}}++happyReduce_47 = happyReduce 5# 11# happyReduction_47+happyReduction_47 (happy_x_5 `HappyStk`+ happy_x_4 `HappyStk`+ happy_x_3 `HappyStk`+ happy_x_2 `HappyStk`+ happy_x_1 `HappyStk`+ happyRest)+ = case happyOutTok happy_x_1 of { happy_var_1 -> + case happyOut18 happy_x_2 of { happy_var_2 -> + case happyOut16 happy_x_4 of { happy_var_4 -> + case happyOutTok happy_x_5 of { happy_var_5 -> + happyIn15+ (InstItemCol (combineSrcSpans (lexSpan happy_var_1) (lexSpan happy_var_5)) (lexStr happy_var_2) happy_var_4+ ) `HappyStk` happyRest}}}}++happyReduce_48 = happySpecReduce_0 12# happyReduction_48+happyReduction_48 = happyIn16+ ([]+ )++happyReduce_49 = happySpecReduce_1 12# happyReduction_49+happyReduction_49 happy_x_1+ = case happyOut19 happy_x_1 of { happy_var_1 -> + happyIn16+ ([happy_var_1]+ )}++happyReduce_50 = happySpecReduce_3 12# happyReduction_50+happyReduction_50 happy_x_3+ happy_x_2+ happy_x_1+ = case happyOut19 happy_x_1 of { happy_var_1 -> + case happyOut16 happy_x_3 of { happy_var_3 -> + happyIn16+ (happy_var_1 : happy_var_3+ )}}++happyReduce_51 = happySpecReduce_0 13# happyReduction_51+happyReduction_51 = happyIn17+ ([]+ )++happyReduce_52 = happySpecReduce_1 13# happyReduction_52+happyReduction_52 happy_x_1+ = case happyOutTok happy_x_1 of { happy_var_1 -> + happyIn17+ ([Var (lexSpan happy_var_1) (tAL happy_var_1)]+ )}++happyReduce_53 = happySpecReduce_3 13# happyReduction_53+happyReduction_53 happy_x_3+ happy_x_2+ happy_x_1+ = case happyOutTok happy_x_1 of { happy_var_1 -> + case happyOut17 happy_x_3 of { happy_var_3 -> + happyIn17+ (Var (lexSpan happy_var_1) (tAL happy_var_1) : happy_var_3+ )}}++happyReduce_54 = happySpecReduce_1 14# happyReduction_54+happyReduction_54 happy_x_1+ = case happyOutTok happy_x_1 of { happy_var_1 -> + happyIn18+ (happy_var_1+ )}++happyReduce_55 = happySpecReduce_1 14# happyReduction_55+happyReduction_55 happy_x_1+ = case happyOutTok happy_x_1 of { happy_var_1 -> + happyIn18+ (parseErrorSDoc (lexSpan happy_var_1) $ text "Keyword 'tags' used incorrectly."+ )}++happyReduce_56 = happySpecReduce_1 14# happyReduction_56+happyReduction_56 happy_x_1+ = case happyOutTok happy_x_1 of { happy_var_1 -> + happyIn18+ (parseErrorSDoc (lexSpan happy_var_1) $ text "Keyword 'items' used incorrectly."+ )}++happyReduce_57 = happySpecReduce_1 14# happyReduction_57+happyReduction_57 happy_x_1+ = case happyOutTok happy_x_1 of { happy_var_1 -> + happyIn18+ (parseErrorSDoc (lexSpan happy_var_1) $ text "Keyword 'reductions' used incorrectly."+ )}++happyReduce_58 = happySpecReduce_1 14# happyReduction_58+happyReduction_58 happy_x_1+ = case happyOutTok happy_x_1 of { happy_var_1 -> + happyIn18+ (parseErrorSDoc (lexSpan happy_var_1) $ text "Keyword 'steps' used incorrectly."+ )}++happyReduce_59 = happySpecReduce_1 14# happyReduction_59+happyReduction_59 happy_x_1+ = case happyOutTok happy_x_1 of { happy_var_1 -> + happyIn18+ (parseErrorSDoc (lexSpan happy_var_1) $ text "Keyword 'dense' used incorrectly."+ )}++happyReduce_60 = happySpecReduce_1 14# happyReduction_60+happyReduction_60 happy_x_1+ = case happyOutTok happy_x_1 of { happy_var_1 -> + happyIn18+ (parseErrorSDoc (lexSpan happy_var_1) $ text "Keyword 'prescribes' used incorrectly."+ )}++happyReduce_61 = happySpecReduce_1 14# happyReduction_61+happyReduction_61 happy_x_1+ = case happyOutTok happy_x_1 of { happy_var_1 -> + happyIn18+ (parseErrorSDoc (lexSpan happy_var_1) $ text "Keyword 'constrain' used incorrectly."+ )}++happyReduce_62 = happySpecReduce_1 14# happyReduction_62+happyReduction_62 happy_x_1+ = case happyOutTok happy_x_1 of { happy_var_1 -> + happyIn18+ (parseErrorSDoc (lexSpan happy_var_1) $ text "Keyword 'module' used incorrectly."+ )}++happyReduce_63 = happySpecReduce_1 15# happyReduction_63+happyReduction_63 happy_x_1+ = case happyOutTok happy_x_1 of { happy_var_1 -> + happyIn19+ (Var (lexSpan happy_var_1) (tAL happy_var_1)+ )}++happyReduce_64 = happySpecReduce_1 15# happyReduction_64+happyReduction_64 happy_x_1+ = case happyOutTok happy_x_1 of { happy_var_1 -> + happyIn19+ (Var (lexSpan happy_var_1) (tAL happy_var_1)+ )}++happyReduce_65 = happySpecReduce_1 15# happyReduction_65+happyReduction_65 happy_x_1+ = case happyOutTok happy_x_1 of { happy_var_1 -> + happyIn19+ (Lit (lexSpan happy_var_1) (LitInt $ read (lexStr happy_var_1))+ )}++happyReduce_66 = happySpecReduce_3 15# happyReduction_66+happyReduction_66 happy_x_3+ happy_x_2+ happy_x_1+ = case happyOut19 happy_x_2 of { happy_var_2 -> + happyIn19+ (happy_var_2+ )}++happyReduce_67 = happyReduce 4# 15# happyReduction_67+happyReduction_67 (happy_x_4 `HappyStk`+ happy_x_3 `HappyStk`+ happy_x_2 `HappyStk`+ happy_x_1 `HappyStk`+ happyRest)+ = case happyOutTok happy_x_1 of { happy_var_1 -> + case happyOut16 happy_x_3 of { happy_var_3 -> + happyIn19+ (App (combineSrcSpans (lexSpan happy_var_1) (getDecor (last happy_var_3)))+ (Var (lexSpan happy_var_1) (tAL happy_var_1)) happy_var_3+ ) `HappyStk` happyRest}}++happyReduce_68 = happySpecReduce_3 15# happyReduction_68+happyReduction_68 happy_x_3+ happy_x_2+ happy_x_1+ = case happyOut19 happy_x_1 of { happy_var_1 -> + case happyOut19 happy_x_3 of { happy_var_3 -> + happyIn19+ (App (combExpSpans happy_var_1 happy_var_3) (Var (combineSrcSpans (getDecor happy_var_1) (getDecor happy_var_3)) (toAtom "+")) [happy_var_1, happy_var_3]+ )}}++happyReduce_69 = happySpecReduce_3 15# happyReduction_69+happyReduction_69 happy_x_3+ happy_x_2+ happy_x_1+ = case happyOut19 happy_x_1 of { happy_var_1 -> + case happyOut19 happy_x_3 of { happy_var_3 -> + happyIn19+ (App (combExpSpans happy_var_1 happy_var_3) (Var (combineSrcSpans (getDecor happy_var_1) (getDecor happy_var_3)) (toAtom "-")) [happy_var_1, happy_var_3]+ )}}++happyReduce_70 = happySpecReduce_3 15# happyReduction_70+happyReduction_70 happy_x_3+ happy_x_2+ happy_x_1+ = case happyOut19 happy_x_1 of { happy_var_1 -> + case happyOut19 happy_x_3 of { happy_var_3 -> + happyIn19+ (App (combExpSpans happy_var_1 happy_var_3) (Var (combineSrcSpans (getDecor happy_var_1) (getDecor happy_var_3)) (toAtom "*")) [happy_var_1, happy_var_3]+ )}}++happyReduce_71 = happySpecReduce_3 15# happyReduction_71+happyReduction_71 happy_x_3+ happy_x_2+ happy_x_1+ = case happyOut19 happy_x_1 of { happy_var_1 -> + case happyOut19 happy_x_3 of { happy_var_3 -> + happyIn19+ (App (combExpSpans happy_var_1 happy_var_3) (Var (combineSrcSpans (getDecor happy_var_1) (getDecor happy_var_3)) (toAtom "/")) [happy_var_1, happy_var_3]+ )}}++happyReduce_72 = happySpecReduce_3 15# happyReduction_72+happyReduction_72 happy_x_3+ happy_x_2+ happy_x_1+ = case happyOut19 happy_x_1 of { happy_var_1 -> + case happyOut19 happy_x_3 of { happy_var_3 -> + happyIn19+ (App (combExpSpans happy_var_1 happy_var_3) (Var (combineSrcSpans (getDecor happy_var_1) (getDecor happy_var_3)) (toAtom "<")) [happy_var_1, happy_var_3]+ )}}++happyReduce_73 = happySpecReduce_3 15# happyReduction_73+happyReduction_73 happy_x_3+ happy_x_2+ happy_x_1+ = case happyOut19 happy_x_1 of { happy_var_1 -> + case happyOut19 happy_x_3 of { happy_var_3 -> + happyIn19+ (App (combExpSpans happy_var_1 happy_var_3) (Var (combineSrcSpans (getDecor happy_var_1) (getDecor happy_var_3)) (toAtom ">")) [happy_var_1, happy_var_3]+ )}}++happyReduce_74 = happySpecReduce_3 15# happyReduction_74+happyReduction_74 happy_x_3+ happy_x_2+ happy_x_1+ = case happyOut19 happy_x_1 of { happy_var_1 -> + case happyOutTok happy_x_2 of { happy_var_2 -> + case happyOut19 happy_x_3 of { happy_var_3 -> + happyIn19+ (App (combExpSpans happy_var_1 happy_var_3) (Var (combineSrcSpans (getDecor happy_var_1) (getDecor happy_var_3)) (tAL happy_var_2)) [happy_var_1, happy_var_3]+ )}}}++happyReduce_75 = happySpecReduce_1 16# happyReduction_75+happyReduction_75 happy_x_1+ = case happyOutTok happy_x_1 of { happy_var_1 -> + happyIn20+ (TSym (toAtom $ lexStr happy_var_1)+ )}++happyReduce_76 = happySpecReduce_2 16# happyReduction_76+happyReduction_76 happy_x_2+ happy_x_1+ = case happyOut20 happy_x_2 of { happy_var_2 -> + happyIn20+ (TDense happy_var_2+ )}++happyReduce_77 = happySpecReduce_2 16# happyReduction_77+happyReduction_77 happy_x_2+ happy_x_1+ = case happyOut20 happy_x_1 of { happy_var_1 -> + happyIn20+ (TPtr happy_var_1+ )}++happyReduce_78 = happySpecReduce_3 16# happyReduction_78+happyReduction_78 happy_x_3+ happy_x_2+ happy_x_1+ = case happyOut21 happy_x_2 of { happy_var_2 -> + happyIn20+ (TTuple happy_var_2+ )}++happyReduce_79 = happyReduce 4# 16# happyReduction_79+happyReduction_79 (happy_x_4 `HappyStk`+ happy_x_3 `HappyStk`+ happy_x_2 `HappyStk`+ happy_x_1 `HappyStk`+ happyRest)+ = case happyOut21 happy_x_3 of { happy_var_3 -> + happyIn20+ (TTuple happy_var_3+ ) `HappyStk` happyRest}++happyReduce_80 = happySpecReduce_0 17# happyReduction_80+happyReduction_80 = happyIn21+ ([]+ )++happyReduce_81 = happySpecReduce_1 17# happyReduction_81+happyReduction_81 happy_x_1+ = case happyOut20 happy_x_1 of { happy_var_1 -> + happyIn21+ ([happy_var_1]+ )}++happyReduce_82 = happySpecReduce_3 17# happyReduction_82+happyReduction_82 happy_x_3+ happy_x_2+ happy_x_1+ = case happyOut20 happy_x_1 of { happy_var_1 -> + case happyOut21 happy_x_3 of { happy_var_3 -> + happyIn21+ (happy_var_1 : happy_var_3+ )}}++happyNewToken action sts stk [] =+ happyDoAction 33# notHappyAtAll action sts stk []++happyNewToken action sts stk (tk:tks) =+ let cont i = happyDoAction i tk action sts stk tks in+ case tk of {+ L _ LVarId "tuple" -> cont 1#;+ L _ LVarId _ -> cont 2#;+ L _ LQVarId _ -> cont 3#;+ L _ LInteger _ -> cont 4#;+ L _ LReservedOp "->" -> cont 5#;+ L _ LReservedOp "<-" -> cont 6#;+ L _ LReservedOp "::" -> cont 7#;+ L _ LSpecial ":" -> cont 8#;+ L _ LSpecial "(" -> cont 9#;+ L _ LSpecial ")" -> cont 10#;+ L _ LSpecial "[" -> cont 11#;+ L _ LSpecial "]" -> cont 12#;+ L _ LSpecial ";" -> cont 13#;+ L _ LSpecial "," -> cont 14#;+ L _ LReservedOp "<" -> cont 15#;+ L _ LReservedOp ">" -> cont 16#;+ L _ LVarOp "=" -> cont 17#;+ L _ LVarOp "+" -> cont 18#;+ L _ LVarOp "-" -> cont 19#;+ L _ LSpecial "*" -> cont 20#;+ L _ LVarOp "/" -> cont 21#;+ L _ LVarOp _ -> cont 22#;+ L _ LReservedId "module" -> cont 23#;+ L _ LReservedId "tags" -> cont 24#;+ L _ LReservedId "items" -> cont 25#;+ L _ LReservedId "steps" -> cont 26#;+ L _ LReservedId "reductions" -> cont 27#;+ L _ LReservedId "dense" -> cont 28#;+ L _ LReservedId "prescribes" -> cont 29#;+ L _ LReservedId "type" -> cont 30#;+ L _ LReservedId "constrain" -> cont 31#;+ L _ LEOF _ -> cont 32#;+ _ -> happyError' (tk:tks)+ }++happyError_ tk tks = happyError' (tk:tks)++newtype HappyIdentity a = HappyIdentity a+happyIdentity = HappyIdentity+happyRunIdentity (HappyIdentity a) = a++instance Monad HappyIdentity where+ return = HappyIdentity+ (HappyIdentity p) >>= q = q p++happyThen :: () => HappyIdentity a -> (a -> HappyIdentity b) -> HappyIdentity b+happyThen = (>>=)+happyReturn :: () => a -> HappyIdentity a+happyReturn = (return)+happyThen1 m k tks = (>>=) m (\a -> k a tks)+happyReturn1 :: () => a -> b -> HappyIdentity a+happyReturn1 = \a tks -> (return) a+happyError' :: () => [(Lexeme)] -> HappyIdentity a+happyError' = HappyIdentity . happyError++parse_cnc tks = happyRunIdentity happySomeParser where+ happySomeParser = happyThen (happyParse 0# tks) (\x -> happyReturn (happyOut4 x))++happySeq = happyDontSeq+++-- Combine two lexical tokens for a source span:+cLL a b = (lexSpan a) `combineSrcSpans` (lexSpan b)+-- more obscure, combine two tokens and the first (if it exists) of a list:+cLLS a b c = combineSrcSpans (lexSpan a) $ combineSrcSpans b (getDecorLs c)++getDecorLs [] = srcLocSpan noSrcLoc+getDecorLs (h:t) = getDecor h+++-- All parsers must declair this function, which is called when an error+-- is detected. Note that currently we do no error recovery.+happyError :: [Lexeme] -> a++happyError [] = error "Parse error. Strange - it's not before any token that I know of..."+happyError ls =+ let loc = lexLoc $ head ls in+ error$ "Parse error before token at location : \n " +++ show (pPrint loc) +++ (if srcColumn loc <= 1+ then "\n(An error at the beginning of the line like this could be a missing semi-colon on the previous line.)\n"+ else "")++parseErrorSDoc span doc =+ error $ show $ text "\n\nPARSE ERROR!\n " <> doc $$+ text "At location: " <> pPrint span++-- Now we declare the datastructure that we are parsing.++runCncParser :: String -> String -> [PStatement SrcSpan]+runCncParser file str =+ let notcomment = filter (not . is_comment) $ scan_to_list str in++ -- FIXME:+ -- Here's a hack that's a bit ineffecient. We POST-FACTO put the right filename in the+ -- sourceloc decorations. It would be better to do it right the first time.+ --+ -- NOTE [2010.07.23] This has another problem. Parse errors will say "unknown file".+ -- I guess I need to thread through a reader monad.+ map (mapDecor (srcSpanSetFileName file)) $+ -- For now filter out comments before parsing:+ if null notcomment+ then error "ERROR: Specification file contains no CnC statements!"+ else parse_cnc $ notcomment++is_comment ( L _ LComment _ ) = True+is_comment _ = False++lexStr :: Lexeme -> String+lexStr (L _ _ str) = str++tAL = toAtom . lexStr++lexLoc :: Lexeme -> SrcLoc+lexLoc (L (AlexPn n l c) _ _) = (SrcLoc "" l c)++lexSpan :: Lexeme -> SrcSpan+-- [2010.07.23] We can do a little better by looking at the length of+-- the string and stretching the src location to include all of it.+-- DANGER, we assume that Lexemes stay on one line!! (not true of multiline comments)+lexSpan (L (AlexPn n l c) _ str) =+ let start = mkSrcLoc "" l c+ end = mkSrcLoc "" l (c + length str)+ in srcLocSpan start `combineSrcSpans` srcLocSpan end++-- Not a span, just a single point:+--lexPointSpan (L (AlexPn n l c) _ _) = srcLocSpan (SrcLoc "unknownfile" l c)+lexPointSpan = srcLocSpan . lexLoc++-- Combine the spans in two expressions.+combExpSpans e1 e2 = combineSrcSpans (getDecor e1) (getDecor e2)++quit = print "runCnc failed\n"+{-# LINE 1 "templates/GenericTemplate.hs" #-}+{-# LINE 1 "templates/GenericTemplate.hs" #-}+{-# LINE 1 "<built-in>" #-}+{-# LINE 1 "<command line>" #-}+{-# LINE 1 "templates/GenericTemplate.hs" #-}+-- Id: GenericTemplate.hs,v 1.26 2005/01/14 14:47:22 simonmar Exp ++{-# LINE 30 "templates/GenericTemplate.hs" #-}+++data Happy_IntList = HappyCons Happy_GHC_Exts.Int# Happy_IntList++++++{-# LINE 51 "templates/GenericTemplate.hs" #-}++{-# LINE 61 "templates/GenericTemplate.hs" #-}++{-# LINE 70 "templates/GenericTemplate.hs" #-}++infixr 9 `HappyStk`+data HappyStk a = HappyStk a (HappyStk a)++-----------------------------------------------------------------------------+-- starting the parse++happyParse start_state = happyNewToken start_state notHappyAtAll notHappyAtAll++-----------------------------------------------------------------------------+-- Accepting the parse++-- If the current token is 0#, it means we've just accepted a partial+-- parse (a %partial parser). We must ignore the saved token on the top of+-- the stack in this case.+happyAccept 0# tk st sts (_ `HappyStk` ans `HappyStk` _) =+ happyReturn1 ans+happyAccept j tk st sts (HappyStk ans _) = + (happyTcHack j (happyTcHack st)) (happyReturn1 ans)++-----------------------------------------------------------------------------+-- Arrays only: do the next action++++happyDoAction i tk st+ = {- nothing -}+++ case action of+ 0# -> {- nothing -}+ happyFail i tk st+ -1# -> {- nothing -}+ happyAccept i tk st+ n | (n Happy_GHC_Exts.<# (0# :: Happy_GHC_Exts.Int#)) -> {- nothing -}++ (happyReduceArr Happy_Data_Array.! rule) i tk st+ where rule = (Happy_GHC_Exts.I# ((Happy_GHC_Exts.negateInt# ((n Happy_GHC_Exts.+# (1# :: Happy_GHC_Exts.Int#))))))+ n -> {- nothing -}+++ happyShift new_state i tk st+ where !(new_state) = (n Happy_GHC_Exts.-# (1# :: Happy_GHC_Exts.Int#))+ where !(off) = indexShortOffAddr happyActOffsets st+ !(off_i) = (off Happy_GHC_Exts.+# i)+ check = if (off_i Happy_GHC_Exts.>=# (0# :: Happy_GHC_Exts.Int#))+ then (indexShortOffAddr happyCheck off_i Happy_GHC_Exts.==# i)+ else False+ !(action)+ | check = indexShortOffAddr happyTable off_i+ | otherwise = indexShortOffAddr happyDefActions st++{-# LINE 130 "templates/GenericTemplate.hs" #-}+++indexShortOffAddr (HappyA# arr) off =+ Happy_GHC_Exts.narrow16Int# i+ where+ !i = Happy_GHC_Exts.word2Int# (Happy_GHC_Exts.or# (Happy_GHC_Exts.uncheckedShiftL# high 8#) low)+ !high = Happy_GHC_Exts.int2Word# (Happy_GHC_Exts.ord# (Happy_GHC_Exts.indexCharOffAddr# arr (off' Happy_GHC_Exts.+# 1#)))+ !low = Happy_GHC_Exts.int2Word# (Happy_GHC_Exts.ord# (Happy_GHC_Exts.indexCharOffAddr# arr off'))+ !off' = off Happy_GHC_Exts.*# 2#++++++data HappyAddr = HappyA# Happy_GHC_Exts.Addr#+++++-----------------------------------------------------------------------------+-- HappyState data type (not arrays)++{-# LINE 163 "templates/GenericTemplate.hs" #-}++-----------------------------------------------------------------------------+-- Shifting a token++happyShift new_state 0# tk st sts stk@(x `HappyStk` _) =+ let !(i) = (case Happy_GHC_Exts.unsafeCoerce# x of { (Happy_GHC_Exts.I# (i)) -> i }) in+-- trace "shifting the error token" $+ happyDoAction i tk new_state (HappyCons (st) (sts)) (stk)++happyShift new_state i tk st sts stk =+ happyNewToken new_state (HappyCons (st) (sts)) ((happyInTok (tk))`HappyStk`stk)++-- happyReduce is specialised for the common cases.++happySpecReduce_0 i fn 0# tk st sts stk+ = happyFail 0# tk st sts stk+happySpecReduce_0 nt fn j tk st@((action)) sts stk+ = happyGoto nt j tk st (HappyCons (st) (sts)) (fn `HappyStk` stk)++happySpecReduce_1 i fn 0# tk st sts stk+ = happyFail 0# tk st sts stk+happySpecReduce_1 nt fn j tk _ sts@((HappyCons (st@(action)) (_))) (v1`HappyStk`stk')+ = let r = fn v1 in+ happySeq r (happyGoto nt j tk st sts (r `HappyStk` stk'))++happySpecReduce_2 i fn 0# tk st sts stk+ = happyFail 0# tk st sts stk+happySpecReduce_2 nt fn j tk _ (HappyCons (_) (sts@((HappyCons (st@(action)) (_))))) (v1`HappyStk`v2`HappyStk`stk')+ = let r = fn v1 v2 in+ happySeq r (happyGoto nt j tk st sts (r `HappyStk` stk'))++happySpecReduce_3 i fn 0# tk st sts stk+ = happyFail 0# tk st sts stk+happySpecReduce_3 nt fn j tk _ (HappyCons (_) ((HappyCons (_) (sts@((HappyCons (st@(action)) (_))))))) (v1`HappyStk`v2`HappyStk`v3`HappyStk`stk')+ = let r = fn v1 v2 v3 in+ happySeq r (happyGoto nt j tk st sts (r `HappyStk` stk'))++happyReduce k i fn 0# tk st sts stk+ = happyFail 0# tk st sts stk+happyReduce k nt fn j tk st sts stk+ = case happyDrop (k Happy_GHC_Exts.-# (1# :: Happy_GHC_Exts.Int#)) sts of+ sts1@((HappyCons (st1@(action)) (_))) ->+ let r = fn stk in -- it doesn't hurt to always seq here...+ happyDoSeq r (happyGoto nt j tk st1 sts1 r)++happyMonadReduce k nt fn 0# tk st sts stk+ = happyFail 0# tk st sts stk+happyMonadReduce k nt fn j tk st sts stk =+ happyThen1 (fn stk tk) (\r -> happyGoto nt j tk st1 sts1 (r `HappyStk` drop_stk))+ where !(sts1@((HappyCons (st1@(action)) (_)))) = happyDrop k (HappyCons (st) (sts))+ drop_stk = happyDropStk k stk++happyMonad2Reduce k nt fn 0# tk st sts stk+ = happyFail 0# tk st sts stk+happyMonad2Reduce k nt fn j tk st sts stk =+ happyThen1 (fn stk tk) (\r -> happyNewToken new_state sts1 (r `HappyStk` drop_stk))+ where !(sts1@((HappyCons (st1@(action)) (_)))) = happyDrop k (HappyCons (st) (sts))+ drop_stk = happyDropStk k stk++ !(off) = indexShortOffAddr happyGotoOffsets st1+ !(off_i) = (off Happy_GHC_Exts.+# nt)+ !(new_state) = indexShortOffAddr happyTable off_i+++++happyDrop 0# l = l+happyDrop n (HappyCons (_) (t)) = happyDrop (n Happy_GHC_Exts.-# (1# :: Happy_GHC_Exts.Int#)) t++happyDropStk 0# l = l+happyDropStk n (x `HappyStk` xs) = happyDropStk (n Happy_GHC_Exts.-# (1#::Happy_GHC_Exts.Int#)) xs++-----------------------------------------------------------------------------+-- Moving to a new state after a reduction+++happyGoto nt j tk st = + {- nothing -}+ happyDoAction j tk new_state+ where !(off) = indexShortOffAddr happyGotoOffsets st+ !(off_i) = (off Happy_GHC_Exts.+# nt)+ !(new_state) = indexShortOffAddr happyTable off_i+++++-----------------------------------------------------------------------------+-- Error recovery (0# is the error token)++-- parse error if we are in recovery and we fail again+happyFail 0# tk old_st _ stk =+-- trace "failing" $ + happyError_ tk++{- We don't need state discarding for our restricted implementation of+ "error". In fact, it can cause some bogus parses, so I've disabled it+ for now --SDM++-- discard a state+happyFail 0# tk old_st (HappyCons ((action)) (sts)) + (saved_tok `HappyStk` _ `HappyStk` stk) =+-- trace ("discarding state, depth " ++ show (length stk)) $+ happyDoAction 0# tk action sts ((saved_tok`HappyStk`stk))+-}++-- Enter error recovery: generate an error token,+-- save the old token and carry on.+happyFail i tk (action) sts stk =+-- trace "entering error recovery" $+ happyDoAction 0# tk action sts ( (Happy_GHC_Exts.unsafeCoerce# (Happy_GHC_Exts.I# (i))) `HappyStk` stk)++-- Internal happy errors:++notHappyAtAll = error "Internal Happy error\n"++-----------------------------------------------------------------------------+-- Hack to get the typechecker to accept our action functions+++happyTcHack :: Happy_GHC_Exts.Int# -> a -> a+happyTcHack x y = y+{-# INLINE happyTcHack #-}+++-----------------------------------------------------------------------------+-- Seq-ing. If the --strict flag is given, then Happy emits +-- happySeq = happyDoSeq+-- otherwise it emits+-- happySeq = happyDontSeq++happyDoSeq, happyDontSeq :: a -> b -> b+happyDoSeq a b = a `seq` b+happyDontSeq a b = b++-----------------------------------------------------------------------------+-- Don't inline any functions from the template. GHC has a nasty habit+-- of deciding to inline happyGoto everywhere, which increases the size of+-- the generated parser quite a bit.+++{-# NOINLINE happyDoAction #-}+{-# NOINLINE happyTable #-}+{-# NOINLINE happyCheck #-}+{-# NOINLINE happyActOffsets #-}+{-# NOINLINE happyGotoOffsets #-}+{-# NOINLINE happyDefActions #-}++{-# NOINLINE happyShift #-}+{-# NOINLINE happySpecReduce_0 #-}+{-# NOINLINE happySpecReduce_1 #-}+{-# NOINLINE happySpecReduce_2 #-}+{-# NOINLINE happySpecReduce_3 #-}+{-# NOINLINE happyReduce #-}+{-# NOINLINE happyMonadReduce #-}+{-# NOINLINE happyGoto #-}+{-# NOINLINE happyFail #-}++-- end of Happy Template.
+ dist/build/cnc/cnc-tmp/Intel/Cnc/Spec/CncLexer.hs view
@@ -0,0 +1,543 @@+{-# OPTIONS -fglasgow-exts -cpp #-}+{-# LINE 2 "Intel/Cnc/Spec/CncLexer.x" #-}++module Intel.Cnc.Spec.CncLexer where+-- import Debug.Trace++#if __GLASGOW_HASKELL__ >= 603+#include "ghcconfig.h"+#elif defined(__GLASGOW_HASKELL__)+#include "config.h"+#endif+#if __GLASGOW_HASKELL__ >= 503+import Data.Array+import Data.Char (ord)+import Data.Array.Base (unsafeAt)+#else+import Array+import Char (ord)+#endif+#if __GLASGOW_HASKELL__ >= 503+import GHC.Exts+#else+import GlaExts+#endif+{-# LINE 1 "templates/wrappers.hs" #-}+{-# LINE 1 "templates/wrappers.hs" #-}+{-# LINE 1 "<built-in>" #-}+{-# LINE 1 "<command line>" #-}+{-# LINE 1 "templates/wrappers.hs" #-}+-- -----------------------------------------------------------------------------+-- Alex wrapper code.+--+-- This code is in the PUBLIC DOMAIN; you may copy it freely and use+-- it for any purpose whatsoever.++{-# LINE 18 "templates/wrappers.hs" #-}++-- -----------------------------------------------------------------------------+-- The input type+++type AlexInput = (AlexPosn, -- current position,+ Char, -- previous char+ String) -- current input string++alexInputPrevChar :: AlexInput -> Char+alexInputPrevChar (p,c,s) = c++alexGetChar :: AlexInput -> Maybe (Char,AlexInput)+alexGetChar (p,c,[]) = Nothing+alexGetChar (p,_,(c:s)) = let p' = alexMove p c in p' `seq`+ Just (c, (p', c, s))+++{-# LINE 51 "templates/wrappers.hs" #-}++-- -----------------------------------------------------------------------------+-- Token positions++-- `Posn' records the location of a token in the input text. It has three+-- fields: the address (number of chacaters preceding the token), line number+-- and column of a token within the file. `start_pos' gives the position of the+-- start of the file and `eof_pos' a standard encoding for the end of file.+-- `move_pos' calculates the new position after traversing a given character,+-- assuming the usual eight character tab stops.+++data AlexPosn = AlexPn !Int !Int !Int+ deriving (Eq,Show)++alexStartPos :: AlexPosn+alexStartPos = AlexPn 0 1 1++alexMove :: AlexPosn -> Char -> AlexPosn+alexMove (AlexPn a l c) '\t' = AlexPn (a+1) l (((c+7) `div` 8)*8+1)+alexMove (AlexPn a l c) '\n' = AlexPn (a+1) (l+1) 1+alexMove (AlexPn a l c) _ = AlexPn (a+1) l (c+1)+++-- -----------------------------------------------------------------------------+-- Default monad+++data AlexState = AlexState {+ alex_pos :: !AlexPosn, -- position at current input location+ alex_inp :: String, -- the current input+ alex_chr :: !Char, -- the character before the input+ alex_scd :: !Int -- the current startcode++++ }++-- Compile with -funbox-strict-fields for best results!++runAlex :: String -> Alex a -> Either String a+runAlex input (Alex f) + = case f (AlexState {alex_pos = alexStartPos,+ alex_inp = input, + alex_chr = '\n',++++ alex_scd = 0}) of Left msg -> Left msg+ Right ( _, a ) -> Right a++newtype Alex a = Alex { unAlex :: AlexState -> Either String (AlexState, a) }++instance Monad Alex where+ m >>= k = Alex $ \s -> case unAlex m s of + Left msg -> Left msg+ Right (s',a) -> unAlex (k a) s'+ return a = Alex $ \s -> Right (s,a)++alexGetInput :: Alex AlexInput+alexGetInput+ = Alex $ \s@AlexState{alex_pos=pos,alex_chr=c,alex_inp=inp} -> + Right (s, (pos,c,inp))++alexSetInput :: AlexInput -> Alex ()+alexSetInput (pos,c,inp)+ = Alex $ \s -> case s{alex_pos=pos,alex_chr=c,alex_inp=inp} of+ s@(AlexState{}) -> Right (s, ())++alexError :: String -> Alex a+alexError message = Alex $ \s -> Left message++alexGetStartCode :: Alex Int+alexGetStartCode = Alex $ \s@AlexState{alex_scd=sc} -> Right (s, sc)++alexSetStartCode :: Int -> Alex ()+alexSetStartCode sc = Alex $ \s -> Right (s{alex_scd=sc}, ())++alexMonadScan = do+ inp <- alexGetInput+ sc <- alexGetStartCode+ case alexScan inp sc of+ AlexEOF -> alexEOF+ AlexError inp' -> alexError "lexical error"+ AlexSkip inp' len -> do+ alexSetInput inp'+ alexMonadScan+ AlexToken inp' len action -> do+ alexSetInput inp'+ action inp len++-- -----------------------------------------------------------------------------+-- Useful token actions++type AlexAction result = AlexInput -> Int -> result++-- just ignore this token and scan another one+-- skip :: AlexAction result+skip input len = alexMonadScan++-- ignore this token, but set the start code to a new value+-- begin :: Int -> AlexAction result+begin code input len = do alexSetStartCode code; alexMonadScan++-- perform an action for this token, and set the start code to a new value+-- andBegin :: AlexAction result -> Int -> AlexAction result+(action `andBegin` code) input len = do alexSetStartCode code; action input len++-- token :: (String -> Int -> token) -> AlexAction token+token t input len = return (t input len)++++-- -----------------------------------------------------------------------------+-- Monad (with ByteString input)++{-# LINE 251 "templates/wrappers.hs" #-}+++-- -----------------------------------------------------------------------------+-- Basic wrapper++{-# LINE 273 "templates/wrappers.hs" #-}+++-- -----------------------------------------------------------------------------+-- Basic wrapper, ByteString version++{-# LINE 297 "templates/wrappers.hs" #-}++{-# LINE 322 "templates/wrappers.hs" #-}+++-- -----------------------------------------------------------------------------+-- Posn wrapper++-- Adds text positions to the basic model.++{-# LINE 339 "templates/wrappers.hs" #-}+++-- -----------------------------------------------------------------------------+-- Posn wrapper, ByteString version++{-# LINE 354 "templates/wrappers.hs" #-}+++-- -----------------------------------------------------------------------------+-- GScan wrapper++-- For compatibility with previous versions of Alex, and because we can.++alex_base :: AlexAddr+alex_base = AlexA# "\xf8\xff\xff\xff\x6e\x00\x00\x00\xe5\x00\x00\x00\xfc\xff\xff\xff\x0b\x01\x00\x00\x2e\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcd\xff\xff\xff\x4c\x01\x00\x00\x1c\x02\x00\x00\xec\x02\x00\x00\xbc\x03\x00\x00\x8c\x04\x00\x00\x5c\x05\x00\x00\x2c\x06\x00\x00\xfc\x06\x00\x00\xcc\x07\x00\x00\x9c\x08\x00\x00\x6c\x09\x00\x00\x3c\x0a\x00\x00\x0c\x0b\x00\x00\xdc\x0b\x00\x00\xac\x0c\x00\x00\x7c\x0d\x00\x00\x4c\x0e\x00\x00\x1c\x0f\x00\x00\xec\x0f\x00\x00\xbc\x10\x00\x00\x8c\x11\x00\x00\x5c\x12\x00\x00\x2c\x13\x00\x00\xfc\x13\x00\x00\xcc\x14\x00\x00\x9c\x15\x00\x00\x6c\x16\x00\x00\x3c\x17\x00\x00\x0c\x18\x00\x00\xdc\x18\x00\x00\xac\x19\x00\x00\x7c\x1a\x00\x00\x4c\x1b\x00\x00\x1c\x1c\x00\x00\xec\x1c\x00\x00\xbc\x1d\x00\x00\x8c\x1e\x00\x00\x5c\x1f\x00\x00\x2c\x20\x00\x00\xfc\x20\x00\x00\xcc\x21\x00\x00\x9c\x22\x00\x00\x6c\x23\x00\x00\x3c\x24\x00\x00\x0c\x25\x00\x00\xdc\x25\x00\x00\xac\x26\x00\x00\x7c\x27\x00\x00\x4c\x28\x00\x00\x1c\x29\x00\x00\xec\x29\x00\x00\xc5\x2a\x00\x00\x9e\x2b\x00\x00\x6e\x2c\x00\x00\x4d\x2d\x00\x00\x26\x2e\x00\x00\xff\x2e\x00\x00\xcf\x2f\x00\x00\xa8\x30\x00\x00\x81\x31\x00\x00\x51\x32\x00\x00\x21\x33\x00\x00\x21\x34\x00\x00\x00\x00\x00\x00\xc0\x34\x00\x00\xe3\x34\x00\x00\x06\x35\x00\x00\x29\x35\x00\x00\x4c\x35\x00\x00\x6f\x35\x00\x00\x92\x35\x00\x00\xb5\x35\x00\x00\xd8\x35\x00\x00\xfb\x35\x00\x00\x4c\x00\x00\x00\xd8\xff\xff\xff\x62\x00\x00\x00\x6c\x00\x00\x00\x76\x00\x00\x00\xe7\xff\xff\xff\xc8\x00\x00\x00\x00\x00\x00\x00\xec\xff\xff\xff\xee\xff\xff\xff\x68\x00\x00\x00\xe6\x00\x00\x00\x1a\x36\x00\x00\x51\x36\x00\x00\xca\xff\xff\xff\xcb\x00\x00\x00\x7e\x01\x00\x00\xbf\xff\xff\xff\xcf\x00\x00\x00\x39\x00\x00\x00\x35\x00\x00\x00\x3a\x00\x00\x00\x3f\x00\x00\x00\x4d\x00\x00\x00\x66\x00\x00\x00\xe1\x00\x00\x00\x5f\x00\x00\x00\x6f\x00\x00\x00\x60\x00\x00\x00\xbc\x00\x00\x00\xe9\x00\x00\x00\x71\x00\x00\x00\xc2\x00\x00\x00\x0c\x01\x00\x00\x84\x00\x00\x00\x69\x00\x00\x00\xb5\x00\x00\x00\xe7\x00\x00\x00\xc1\x00\x00\x00\xd5\x00\x00\x00\xd8\x00\x00\x00\xda\x00\x00\x00\xeb\x00\x00\x00\x00\x00\x00\x00\xb1\x36\x00\x00\xa9\x37\x00\x00\xa1\x38\x00\x00\x99\x39\x00\x00\x91\x3a\x00\x00\x48\x3b\x00\x00\x7f\x3b\x00\x00\xf0\x00\x00\x00\xf1\x00\x00\x00\x80\x01\x00\x00\xdb\x00\x00\x00\x02\x01\x00\x00\x11\x01\x00\x00\xee\x00\x00\x00\xe4\x00\x00\x00\xfa\x00\x00\x00\x09\x01\x00\x00\x01\x01\x00\x00\x1d\x01\x00\x00\xfc\x00\x00\x00\x08\x01\x00\x00\x03\x01\x00\x00\x22\x01\x00\x00\x14\x01\x00\x00\x2a\x01\x00\x00\x2f\x01\x00\x00\x45\x01\x00\x00\x26\x01\x00\x00\x2c\x01\x00\x00\x38\x01\x00\x00\x46\x01\x00\x00\x13\x01\x00\x00\x54\x01\x00\x00\x55\x01\x00\x00\x56\x01\x00\x00\x3f\x01\x00\x00\xfa\x01\x00\x00"#++alex_table :: AlexAddr+alex_table = AlexA# "\x00\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\xff\xff\x4a\x00\x56\x00\x56\x00\x56\x00\x56\x00\x56\x00\x56\x00\x56\x00\x56\x00\x56\x00\x56\x00\x59\x00\x5c\x00\x59\x00\x5c\x00\x5d\x00\x5d\x00\x01\x00\x53\x00\x81\x00\x53\x00\x53\x00\x53\x00\x53\x00\x49\x00\x07\x00\x07\x00\x07\x00\x53\x00\x07\x00\x50\x00\x53\x00\x05\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x0a\x00\x07\x00\x4c\x00\x53\x00\x4f\x00\x53\x00\x53\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x07\x00\x53\x00\x07\x00\x53\x00\x44\x00\x07\x00\x44\x00\x44\x00\x32\x00\x2a\x00\x44\x00\x12\x00\x44\x00\x44\x00\x19\x00\x44\x00\x44\x00\x44\x00\x10\x00\x44\x00\x44\x00\x3b\x00\x44\x00\x22\x00\x26\x00\x15\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x08\x00\x4b\x00\x09\x00\x53\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x5d\x00\x6a\x00\x69\x00\x5d\x00\x5d\x00\x5d\x00\x7b\x00\x67\x00\x01\x00\x5c\x00\x6b\x00\x5a\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x56\x00\x56\x00\x56\x00\x56\x00\x56\x00\x56\x00\x56\x00\x56\x00\x56\x00\x56\x00\x5d\x00\x5a\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x5d\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\xff\xff\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x5d\x00\x5d\x00\x5d\x00\x76\x00\x04\x00\x7f\x00\x04\x00\x04\x00\x04\x00\x04\x00\x77\x00\x5c\x00\x74\x00\x5d\x00\x04\x00\x5d\x00\x04\x00\x04\x00\x04\x00\xff\xff\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x63\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x6d\x00\x5d\x00\x5d\x00\x5d\x00\x79\x00\x5d\x00\x04\x00\x5d\x00\x04\x00\x04\x00\x04\x00\x04\x00\x9c\x00\x82\x00\x5d\x00\x82\x00\x04\x00\x5d\x00\x04\x00\x04\x00\x04\x00\x5d\x00\x82\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x04\x00\x82\x00\x04\x00\x82\x00\x82\x00\x88\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x90\x00\x82\x00\x82\x00\x54\x00\x82\x00\x54\x00\x54\x00\x54\x00\x54\x00\x9e\x00\x82\x00\x82\x00\x06\x00\x54\x00\x82\x00\x54\x00\x54\x00\x02\x00\x82\x00\x8f\x00\x8e\x00\x04\x00\x92\x00\x04\x00\xa0\x00\x8c\x00\x82\x00\x04\x00\x82\x00\x04\x00\x54\x00\x54\x00\x54\x00\x54\x00\x54\x00\x82\x00\x82\x00\x82\x00\x9b\x00\x44\x00\xa4\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x99\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x82\x00\x04\x00\x82\x00\x04\x00\x54\x00\x82\x00\x54\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x82\x00\x82\x00\x82\x00\x54\x00\x44\x00\x54\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x5d\x00\x00\x00\x82\x00\x00\x00\x00\x00\x00\x00\x5f\x00\x5d\x00\x84\x00\x82\x00\x00\x00\x66\x00\x7a\x00\x8b\x00\x9f\x00\x00\x00\x78\x00\x00\x00\x9d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa5\x00\xa5\x00\xa5\x00\xa5\x00\xa5\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x82\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x0b\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x0c\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x0d\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x0e\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x0f\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x0b\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x11\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x0b\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x13\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x14\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x3d\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x0b\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x16\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x17\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x18\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x0b\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x1a\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x1b\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x1c\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x1d\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x44\x00\x44\x00\x1e\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x1f\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x20\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x21\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x0b\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x23\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x24\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x25\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x0b\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x27\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x28\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x29\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x0b\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x2b\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x2c\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x2d\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x2e\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x2f\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x30\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x31\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x0b\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x33\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x44\x00\x34\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x35\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x36\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x44\x00\x44\x00\x37\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x38\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x39\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x3a\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x0b\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x3c\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x3f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x41\x00\x00\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3f\x00\x00\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x00\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x00\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x41\x00\x00\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3f\x00\x00\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x00\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x40\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x00\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x00\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x51\x00\x00\x00\x51\x00\x51\x00\x51\x00\x51\x00\x40\x00\x00\x00\x00\x00\x00\x00\x51\x00\x00\x00\x51\x00\x51\x00\x51\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x00\x00\x00\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x00\x00\x51\x00\x00\x00\x51\x00\x40\x00\x00\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x00\x00\x51\x00\x00\x00\x51\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x00\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x00\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x43\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x41\x00\x00\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x00\x00\x00\x00\x00\x00\x00\x00\x43\x00\x00\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x00\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x00\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x41\x00\x00\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x00\x00\x00\x00\x00\x00\x00\x00\x43\x00\x00\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x00\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x44\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x46\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x46\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x5b\x00\x00\x00\x5b\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x47\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\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\x5e\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x44\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5d\x00\x61\x00\x5d\x00\x5d\x00\x00\x00\x5d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5d\x00\x5d\x00\x5d\x00\x5d\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\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\x54\x00\x00\x00\x54\x00\x54\x00\x54\x00\x54\x00\x00\x00\x00\x00\x00\x00\x00\x00\x54\x00\x00\x00\x54\x00\x54\x00\x54\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x54\x00\x54\x00\x54\x00\x54\x00\x54\x00\x00\x00\x00\x00\x00\x00\x54\x00\x00\x00\x54\x00\x54\x00\x54\x00\x54\x00\x00\x00\x00\x00\x00\x00\x00\x00\x54\x00\x00\x00\x4d\x00\x54\x00\x54\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x54\x00\x00\x00\x54\x00\x54\x00\x54\x00\x54\x00\x54\x00\x54\x00\x00\x00\x00\x00\x00\x00\x54\x00\x00\x00\x54\x00\x54\x00\x54\x00\x54\x00\x00\x00\x00\x00\x00\x00\x00\x00\x54\x00\x00\x00\x54\x00\x54\x00\x54\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x54\x00\x00\x00\x54\x00\x54\x00\x00\x00\x54\x00\x54\x00\x54\x00\x54\x00\x54\x00\x54\x00\x00\x00\x00\x00\x00\x00\x54\x00\x00\x00\x54\x00\x54\x00\x54\x00\x54\x00\x00\x00\x00\x00\x00\x00\x00\x00\x54\x00\x00\x00\x54\x00\x54\x00\x54\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x54\x00\x00\x00\x54\x00\x54\x00\x00\x00\x54\x00\x54\x00\x54\x00\x54\x00\x54\x00\x54\x00\x00\x00\x00\x00\x00\x00\x54\x00\x00\x00\x54\x00\x54\x00\x54\x00\x54\x00\x00\x00\x00\x00\x00\x00\x00\x00\x54\x00\x00\x00\x54\x00\x54\x00\x54\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x54\x00\x00\x00\x54\x00\x54\x00\x00\x00\x54\x00\x54\x00\x54\x00\x54\x00\x54\x00\x54\x00\x00\x00\x00\x00\x00\x00\x54\x00\x00\x00\x54\x00\x54\x00\x54\x00\x54\x00\x00\x00\x00\x00\x00\x00\x00\x00\x54\x00\x00\x00\x54\x00\x54\x00\x54\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x54\x00\x00\x00\x54\x00\x54\x00\x00\x00\x54\x00\x54\x00\x54\x00\x4e\x00\x54\x00\x54\x00\x00\x00\x00\x00\x00\x00\x52\x00\x00\x00\x52\x00\x52\x00\x52\x00\x52\x00\x00\x00\x00\x00\x00\x00\x00\x00\x52\x00\x00\x00\x52\x00\x52\x00\x52\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x54\x00\x00\x00\x54\x00\x54\x00\x00\x00\x54\x00\x52\x00\x52\x00\x52\x00\x52\x00\x52\x00\x00\x00\x00\x00\x00\x00\x52\x00\x00\x00\x52\x00\x52\x00\x52\x00\x52\x00\x00\x00\x00\x00\x00\x00\x00\x00\x52\x00\x00\x00\x52\x00\x52\x00\x52\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x54\x00\x00\x00\x54\x00\x52\x00\x00\x00\x52\x00\x52\x00\x52\x00\x52\x00\x52\x00\x52\x00\x00\x00\x00\x00\x00\x00\x54\x00\x00\x00\x54\x00\x54\x00\x54\x00\x54\x00\x00\x00\x00\x00\x00\x00\x00\x00\x54\x00\x00\x00\x54\x00\x54\x00\x54\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x52\x00\x00\x00\x52\x00\x52\x00\x00\x00\x52\x00\x54\x00\x54\x00\x54\x00\x54\x00\x54\x00\x00\x00\x00\x00\x00\x00\x54\x00\x00\x00\x54\x00\x54\x00\x54\x00\x54\x00\x00\x00\x00\x00\x00\x00\x00\x00\x54\x00\x00\x00\x54\x00\x54\x00\x54\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x52\x00\x00\x00\x52\x00\x54\x00\x00\x00\x54\x00\x54\x00\x54\x00\x54\x00\x54\x00\x54\x00\x5d\x00\x00\x00\x00\x00\x00\x00\x5d\x00\x5d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x54\x00\x00\x00\x54\x00\x54\x00\x00\x00\x54\x00\x00\x00\x6c\x00\x6e\x00\x73\x00\x75\x00\x68\x00\x72\x00\x7c\x00\x6f\x00\x00\x00\x00\x00\x00\x00\x70\x00\x00\x00\x64\x00\x00\x00\x00\x00\x00\x00\x7d\x00\x65\x00\x00\x00\x7e\x00\x71\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5d\x00\x54\x00\x62\x00\x54\x00\x00\x00\x5d\x00\x5d\x00\x00\x00\x00\x00\x00\x00\x5d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5d\x00\x00\x00\x00\x00\x00\x00\x5d\x00\x00\x00\x5d\x00\x00\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\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\x83\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x86\x00\x00\x00\x00\x00\x00\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x00\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\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\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\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\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\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\x83\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x86\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\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\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\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\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\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\x83\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x86\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\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\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\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\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\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\x83\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x86\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\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\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\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\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\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\x83\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x85\x00\x85\x00\x85\x00\x85\x00\x85\x00\x85\x00\x85\x00\x85\x00\x85\x00\x85\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x86\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\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\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\xa5\x00\xa5\x00\xa5\x00\xa5\x00\xa5\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x00\x00\x82\x00\x00\x00\x00\x00\x00\x00\x82\x00\x82\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x85\x00\x85\x00\x85\x00\x85\x00\x85\x00\x85\x00\x85\x00\x85\x00\x85\x00\x85\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x91\x00\x93\x00\x98\x00\x9a\x00\x8d\x00\x97\x00\xa1\x00\x94\x00\x00\x00\x00\x00\x00\x00\x95\x00\x00\x00\x89\x00\x00\x00\x00\x00\x00\x00\xa2\x00\x8a\x00\x00\x00\xa3\x00\x96\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x82\x00\x00\x00\x87\x00\x00\x00\x00\x00\x82\x00\x82\x00\x00\x00\x00\x00\x00\x00\x82\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x82\x00\x00\x00\x00\x00\x00\x00\x82\x00\x00\x00\x82\x00\x00\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\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\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x00\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"#++alex_check :: AlexAddr+alex_check = AlexA# "\xff\xff\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0a\x00\x3a\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x2b\x00\x27\x00\x2d\x00\x27\x00\x4c\x00\x58\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x7b\x00\x7c\x00\x7d\x00\x7e\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x4d\x00\x4e\x00\x4f\x00\x54\x00\x4b\x00\x51\x00\x53\x00\x54\x00\x20\x00\x27\x00\x43\x00\x45\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x48\x00\x65\x00\x4c\x00\x54\x00\x54\x00\x46\x00\x45\x00\x4e\x00\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\x4b\x00\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\x0a\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x46\x00\x4e\x00\x43\x00\x43\x00\x21\x00\x45\x00\x23\x00\x24\x00\x25\x00\x26\x00\x41\x00\x27\x00\x4c\x00\x53\x00\x2b\x00\x42\x00\x2d\x00\x2e\x00\x2f\x00\x0a\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x55\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x45\x00\x58\x00\x53\x00\x42\x00\x41\x00\x53\x00\x21\x00\x53\x00\x23\x00\x24\x00\x25\x00\x26\x00\x41\x00\x58\x00\x53\x00\x51\x00\x2b\x00\x4c\x00\x2d\x00\x2e\x00\x2f\x00\x52\x00\x4c\x00\x31\x00\x32\x00\x33\x00\x34\x00\x5c\x00\x54\x00\x5e\x00\x42\x00\x4b\x00\x55\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x43\x00\x4c\x00\x46\x00\x21\x00\x54\x00\x23\x00\x24\x00\x25\x00\x26\x00\x41\x00\x43\x00\x54\x00\x2a\x00\x2b\x00\x58\x00\x2d\x00\x2e\x00\x2f\x00\x4d\x00\x4e\x00\x4f\x00\x7c\x00\x45\x00\x7e\x00\x53\x00\x54\x00\x52\x00\x5c\x00\x46\x00\x5e\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x45\x00\x53\x00\x4b\x00\x43\x00\x27\x00\x45\x00\x53\x00\x31\x00\x32\x00\x33\x00\x34\x00\x4e\x00\x4c\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x4e\x00\x7c\x00\x42\x00\x7e\x00\x5c\x00\x4c\x00\x5e\x00\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\x53\x00\x53\x00\x53\x00\x7c\x00\x5f\x00\x7e\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x49\x00\xff\xff\x49\x00\xff\xff\xff\xff\xff\xff\x4f\x00\x50\x00\x4f\x00\x50\x00\xff\xff\x54\x00\x55\x00\x54\x00\x55\x00\xff\xff\x59\x00\xff\xff\x59\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\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\x27\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x5c\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\x27\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\x27\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\x27\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\x27\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\x27\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\x27\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\x27\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\x27\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\x27\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\x27\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\x27\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\x27\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\x27\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\x27\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\x27\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\x27\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\x27\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\x27\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\x27\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\x27\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\x27\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\x27\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\x27\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\x27\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\x27\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\x27\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\x27\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\x27\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\x27\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\x27\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\x27\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\x27\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\x27\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\x27\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\x27\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\x27\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\x27\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\x27\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\x27\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\x27\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\x27\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\x27\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\x27\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\x27\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\x27\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\x27\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\x27\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\x27\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\x27\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x27\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x2e\x00\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x27\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x2e\x00\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\x27\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x21\x00\xff\xff\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\xff\xff\xff\xff\xff\xff\x2b\x00\xff\xff\x2d\x00\x2e\x00\x2f\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\xff\xff\x7c\x00\xff\xff\x7e\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x27\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x2e\x00\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x27\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x2e\x00\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\x27\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x27\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x2e\x00\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x27\x00\xff\xff\xff\xff\xff\xff\x2b\x00\xff\xff\x2d\x00\xff\xff\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\x27\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\x27\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\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\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\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\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\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\x5b\x00\x5c\x00\x5d\x00\x5e\x00\xff\xff\x60\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\x7b\x00\x7c\x00\x7d\x00\x7e\x00\x7f\x00\x80\x00\x81\x00\x82\x00\x83\x00\x84\x00\x85\x00\x86\x00\x87\x00\x88\x00\x89\x00\x8a\x00\x8b\x00\x8c\x00\x8d\x00\x8e\x00\x8f\x00\x90\x00\x91\x00\x92\x00\x93\x00\x94\x00\x95\x00\x96\x00\x97\x00\x98\x00\x99\x00\x9a\x00\x9b\x00\x9c\x00\x9d\x00\x9e\x00\x9f\x00\xa0\x00\xa1\x00\xa2\x00\xa3\x00\xa4\x00\xa5\x00\xa6\x00\xa7\x00\xa8\x00\xa9\x00\xaa\x00\xab\x00\xac\x00\xad\x00\xae\x00\xaf\x00\xb0\x00\xb1\x00\xb2\x00\xb3\x00\xb4\x00\xb5\x00\xb6\x00\xb7\x00\xb8\x00\xb9\x00\xba\x00\xbb\x00\xbc\x00\xbd\x00\xbe\x00\xbf\x00\x21\x00\xff\xff\x23\x00\x24\x00\x25\x00\x26\x00\xff\xff\xff\xff\xff\xff\xff\xff\x2b\x00\xff\xff\x2d\x00\x2e\x00\x2f\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xd7\x00\xff\xff\xff\xff\xff\xff\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\xff\xff\xff\xff\xff\xff\x21\x00\xff\xff\x23\x00\x24\x00\x25\x00\x26\x00\xff\xff\xff\xff\xff\xff\xff\xff\x2b\x00\xff\xff\x2d\x00\x2e\x00\x2f\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf7\x00\xff\xff\xff\xff\xff\xff\x5c\x00\xff\xff\x5e\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\xff\xff\xff\xff\xff\xff\x21\x00\xff\xff\x23\x00\x24\x00\x25\x00\x26\x00\xff\xff\xff\xff\xff\xff\xff\xff\x2b\x00\xff\xff\x2d\x00\x2e\x00\x2f\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7c\x00\xff\xff\x7e\x00\x5c\x00\xff\xff\x5e\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\xff\xff\xff\xff\xff\xff\x21\x00\xff\xff\x23\x00\x24\x00\x25\x00\x26\x00\xff\xff\xff\xff\xff\xff\xff\xff\x2b\x00\xff\xff\x2d\x00\x2e\x00\x2f\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7c\x00\xff\xff\x7e\x00\x5c\x00\xff\xff\x5e\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\xff\xff\xff\xff\xff\xff\x21\x00\xff\xff\x23\x00\x24\x00\x25\x00\x26\x00\xff\xff\xff\xff\xff\xff\xff\xff\x2b\x00\xff\xff\x2d\x00\x2e\x00\x2f\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7c\x00\xff\xff\x7e\x00\x5c\x00\xff\xff\x5e\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\xff\xff\xff\xff\xff\xff\x21\x00\xff\xff\x23\x00\x24\x00\x25\x00\x26\x00\xff\xff\xff\xff\xff\xff\xff\xff\x2b\x00\xff\xff\x2d\x00\x2e\x00\x2f\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7c\x00\xff\xff\x7e\x00\x5c\x00\xff\xff\x5e\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\xff\xff\xff\xff\xff\xff\x21\x00\xff\xff\x23\x00\x24\x00\x25\x00\x26\x00\xff\xff\xff\xff\xff\xff\xff\xff\x2b\x00\xff\xff\x2d\x00\x2e\x00\x2f\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7c\x00\xff\xff\x7e\x00\x5c\x00\xff\xff\x5e\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\xff\xff\xff\xff\xff\xff\x21\x00\xff\xff\x23\x00\x24\x00\x25\x00\x26\x00\xff\xff\xff\xff\xff\xff\xff\xff\x2b\x00\xff\xff\x2d\x00\x2e\x00\x2f\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7c\x00\xff\xff\x7e\x00\x5c\x00\xff\xff\x5e\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\xff\xff\xff\xff\xff\xff\x21\x00\xff\xff\x23\x00\x24\x00\x25\x00\x26\x00\xff\xff\xff\xff\xff\xff\xff\xff\x2b\x00\xff\xff\x2d\x00\x2e\x00\x2f\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7c\x00\xff\xff\x7e\x00\x5c\x00\xff\xff\x5e\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\xff\xff\xff\xff\xff\xff\x21\x00\xff\xff\x23\x00\x24\x00\x25\x00\x26\x00\xff\xff\xff\xff\xff\xff\xff\xff\x2b\x00\xff\xff\x2d\x00\x2e\x00\x2f\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7c\x00\xff\xff\x7e\x00\x5c\x00\xff\xff\x5e\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x22\x00\xff\xff\xff\xff\xff\xff\x26\x00\x27\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x7c\x00\xff\xff\x7e\x00\x5c\x00\xff\xff\x5e\x00\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\xff\xff\xff\xff\xff\xff\x4c\x00\xff\xff\x4e\x00\xff\xff\xff\xff\xff\xff\x52\x00\x53\x00\xff\xff\x55\x00\x56\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5c\x00\x7c\x00\x5e\x00\x7e\x00\xff\xff\x61\x00\x62\x00\xff\xff\xff\xff\xff\xff\x66\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x6e\x00\xff\xff\xff\xff\xff\xff\x72\x00\xff\xff\x74\x00\xff\xff\x76\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\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\xff\xff\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\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\x5c\x00\xff\xff\xff\xff\xff\xff\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\x7f\x00\x80\x00\x81\x00\x82\x00\x83\x00\x84\x00\x85\x00\x86\x00\x87\x00\x88\x00\x89\x00\x8a\x00\x8b\x00\x8c\x00\x8d\x00\x8e\x00\x8f\x00\x90\x00\x91\x00\x92\x00\x93\x00\x94\x00\x95\x00\x96\x00\x97\x00\x98\x00\x99\x00\x9a\x00\x9b\x00\x9c\x00\x9d\x00\x9e\x00\x9f\x00\xa0\x00\xa1\x00\xa2\x00\xa3\x00\xa4\x00\xa5\x00\xa6\x00\xa7\x00\xa8\x00\xa9\x00\xaa\x00\xab\x00\xac\x00\xad\x00\xae\x00\xaf\x00\xb0\x00\xb1\x00\xb2\x00\xb3\x00\xb4\x00\xb5\x00\xb6\x00\xb7\x00\xb8\x00\xb9\x00\xba\x00\xbb\x00\xbc\x00\xbd\x00\xbe\x00\xbf\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\xd7\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\xf7\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\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\xff\xff\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\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\x5c\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\x7f\x00\x80\x00\x81\x00\x82\x00\x83\x00\x84\x00\x85\x00\x86\x00\x87\x00\x88\x00\x89\x00\x8a\x00\x8b\x00\x8c\x00\x8d\x00\x8e\x00\x8f\x00\x90\x00\x91\x00\x92\x00\x93\x00\x94\x00\x95\x00\x96\x00\x97\x00\x98\x00\x99\x00\x9a\x00\x9b\x00\x9c\x00\x9d\x00\x9e\x00\x9f\x00\xa0\x00\xa1\x00\xa2\x00\xa3\x00\xa4\x00\xa5\x00\xa6\x00\xa7\x00\xa8\x00\xa9\x00\xaa\x00\xab\x00\xac\x00\xad\x00\xae\x00\xaf\x00\xb0\x00\xb1\x00\xb2\x00\xb3\x00\xb4\x00\xb5\x00\xb6\x00\xb7\x00\xb8\x00\xb9\x00\xba\x00\xbb\x00\xbc\x00\xbd\x00\xbe\x00\xbf\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\xd7\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\xf7\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\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\xff\xff\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\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\x5c\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\x7f\x00\x80\x00\x81\x00\x82\x00\x83\x00\x84\x00\x85\x00\x86\x00\x87\x00\x88\x00\x89\x00\x8a\x00\x8b\x00\x8c\x00\x8d\x00\x8e\x00\x8f\x00\x90\x00\x91\x00\x92\x00\x93\x00\x94\x00\x95\x00\x96\x00\x97\x00\x98\x00\x99\x00\x9a\x00\x9b\x00\x9c\x00\x9d\x00\x9e\x00\x9f\x00\xa0\x00\xa1\x00\xa2\x00\xa3\x00\xa4\x00\xa5\x00\xa6\x00\xa7\x00\xa8\x00\xa9\x00\xaa\x00\xab\x00\xac\x00\xad\x00\xae\x00\xaf\x00\xb0\x00\xb1\x00\xb2\x00\xb3\x00\xb4\x00\xb5\x00\xb6\x00\xb7\x00\xb8\x00\xb9\x00\xba\x00\xbb\x00\xbc\x00\xbd\x00\xbe\x00\xbf\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\xd7\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\xf7\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\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\xff\xff\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\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\x5c\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\x7f\x00\x80\x00\x81\x00\x82\x00\x83\x00\x84\x00\x85\x00\x86\x00\x87\x00\x88\x00\x89\x00\x8a\x00\x8b\x00\x8c\x00\x8d\x00\x8e\x00\x8f\x00\x90\x00\x91\x00\x92\x00\x93\x00\x94\x00\x95\x00\x96\x00\x97\x00\x98\x00\x99\x00\x9a\x00\x9b\x00\x9c\x00\x9d\x00\x9e\x00\x9f\x00\xa0\x00\xa1\x00\xa2\x00\xa3\x00\xa4\x00\xa5\x00\xa6\x00\xa7\x00\xa8\x00\xa9\x00\xaa\x00\xab\x00\xac\x00\xad\x00\xae\x00\xaf\x00\xb0\x00\xb1\x00\xb2\x00\xb3\x00\xb4\x00\xb5\x00\xb6\x00\xb7\x00\xb8\x00\xb9\x00\xba\x00\xbb\x00\xbc\x00\xbd\x00\xbe\x00\xbf\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\xd7\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\xf7\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\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\xff\xff\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\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\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\x5c\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\x7f\x00\x80\x00\x81\x00\x82\x00\x83\x00\x84\x00\x85\x00\x86\x00\x87\x00\x88\x00\x89\x00\x8a\x00\x8b\x00\x8c\x00\x8d\x00\x8e\x00\x8f\x00\x90\x00\x91\x00\x92\x00\x93\x00\x94\x00\x95\x00\x96\x00\x97\x00\x98\x00\x99\x00\x9a\x00\x9b\x00\x9c\x00\x9d\x00\x9e\x00\x9f\x00\xa0\x00\xa1\x00\xa2\x00\xa3\x00\xa4\x00\xa5\x00\xa6\x00\xa7\x00\xa8\x00\xa9\x00\xaa\x00\xab\x00\xac\x00\xad\x00\xae\x00\xaf\x00\xb0\x00\xb1\x00\xb2\x00\xb3\x00\xb4\x00\xb5\x00\xb6\x00\xb7\x00\xb8\x00\xb9\x00\xba\x00\xbb\x00\xbc\x00\xbd\x00\xbe\x00\xbf\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\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\xd7\x00\xff\xff\x22\x00\xff\xff\xff\xff\xff\xff\x26\x00\x27\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf7\x00\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\xff\xff\xff\xff\xff\xff\x4c\x00\xff\xff\x4e\x00\xff\xff\xff\xff\xff\xff\x52\x00\x53\x00\xff\xff\x55\x00\x56\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5c\x00\xff\xff\x5e\x00\xff\xff\xff\xff\x61\x00\x62\x00\xff\xff\xff\xff\xff\xff\x66\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x6e\x00\xff\xff\xff\xff\xff\xff\x72\x00\xff\xff\x74\x00\xff\xff\x76\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\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\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\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\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\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"#++alex_deflt :: AlexAddr+alex_deflt = AlexA# "\xff\xff\xff\xff\x03\x00\x03\x00\x03\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\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\x48\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\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x82\x00\x82\x00\x82\x00\x82\x00\x82\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"#++alex_accept = listArray (0::Int,165) [[],[(AlexAcc (alex_action_0))],[(AlexAcc (alex_action_1))],[(AlexAcc (alex_action_1))],[(AlexAcc (alex_action_1))],[(AlexAcc (alex_action_10))],[(AlexAcc (alex_action_2))],[(AlexAcc (alex_action_3))],[(AlexAcc (alex_action_3))],[(AlexAcc (alex_action_3))],[(AlexAcc (alex_action_3))],[(AlexAcc (alex_action_4))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_5))],[(AlexAcc (alex_action_5))],[(AlexAcc (alex_action_5))],[],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_8))],[(AlexAcc (alex_action_8))],[(AlexAcc (alex_action_8))],[(AlexAcc (alex_action_8))],[(AlexAcc (alex_action_8))],[(AlexAcc (alex_action_8))],[(AlexAcc (alex_action_10))],[(AlexAcc (alex_action_9))],[(AlexAcc (alex_action_9))],[(AlexAcc (alex_action_10))],[(AlexAcc (alex_action_10))],[(AlexAcc (alex_action_11))],[(AlexAcc (alex_action_11))],[(AlexAcc (alex_action_11))],[],[],[],[],[(AlexAcc (alex_action_13))],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[(AlexAcc (alex_action_14))],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]]+{-# LINE 102 "Intel/Cnc/Spec/CncLexer.x" #-}+ -- Begin Haskell code block to include in output:++-- The type of tokens:+data Lexeme = L AlexPosn LexemeClass String+ deriving Show++data LexemeClass+ = LInteger+ | LFloat+ | LChar+ | LString+ + | LComment++ | LSpecial+ | LReservedId+ | LReservedOp+ | LVarId+ | LQVarId+ | LCapid+ | LQCapid+ | LVarOp+ | LQVarOp+-- | LConSym+-- | LQConSym+ | LEOF+ deriving (Eq, Show)+ +-- Handle a common case: create one token +mkL :: LexemeClass -> AlexInput -> Int -> Alex Lexeme+mkL c (p,_,str) len = return (L p c (take len str))+++-- This handles arbitrarily nested comments:+nested_comment :: AlexInput -> Int -> Alex Lexeme+nested_comment (apos, chr, str) int = do+ input <- alexGetInput+ go 1 input "*/"+ -- When finished, set the position to after the comment ('input')+-- where go 0 input acc = do alexSetInput input; alexMonadScan+ where go 0 input acc = do alexSetInput input; (mkL LComment (apos,chr, reverse acc) (length acc))+ go n input acc = do+ -- The 'n' parameter here keepstrack of the nesting.+ let prev = alexInputPrevChar input + case alexGetChar input of+ Nothing -> err input+ Just (c,input) -> do+ case c of++ -- We've got a potential comment ENDING:+ '/' -> do+ case prev of+ ('*') -> go (n-1) input ('/':acc) -- CLOSE a level.+ (c) -> go n input ('/':acc)+ + -- Here we've got another comment BEGINNING:+ '*' -> do+ case prev of+ ('/') -> go (n+1) input ('*':acc) -- OPEN a level+ (c) -> go n input ('*':acc)++ -- Other characters: add to the pile and keep going:+ c -> go n input (c:acc)++ err input = do alexSetInput input; lexError "error in nested comment" +++lexError :: String -> Alex b +lexError s = do+ (p,c,input) <- alexGetInput+ alexError (showPosn p ++ ": " ++ s ++ + (if (not (null input))+ then " before " ++ show (head input)+ else " at end of file"))++-- Returns either a list of tokens or an error:+scan_to_list :: String -> [Lexeme]+scan_to_list str = + case result of + Left err -> error$ "Error in lexing stage:\n" ++ err+ Right ls -> ls+ where + result = runAlex str $ do+{-+-- TODO: get line number for lex error:+ let loop i = do tok@(L _ cl _) <- alexMonadScan; +-} +-- Maybe we can hack the monad here by replacing bind with our own version.+ let loop i = do tok@(L _ cl _) <- alexMonadScan; + if cl == LEOF+ then return [tok]+ else do ls <- loop $! (i+1)+ return (tok:ls)+ loop 0+++--alexEOF = return (L (error "EOF has no position") LEOF "")+alexEOF = return (L (AlexPn (-1) (-1) (-1)) LEOF "")+--alexEOF = return (L (noSrcLoc) LEOF "")++showPosn (AlexPn _ line col) = "line " ++ show line ++ ", col " ++ show col++main = do+ putStrLn "HEllo!\n"+ s <- getContents+ --s <- getLine+ --print (scanner s)+ sequence_ (map print $ scan_to_list s)+ -- case scan_to_list s of + -- Left err -> print err+ -- Right ls -> sequence_ (map print ls)+++alex_action_0 = skip +alex_action_1 = mkL LComment +alex_action_2 = nested_comment +alex_action_3 = mkL LSpecial +alex_action_4 = mkL LReservedId +alex_action_5 = mkL LQVarId +alex_action_6 = mkL LVarId +alex_action_7 = mkL LCapid +alex_action_8 = mkL LReservedOp +alex_action_9 = mkL LVarOp +alex_action_10 = mkL LVarOp +alex_action_11 = mkL LFloat +alex_action_12 = mkL LInteger +alex_action_13 = mkL LChar +alex_action_14 = mkL LString +{-# LINE 1 "templates/GenericTemplate.hs" #-}+{-# LINE 1 "templates/GenericTemplate.hs" #-}+{-# LINE 1 "<built-in>" #-}+{-# LINE 1 "<command line>" #-}+{-# LINE 1 "templates/GenericTemplate.hs" #-}+-- -----------------------------------------------------------------------------+-- ALEX TEMPLATE+--+-- This code is in the PUBLIC DOMAIN; you may copy it freely and use+-- it for any purpose whatsoever.++-- -----------------------------------------------------------------------------+-- INTERNALS and main scanner engine++{-# LINE 37 "templates/GenericTemplate.hs" #-}++{-# LINE 47 "templates/GenericTemplate.hs" #-}+++data AlexAddr = AlexA# Addr#++#if __GLASGOW_HASKELL__ < 503+uncheckedShiftL# = shiftL#+#endif++{-# INLINE alexIndexInt16OffAddr #-}+alexIndexInt16OffAddr (AlexA# arr) off =+#ifdef WORDS_BIGENDIAN+ narrow16Int# i+ where+ i = word2Int# ((high `uncheckedShiftL#` 8#) `or#` low)+ high = int2Word# (ord# (indexCharOffAddr# arr (off' +# 1#)))+ low = int2Word# (ord# (indexCharOffAddr# arr off'))+ off' = off *# 2#+#else+ indexInt16OffAddr# arr off+#endif++++++{-# INLINE alexIndexInt32OffAddr #-}+alexIndexInt32OffAddr (AlexA# arr) off = +#ifdef WORDS_BIGENDIAN+ narrow32Int# i+ where+ i = word2Int# ((b3 `uncheckedShiftL#` 24#) `or#`+ (b2 `uncheckedShiftL#` 16#) `or#`+ (b1 `uncheckedShiftL#` 8#) `or#` b0)+ b3 = int2Word# (ord# (indexCharOffAddr# arr (off' +# 3#)))+ b2 = int2Word# (ord# (indexCharOffAddr# arr (off' +# 2#)))+ b1 = int2Word# (ord# (indexCharOffAddr# arr (off' +# 1#)))+ b0 = int2Word# (ord# (indexCharOffAddr# arr off'))+ off' = off *# 4#+#else+ indexInt32OffAddr# arr off+#endif++++++#if __GLASGOW_HASKELL__ < 503+quickIndex arr i = arr ! i+#else+-- GHC >= 503, unsafeAt is available from Data.Array.Base.+quickIndex = unsafeAt+#endif+++++-- -----------------------------------------------------------------------------+-- Main lexing routines++data AlexReturn a+ = AlexEOF+ | AlexError !AlexInput+ | AlexSkip !AlexInput !Int+ | AlexToken !AlexInput !Int a++-- alexScan :: AlexInput -> StartCode -> AlexReturn a+alexScan input (I# (sc))+ = alexScanUser undefined input (I# (sc))++alexScanUser user input (I# (sc))+ = case alex_scan_tkn user input 0# input sc AlexNone of+ (AlexNone, input') ->+ case alexGetChar input of+ Nothing -> ++++ AlexEOF+ Just _ ->++++ AlexError input'++ (AlexLastSkip input'' len, _) ->++++ AlexSkip input'' len++ (AlexLastAcc k input''' len, _) ->++++ AlexToken input''' len k+++-- Push the input through the DFA, remembering the most recent accepting+-- state it encountered.++alex_scan_tkn user orig_input len input s last_acc =+ input `seq` -- strict in the input+ let + new_acc = check_accs (alex_accept `quickIndex` (I# (s)))+ in+ new_acc `seq`+ case alexGetChar input of+ Nothing -> (new_acc, input)+ Just (c, new_input) -> ++++ let+ !(base) = alexIndexInt32OffAddr alex_base s+ !((I# (ord_c))) = ord c+ !(offset) = (base +# ord_c)+ !(check) = alexIndexInt16OffAddr alex_check offset+ + !(new_s) = if (offset >=# 0#) && (check ==# ord_c)+ then alexIndexInt16OffAddr alex_table offset+ else alexIndexInt16OffAddr alex_deflt s+ in+ case new_s of + -1# -> (new_acc, input)+ -- on an error, we want to keep the input *before* the+ -- character that failed, not after.+ _ -> alex_scan_tkn user orig_input (len +# 1#) + new_input new_s new_acc++ where+ check_accs [] = last_acc+ check_accs (AlexAcc a : _) = AlexLastAcc a input (I# (len))+ check_accs (AlexAccSkip : _) = AlexLastSkip input (I# (len))+ check_accs (AlexAccPred a predx : rest)+ | predx user orig_input (I# (len)) input+ = AlexLastAcc a input (I# (len))+ check_accs (AlexAccSkipPred predx : rest)+ | predx user orig_input (I# (len)) input+ = AlexLastSkip input (I# (len))+ check_accs (_ : rest) = check_accs rest++data AlexLastAcc a+ = AlexNone+ | AlexLastAcc a !AlexInput !Int+ | AlexLastSkip !AlexInput !Int++data AlexAcc a user+ = AlexAcc a+ | AlexAccSkip+ | AlexAccPred a (AlexAccPred user)+ | AlexAccSkipPred (AlexAccPred user)++type AlexAccPred user = user -> AlexInput -> Int -> AlexInput -> Bool++-- -----------------------------------------------------------------------------+-- Predicates on a rule++alexAndPred p1 p2 user in1 len in2+ = p1 user in1 len in2 && p2 user in1 len in2++--alexPrevCharIsPred :: Char -> AlexAccPred _ +alexPrevCharIs c _ input _ _ = c == alexInputPrevChar input++--alexPrevCharIsOneOfPred :: Array Char Bool -> AlexAccPred _ +alexPrevCharIsOneOf arr _ input _ _ = arr ! alexInputPrevChar input++--alexRightContext :: Int -> AlexAccPred _+alexRightContext (I# (sc)) user _ _ input = + case alex_scan_tkn user input 0# input sc AlexNone of+ (AlexNone, _) -> False+ _ -> True+ -- TODO: there's no need to find the longest+ -- match when checking the right context, just+ -- the first match will do.++-- used by wrappers+iUnbox (I# (i)) = i