diff --git a/.gitignore b/.gitignore index 96efdba0c..490e5debb 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,6 @@ .DS_Store .vs/ .vscode/ -.koka/ node_modules/ out/ bundle/ @@ -30,3 +29,5 @@ test.kk /*.cmake bench test/bench +.koka +scratch diff --git a/LICENSE b/LICENSE index 5454086ac..82b129365 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ -Copyright 2012-2021, Microsoft Research, Daan Leijen. +Copyright 2012-2023, Microsoft Research, Daan Leijen. -Koka is free software; You can redistribute it and/or +Koka is free software; You can redistribute it and/or modify it under the terms of this license. @@ -13,185 +13,185 @@ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. -"License" shall mean the terms and conditions for use, reproduction, and +"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. -"Licensor" shall mean the copyright owner or entity authorized by the +"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. -"Legal Entity" shall mean the union of the acting entity and all other -entities that control, are controlled by, or are under common control -with that entity. For the purposes of this definition, "control" means -(i) the power, direct or indirect, to cause the direction or management -of such entity, whether by contract or otherwise, or (ii) ownership of -fifty percent (50%) or more of the outstanding shares, or (iii) +"Legal Entity" shall mean the union of the acting entity and all other +entities that control, are controlled by, or are under common control +with that entity. For the purposes of this definition, "control" means +(i) the power, direct or indirect, to cause the direction or management +of such entity, whether by contract or otherwise, or (ii) ownership of +fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. -"You" (or "Your") shall mean an individual or Legal Entity exercising +"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. -"Source" form shall mean the preferred form for making modifications, -including but not limited to software source code, documentation source, +"Source" form shall mean the preferred form for making modifications, +including but not limited to software source code, documentation source, and configuration files. -"Object" form shall mean any form resulting from mechanical -transformation or translation of a Source form, including but not limited -to compiled object code, generated documentation, and conversions to +"Object" form shall mean any form resulting from mechanical +transformation or translation of a Source form, including but not limited +to compiled object code, generated documentation, and conversions to other media types. -"Work" shall mean the work of authorship, whether in Source or Object -form, made available under the License, as indicated by a copyright -notice that is included in or attached to the work (an example is +"Work" shall mean the work of authorship, whether in Source or Object +form, made available under the License, as indicated by a copyright +notice that is included in or attached to the work (an example is provided in the Appendix below). -"Derivative Works" shall mean any work, whether in Source or Object form, -that is based on (or derived from) the Work and for which the editorial -revisions, annotations, elaborations, or other modifications represent, -as a whole, an original work of authorship. For the purposes of this -License, Derivative Works shall not include works that remain separable -from, or merely link (or bind by name) to the interfaces of, the Work and +"Derivative Works" shall mean any work, whether in Source or Object form, +that is based on (or derived from) the Work and for which the editorial +revisions, annotations, elaborations, or other modifications represent, +as a whole, an original work of authorship. For the purposes of this +License, Derivative Works shall not include works that remain separable +from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. -"Contribution" shall mean any work of authorship, including the original -version of the Work and any modifications or additions to that Work or -Derivative Works thereof, that is intentionally submitted to Licensor for -inclusion in the Work by the copyright owner or by an individual or Legal -Entity authorized to submit on behalf of the copyright owner. For the -purposes of this definition, "submitted" means any form of electronic, -verbal, or written communication sent to the Licensor or its -representatives, including but not limited to communication on electronic -mailing lists, source code control systems, and issue tracking systems -that are managed by, or on behalf of, the Licensor for the purpose of -discussing and improving the Work, but excluding communication that is -conspicuously marked or otherwise designated in writing by the copyright +"Contribution" shall mean any work of authorship, including the original +version of the Work and any modifications or additions to that Work or +Derivative Works thereof, that is intentionally submitted to Licensor for +inclusion in the Work by the copyright owner or by an individual or Legal +Entity authorized to submit on behalf of the copyright owner. For the +purposes of this definition, "submitted" means any form of electronic, +verbal, or written communication sent to the Licensor or its +representatives, including but not limited to communication on electronic +mailing lists, source code control systems, and issue tracking systems +that are managed by, or on behalf of, the Licensor for the purpose of +discussing and improving the Work, but excluding communication that is +conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." -"Contributor" shall mean Licensor and any individual or Legal Entity on -behalf of whom a Contribution has been received by Licensor and +"Contributor" shall mean Licensor and any individual or Legal Entity on +behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. -Subject to the terms and conditions of this License, each Contributor -hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, -royalty-free, irrevocable copyright license to reproduce, prepare -Derivative Works of, publicly display, publicly perform, sublicense, and +Subject to the terms and conditions of this License, each Contributor +hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, +royalty-free, irrevocable copyright license to reproduce, prepare +Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. -Subject to the terms and conditions of this License, each Contributor -hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, -royalty-free, irrevocable (except as stated in this section) patent -license to make, have made, use, offer to sell, sell, import, and -otherwise transfer the Work, where such license applies only to those -patent claims licensable by such Contributor that are necessarily -infringed by their Contribution(s) alone or by combination of their -Contribution(s) with the Work to which such Contribution(s) was -submitted. If You institute patent litigation against any entity -(including a cross-claim or counterclaim in a lawsuit) alleging that the -Work or a Contribution incorporated within the Work constitutes direct or -contributory patent infringement, then any patent licenses granted to You -under this License for that Work shall terminate as of the date such +Subject to the terms and conditions of this License, each Contributor +hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, +royalty-free, irrevocable (except as stated in this section) patent +license to make, have made, use, offer to sell, sell, import, and +otherwise transfer the Work, where such license applies only to those +patent claims licensable by such Contributor that are necessarily +infringed by their Contribution(s) alone or by combination of their +Contribution(s) with the Work to which such Contribution(s) was +submitted. If You institute patent litigation against any entity +(including a cross-claim or counterclaim in a lawsuit) alleging that the +Work or a Contribution incorporated within the Work constitutes direct or +contributory patent infringement, then any patent licenses granted to You +under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. -You may reproduce and distribute copies of the Work or Derivative Works -thereof in any medium, with or without modifications, and in Source or +You may reproduce and distribute copies of the Work or Derivative Works +thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: -You must give any other recipients of the Work or Derivative Works a copy +You must give any other recipients of the Work or Derivative Works a copy of this License; and -You must cause any modified files to carry prominent notices stating that +You must cause any modified files to carry prominent notices stating that You changed the files; and -You must retain, in the Source form of any Derivative Works that You -distribute, all copyright, patent, trademark, and attribution notices -from the Source form of the Work, excluding those notices that do not +You must retain, in the Source form of any Derivative Works that You +distribute, all copyright, patent, trademark, and attribution notices +from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and -If the Work includes a "NOTICE" text file as part of its distribution, -then any Derivative Works that You distribute must include a readable -copy of the attribution notices contained within such NOTICE file, -excluding those notices that do not pertain to any part of the Derivative -Works, in at least one of the following places: within a NOTICE text file -distributed as part of the Derivative Works; within the Source form or -documentation, if provided along with the Derivative Works; or, within a -display generated by the Derivative Works, if and wherever such -third-party notices normally appear. The contents of the NOTICE file are -for informational purposes only and do not modify the License. You may -add Your own attribution notices within Derivative Works that You -distribute, alongside or as an addendum to the NOTICE text from the Work, -provided that such additional attribution notices cannot be construed as +If the Work includes a "NOTICE" text file as part of its distribution, +then any Derivative Works that You distribute must include a readable +copy of the attribution notices contained within such NOTICE file, +excluding those notices that do not pertain to any part of the Derivative +Works, in at least one of the following places: within a NOTICE text file +distributed as part of the Derivative Works; within the Source form or +documentation, if provided along with the Derivative Works; or, within a +display generated by the Derivative Works, if and wherever such +third-party notices normally appear. The contents of the NOTICE file are +for informational purposes only and do not modify the License. You may +add Your own attribution notices within Derivative Works that You +distribute, alongside or as an addendum to the NOTICE text from the Work, +provided that such additional attribution notices cannot be construed as modifying the License. -You may add Your own copyright statement to Your modifications and may -provide additional or different license terms and conditions for use, -reproduction, or distribution of Your modifications, or for any such -Derivative Works as a whole, provided Your use, reproduction, and -distribution of the Work otherwise complies with the conditions stated in +You may add Your own copyright statement to Your modifications and may +provide additional or different license terms and conditions for use, +reproduction, or distribution of Your modifications, or for any such +Derivative Works as a whole, provided Your use, reproduction, and +distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. -Unless You explicitly state otherwise, any Contribution intentionally -submitted for inclusion in the Work by You to the Licensor shall be under -the terms and conditions of this License, without any additional terms or -conditions. Notwithstanding the above, nothing herein shall supersede or -modify the terms of any separate license agreement you may have executed +Unless You explicitly state otherwise, any Contribution intentionally +submitted for inclusion in the Work by You to the Licensor shall be under +the terms and conditions of this License, without any additional terms or +conditions. Notwithstanding the above, nothing herein shall supersede or +modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. -This License does not grant permission to use the trade names, -trademarks, service marks, or product names of the Licensor, except as -required for reasonable and customary use in describing the origin of the +This License does not grant permission to use the trade names, +trademarks, service marks, or product names of the Licensor, except as +required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. -Unless required by applicable law or agreed to in writing, Licensor -provides the Work (and each Contributor provides its Contributions) on an -"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either -express or implied, including, without limitation, any warranties or -conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A -PARTICULAR PURPOSE. You are solely responsible for determining the -appropriateness of using or redistributing the Work and assume any risks +Unless required by applicable law or agreed to in writing, Licensor +provides the Work (and each Contributor provides its Contributions) on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +express or implied, including, without limitation, any warranties or +conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A +PARTICULAR PURPOSE. You are solely responsible for determining the +appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. -In no event and under no legal theory, whether in tort (including -negligence), contract, or otherwise, unless required by applicable law -(such as deliberate and grossly negligent acts) or agreed to in writing, -shall any Contributor be liable to You for damages, including any direct, -indirect, special, incidental, or consequential damages of any character -arising as a result of this License or out of the use or inability to use -the Work (including but not limited to damages for loss of goodwill, work -stoppage, computer failure or malfunction, or any and all other -commercial damages or losses), even if such Contributor has been advised +In no event and under no legal theory, whether in tort (including +negligence), contract, or otherwise, unless required by applicable law +(such as deliberate and grossly negligent acts) or agreed to in writing, +shall any Contributor be liable to You for damages, including any direct, +indirect, special, incidental, or consequential damages of any character +arising as a result of this License or out of the use or inability to use +the Work (including but not limited to damages for loss of goodwill, work +stoppage, computer failure or malfunction, or any and all other +commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. -While redistributing the Work or Derivative Works thereof, You may choose -to offer, and charge a fee for, acceptance of support, warranty, -indemnity, or other liability obligations and/or rights consistent with -this License. However, in accepting such obligations, You may act only on -Your own behalf and on Your sole responsibility, not on behalf of any -other Contributor, and only if You agree to indemnify, defend, and hold -each Contributor harmless for any liability incurred by, or claims -asserted against, such Contributor by reason of your accepting any such +While redistributing the Work or Derivative Works thereof, You may choose +to offer, and charge a fee for, acceptance of support, warranty, +indemnity, or other liability obligations and/or rights consistent with +this License. However, in accepting such obligations, You may act only on +Your own behalf and on Your sole responsibility, not on behalf of any +other Contributor, and only if You agree to indemnify, defend, and hold +each Contributor harmless for any liability incurred by, or claims +asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work -To apply the Apache License to your work, attach the following -boilerplate notice, with the fields enclosed by brackets "[]" replaced -with your own identifying information. (Don't include the brackets!) The -text should be enclosed in the appropriate comment syntax for the file -format. We also recommend that a file or class name and description of -purpose be included on the same "printed page" as the copyright notice +To apply the Apache License to your work, attach the following +boilerplate notice, with the fields enclosed by brackets "[]" replaced +with your own identifying information. (Don't include the brackets!) The +text should be enclosed in the appropriate comment syntax for the file +format. We also recommend that a file or class name and description of +purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] @@ -204,7 +204,7 @@ for easier identification within third-party archives. Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. diff --git a/koka.cabal b/koka.cabal index 90bf0f927..340b12a77 100644 --- a/koka.cabal +++ b/koka.cabal @@ -1,6 +1,6 @@ cabal-version: 1.12 --- This file has been generated from package.yaml by hpack version 0.35.0. +-- This file has been generated from package.yaml by hpack version 0.36.0. -- -- see: https://github.com/sol/hpack @@ -21,9 +21,8 @@ source-repository head type: git location: https://github.com/koka-lang/koka -executable koka - main-is: Main.hs - other-modules: +library + exposed-modules: Backend.C.Box Backend.C.FromCore Backend.C.Parc @@ -125,6 +124,7 @@ executable koka Platform.ReadLine Platform.Runtime Platform.Var + other-modules: Paths_koka hs-source-dirs: src @@ -132,7 +132,7 @@ executable koka other-extensions: CPP OverloadedStrings - ghc-options: -rtsopts -j8 + ghc-options: -j8 -O2 cpp-options: -DKOKA_MAIN="koka" -DKOKA_VARIANT="release" -DKOKA_VERSION="2.4.3" -DREADLINE=0 include-dirs: src/Platform/cpp/Platform @@ -158,6 +158,71 @@ executable koka if os(darwin) cpp-options: -DDARWIN +executable koka + main-is: Main.hs + other-modules: + LanguageServer.Conversions + LanguageServer.Handler.Commands + LanguageServer.Handler.Completion + LanguageServer.Handler.Definition + LanguageServer.Handler.DocumentSymbol + LanguageServer.Handler.Folding + LanguageServer.Handler.Hover + LanguageServer.Handler.InlayHints + LanguageServer.Handler.TextDocument + LanguageServer.Handlers + LanguageServer.Monad + LanguageServer.Run + Paths_koka + hs-source-dirs: + src/Main/langserver + ghc-options: -rtsopts -j8 -O2 -threaded "-with-rtsopts=-N8" + build-depends: + aeson + , array + , async + , base >=4.9 + , bytestring + , co-log-core + , containers + , directory + , isocline >=1.0.6 + , koka + , lens + , lsp + , mtl + , network + , network-simple + , parsec + , process + , stm + , text + , text-rope + , time + default-language: Haskell2010 + +executable koka-plain + main-is: Main.hs + other-modules: + Paths_koka + hs-source-dirs: + src/Main/plain + ghc-options: -rtsopts -j8 -O2 -threaded "-with-rtsopts=-N8" + build-depends: + array + , base >=4.9 + , bytestring + , containers + , directory + , isocline >=1.0.6 + , koka + , mtl + , parsec + , process + , text + , time + default-language: Haskell2010 + test-suite koka-test type: exitcode-stdio-1.0 main-is: Spec.hs diff --git a/package.yaml b/package.yaml index 0b625d72d..3175bf8b6 100644 --- a/package.yaml +++ b/package.yaml @@ -4,6 +4,8 @@ # - util/install.bat # - util/Dockerfile # - util/minbuild +# - support/vscode/koka.language-koka/src/workspace.ts +# - support/vscode/koka.language-koka/package.json name: koka version: 2.4.3 @@ -29,37 +31,66 @@ dependencies: - text - time - isocline >= 1.0.6 - + +library: + other-extensions: + - CPP + - OverloadedStrings + source-dirs: + - src + - src/Platform/cpp + c-sources: + - src/Platform/cpp/Platform/cconsole.c + include-dirs: + - src/Platform/cpp/Platform + build-tools: + - alex + ghc-options: + - -j8 + - -O2 + cpp-options: + - -DKOKA_MAIN="koka" + - -DKOKA_VARIANT="release" + - -DKOKA_VERSION="2.4.3" + - -DREADLINE=0 # 1:getline, 2:readline, 3:haskeline, or 0:isocline + when: + - condition: os(windows) + cpp-options: -DWINDOWS + - condition: os(darwin) + cpp-options: -DDARWIN + executables: koka: main: Main.hs - # source-dirs: app - # dependencies: koka - other-extensions: - - CPP - - OverloadedStrings - source-dirs: - - src - - src/Platform/cpp - c-sources: - - src/Platform/cpp/Platform/cconsole.c - include-dirs: - - src/Platform/cpp/Platform - build-tools: - - alex + source-dirs: src/Main/langserver + dependencies: + - aeson + - async + - co-log-core + - koka + - lens + - lsp + - network-simple + - network + - text-rope + - stm ghc-options: - - -rtsopts + - -rtsopts - -j8 - cpp-options: - - -DKOKA_MAIN="koka" - - -DKOKA_VARIANT="release" - - -DKOKA_VERSION="2.4.3" - - -DREADLINE=0 # 1:getline, 2:readline, 3:haskeline, or 0:isocline - when: - - condition: os(windows) - cpp-options: -DWINDOWS - - condition: os(darwin) - cpp-options: -DDARWIN + - -O2 + - -threaded + - '"-with-rtsopts=-N8"' + + koka-plain: + main: Main.hs + source-dirs: src/Main/plain + dependencies: koka + ghc-options: + - -rtsopts + - -j8 + - -O2 + - -threaded + - '"-with-rtsopts=-N8"' tests: koka-test: diff --git a/readme.md b/readme.md index 45ac329fe..fea42eb06 100644 --- a/readme.md +++ b/readme.md @@ -279,9 +279,6 @@ More advanced projects: * [x] Update the JavaScript backend to 1) use modern modules instead of amdefine, 2) use the new bigints instead of bigint.js, and 3) add support for int64. (landed in the `dev` branch) * [x] Port `std/text/regex` from v1 (using PCRE) -* [ ] A language server for Visual Studio Code and Atom. Koka can already generate a - typed [range map](src/Syntax/RangeMap.hs) so this should be managable. Partially done: see PR #100 (by @fwcd) -- it just - needs work on packaging it to make it easy to build and install as part of the Koka installer. * [ ] Package management of Koka modules. * [x] Compile to WASM (using emscripten on the current C backend) * [ ] Improve compilation of local state to use local variables directly (in C) without allocation. Tricky though due to multiple resumptions. @@ -318,6 +315,17 @@ The following is the immediate todo list to be completed in the coming months: * [ ] Port `std/async` (using `libuv`). * [ ] Proper overloading with (a form of) type classes. (in design phase). +LSP Related Tasks: +* [ ] Generate completions for effect handlers (with empty bodies of all the functions) +* [ ] Generate show / (==) for datatypes +* [ ] Find References +* [ ] Generate Type Annotations + +Extension Related Tasks: + +VSCode: +* [ ] Add support for debugging an executable + Contact me if you are interested in tackling some of these :-) # Build Notes @@ -460,6 +468,51 @@ $ out\v2.0.5\cl-release\test_bench_koka_rbtree --kktime info: elapsed: 1.483s, user: 1.484s, sys: 0.000s, rss: 164mb ``` +## Language Server + +The language server is started by running the koka compilter with the --language-server flag +and then connecting to it with a client that supports the Language Server Protocol (LSP) + +For example, using VSCode, install the Koka extension or run the extension debug configuration in the project. +Open up a folder and start editing `.kk` files. (The extension finds the koka executable and then automatically starts the language server for you). + +The VSCode extension searches in the following locations for the koka executable: +- A koka development environment in ~/koka +- A local install ~/.local/bin +- The PATH environment variable + +To specify the command to start the language server manually, such as to provide additional flags to the koka compiler override the `koka.languageServer.command` VSCode setting. +To specify the current working directory to run the compiler from use the `koka.languageServer.cwd` setting. If there are problems with the language server, you can enable the `koka.languageServer.trace.server` setting to see the language server logs, or turn off the language server by setting the `koka.languageServer.enable` setting to `false`. + +To develop the language server, you can use this VSCode debug configuration (add the configuration to .vscode/launch.json). + +```json +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Launch Extension", + "request": "launch", + "type": "extensionHost", + "args": [ + "--extensionDevelopmentPath=${workspaceFolder}/support/vscode/koka.language-koka" + ], + "outFiles": [ + "${workspaceFolder}/support/vscode/koka.language-koka/out/**/*.js" + ] + } +] +} +``` + +- Run `npm install && npm run build` in the `support/vscode/koka.language-koka` directory +- Update the LSP server in the `src/LanguageServer` directory with your changes +- Run `stack build` +- Restart the debug configuration and make sure a notification pops up that you are using the development version of the koka sdk + ## Older Release Notes * `v2.1.9`, 2021-06-23: initial support for cross-module specialization (by Steven Fontanella). diff --git a/samples/basic/fibonacci.kk b/samples/basic/fibonacci.kk index 6f8d20ce7..2cb62599f 100644 --- a/samples/basic/fibonacci.kk +++ b/samples/basic/fibonacci.kk @@ -1,14 +1,20 @@ module fibonacci -pub fun main() +pub fun mainx() val n = 10000 println("The " ++ n.show ++ "th fibonacci number is " ++ fibonacci(10000).show) -fun fibonacci(n : int) : div int +fun fibonacci(n : int) : div int fib(n, 0, 1) -fun fib(n : int, x1 : int, x2 : int) : div int +fun fib(n : int, x1 : int, x2 : int) : div int if n<=0 then x1 else fib(n - 1, x2, x1+x2) +pub fun testx() + fibonacci(100).println + + +pub fun test2() + fibonacci(1000).println diff --git a/samples/basic/rbtree.kk b/samples/basic/rbtree.kk index f6d4ca7d2..22f737f82 100644 --- a/samples/basic/rbtree.kk +++ b/samples/basic/rbtree.kk @@ -15,7 +15,7 @@ type color type tree Node(color : color, left : tree, key : int, value : a, right : tree) Leaf - + fun is-red(t : tree) : bool match t @@ -32,7 +32,7 @@ fun balance-left(l :tree, k : int, v : a, r : tree) : tree Node(_, lx, kx, vx, rx) -> Node(Black, Node(Red, lx, kx, vx, rx), k, v, r) Leaf -> Leaf - + fun balance-right(l : tree, k : int, v : a, r : tree) : tree @@ -44,7 +44,7 @@ fun balance-right(l : tree, k : int, v : a, r : tree) : tree Node(_, lx, kx, vx, rx) -> Node(Black, l, k, v, Node(Red, lx, kx, vx, rx)) Leaf -> Leaf - + fun ins(t : tree, k : int, v : a) : tree match t @@ -88,7 +88,7 @@ fun make-tree(n : int) : tree // Count the nodes with `True` values. -fun count( t : tree ) : int +fun count( t : tree ) : int t.fold(0) fn(k,v,r) if v then r + 1 else r diff --git a/src/Backend/C/FromCore.hs b/src/Backend/C/FromCore.hs index 02cc06cf3..0ae20637f 100644 --- a/src/Backend/C/FromCore.hs +++ b/src/Backend/C/FromCore.hs @@ -2663,6 +2663,7 @@ reserved , "instanceof" , "new" , "return" + , "register" , "switch" , "this" , "throw" diff --git a/src/Common/ColorScheme.hs b/src/Common/ColorScheme.hs index 7094ca3a1..22fa00fc2 100644 --- a/src/Common/ColorScheme.hs +++ b/src/Common/ColorScheme.hs @@ -12,6 +12,8 @@ module Common.ColorScheme( ColorScheme(..) , Color(..) , defaultColorScheme + , darkColorScheme + , lightColorScheme -- * Flags , readColorFlags , ansiColor @@ -55,7 +57,7 @@ data ColorScheme = ColorScheme , colorTypeSpecial :: Color , colorTypeParam :: Color , colorNameQual :: Color - } + } deriving (Show, Eq) -- | The default color scheme defaultColorScheme, darkColorScheme, lightColorScheme :: ColorScheme @@ -89,7 +91,7 @@ darkColorScheme , colorTypeKeywordOp = colorType c -- colorReservedOp c , colorTypeParam = colorParameter c } - in c + in defaultTo c White lightColorScheme = let c = darkColorScheme { @@ -104,7 +106,44 @@ lightColorScheme , colorMarker = colorInterpreter c , colorString = Red } - in c + in defaultTo c Black + +defaultColor :: Color -> Color -> Color +defaultColor color clr + = if (clr == ColorDefault) then color else clr + +defaultTo :: ColorScheme -> Color -> ColorScheme +defaultTo cs color = + cs{ colorType = defaultColor color $ colorType cs + , colorParameter = defaultColor color $ colorParameter cs + , colorKind = defaultColor color $ colorKind cs + , colorMarker = defaultColor color $ colorMarker cs + , colorWarning = defaultColor color $ colorWarning cs + , colorError = defaultColor color $ colorError cs + , colorSource = defaultColor color $ colorSource cs + , colorInterpreter = defaultColor color $ colorInterpreter cs + , colorCommand = defaultColor color $ colorCommand cs + , colorKeyword = defaultColor color $ colorKeyword cs + , colorEffect = defaultColor color $ colorEffect cs + , colorRange = defaultColor color $ colorRange cs + , colorSep = defaultColor color $ colorSep cs + -- syntax coloring + , colorComment = defaultColor color $ colorComment cs + , colorReserved = defaultColor color $ colorReserved cs + , colorReservedOp = defaultColor color $ colorReservedOp cs + , colorSpecial = defaultColor color $ colorSpecial cs + , colorString = defaultColor color $ colorString cs + , colorNumber = defaultColor color $ colorNumber cs + , colorModule = defaultColor color $ colorModule cs + , colorCons = defaultColor color $ colorCons cs + , colorTypeCon = defaultColor color $ colorTypeCon cs + , colorTypeVar = defaultColor color $ colorTypeVar cs + , colorTypeKeyword = defaultColor color $ colorTypeKeyword cs + , colorTypeKeywordOp = defaultColor color $ colorTypeKeywordOp cs + , colorTypeSpecial = defaultColor color $ colorTypeSpecial cs + , colorTypeParam = defaultColor color $ colorTypeParam cs + , colorNameQual = defaultColor color $ colorNameQual cs + } emptyColorScheme = makeColorScheme ColorDefault diff --git a/src/Common/Error.hs b/src/Common/Error.hs index 204af4a0b..5e3065e00 100644 --- a/src/Common/Error.hs +++ b/src/Common/Error.hs @@ -9,9 +9,9 @@ Internal error monad. -} ----------------------------------------------------------------------------- -module Common.Error( Error, ErrorMessage(..), errorMsg, ok - , catchError, checkError, warningMsg, addWarnings, ignoreWarnings - , ppErrorMessage, errorWarning ) where +module Common.Error( Error, ErrorMessage(..), errorMsg, errorMsgPartial, ok + , catchError, checkError, checkPartial, setPartial, warningMsg, addWarnings, addPartialResult, ignoreWarnings + , ppErrorMessage, errorWarning, prettyWarnings ) where import Control.Monad import Control.Monad.Fail @@ -25,8 +25,8 @@ import Common.Message Errors --------------------------------------------------------------------------} -- | Error monad -data Error a = Error !ErrorMessage ![(Range,Doc)] - | Ok !a ![(Range,Doc)] +data Error b a = Error !ErrorMessage ![(Range,Doc)] (Maybe b) -- B is a partial result + | Ok !a ![(Range,Doc)] (Maybe b) -- | Error messages @@ -41,35 +41,61 @@ data ErrorMessage = ErrorGeneral !Range !Doc deriving (Show) -- | Check an 'Error' -checkError :: Error a -> Either ErrorMessage (a,[(Range,Doc)]) +checkError :: Error b a -> Either ErrorMessage (a,[(Range,Doc)]) checkError err = case err of - Error msg w -> Left (errorWarning w msg) - Ok x w -> Right (x,w) + Error msg w m -> Left (errorWarning w msg) + Ok x w m -> Right (x,w) -catchError :: Error a -> (ErrorMessage -> Error a) -> Error a +checkPartial :: Error b a -> Either (ErrorMessage, Maybe b) (a,[(Range,Doc)], Maybe b) +checkPartial err + = case err of + Error msg w m -> Left (errorWarning w msg,m) + Ok x w m -> Right (x,w,m) + +setPartial :: Maybe c -> Error b a -> Error c a +setPartial c err + = case err of + Error msg w m -> Error msg w c + Ok x w m -> Ok x w c + +catchError :: Error b a -> (ErrorMessage -> Error b a) -> Error b a catchError err handle = case err of - Error msg w -> addWarnings w (handle msg) - Ok x w -> Ok x w + Error msg w m -> addPartialResult (addWarnings w (handle msg)) m + Ok x w m -> Ok x w m -ok :: a -> Error a -ok x = Ok x [] +ok :: a -> Error b a +ok x = Ok x [] Nothing -errorMsg :: ErrorMessage -> Error a -errorMsg msg = Error msg [] +errorMsg :: ErrorMessage -> Error b a +errorMsg msg = Error msg [] Nothing -warningMsg :: (Range,Doc) -> Error () -warningMsg w - = Ok () [w] +errorMsgPartial :: ErrorMessage -> Maybe b -> Error b a +errorMsgPartial msg b = Error msg [] b +warningMsg :: (Range,Doc) -> Error b () +warningMsg w + = Ok () [w] Nothing -addWarnings :: [(Range,Doc)] -> Error a -> Error a +addWarnings :: [(Range,Doc)] -> Error b a -> Error b a addWarnings [] err = err addWarnings ws err = case err of - Error msg ws2 -> Error msg (ws ++ ws2) - Ok x ws2 -> Ok x (ws ++ ws2) + Error msg ws2 m -> Error msg (ws ++ ws2) m + Ok x ws2 m -> Ok x (ws ++ ws2) m + +addPartialResult :: Error b a -> Maybe b -> Error b a +addPartialResult err m + = case err of + Error msg ws m1 -> Error msg ws (m1 <|> m) + Ok x ws m1 -> Ok x ws (m1 <|> m) + +overridePartialResult :: Error b a -> Maybe b -> Error b a +overridePartialResult err m + = case err of + Error msg ws m1 -> Error msg ws (m <|> m1) + Ok x ws m1 -> Ok x ws (m <|> m1) errorWarning :: [(Range,Doc)] -> ErrorMessage -> ErrorMessage errorWarning [] msg = msg @@ -91,10 +117,10 @@ errorMerge err1 err2 unwarn (ErrorWarning warnings msg) = (warnings, msg) unwarn msg = ([],msg) -ignoreWarnings :: Error a -> Error a -ignoreWarnings (Error (ErrorWarning _ err) _) = Error err [] -ignoreWarnings (Error err _) = Error err [] -ignoreWarnings (Ok x _) = Ok x [] +ignoreWarnings :: Error b a -> Error b a +ignoreWarnings (Error (ErrorWarning _ err) _ m) = Error err [] m +ignoreWarnings (Error err _ m) = Error err [] m +ignoreWarnings (Ok x _ m) = Ok x [] m {-------------------------------------------------------------------------- pretty @@ -129,34 +155,34 @@ prettyWarnings endToo cscheme warnings {-------------------------------------------------------------------------- instances --------------------------------------------------------------------------} -instance Functor Error where +instance Functor (Error b) where fmap f e = case e of - Ok x w -> Ok (f x) w - Error msg w -> Error msg w + Ok x w m -> Ok (f x) w m + Error msg w m -> Error msg w m -instance Applicative Error where - pure x = Ok x [] - (<*>) = ap +instance Applicative (Error b) where + pure x = Ok x [] Nothing + (<*>) = ap -instance Monad Error where +instance Monad (Error b) where -- return = pure e >>= f = case e of - Ok x w -> addWarnings w (f x) - Error msg w -> Error msg w + Ok x w m -> addPartialResult (addWarnings w (f x)) m + Error msg w m -> Error msg w m -instance MonadFail Error where - fail s = Error (ErrorGeneral rangeNull (text s)) [] +instance MonadFail (Error b) where + fail s = Error (ErrorGeneral rangeNull (text s)) [] Nothing -instance MonadPlus Error where - mzero = Error ErrorZero [] +instance MonadPlus (Error b) where + mzero = Error ErrorZero [] Nothing mplus e1 e2 = case e1 of - Ok _ _ -> e1 - Error m1 w1 -> case e2 of - Ok _ _ -> e2 - Error m2 w2 -> Error (errorMerge m1 m2) (w1 ++ w2) + Ok{} -> e1 + Error m1 w1 m11 -> case e2 of + Ok{} -> addPartialResult e2 m11 + Error m2 w2 m12 -> Error (errorMerge m1 m2) (w1 ++ w2) (m12 `mplus` m11) -instance Alternative Error where +instance Alternative (Error b) where (<|>) = mplus empty = mzero diff --git a/src/Common/File.hs b/src/Common/File.hs index 739b60c35..c62811934 100644 --- a/src/Common/File.hs +++ b/src/Common/File.hs @@ -305,7 +305,8 @@ readTextFile :: FilePath -> IO (Maybe String) readTextFile fpath = B.exCatch (do content <- readFile fpath return (if null content then Just content else (seq (last content) $ Just content))) - (\exn -> return Nothing) + (\exn -> -- trace ("reading file " ++ fpath ++ " exception: " ++ exn) + return Nothing) writeTextFile :: FilePath -> String -> IO () writeTextFile fpath content diff --git a/src/Common/Range.hs b/src/Common/Range.hs index 9e46c9245..01c9ec789 100644 --- a/src/Common/Range.hs +++ b/src/Common/Range.hs @@ -14,7 +14,7 @@ module Common.Range ( Pos, makePos, minPos, maxPos, posColumn, posLine, posOfs , posMove8, posMoves8, posNull , Range, showFullRange - , makeRange, rangeNull, combineRange, rangeEnd, rangeStart + , makeRange, rangeNull, combineRange, rangeEnd, rangeStart, rangeLength , Ranged( getRange ), combineRanged , combineRangeds, combineRanges, extendRange , Source(Source,sourceName, sourceBString), sourceText, sourceFromRange @@ -275,6 +275,10 @@ rangeStart (Range p1 p2) = p1 rangeEnd :: Range -> Pos rangeEnd (Range p1 p2) = p2 +-- | Return the length of a range +rangeLength :: Range -> Int +rangeLength (Range p1 p2) = posOfs p2 - posOfs p1 + -- | Return the source of a range rangeSource :: Range -> Source rangeSource = posSource . rangeStart diff --git a/src/Common/Syntax.hs b/src/Common/Syntax.hs index 4c3fae317..1189233ef 100644 --- a/src/Common/Syntax.hs +++ b/src/Common/Syntax.hs @@ -75,7 +75,7 @@ data Platform = Platform{ sizePtr :: Int -- sizeof(intptr_t) , sizeSize :: Int -- sizeof(size_t) , sizeField :: Int -- sizeof(kk_field_t), usually intptr_t but may be smaller for compression , sizeHeader:: Int -- used for correct alignment calculation - } + } deriving Eq platform32, platform64, platform64c, platformJS, platformCS :: Platform platform32 = Platform 4 4 4 8 @@ -147,7 +147,7 @@ isHandlerNormal _ = False data OperationSort - = OpVal | OpFun | OpExcept | OpControlRaw | OpControl + = OpVal | OpFun | OpExcept | OpControlRaw | OpControl | OpControlErr deriving (Eq,Ord) instance Show OperationSort where @@ -157,6 +157,7 @@ instance Show OperationSort where OpExcept -> "brk" OpControl -> "ctl" OpControlRaw -> "rawctl" + OpControlErr -> "" readOperationSort :: String -> Maybe OperationSort readOperationSort s diff --git a/src/Compiler/Compile.hs b/src/Compiler/Compile.hs index d16cbdc6e..98a966970 100644 --- a/src/Compiler/Compile.hs +++ b/src/Compiler/Compile.hs @@ -9,6 +9,7 @@ Main module. -} ----------------------------------------------------------------------------- +{-# LANGUAGE InstanceSigs #-} module Compiler.Compile( -- * Compile compileFile , compileModule @@ -19,6 +20,7 @@ module Compiler.Compile( -- * Compile , compileValueDef, compileTypeDef , compileProgram , gammaFind + , codeGen -- * Types , Module(..) @@ -32,8 +34,8 @@ import Lib.Trace ( trace ) import Data.Char ( isAlphaNum, toLower, isSpace ) import System.Directory ( createDirectoryIfMissing, canonicalizePath, getCurrentDirectory, doesDirectoryExist ) -import Data.Maybe ( catMaybes ) -import Data.List ( isPrefixOf, intersperse ) +import Data.Maybe ( catMaybes, fromJust ) +import Data.List ( isPrefixOf, intersperse, intercalate ) import qualified Data.Set as S import Control.Applicative import Control.Monad ( ap, when ) @@ -51,7 +53,7 @@ import Common.Syntax import Common.Unique import Syntax.Syntax -- import Syntax.Lexer ( readInput ) -import Syntax.Parse ( parseProgramFromFile, parseValueDef, parseExpression, parseTypeDef, parseType ) +import Syntax.Parse ( parseProgramFromFile, parseValueDef, parseExpression, parseTypeDef, parseType, parseProgramFromString ) import Syntax.RangeMap import Syntax.Colorize ( colorize ) @@ -85,7 +87,7 @@ import Type.Pretty hiding ( verbose ) import Compiler.Options ( Flags(..), CC(..), BuildType(..), buildType, ccFlagsBuildFromFlags, unquote, prettyEnvFromFlags, colorSchemeFromFlags, prettyIncludePath, isValueFromFlags, fullBuildDir, outName, buildVariant, osName, targetExeExtension, - conanSettingsFromFlags, vcpkgFindRoot, onWindows, onMacOS) + conanSettingsFromFlags, vcpkgFindRoot, onWindows, onMacOS, Mode (ModeLanguageServer)) import Compiler.Module @@ -113,6 +115,7 @@ import Compiler.Package import Lib.Trace import qualified Data.Map +import Core.Core (Core(coreProgImports)) {-------------------------------------------------------------------------- @@ -127,47 +130,50 @@ data Terminal = Terminal{ termError :: ErrorMessage -> IO () } -data IOErr a = IOErr (IO (Error a)) +data IOErr b a = IOErr (IO (Error b a)) -runIOErr :: IOErr a -> IO (Error a) +runIOErr :: IOErr b a -> IO (Error b a) runIOErr (IOErr ie) = ie -liftError :: Error a -> IOErr a +liftErrorPartial :: c -> Error b a -> IOErr c a +liftErrorPartial partialT err = IOErr (return $ setPartial (Just partialT) err) + +liftError :: Error c a -> IOErr c a liftError err = IOErr (return err) -liftIO :: IO a -> IOErr a +liftIO :: IO a -> IOErr b a liftIO io = IOErr (do x <- io return (return x)) -lift :: IO (Error a) -> IOErr a +lift :: IO (Error b a) -> IOErr b a lift ie = IOErr ie -instance Functor IOErr where +instance Functor (IOErr b) where fmap f (IOErr ie) = IOErr (fmap (fmap f) ie) -instance Applicative IOErr where +instance Applicative (IOErr b) where pure x = IOErr (return (return x)) (<*>) = ap -instance Monad IOErr where +instance Monad (IOErr b) where -- return = pure (IOErr ie) >>= f = IOErr (do err <- ie - case checkError err of - Right (x,w) -> case f x of + case checkPartial err of + Right (x,w,b) -> case f x of IOErr ie' -> do err <- ie' - return (addWarnings w err) - Left msg -> return (errorMsg msg )) + return (addPartialResult (addWarnings w err) b) + Left (msg, b) -> return (errorMsgPartial msg b)) -instance F.MonadFail IOErr where +instance F.MonadFail (IOErr b) where fail = liftError . fail -bindIO :: IO (Error a) -> (a -> IO (Error b)) -> IO (Error b) +bindIO :: IO (Error b a) -> (a -> IO (Error b c)) -> IO (Error b c) bindIO io f = do err <- io - case checkError err of - Left msg -> return (errorMsg msg) - Right (x,w) -> fmap (addWarnings w) (f x) + case checkPartial err of + Left (msg, b) -> return (errorMsgPartial msg b) + Right (x,w,b) -> fmap (flip addPartialResult b . addWarnings w) (f x) gammaFind name g = case (gammaLookupQ name g) of @@ -175,33 +181,29 @@ gammaFind name g [] -> failure ("Compiler.Compile.gammaFind: can't locate " ++ show name) _ -> failure ("Compiler.Compile.gammaFind: multiple definitions for " ++ show name) - - - -compileExpression :: Terminal -> Flags -> Loaded -> CompileTarget () -> UserProgram -> Int -> String -> IO (Error Loaded) -compileExpression term flags loaded compileTarget program line input +compileExpression :: (FilePath -> Maybe (BString, FileTime)) -> Terminal -> Flags -> Loaded -> CompileTarget () -> UserProgram -> Int -> String -> IO (Error Loaded (Loaded, Maybe FilePath)) +compileExpression maybeContents term flags loaded compileTarget program line input = runIOErr $ do let qnameExpr = (qualify (getName program) nameExpr) - def <- liftError (parseExpression (semiInsert flags) (show nameInteractiveModule) line qnameExpr input) + def <- liftErrorPartial loaded (parseExpression (semiInsert flags) (show nameInteractiveModule) line qnameExpr input) let programDef = programAddDefs program [] [def] -- specialized code: either just call the expression, or wrap in a show function case compileTarget of -- run a particular entry point Executable name () | name /= nameExpr - -> compileProgram' term flags (loadedModules loaded) compileTarget "" programDef - + -> compileProgram' maybeContents term flags (loadedModules loaded) [] compileTarget "" programDef [] -- entry point is the expression: compile twice: -- first to get the type of the expression and create a 'show' wrapper, -- then to actually run the program | otherwise - -> do ld <- compileProgram' term flags{ evaluate = False } (loadedModules loaded) Object {-compileTarget-} "" programDef + -> do (ld, f) <- compileProgram' maybeContents term flags{ evaluate = False } (loadedModules loaded) [] Object {-compileTarget-} "" programDef [] let tp = infoType (gammaFind qnameExpr (loadedGamma ld)) (_,_,rho) = splitPredType tp -- _ <- liftError $ checkUnhandledEffects flags loaded nameExpr rangeNull rho case splitFunType rho of -- return unit: just run the expression (for its assumed side effect) Just (_,_,tres) | isTypeUnit tres - -> compileProgram' term flags (loadedModules ld) compileTarget "" programDef + -> compileProgram' maybeContents term flags (loadedModules ld) [] compileTarget "" programDef [] -- check if there is a show function, or use generic print if not. Just (_,_,tres) -> do -- ld <- compileProgram' term flags (loadedModules ld0) Nothing "" programDef @@ -218,16 +220,15 @@ compileExpression term flags loaded compileTarget program line input [mkApp (Var qnameShow False r) [mkApp (Var qnameExpr False r) []]] let defMain = Def (ValueBinder (qualify (getName program) nameMain) () (Lam [] expression r) r r) r Public (defFun []) InlineNever "" let programDef' = programAddDefs programDef [] [defMain] - compileProgram' term flags (loadedModules ld) (Executable nameMain ()) "" programDef' - return ld + compileProgram' maybeContents term flags (loadedModules ld) [] (Executable nameMain ()) "" programDef' [] - _ -> liftError $ errorMsg (ErrorGeneral rangeNull (text "no 'show' function defined for values of type:" <+> ppType (prettyEnvFromFlags flags) tres)) + _ -> liftErrorPartial loaded $ errorMsg (ErrorGeneral rangeNull (text "no 'show' function defined for values of type:" <+> ppType (prettyEnvFromFlags flags) tres)) -- mkApp (Var (qualify nameSystemCore (newName "gprintln")) False r) -- [mkApp (Var nameExpr False r) []] Nothing -> failure ("Compile.Compile.compileExpression: should not happen") -- no evaluation - _ -> compileProgram' term flags (loadedModules loaded) compileTarget "" programDef + _ -> compileProgram' (const Nothing) term flags (loadedModules loaded) [] compileTarget "" programDef [] errorModuleNotFound :: Flags -> Range -> Name -> ErrorMessage @@ -249,30 +250,31 @@ prettyEnv loaded flags = (prettyEnvFromFlags flags){ context = loadedName loaded, importsMap = loadedImportMap loaded } -compileType :: Terminal -> Flags -> Loaded -> UserProgram -> Int -> String -> IO (Error Loaded) +compileType :: Terminal -> Flags -> Loaded -> UserProgram -> Int -> String -> IO (Error Loaded Loaded) compileType term flags loaded program line input = runIOErr $ do let qnameType = qualify (getName program) nameType - tdef <- liftError $ parseType (semiInsert flags) (show nameInteractiveModule) line nameType input + tdef <- liftErrorPartial loaded $ parseType (semiInsert flags) (show nameInteractiveModule) line nameType input let programDef = programAddDefs (programRemoveAllDefs program) [tdef] [] -- typeCheck (loaded) flags line programDef - compileProgram' term flags (loadedModules loaded) Object "" programDef + (ld, _) <- compileProgram' (const Nothing) term flags (loadedModules loaded) [] Object "" programDef [] + return ld -compileValueDef :: Terminal -> Flags -> Loaded -> UserProgram -> Int -> String -> IO (Error (Name,Loaded)) +compileValueDef :: Terminal -> Flags -> Loaded -> UserProgram -> Int -> String -> IO (Error Loaded (Name,Loaded)) compileValueDef term flags loaded program line input = runIOErr $ - do def <- liftError $ parseValueDef (semiInsert flags) (show nameInteractiveModule) line input + do def <- liftErrorPartial loaded $ parseValueDef (semiInsert flags) (show nameInteractiveModule) line input let programDef = programAddDefs program [] [def] - ld <- compileProgram' term flags (loadedModules loaded) Object "" programDef + (ld, _) <- compileProgram' (const Nothing) term flags (loadedModules loaded) [] Object "" programDef [] return (qualify (getName program) (defName def),ld) -compileTypeDef :: Terminal -> Flags -> Loaded -> UserProgram -> Int -> String -> IO (Error (Name,Loaded)) +compileTypeDef :: Terminal -> Flags -> Loaded -> UserProgram -> Int -> String -> IO (Error Loaded (Name,Loaded)) compileTypeDef term flags loaded program line input = runIOErr $ - do (tdef,cdefs) <- liftError $ parseTypeDef (semiInsert flags) (show nameInteractiveModule) line input + do (tdef,cdefs) <- liftErrorPartial loaded $ parseTypeDef (semiInsert flags) (show nameInteractiveModule) line input let programDef = programAddDefs program [tdef] cdefs - ld <- compileProgram' term flags (loadedModules loaded) Object "" programDef + (ld, _) <- compileProgram' (const Nothing) term flags (loadedModules loaded) [] Object "" programDef [] return (qualify (getName program) (typeDefName tdef),ld) @@ -281,35 +283,40 @@ compileTypeDef term flags loaded program line input These are meant to be called from the interpreter/main compiler ---------------------------------------------------------------} -compileModuleOrFile :: Terminal -> Flags -> Modules -> String -> Bool -> IO (Error Loaded) -compileModuleOrFile term flags modules fname force - | any (not . validModChar) fname = compileFile term flags modules Object fname +compileModuleOrFile :: (FilePath -> Maybe (BString, FileTime)) -> Maybe BString -> Terminal -> Flags -> Modules -> Modules -> String -> Bool -> CompileTarget () -> [Name] -> IO (Error Loaded (Loaded, Maybe FilePath)) +compileModuleOrFile maybeContents contents term flags modules cachedModules fname force compileTarget importPath + | any (not . validModChar) fname = compileFile maybeContents contents term flags modules cachedModules compileTarget importPath fname | otherwise = -- trace ("compileModuleOrFile: " ++ show fname ++ ", modules: " ++ show (map modName modules)) $ - do let modName = pathToModuleName fname - exist <- searchModule flags "" modName - case (exist) of + do + let modName = pathToModuleName fname + exist <- searchModule flags "" modName + case (exist) of Just (fpath) -> compileModule term (if force then flags{ forceModule = fpath } else flags) - modules modName - _ -> do fexist <- searchSourceFile flags "" fname - runIOErr $ - case (fexist) of - Just (root,stem) - -> compileProgramFromFile term flags modules Object root stem - Nothing - -> liftError $ errorMsg $ errorFileNotFound flags fname + modules cachedModules modName compileTarget importPath + _ -> do + fexist <- searchSourceFile flags "" fname + runIOErr $ + case (fexist) of + Just (root,stem) + -> compileProgramFromFile maybeContents contents term flags modules cachedModules Object importPath root stem + Nothing + -> liftError $ errorMsg $ errorFileNotFound flags fname where validModChar c = isAlphaNum c || c `elem` "/_" -compileFile :: Terminal -> Flags -> Modules -> CompileTarget () -> FilePath -> IO (Error Loaded) -compileFile term flags modules compileTarget fpath +compileFile :: (FilePath -> Maybe (BString, FileTime)) -> Maybe BString -> Terminal -> Flags -> Modules -> Modules -> CompileTarget () -> [Name] -> FilePath -> IO (Error Loaded (Loaded, Maybe FilePath)) +compileFile maybeContents contents term flags modules cachedModules compileTarget importPath fpath = runIOErr $ do mbP <- liftIO $ searchSourceFile flags "" fpath case mbP of Nothing -> liftError $ errorMsg (errorFileNotFound flags fpath) Just (root,stem) - -> compileProgramFromFile term flags modules compileTarget root stem + -> do + -- trace ("Includes : " ++ show (includePath flags)) $ return () + -- trace ("Root: " ++ root ++ " STEM: " ++ stem) $ return () + compileProgramFromFile maybeContents contents term flags modules cachedModules compileTarget importPath root stem -- | Make a file path relative to a set of given paths: return the (maximal) root and stem -- if it is not relative to the paths, return dirname/notdir @@ -322,34 +329,32 @@ makeRelativeToPaths paths fname (root,stem) -compileModule :: Terminal -> Flags -> Modules -> Name -> IO (Error Loaded) -compileModule term flags modules name -- todo: take force into account +compileModule :: Terminal -> Flags -> Modules -> Modules -> Name -> CompileTarget () -> [Name] -> IO (Error Loaded (Loaded, Maybe FilePath)) +compileModule term flags modules cachedModules name compileTarget importPath -- todo: take force into account = runIOErr $ do let imp = ImpProgram (Import name name rangeNull Private) - loaded <- resolveImports name term flags "" initialLoaded{ loadedModules = modules } [imp] + loaded <- resolveImports compileTarget (const Nothing) (newName "") term flags "" initialLoaded{ loadedModules = modules } cachedModules importPath [imp] -- trace ("compileModule: loaded modules: " ++ show (map modName (loadedModules loaded))) $ return () case filter (\m -> modName m == name) (loadedModules loaded) of - (mod:_) -> return loaded{ loadedModule = mod } + (mod:_) -> return (loaded{ loadedModule = mod }, Nothing) [] -> fail $ "Compiler.Compile.compileModule: module not found in imports: " ++ show name ++ " not in " ++ show (map (show . modName) (loadedModules loaded)) {--------------------------------------------------------------- Internal compilation ---------------------------------------------------------------} -compileProgram :: Terminal -> Flags -> Modules -> CompileTarget () -> FilePath -> UserProgram -> IO (Error Loaded) -compileProgram term flags modules compileTarget fname program - = runIOErr $ compileProgram' term flags modules compileTarget fname program +compileProgram :: Terminal -> Flags -> Modules -> Modules -> CompileTarget () -> FilePath -> UserProgram -> [Name] -> IO (Error Loaded (Loaded, Maybe FilePath)) +compileProgram term flags modules cachedModules compileTarget fname program importPath + = runIOErr $ compileProgram' (const Nothing) term flags modules cachedModules compileTarget fname program importPath - -compileProgramFromFile :: Terminal -> Flags -> Modules -> CompileTarget () -> FilePath -> FilePath -> IOErr Loaded -compileProgramFromFile term flags modules compileTarget rootPath stem - = do let fname = joinPath rootPath stem +compileProgramFromFile :: (FilePath -> Maybe (BString, FileTime)) -> Maybe BString -> Terminal -> Flags -> Modules -> Modules -> CompileTarget () -> [Name] -> FilePath -> FilePath -> IOErr Loaded (Loaded, Maybe FilePath) +compileProgramFromFile maybeContents contents term flags modules cachedModules compileTarget importPath rootPath stem + = do fname <- liftIO $ realPath $ normalize $ joinPath rootPath stem -- trace ("compileProgramFromFile: " ++ show fname ++ ", modules: " ++ show (map modName modules)) $ return () liftIO $ termPhaseDoc term (color (colorInterpreter (colorScheme flags)) (text "compile:") <+> color (colorSource (colorScheme flags)) (text (normalizeWith '/' fname))) - liftIO $ termPhase term ("parsing " ++ fname) exist <- liftIO $ doesFileExist fname if (exist) then return () else liftError $ errorMsg (errorFileNotFound flags fname) - program <- lift $ parseProgramFromFile (semiInsert flags) fname + program <- lift $ case contents of { Just x -> return $ parseProgramFromString (semiInsert flags) x fname; _ -> parseProgramFromFile (semiInsert flags) fname} let isSuffix = -- asciiEncode True (noexts stem) `endsWith` asciiEncode True (show (programName program)) -- map (\c -> if isPathSep c then '/' else c) (noexts stem) show (pathToModuleName (noexts stem)) `endsWith` show (programName program) @@ -364,42 +369,54 @@ compileProgramFromFile term flags modules compileTarget rootPath stem parens (ppcolor colorSource $ text $ dquote $ stem) )) let stemName = nameFromFile stem - compileProgram' term flags modules compileTarget fname program{ programName = stemName } + -- let flags2 = flags{forceModule = fname} + compileProgram' maybeContents term flags modules cachedModules compileTarget fname program{ programName = stemName } importPath nameFromFile :: FilePath -> Name nameFromFile fname = pathToModuleName $ dropWhile isPathSep $ noexts fname data CompileTarget a - = Object + = InMemory + | Object | Library - | Executable { entry :: Name, info :: a } + | Executable { entry :: Name, info :: a } deriving Show + +isInMemory :: CompileTarget a -> Bool +isInMemory InMemory = True +isInMemory _ = False isExecutable (Executable _ _) = True isExecutable _ = False -compileProgram' :: Terminal -> Flags -> Modules -> CompileTarget () -> FilePath -> UserProgram -> IOErr Loaded -compileProgram' term flags modules compileTarget fname program +compileProgram' :: (FilePath -> Maybe (BString, FileTime)) -> Terminal -> Flags -> Modules -> Modules -> CompileTarget () -> FilePath -> UserProgram -> [Name] -> IOErr Loaded (Loaded, Maybe FilePath) +compileProgram' maybeContents term flags modules cachedModules compileTarget fname program importPath = do liftIO $ termPhase term ("compile program' " ++ show (getName program)) - ftime <- liftIO (getFileTimeOrCurrent fname) let name = getName program outIFace = outName flags (showModName name) ++ ifaceExtension - mod = (moduleNull name){ + ftime <- liftIO (getCurrentFileTime fname maybeContents) + iftime <- liftIO (maybeGetCurrentFileTime outIFace (const Nothing)) + let mod = (moduleNull name){ modPath = outIFace, - modSourcePath = fname, + modSourcePath = normalize fname, modProgram = (Just program), - modCore = failure "Compiler.Compile.compileProgram: recursive module import", - modTime = ftime + modCore = failure ("Compiler.Compile.compileProgram: recursive module import (" ++ fname ++ ")"), + modSourceTime = ftime, + modTime = iftime, + modOutputTime = iftime } allmods = addOrReplaceModule mod modules loaded = initialLoaded { loadedModule = mod , loadedModules = allmods } + depTarget = case compileTarget of + InMemory -> InMemory + _ -> Object -- trace ("compile file: " ++ show fname ++ "\n time: " ++ show ftime ++ "\n latest: " ++ show (loadedLatest loaded)) $ return () liftIO $ termPhase term ("resolve imports " ++ show (getName program)) - loaded1 <- resolveImports (getName program) term flags (dirname fname) loaded (map ImpProgram (programImports program)) - --trace (" loaded modules: " ++ show (map modName (loadedModules loaded1))) $ return () - --trace ("------\nloaded1:\n" ++ show (loadedNewtypes loaded1) ++ "\n----") $ return () + loaded1 <- resolveImports depTarget maybeContents (getName program) term flags (dirname fname) loaded cachedModules importPath (map ImpProgram (programImports program)) + -- trace (" loaded modules: " ++ show (map modName (loadedModules loaded1))) $ return () + --trace ("------\nloaded1:\n" ++ show (loadedNewtypes loaded1) ++ "\n----") $ return () -- trace ("inlines: " ++ show (loadedInlines loaded1)) $ return () if (name /= nameInteractiveModule || verbose flags > 0) @@ -412,7 +429,8 @@ compileProgram' term flags modules compileTarget fname program (imp:_) -> importVis imp -- TODO: get max in if (modName mod == name) then [] else [Core.Import (modName mod) (modPackagePath mod) vis (Core.coreProgDoc (modCore mod))] - (loaded2a, coreDoc) <- liftError $ typeCheck loaded1 flags 0 coreImports program + + (loaded2a, coreDoc) <- liftErrorPartial loaded1 $ typeCheck loaded1 flags 0 coreImports program ftime when (showCore flags) $ liftIO (termDoc term (vcat [ text "-------------------------", @@ -422,6 +440,8 @@ compileProgram' term flags modules compileTarget fname program text "-------------------------" ])) + -- use time of type check as modTime + time <- liftIO getCurrentTime -- cull imports to only the real dependencies let mod = loadedModule loaded2a inlineDefs = case (modInlines mod) of @@ -430,50 +450,68 @@ compileProgram' term flags modules compileTarget fname program deps = Core.dependencies inlineDefs (modCore mod) imps = filter (\imp -> isPublic (Core.importVis imp) || Core.importName imp == nameSystemCore || S.member (Core.importName imp) deps) (Core.coreProgImports (modCore mod)) - mod' = mod{ modCore = (modCore mod){ Core.coreProgImports = imps } } + mod' = mod{ modCore = (modCore mod){ Core.coreProgImports = imps }, modTime = Just time } loaded2 = loaded2a{ loadedModule = mod' } -- codegen liftIO $ termPhase term ("codegen " ++ show (getName program)) - (newTarget,loaded3) <- liftError $ - case compileTarget of - Executable entryName _ - -> let mainName = if (isQualified entryName) then entryName else qualify (getName program) (entryName) in - case gammaLookupQ mainName (loadedGamma loaded2) of - [] -> errorMsg (ErrorGeneral rangeNull (text "there is no 'main' function defined" <-> text "hint: use the '-l' flag to generate a library?")) - infos-> let mainType = TFun [] (TCon (TypeCon nameTpIO kindEffect)) typeUnit -- just for display, so IO can be TCon - isMainType tp = case expandSyn tp of - TFun [] eff resTp -> True -- resTp == typeUnit - _ -> False - in case filter (isMainType . infoType) infos of - [InfoFun{infoType=tp,infoRange=r}] - -> do mbF <- checkUnhandledEffects flags loaded2 mainName r tp - case mbF of - Nothing -> return (Executable mainName tp, loaded2) - Just f -> - let mainName2 = qualify (getName program) (newHiddenName "hmain") - expression = App (Var (if (isHiddenName mainName) then mainName -- .expr - else unqualify mainName -- main - ) False r) [] r - defMain = Def (ValueBinder (unqualify mainName2) () (Lam [] (f expression) r) r r) r Public (defFun []) InlineNever "" - program2 = programAddDefs program [] [defMain] - in do (loaded3,_) <- ignoreWarnings $ typeCheck loaded1 flags 0 coreImports program2 - return (Executable mainName2 tp, loaded3) -- TODO: refine the type of main2 - [info] - -> errorMsg (ErrorGeneral (infoRange info) (text "'main' must be declared as a function (fun)")) - [] -> errorMsg (ErrorGeneral rangeNull (text "the type of 'main' must be a function without arguments" <-> - table [(text "expected type", ppType (prettyEnvFromFlags flags) mainType) - ,(text "inferred type", ppType (prettyEnvFromFlags flags) (head (map infoType infos)))])) - _ -> errorMsg (ErrorGeneral rangeNull (text "found multiple definitions for the 'main' function")) - Object -> return (Object,loaded2) - Library -> return (Library,loaded2) - - loaded4 <- liftIO $ codeGen term flags newTarget loaded3 + (newTarget,loaded3) <- doCodeGen term flags loaded2 loaded1 compileTarget program coreImports + (loaded4, outFile) <- liftIO $ case newTarget of + InMemory -> return (loaded3{loadedModule = (loadedModule loaded3){modOutputTime = Nothing}}, Nothing) + _ -> do + -- TODO: Get output file time and check if it is different from the source time used to type-check + (loadedNew, mbRun) <- codeGen term flags newTarget loaded3 + -- run the program + when (evaluate flags && isExecutable newTarget) $ + compilerCatch "program run" term () $ + case mbRun of + Just (_,run) -> do termPhase term "evaluate" + termDoc term space + run + _ -> termDoc term space + return (loadedNew, fmap fst mbRun) -- liftIO $ termDoc term (text $ show (loadedGamma loaded4)) - -- trace (" final loaded modules: " ++ show (map modName (loadedModules loaded4))) $ return () - return loaded4{ loadedModules = addOrReplaceModule (loadedModule loaded4) (loadedModules loaded4) } - -checkUnhandledEffects :: Flags -> Loaded -> Name -> Range -> Type -> Error (Maybe (UserExpr -> UserExpr)) + --trace (" final loaded modules: " ++ show (map modName (loadedModules loaded4))) $ return () + return (loaded4{ loadedModules = addOrReplaceModule (loadedModule loaded4) (loadedModules loaded4) }, outFile) + +doCodeGen :: Terminal -> Flags -> Loaded -> Loaded -> CompileTarget a -> Program UserType UserKind -> [Core.Import] -> IOErr Loaded (CompileTarget Scheme, Loaded) +doCodeGen term flags loaded0 loaded1 compileTarget program coreImports = do + liftIO $ termPhase term ("codegen " ++ show (getName program)) + liftErrorPartial loaded1 $ + case compileTarget of + Executable entryName _ + -> let mainName = if (isQualified entryName) then entryName else qualify (getName program) (entryName) in + case gammaLookupQ mainName (loadedGamma loaded0) of + [] -> errorMsg (ErrorGeneral rangeNull (text "there is no 'main' function defined" <-> text "hint: use the '-l' flag to generate a library?")) + infos-> let mainType = TFun [] (TCon (TypeCon nameTpIO kindEffect)) typeUnit -- just for display, so IO can be TCon + isMainType tp = case expandSyn tp of + TFun [] eff resTp -> True -- resTp == typeUnit + _ -> False + in case filter (isMainType . infoType) infos of + [InfoFun{infoType=tp,infoRange=r}] + -> do mbF <- checkUnhandledEffects flags loaded0 mainName r tp + case mbF of + Nothing -> return (Executable mainName tp, loaded0) + Just f -> + let mainName2 = qualify (getName program) (newHiddenName "hmain") + expression = App (Var (if (isHiddenName mainName) then mainName -- .expr + else unqualify mainName -- main + ) False r) [] r + defMain = Def (ValueBinder (unqualify mainName2) () (Lam [] (f expression) r) r r) r Public (defFun []) InlineNever "" + program2 = programAddDefs program [] [defMain] + in do (loaded3,_) <- ignoreWarnings $ typeCheck loaded1 flags 0 coreImports program2 (modSourceTime $ loadedModule loaded1) + return (Executable mainName2 tp, loaded3) -- TODO: refine the type of main2 + [info] + -> errorMsg (ErrorGeneral (infoRange info) (text "'main' must be declared as a function (fun)")) + [] -> errorMsg (ErrorGeneral rangeNull (text "the type of 'main' must be a function without arguments" <-> + table [(text "expected type", ppType (prettyEnvFromFlags flags) mainType) + ,(text "inferred type", ppType (prettyEnvFromFlags flags) (head (map infoType infos)))])) + _ -> errorMsg (ErrorGeneral rangeNull (text "found multiple definitions for the 'main' function")) + Object -> return (Object,loaded0) + Library -> return (Library,loaded0) + InMemory -> return (InMemory,loaded0) + +checkUnhandledEffects :: Flags -> Loaded -> Name -> Range -> Type -> Error Loaded (Maybe (UserExpr -> UserExpr)) checkUnhandledEffects flags loaded name range tp = case expandSyn tp of TFun _ eff _ @@ -484,7 +522,7 @@ checkUnhandledEffects flags loaded name range tp where exclude = [nameTpCps,nameTpNamed] -- nameTpAsync - combine :: Effect -> Maybe (UserExpr -> UserExpr) -> [Effect] -> Error (Maybe (UserExpr -> UserExpr)) + combine :: Effect -> Maybe (UserExpr -> UserExpr) -> [Effect] -> Error Loaded (Maybe (UserExpr -> UserExpr)) combine eff mf [] = return mf combine eff mf (l:ls) = case getHandledEffectX exclude l of Nothing -> combine eff mf ls @@ -526,26 +564,26 @@ impFullName (ImpProgram imp) = importFullName imp impFullName (ImpCore cimp) = Core.importName cimp -resolveImports :: Name -> Terminal -> Flags -> FilePath -> Loaded -> [ModImport] -> IOErr (Loaded) -resolveImports mname term flags currentDir loaded0 imports0 +resolveImports :: CompileTarget () -> (FilePath -> Maybe (BString, FileTime)) -> Name -> Terminal -> Flags -> FilePath -> Loaded -> Modules -> [Name] -> [ModImport] -> IOErr Loaded Loaded +resolveImports compileTarget maybeContents mname term flags currentDir loaded0 cachedModules importPath imports0 = do -- trace (show mname ++ ": resolving imports: current modules: " ++ show (map (show . modName) (loadedModules loaded0)) ++ "\n") $ return () - (imports,resolved) <- resolveImportModules mname term flags currentDir (removeModule mname (loadedModules loaded0)) imports0 + (imports,resolved) <- resolveImportModules compileTarget maybeContents mname term flags currentDir (removeModule mname (loadedModules loaded0)) cachedModules (mname:importPath) imports0 -- trace (show mname ++ ": resolved imports, imported: " ++ show (map (show . modName) imports) ++ "\n resolved to: " ++ show (map (show . modName) resolved) ++ "\n") $ return () let load msg loaded [] = return loaded load msg loaded (mod:mods) = do let (loaded1,errs) = loadedImportModule (isValueFromFlags flags) loaded mod (rangeNull) (modName mod) -- trace ("loaded " ++ msg ++ " module: " ++ show (modName mod)) $ return () - mapM_ (\err -> liftError (errorMsg err)) errs + mapM_ (\err -> liftErrorPartial loaded0 (errorMsg err)) errs load msg loaded1 mods - loadInlines :: Loaded -> Module -> IOErr [Core.InlineDef] + loadInlines :: Loaded -> Module -> IOErr Loaded [Core.InlineDef] loadInlines loaded mod = case modInlines mod of Right idefs -> return idefs Left parseInlines -> do -- trace ("load module inline defs: " ++ show (modName mod)) $ return () - liftError $ parseInlines (loadedGamma loaded) -- process inlines after all have been loaded + liftErrorPartial loaded $ parseInlines (loadedGamma loaded) -- process inlines after all have been loaded loadedImp <- load "import" loaded0 imports @@ -557,19 +595,26 @@ resolveImports mname term flags currentDir loaded0 imports0 -- trace ("resolved inlines: " ++ show (length inlineDefss, length inlineDefs)) $ return () return loadedImp{ loadedModules = modsFull, loadedInlines = inlines } -resolveImportModules :: Name -> Terminal -> Flags -> FilePath -> [Module] -> [ModImport] -> IOErr ([Module],[Module]) -resolveImportModules mname term flags currentDir resolved [] +resolveImportModules :: CompileTarget () -> (FilePath -> Maybe (BString, FileTime)) -> Name -> Terminal -> Flags -> FilePath -> [Module] -> Modules -> [Name] -> [ModImport] -> IOErr Loaded ([Module],[Module]) +resolveImportModules compileTarget maybeContents mname term flags currentDir resolved cachedModules importPath [] = return ([],resolved) -resolveImportModules mname term flags currentDir resolved0 (imp:imps) - = do -- trace (show mname ++ ": resolving imported modules: " ++ show (impName imp) ++ ", resolved: " ++ show (map (show . modName) resolved0)) $ return () +resolveImportModules compileTarget maybeContents mname term flags currentDir resolved0 cachedModules importPath (imp:imps) + = if impName imp `elem` importPath then do + liftError $ errorMsg $ ErrorStatic [(getRange imp, text "cyclic module dependency detected when importing: " <+> ppName (prettyEnvFromFlags flags) mname <+> text " import path: " <-> vsep (reverse (map (ppName (prettyEnvFromFlags flags)) importPath)))] + return (resolved0,resolved0) + else + do -- trace ("\t" ++ show mname ++ ": resolving imported modules: " ++ show (impName imp) ++ ", resolved: " ++ show (map (show . modName) resolved0) ++ ", path:" ++ show importPath) $ return () (mod,resolved1) <- case filter (\m -> impName imp == modName m) resolved0 of - (mod:_) -> return (mod,resolved0) - _ -> resolveModule term flags currentDir resolved0 imp - -- trace (" newly resolved from " ++ show (modName mod) ++ ": " ++ show (map (show . modName) resolved1)) $ return () + (mod:_) -> + if modInMemory mod && not (isInMemory compileTarget) || Just flags /= modCompiled mod then resolveModule compileTarget maybeContents term flags currentDir resolved0 cachedModules importPath imp + else + return (mod,resolved0) + _ -> resolveModule compileTarget maybeContents term flags currentDir resolved0 cachedModules importPath imp + -- trace ("\tnewly resolved from " ++ show (modName mod) ++ ": " ++ show (map (show . modName) resolved1)) $ return () let imports = Core.coreProgImports $ modCore mod pubImports = map ImpCore (filter (\imp -> Core.importVis imp == Public) imports) -- trace (" resolve further imports (from " ++ show (modName mod) ++ ") (added module: " ++ show (impName imp) ++ " public imports: " ++ show (map (show . impName) pubImports) ++ ")") $ return () - (needed,resolved2) <- resolveImportModules mname term flags currentDir resolved1 (pubImports ++ imps) + (needed,resolved2) <- resolveImportModules compileTarget maybeContents mname term flags currentDir resolved1 cachedModules importPath (pubImports ++ imps) let needed1 = filter (\m -> modName m /= modName mod) needed -- no dups return (mod:needed1,resolved2) @@ -584,9 +629,26 @@ searchModule flags currentDir name Nothing -> searchPackageIface flags currentDir Nothing name Just iface -> return (Just iface) - -resolveModule :: Terminal -> Flags -> FilePath -> [Module] -> ModImport -> IOErr (Module,[Module]) -resolveModule term flags currentDir modules mimp +getCurrentFileTime :: FilePath -> (FilePath -> Maybe (BString, FileTime)) -> IO FileTime +getCurrentFileTime fp maybeContents = do + f <- realPath fp + case maybeContents (normalize f) of + Just (_, t) -> return t + Nothing -> getFileTimeOrCurrent fp + +maybeGetCurrentFileTime :: FilePath -> (FilePath -> Maybe (BString, FileTime)) -> IO (Maybe FileTime) +maybeGetCurrentFileTime fp maybeContents = do + f <- realPath fp + case maybeContents (normalize f) of + Just (_, t) -> return $ Just t + Nothing -> do + -- trace ("File " ++ show fp ++ " not in virtual filesystem") $ return () + ft <- getFileTime fp + if ft == fileTime0 then return Nothing else return $ -- (trace $ "Get maybe " ++ show ft) $ + Just ft + +resolveModule :: CompileTarget () -> (FilePath -> Maybe (BString, FileTime)) -> Terminal -> Flags -> FilePath -> [Module] -> Modules -> [Name] -> ModImport -> IOErr Loaded (Module,[Module]) +resolveModule compileTarget maybeContents term flags currentDir modules cachedModules importPath mimp = -- trace ("resolve module: " ++ show (impFullName mimp) ++ ", resolved: " ++ show (map (show . modName) modules) ++ ", in " ++ show currentDir) $ case mimp of -- program import @@ -604,15 +666,15 @@ resolveModule term flags currentDir modules mimp Nothing -> liftError $ errorMsg $ errorModuleNotFound flags (importRange imp) name Just iface -> -- it is a package interface do -- TODO: check there is no (left-over) iface in the outputDir? - loadFromIface iface "" "" - Just iface -> do loadFromIface iface "" "" + loadFromIface iface "" "" (importName imp) + Just iface -> do loadFromIface iface "" "" (importName imp) Just (root,stem,mname) -> -- source found, search output iface do mbIface <- liftIO $ searchOutputIface flags mname - -- trace ("load from program: " ++ show (mbSource,mbIface)) $ return () + -- trace ("load from program: " ++ show (mbSource,mbIface)) $ return () case mbIface of - Nothing -> loadFromSource modules root stem - Just iface -> loadDepend iface root stem + Nothing -> loadFromSource False False modules root stem mname + Just iface -> loadDepend iface root stem mname -- core import in source ImpCore cimp | (null (Core.importPackage cimp)) && (currentDir == fullBuildDir flags) -> @@ -623,14 +685,14 @@ resolveModule term flags currentDir modules mimp (Nothing,Nothing) -> liftError $ errorMsg $ errorModuleNotFound flags rangeNull name (Nothing,Just (root,stem,mname)) - -> loadFromSource modules root stem + -> loadFromSource False False modules root stem mname (Just iface,Nothing) -> do let cscheme = (colorSchemeFromFlags flags) liftIO $ termDoc term $ color (colorWarning cscheme) $ text "warning: interface" <+> color (colorModule cscheme) (pretty name) <+> text "found but no corresponding source module" - loadFromIface iface "" "" + loadFromIface iface "" "" (Core.importName cimp) (Just iface,Just (root,stem,mname)) - -> loadDepend iface root stem + -> loadDepend iface root stem mname -- core import of package ImpCore cimp -> @@ -638,38 +700,84 @@ resolveModule term flags currentDir modules mimp -- trace ("core import pkg: " ++ Core.importPackage cimp ++ "/" ++ show name ++ ": found: " ++ show (mbIface)) $ return () case mbIface of Nothing -> liftError $ errorMsg $ errorModuleNotFound flags rangeNull name - Just iface -> loadFromIface iface "" "" + Just iface -> loadFromIface iface "" "" (Core.importName cimp) where name = impFullName mimp - loadDepend iface root stem - = do let srcpath = joinPath root stem - ifaceTime <- liftIO $ getFileTimeOrCurrent iface - sourceTime <- liftIO $ getFileTimeOrCurrent srcpath + tryLoadFromCache :: Name -> FilePath -> FilePath -> IOErr Loaded (Maybe (Module, Modules)) + tryLoadFromCache mname root stem + = do + let srcpath = joinPath root stem + sourceTime0 <- liftIO $ maybeGetCurrentFileTime srcpath maybeContents + case sourceTime0 of + Nothing -> trace ("Error " ++ show srcpath ++ " doesn't exist") $ return Nothing + Just sourceTime -> + case lookupImportName mname cachedModules of + Just mod -> + if srcpath /= forceModule flags && modSourceTime mod == sourceTime + then do + -- trace ("Loading module " ++ show mname ++ " from cache") $ return () + x <- loadFromModule mname (modPath mod) root stem srcpath mod + return $ Just x + else + -- trace ("Found mod " ++ show mname ++ " in cache but was forced or old modTime " ++ show (modSourceTime mod) ++ " srctime " ++ show sourceTime ++ " force " ++ forceModule flags ) + return Nothing + _ -> + -- trace ("Could not find mod " ++ show mname ++ " in cache " ++ show (map modSourcePath cachedModules)) $ + return Nothing + + loadDepend iface root stem mname + = -- trace ("loadDepend " ++ iface ++ " root: " ++ root ++ " stem: " ++ stem) $ + do let srcpath = joinPath root stem + ifaceTime <- liftIO $ getCurrentFileTime iface maybeContents + sourceTime <- liftIO $ getCurrentFileTime srcpath maybeContents + -- trace ("loadDepend: " ++ show (ifaceTime, sourceTime)) $ return () case lookupImport iface modules of - Just mod -> - if (srcpath /= forceModule flags && modTime mod >= sourceTime) - then -- trace ("module " ++ show (name) ++ " already loaded") $ - -- loadFromModule iface root stem mod - return (mod,modules) -- TODO: revise! do proper dependency checking instead.. - else -- trace ("module " ++ show ( name) ++ " already loaded but not recent enough..\n " ++ show (modTime mod, sourceTime)) $ - loadFromSource modules root stem - Nothing -> - -- trace ("module " ++ show (name) ++ " not yet loaded") $ - if (not (rebuild flags) && srcpath /= forceModule flags && ifaceTime >= sourceTime) - then loadFromIface iface root stem - else loadFromSource modules root stem - - loadFromSource modules1 root fname - = -- trace ("loadFromSource: " ++ root ++ "/" ++ fname) $ - do loadedImp <- compileProgramFromFile term flags modules1 Object root fname - let mod = loadedModule loadedImp - allmods = addOrReplaceModule mod modules - return (mod, loadedModules loadedImp) - - loadFromIface iface root stem - = -- trace ("loadFromIFace: " ++ iface ++ ": " ++ root ++ "/" ++ stem ++ "\n in modules: " ++ show (map modName modules)) $ + Just mod -> + if (srcpath /= forceModule flags && modSourceTime mod == sourceTime) + then -- trace ("module " ++ show (name) ++ " already loaded") $ + return (mod,modules) -- TODO: revise! do proper dependency checking instead.. + else if (not (rebuild flags) && srcpath /= forceModule flags && ifaceTime >= sourceTime) + then loadFromIface iface root stem mname + else loadFromSource False True modules root stem mname + _ -> do + cached <- tryLoadFromCache mname root stem + case cached of + Just (mod, mods) -> + do liftIO $ termPhaseDoc term (color (colorInterpreter (colorScheme flags)) (text "reusing:") <+> + color (colorSource (colorScheme flags)) + (pretty (nameFromFile iface))) + return (mod, mods) + Nothing -> + -- trace ("module " ++ show (name) ++ " not yet loaded") $ + if (not (rebuild flags) && srcpath /= forceModule flags && ifaceTime >= sourceTime) + then loadFromIface iface root stem mname + else loadFromSource False True modules root stem mname + + loadFromSource force genUpdate modules1 root stem mname + = -- trace ("loadFromSource: " ++ show force ++ " " ++ " update " ++ show genUpdate ++ " root:" ++ root ++ " stem:" ++ stem) $ + do + let fname = joinPath root stem + cached <- tryLoadFromCache mname root stem + mbIface <- liftIO $ searchOutputIface flags name + let noNeedsGen = isJust mbIface || isInMemory compileTarget + -- trace ("loadFromSource: " ++ show (force, genUpdate, noNeedsGen, mbIface, compileTarget)) $ return () + case cached of + Just (mod, modules) | not genUpdate && not force && noNeedsGen -> + do liftIO $ termPhaseDoc term (color (colorInterpreter (colorScheme flags)) (text "reusing:") <+> + color (colorSource (colorScheme flags)) + (pretty mname)) + return (mod, modules) + _ -> do + f <- liftIO $ realPath fname + (loadedImp, _) <- compileProgramFromFile maybeContents (fst <$> maybeContents (normalize f)) term flags modules1 cachedModules (if genUpdate then Object else compileTarget) importPath root stem + let mod = loadedModule loadedImp + allmods = addOrReplaceModule mod modules + return (mod, loadedModules loadedImp) + + loadFromIface iface root stem mname + = -- trace ("loadFromIFace: " ++ iface ++ ": root:" ++ root ++ " stem:" ++ stem ++ "\n in modules: " ++ show (map modName modules)) $ do let (pkgQname,pkgLocal) = packageInfoFromDir (packages flags) (dirname iface) loadMessage msg = liftIO $ termPhaseDoc term (color (colorInterpreter (colorScheme flags)) (text msg) <+> color (colorSource (colorScheme flags)) @@ -679,32 +787,62 @@ resolveModule term flags currentDir modules mimp -> do loadMessage "reusing:" return mod Nothing - -> do loadMessage "loading:" - ftime <- liftIO $ getFileTime iface - (core,parseInlines) <- lift $ parseCore iface - -- let core = uniquefy core0 - outIFace <- liftIO $ copyIFaceToOutputDir term flags iface core - let mod = Module (Core.coreName core) outIFace (joinPath root stem) pkgQname pkgLocal [] - Nothing -- (error ("getting program from core interface: " ++ iface)) - core (Left parseInlines) Nothing ftime - return mod - loadFromModule (modPath mod){-iface-} root stem mod - - loadFromModule iface root source mod + -> do + loadMessage "loading:" + iftime <- liftIO $ getFileTime iface + ftime <- liftIO $ getCurrentFileTime (joinPath root stem) maybeContents + mbCore <- liftIO $ parseCore iface + (core,parseInlines) <- liftError mbCore + -- let core = uniquefy core0 + outIFace <- liftIO $ copyIFaceToOutputDir term flags iface core + let mod = Module (Core.coreName core) outIFace (joinPath root stem) pkgQname pkgLocal [] + Nothing -- (error ("getting program from core interface: " ++ iface)) + core (Just flags) False (Left parseInlines) Nothing ftime (Just iftime) Nothing + return mod + loadFromModule mname (modPath mod){-iface-} root stem (joinPath root stem) mod + + loadFromModule mname iface root stem source mod = -- trace ("load from module: " ++ iface ++ ": " ++ root ++ "/" ++ source) $ do -- loaded = initialLoaded { loadedModule = mod -- , loadedModules = allmods -- } -- (loadedImp,impss) <- resolveImports term flags (dirname iface) loaded (map ImpCore (Core.coreProgImports (modCore mod))) - (imports,resolved1) <- resolveImportModules name term flags (dirname iface) modules (map ImpCore (Core.coreProgImports (modCore mod))) - let latest = maxFileTimes (map modTime imports) - -- trace ("loaded iface: " ++ show iface ++ "\n time: " ++ show (modTime mod) ++ "\n latest: " ++ show (latest)) $ return () - if (latest >= modTime mod + (imports,resolved1) <- resolveImportModules compileTarget maybeContents name term flags (dirname iface) modules cachedModules (name:importPath) (map ImpCore (Core.coreProgImports (modCore mod))) + let latest = maxFileTimes (map modSourceTime imports) + + let allmods = addOrReplaceModule mod resolved1 + result = (mod{ modSourcePath = normalize $ joinPath root stem }, allmods) + -- trace ("loaded iface: " ++ show iface ++ "\n time: " ++ show (modTime mod) ++ "\n latest: " ++ show (latest)) $ return () + if (latest > (fromJust $ modTime mod) && not (null source)) -- happens if no source is present but (package) depencies have updated... - then loadFromSource resolved1 root source -- load from source after all - else do liftIO $ copyPkgIFaceToOutputDir term flags iface (modCore mod) (modPackageQPath mod) imports - let allmods = addOrReplaceModule mod resolved1 - return (mod{ modSourcePath = joinPath root source }, allmods) + then do + -- trace ("iface " ++ show (modName mod) ++ " is out of date, reloading..." ++ (show (modTime mod) ++ " dependencies:\n" ++ intercalate "\n" (map (\m -> show (modName m, modTime m)) imports))) $ return () + -- load from source after all + loadFromSource True True resolved1 root stem (nameFromFile iface) + else + -- trace ("using loaded module: " ++ show (modName mod) ++ " compile target " ++ show compileTarget) $ + case compileTarget of + InMemory -> return result + _ -> do + -- trace ("loaded module requires compiling") $ return () + outputTime <- liftIO $ getFileTime iface + if fromJust (modTime mod) > outputTime then do + -- (imports,resolved1) <- resolveImportModules Object maybeContents name term flags (dirname iface) modules cachedModules (name:importPath) (map ImpCore (Core.coreProgImports (modCore mod))) + let allmods = addOrReplaceModule mod resolved1 + -- Compile from cache if CompileTarget is Executable / Object and module is InMemory and outputFileTime < modTime + liftIO $ termPhaseDoc term (color (colorInterpreter (colorScheme flags)) (text "generating:") <+> + color (colorSource (colorScheme flags)) + (pretty (modName mod))) + liftIO $ copyPkgIFaceToOutputDir term flags iface (modCore mod) (modPackageQPath mod) imports + let loaded = initialLoaded { + loadedModule = mod, + loadedModules = allmods + } + (newLoaded, _) <- liftIO $! codeGen term flags Object loaded + return (loadedModule newLoaded, loadedModules newLoaded) + else return result + + lookupImport :: FilePath {- interface name -} -> Modules -> Maybe Module @@ -712,7 +850,18 @@ lookupImport imp [] = Nothing lookupImport imp (mod:mods) = if (modPath mod == imp) then Just (mod) - else lookupImport imp mods + else + -- trace ("lookupImport: " ++ show imp ++ " /= " ++ show (modPath mod)) $ + lookupImport imp mods + +lookupImportName :: Name -> Modules -> Maybe Module +lookupImportName imp [] = Nothing +lookupImportName imp (mod:mods) + = if modName mod == imp + then Just mod + else + -- trace ("lookupImportName: " ++ show imp ++ " /= " ++ show (modName mod)) $ + lookupImportName imp mods searchPackageIface :: Flags -> FilePath -> Maybe PackageName -> Name -> IO (Maybe FilePath) @@ -774,8 +923,8 @@ searchIncludeIface flags currentDir name {--------------------------------------------------------------- ---------------------------------------------------------------} -typeCheck :: Loaded -> Flags -> Int -> [Core.Import] -> UserProgram -> Error (Loaded,Doc) -typeCheck loaded flags line coreImports program +typeCheck :: Loaded -> Flags -> Int -> [Core.Import] -> UserProgram -> FileTime -> Error Loaded (Loaded,Doc) +typeCheck loaded flags line coreImports program srcTime = do -- static checks -- program1 <- {- mergeSignatures (colorSchemeFromFlags flags) -} (implicitPromotion program) let program0 = -- implicitPromotion (loadedConstructors loaded) @@ -788,14 +937,14 @@ typeCheck loaded flags line coreImports program fixitiesAll = fixitiesNew [(name,fix) | FixDef name fix rng vis <- programFixDefs program0] (program2,_) <- fixityResolve (colorSchemeFromFlags flags) (fixitiesCompose (loadedFixities loaded) fixitiesAll) program0 - let warnings = warnings1 fname = sourceName (programSource program) module1 = (moduleNull (getName program)) - { modSourcePath = fname + { modSourcePath = normalize fname , modPath = outName flags (showModName (getName program)) ++ ifaceExtension , modProgram = Just program , modWarnings = warnings + , modSourceTime = srcTime } -- module0 = loadedModule loaded fixitiesPub = fixitiesNew [(name,fix) | FixDef name fix rng vis <- programFixDefs program0, vis == Public] @@ -809,7 +958,7 @@ typeCheck loaded flags line coreImports program addWarnings warnings (inferCheck loaded1 flags line coreImports program2 ) -inferCheck :: Loaded -> Flags -> Int -> [Core.Import] -> UserProgram -> Error (Loaded,Doc) +inferCheck :: Loaded -> Flags -> Int -> [Core.Import] -> UserProgram -> Error Loaded (Loaded,Doc) inferCheck loaded0 flags line coreImports program = Core.runCorePhase (loadedUnique loaded0) $ do -- kind inference @@ -819,7 +968,7 @@ inferCheck loaded0 flags line coreImports program (isValueFromFlags flags) (colorSchemeFromFlags flags) (platform flags) - (if (outHtml flags > 0) then Just rangeMapNew else Nothing) + (if (outHtml flags > 0 || genRangeMap flags) then Just rangeMapNew else Nothing) (loadedImportMap loaded0) (loadedKGamma loaded0) (loadedSynonyms loaded0) @@ -840,14 +989,13 @@ inferCheck loaded0 flags line coreImports program traceDefGroups title = do dgs <- Core.getCoreDefs - -- let doc = Core.Pretty.prettyCore (prettyEnvFromFlags flags){ coreIface = False, coreShowDef = True } C [] + -- let doc = Core.Pretty.prettyCore (prettyEnvFromFlags flags){ coreIface = False, coreShowDef = True } C [] -- (coreProgram{ Core.coreProgDefs = dgs }) trace (unlines (["","/* -----------------", title, "--------------- */"] ++ -- ++ [show doc])) $ return () map showDef (Core.flattenDefGroups dgs))) $ return () where showDef def = show (Core.Pretty.prettyDef (penv{coreShowDef=True}) def) - - + -- Type inference (gamma,cdefs,mbRangeMap) <- inferTypes @@ -903,7 +1051,7 @@ inferCheck loaded0 flags line coreImports program simplifyDupN -- traceDefGroups "inlined" - -- specialize + -- specialize specializeDefs <- if (isPrimitiveModule (Core.coreProgName coreProgram)) then return [] else Core.withCoreDefs (\defs -> extractSpecializeDefs (loadedInlines loaded) defs) -- traceM ("Spec defs:\n" ++ unlines (map show specializeDefs)) @@ -943,7 +1091,7 @@ inferCheck loaded0 flags line coreImports program -- simplify open applications (needed before inlining open defs) simplifyNoDup - -- traceDefGroups "open resolved" + -- traceDefGroups "open resolved" -- monadic lifting to create fast inlined paths monadicLift penv @@ -984,7 +1132,8 @@ inferCheck loaded0 flags line coreImports program , loadedModule = (loadedModule loaded){ modCore = coreProgramFinal, modRangeMap = mbRangeMap, - modInlines = Right allInlineDefs + modInlines = Right allInlineDefs, + modCompiled = Just flags } , loadedInlines = inlinesExtends allInlineDefs (loadedInlines loaded) } @@ -1007,9 +1156,9 @@ capitalize s _ -> s -codeGen :: Terminal -> Flags -> CompileTarget Type -> Loaded -> IO Loaded +codeGen :: Terminal -> Flags -> CompileTarget Type -> Loaded -> IO (Loaded, Maybe (FilePath, IO())) codeGen term flags compileTarget loaded - = compilerCatch "code generation" term loaded $ + = compilerCatch "code generation" term (loaded, Nothing) $ do let mod = loadedModule loaded outBase = outName flags (showModName (modName mod)) @@ -1053,12 +1202,12 @@ codeGen term flags compileTarget loaded withNewFilePrinter (outBase ++ ".xmp.html") $ \printer -> genDoc cenv (loadedKGamma loaded) (loadedGamma loaded) (modCore mod) printer - mbRun <- backend term flags (loadedModules loaded) compileTarget outBase (modCore mod) + mbRun <- backend term flags (loadedModules loaded) compileTarget outBase (modCore mod) -- write interface file last so on any error it will not be written writeDocW 10000 outIface ifaceDoc ftime <- getFileTimeOrCurrent outIface - let mod1 = (loadedModule loaded){ modTime = ftime } + let mod1 = (loadedModule loaded){ modTime = Just ftime, modOutputTime = Just ftime, modInMemory=False } loaded1 = loaded{ loadedModule = mod1 } -- copy final exe if -o is given @@ -1076,16 +1225,7 @@ codeGen term flags compileTarget loaded color (colorSource (colorScheme flags)) (text (normalizeWith pathSep exe)) _ -> return () - -- run the program - when ((evaluate flags && isExecutable compileTarget)) $ - compilerCatch "program run" term () $ - case mbRun of - Just (_,run) -> do termPhase term $ "evaluate" - termDoc term $ space - run - _ -> termDoc term $ space - - return loaded1 -- { loadedArities = arities, loadedExternals = externals } + return (loaded1, mbRun) -- { loadedArities = arities, loadedExternals = externals } where concatMaybe :: [Maybe a] -> [a] concatMaybe mbs = concatMap (maybe [] (\x -> [x])) mbs @@ -1099,7 +1239,7 @@ codeGen term flags compileTarget loaded -- imported modules. newtypesAll = foldr1 newtypesCompose (map (extractNewtypes . modCore) (loadedModule loaded : loadedModules loaded)) in codeGenC (modSourcePath (loadedModule loaded)) - -- (loadedNewtypes loaded) + -- (loadedNewtypes loaded) newtypesAll (loadedBorrowed loaded) (loadedUnique loaded) @@ -1218,9 +1358,6 @@ codeGenJS term flags modules compileTarget outBase core do let stksize = if (stackSize flags == 0) then 100000 else (stackSize flags `div` 1024) return (Just (outjs, runCommand term flags [node flags,"--stack-size=" ++ show stksize,outjs])) - - - codeGenC :: FilePath -> Newtypes -> Borrowed -> Int -> Terminal -> Flags -> [Module] -> CompileTarget Type -> FilePath -> Core.Core -> IO (Maybe (FilePath,IO ())) codeGenC sourceFile newtypes borrowed0 unique0 term flags modules compileTarget outBase core0 = -- compilerCatch "c compilation" term Nothing $ @@ -1251,9 +1388,9 @@ codeGenC sourceFile newtypes borrowed0 unique0 term flags modules compileTarget let cc = ccomp flags eimports = externalImportsFromCore (target flags) bcore clibs = clibsFromCore flags bcore - extraIncDirs <- fmap concat $ mapM (copyCLibrary term flags cc) eimports + extraIncDirs <- concat <$> mapM (copyCLibrary term flags cc) eimports - -- compile + -- compile ccompile term flags cc outBase extraIncDirs [outC] -- compile and link? @@ -1270,16 +1407,15 @@ codeGenC sourceFile newtypes borrowed0 unique0 term flags modules compileTarget -- cmakeLib term flags cc "kklib" (ccLibFile cc "kklib") cmakeGeneratorFlag kklibObj <- kklibBuild term flags cc "kklib" (ccObjFile cc "kklib") - let objs = [kklibObj] ++ - [outName flags (ccObjFile cc (showModName mname)) - | mname <- (map modName modules ++ [Core.coreProgName core0])] + let objs = kklibObj : [outName flags (ccObjFile cc (showModName mname)) + | mname <- map modName modules ++ [Core.coreProgName core0]] syslibs= concat [csyslibsFromCore flags mcore | mcore <- map modCore modules] ++ ccompLinkSysLibs flags ++ (if onWindows && not (isTargetWasm (target flags)) then ["bcrypt","psapi","advapi32"] else ["m","pthread"]) libs = -- ["kklib"] -- [normalizeWith '/' (outName flags (ccLibFile cc "kklib"))] ++ ccompLinkLibs flags - -- ++ + -- ++ clibs ++ concat [clibsFromCore flags mcore | mcore <- map modCore modules] @@ -1377,7 +1513,7 @@ copyCLibrary term flags cc eimport Just (libPath,includes) -> do termPhaseDoc term (color (colorInterpreter (colorScheme flags)) (text "library:") <+> color (colorSource (colorScheme flags)) (text libPath)) - -- this also renames a suffixed libname to a canonical name (e.g. /pcre2-8d.lib -> /pcre2-8.lib) + -- this also renames a suffixed libname to a canonical name (e.g. /pcre2-8d.lib -> /pcre2-8.lib) copyBinaryIfNewer (rebuild flags) libPath (outName flags (ccLibFile cc clib)) return includes Nothing diff --git a/src/Compiler/Module.hs b/src/Compiler/Module.hs index 1c1bd29f9..377e63f2c 100644 --- a/src/Compiler/Module.hs +++ b/src/Compiler/Module.hs @@ -46,6 +46,8 @@ import Core.Borrowed ( Borrowed, borrowedEmpty, borrowedExtendICore ) import Syntax.RangeMap import Compiler.Package ( PackageName, joinPkg ) import qualified Core.Core as Core +import Data.Maybe (fromJust) +import Compiler.Options (Flags) {-------------------------------------------------------------------------- Compilation @@ -61,9 +63,13 @@ data Module = Module{ modName :: Name , modWarnings :: [(Range,Doc)] , modProgram :: Maybe (Program UserType UserKind) -- not for interfaces , modCore :: Core.Core - , modInlines :: Either (Gamma -> Error [Core.InlineDef]) ([Core.InlineDef]) + , modCompiled :: Maybe Flags + , modInMemory :: Bool + , modInlines :: Either (Gamma -> Error () [Core.InlineDef]) ([Core.InlineDef]) , modRangeMap :: Maybe RangeMap - , modTime :: FileTime + , modSourceTime :: FileTime + , modTime :: Maybe FileTime + , modOutputTime :: Maybe FileTime } data Loaded = Loaded{ loadedGamma :: Gamma @@ -80,9 +86,13 @@ data Loaded = Loaded{ loadedGamma :: Gamma , loadedBorrowed :: Borrowed } +instance Show Loaded where + show ld + = show (map modName $ loadedModules ld) + loadedLatest :: Loaded -> FileTime loadedLatest loaded - = maxFileTimes (map modTime (loadedModules loaded)) + = maxFileTimes (map (fromJust . modTime) (loadedModules loaded)) initialLoaded :: Loaded initialLoaded @@ -101,7 +111,7 @@ initialLoaded moduleNull :: Name -> Module moduleNull modName - = Module (modName) "" "" "" "" [] Nothing (Core.coreNull modName) (Left (\g -> return [])) Nothing fileTime0 + = Module (modName) "" "" "" "" [] Nothing (Core.coreNull modName) Nothing True (Left (\g -> return [])) Nothing fileTime0 Nothing Nothing loadedName :: Loaded -> Name loadedName ld @@ -162,7 +172,7 @@ addOrReplaceModule :: Module -> Modules -> Modules addOrReplaceModule mod [] = [mod] addOrReplaceModule mod (m:ms) - = if (modPath mod == modPath m) + = if modPath mod == modPath m then mod:ms else m : addOrReplaceModule mod ms diff --git a/src/Compiler/Options.hs b/src/Compiler/Options.hs index 34663405d..cdfab08af 100644 --- a/src/Compiler/Options.hs +++ b/src/Compiler/Options.hs @@ -18,12 +18,14 @@ module Compiler.Options( -- * Command line options , colorSchemeFromFlags , prettyIncludePath , isValueFromFlags + , updateFlagsFromArgs , CC(..), BuildType(..), ccFlagsBuildFromFlags , buildType, unquote , outName, fullBuildDir, buildVariant , cpuArch, osName , optionCompletions , targetExeExtension + , targets , conanSettingsFromFlags , vcpkgFindRoot , onWindows, onMacOS @@ -83,11 +85,13 @@ prettyIncludePath flags data Mode = ModeHelp | ModeVersion - | ModeCompiler { files :: [FilePath] } - | ModeInteractive { files :: [FilePath] } + | ModeCompiler { files :: [FilePath] } + | ModeInteractive { files :: [FilePath] } + | ModeLanguageServer { files :: [FilePath] } data Option = Interactive + | LanguageServer | Version | Help | Flag (Flags -> Flags) @@ -165,6 +169,8 @@ data Flags , coreCheck :: Bool , enableMon :: Bool , semiInsert :: Bool + , genRangeMap :: Bool + , languageServerPort :: Int , localBinDir :: FilePath -- directory of koka executable , localDir :: FilePath -- install prefix: /usr/local , localLibDir :: FilePath -- precompiled object files: /lib/koka/v2.x.x /-/libkklib.a, /-/std_core.kki, ... @@ -186,7 +192,7 @@ data Flags , useStdAlloc :: Bool -- don't use mimalloc for better asan and valgrind support , optSpecialize :: Bool , mimallocStats :: Bool - } + } deriving Eq flagsNull :: Flags flagsNull @@ -261,6 +267,8 @@ flagsNull False -- coreCheck True -- enableMonadic True -- semi colon insertion + False -- generate range map + 6061 -- language server port "" -- koka executable dir "" -- prefix dir (default: /..) "" -- localLib dir @@ -292,6 +300,9 @@ isVersion _ = False isInteractive Interactive = True isInteractive _ = False +isLanguageServer LanguageServer = True +isLanguageServer _ = False + isValueFromFlags flags = dataInfoIsValue @@ -308,6 +319,7 @@ options = (\(xss,yss) -> (concat xss, concat yss)) $ unzip [ option ['?','h'] ["help"] (NoArg Help) "show this information" , option [] ["version"] (NoArg Version) "show the compiler version" , option ['p'] ["prompt"] (NoArg Interactive) "interactive mode" + , option [] ["language-server"] (NoArg LanguageServer) "language server mode" , flag ['e'] ["execute"] (\b f -> f{evaluate= b}) "compile and execute" , flag ['c'] ["compile"] (\b f -> f{evaluate= not b}) "only compile, do not execute (default)" , option ['i'] ["include"] (OptArg includePathFlag "dirs") "add to module search path (empty resets)" @@ -388,6 +400,7 @@ options = (\(xss,yss) -> (concat xss, concat yss)) $ unzip , hide $ fflag ["specialize"] (\b f -> f{optSpecialize=b}) "enable inline specialization" , hide $ fflag ["unroll"] (\b f -> f{optUnroll=(if b then 1 else 0)}) "enable recursive definition unrolling" , hide $ fflag ["eagerpatbind"] (\b f -> f{optEagerPatBind=b}) "load pattern fields as early as possible" + , numOption (-1) "port" [] ["lsport"] (\i f -> f{languageServerPort=i}) "Language Server port to connect to" -- deprecated , hide $ option [] ["cmake"] (ReqArg cmakeFlag "cmd") "use to invoke cmake" @@ -440,24 +453,6 @@ options = (\(xss,yss) -> (concat xss, concat yss)) $ unzip configstr short long opts argDesc f desc = config short long (map (\s -> (s,s)) opts) argDesc f desc - - targets :: [(String,Flags -> Flags)] - targets = - [("c", \f -> f{ target=C LibC, platform=platform64 }), - ("c64", \f -> f{ target=C LibC, platform=platform64 }), - ("c32", \f -> f{ target=C LibC, platform=platform32 }), - ("c64c", \f -> f{ target=C LibC, platform=platform64c }), - ("js", \f -> f{ target=JS JsNode, platform=platformJS }), - ("jsnode", \f -> f{ target=JS JsNode, platform=platformJS }), - ("jsweb", \f -> f{ target=JS JsWeb, platform=platformJS }), - ("wasm", \f -> f{ target=C Wasm, platform=platform32 }), - ("wasm32", \f -> f{ target=C Wasm, platform=platform32 }), - ("wasm64", \f -> f{ target=C Wasm, platform=platform64 }), - ("wasmjs", \f -> f{ target=C WasmJs, platform=platform32 }), - ("wasmweb",\f -> f{ target=C WasmWeb, platform=platform32 }), - ("cs", \f -> f{ target=CS, platform=platformCS }) - ] - targetFlag t f = case lookup t targets of Just update -> update f @@ -593,6 +588,23 @@ readHtmlBases s (_:post) -> (pre,post) _ -> ("",xs) +targets :: [(String,Flags -> Flags)] +targets = + [("c", \f -> f{ target=C LibC, platform=platform64 }), + ("c64", \f -> f{ target=C LibC, platform=platform64 }), + ("c32", \f -> f{ target=C LibC, platform=platform32 }), + ("c64c", \f -> f{ target=C LibC, platform=platform64c }), + ("js", \f -> f{ target=JS JsNode, platform=platformJS }), + ("jsnode", \f -> f{ target=JS JsNode, platform=platformJS }), + ("jsweb", \f -> f{ target=JS JsWeb, platform=platformJS }), + ("wasm", \f -> f{ target=C Wasm, platform=platform32 }), + ("wasm32", \f -> f{ target=C Wasm, platform=platform32 }), + ("wasm64", \f -> f{ target=C Wasm, platform=platform64 }), + ("wasmjs", \f -> f{ target=C WasmJs, platform=platform32 }), + ("wasmweb",\f -> f{ target=C WasmWeb, platform=platform32 }), + ("cs", \f -> f{ target=CS, platform=platformCS }) + ] + -- | Environment table environment :: [ (String, String, (String -> [String]), String) ] environment @@ -632,6 +644,18 @@ getOptions extra args <- getArgs processOptions flagsNull (env ++ words extra ++ args) +updateFlagsFromArgs :: Flags -> String -> Maybe Flags +updateFlagsFromArgs flags0 args = + let + (preOpts,postOpts) = span (/="--") (words args) + flags1 = case postOpts of + [] -> flags0 + (_:rest) -> flags0{ execOpts = concat (map (++" ") rest) } + (options,files,errs0) = getOpt Permute optionsAll preOpts + errs = errs0 ++ extractErrors options + in if (null errs) + then Just $ extractFlags flags1 options else Nothing + processOptions :: Flags -> [String] -> IO (Flags,Flags,Mode) processOptions flags0 opts = let (preOpts,postOpts) = span (/="--") opts @@ -645,6 +669,7 @@ processOptions flags0 opts mode = if (any isHelp options) then ModeHelp else if (any isVersion options) then ModeVersion else if (any isInteractive options) then ModeInteractive files + else if (any isLanguageServer options) then ModeLanguageServer files else if (null files) then ModeInteractive files else ModeCompiler files flags = case mode of @@ -658,6 +683,7 @@ processOptions flags0 opts (localDir,localLibDir,localShareDir,localBinDir) <- getKokaDirs (localLibDir flags) (localShareDir flags) buildDir + normalizedIncludes <- mapM realPath (includePath flags) -- cc ccmd <- if (ccompPath flags == "") then detectCC (target flags) @@ -719,8 +745,10 @@ processOptions flags0 opts asan = asan, useStdAlloc = stdAlloc, editor = ed, - includePath = (localShareDir ++ "/lib") : includePath flags, + includePath = (localShareDir ++ "/lib") : (map normalize normalizedIncludes), + genRangeMap = outHtml flags > 0 || any isLanguageServer options, vcpkgTriplet= triplet + {- vcpkgRoot = vcpkgRoot, @@ -914,6 +942,10 @@ data CC = CC{ ccName :: String, ccObjFile :: String -> FilePath -- make object file namen } +instance Eq CC where + CC{ccName = name1, ccPath = path1, ccFlags = flags1, ccFlagsBuild = flagsB1, ccFlagsCompile= flagsC1, ccFlagsLink=flagsL1} == + CC{ccName = name2, ccPath = path2, ccFlags = flags2, ccFlagsBuild = flagsB2, ccFlagsCompile= flagsC2, ccFlagsLink=flagsL2} + = name1 == name2 && path1 == path2 && flags1 == flags2 && flagsB1 == flagsB2 && flagsC1 == flagsC2 && flagsL1 == flagsL2 targetExeExtension target = case target of diff --git a/src/Compiler/Package.hs b/src/Compiler/Package.hs index f855f788e..e6858cfef 100644 --- a/src/Compiler/Package.hs +++ b/src/Compiler/Package.hs @@ -38,12 +38,12 @@ import Lib.JSON type PackageName = String data Packages = Packages { packages :: [Package], - roots :: [FilePath] } + roots :: [FilePath] } deriving Eq data Package = Package { pkgDir :: FilePath, -- /x/node_modules/A/lib pkgQualName :: PackageName, -- A/B/C pkgLocal :: FilePath, -- lib - pkgSub :: [Package] } + pkgSub :: [Package] } deriving Eq packagesEmpty :: Packages packagesEmpty = Packages [] [] diff --git a/src/Core/AnalysisMatch.hs b/src/Core/AnalysisMatch.hs index 0cc0f47aa..9ace1eda7 100644 --- a/src/Core/AnalysisMatch.hs +++ b/src/Core/AnalysisMatch.hs @@ -207,7 +207,7 @@ lookupConInfos newtypes tp = case expandSyn tp of TCon tcon -> case lookupDataInfo newtypes (typeconName tcon) of Just di -> dataInfoGetConInfos di -- [] for open or literals - Nothing -> trace ("Core.AnalysisMatch.lookupConInfos: not found: " ++ show (typeconName tcon) ++ ": " ++ show newtypes) $ + Nothing -> trace ("Core.AnalysisMatch.lookupConInfos: not found: " ++ show (typeconName tcon)) $ [] TApp t targs -> lookupConInfos newtypes t -- list _ -> -- trace ("Core.AnalysisMatch.lookupConInfos: not a tcon: " ++ show (pretty t)) $ diff --git a/src/Core/CTail.hs b/src/Core/CTail.hs index 2f5afdc8c..436f59a4f 100644 --- a/src/Core/CTail.hs +++ b/src/Core/CTail.hs @@ -43,7 +43,7 @@ import Core.Pretty -------------------------------------------------------------------------- -- Reference count transformation -------------------------------------------------------------------------- -ctailOptimize :: Pretty.Env -> Newtypes -> Gamma -> Bool -> CorePhase () +ctailOptimize :: Pretty.Env -> Newtypes -> Gamma -> Bool -> CorePhase b () ctailOptimize penv newtypes gamma useContextPath = liftCorePhaseUniq $ \uniq defs -> runUnique uniq (uctailOptimize penv newtypes gamma useContextPath defs) diff --git a/src/Core/Check.hs b/src/Core/Check.hs index 4a7413295..6c0193381 100644 --- a/src/Core/Check.hs +++ b/src/Core/Check.hs @@ -43,7 +43,7 @@ import qualified Type.Operations as Op ( instantiateNoEx ) import qualified Data.Set as S -checkCore :: Bool -> Bool -> Env -> Gamma -> CorePhase () +checkCore :: Bool -> Bool -> Env -> Gamma -> CorePhase b () checkCore liberalEffects allowPartialApps prettyEnv gamma = do uniq <- unique defGroups <- getCoreDefs diff --git a/src/Core/CheckFBIP.hs b/src/Core/CheckFBIP.hs index 586a979f3..a7b157320 100644 --- a/src/Core/CheckFBIP.hs +++ b/src/Core/CheckFBIP.hs @@ -53,7 +53,7 @@ trace s x = x -checkFBIP :: Pretty.Env -> Platform -> Newtypes -> Borrowed -> Gamma -> CorePhase () +checkFBIP :: Pretty.Env -> Platform -> Newtypes -> Borrowed -> Gamma -> CorePhase b () checkFBIP penv platform newtypes borrowed gamma = do uniq <- unique defGroups <- getCoreDefs diff --git a/src/Core/Core.hs b/src/Core/Core.hs index cd017a517..4cd8e6af1 100644 --- a/src/Core/Core.hs +++ b/src/Core/Core.hs @@ -609,55 +609,55 @@ instance Show InlineDef where = "InlineDef " ++ show sort ++ " " ++ show name ++ " " ++ (if isRec then "rec " else "") ++ show kind ++ " " ++ show cost ++ " " ++ show specArgs -newtype CorePhase a = CP (Int -> DefGroups -> Error (CPState a)) +newtype CorePhase b a = CP (Int -> DefGroups -> Error b (CPState a)) data CPState a = CPState !a !Int !DefGroups -instance Functor CorePhase where +instance Functor (CorePhase b) where fmap f (CP cp) = CP (\uniq defs -> do (CPState x uniq' defs') <- cp uniq defs return (CPState (f x) uniq' defs')) -instance Applicative CorePhase where +instance Applicative (CorePhase b) where pure x = CP (\uniq defs -> return (CPState x uniq defs)) (<*>) = ap -instance Monad CorePhase where +instance Monad (CorePhase b) where -- return = pure (CP cp) >>= f = CP (\uniq defs -> do (CPState x uniq' defs') <- cp uniq defs case f x of CP cp' -> cp' uniq' defs') -instance HasUnique CorePhase where +instance HasUnique (CorePhase b) where updateUnique f = CP (\uniq defs -> return (CPState uniq (f uniq) defs)) setUnique uniq = CP (\_ defs -> return (CPState () uniq defs)) unique = CP (\uniq defs -> return (CPState uniq uniq defs)) -getCoreDefs :: CorePhase DefGroups +getCoreDefs :: CorePhase b DefGroups getCoreDefs = CP (\uniq defs -> return (CPState defs uniq defs)) -setCoreDefs :: DefGroups -> CorePhase () +setCoreDefs :: DefGroups -> CorePhase b () setCoreDefs defs = CP (\uniq _ -> return (CPState () uniq defs)) -withCoreDefs :: (DefGroups -> a) -> CorePhase a +withCoreDefs :: (DefGroups -> a) -> CorePhase b a withCoreDefs f = do defs <- getCoreDefs return (f defs) -runCorePhase :: Int -> CorePhase a -> Error a +runCorePhase :: Int -> CorePhase b a -> Error b a runCorePhase uniq (CP cp) = do (CPState x _ _) <- cp uniq [] return x -liftCorePhaseUniq :: (Int -> DefGroups -> (DefGroups,Int)) -> CorePhase () +liftCorePhaseUniq :: (Int -> DefGroups -> (DefGroups,Int)) -> CorePhase b () liftCorePhaseUniq f = CP (\uniq defs -> let (defs',uniq') = f uniq defs in return (CPState () uniq' defs')) -liftCorePhase :: (DefGroups -> DefGroups) -> CorePhase () +liftCorePhase :: (DefGroups -> DefGroups) -> CorePhase b () liftCorePhase f = liftCorePhaseUniq (\u defs -> (f defs, u)) -liftError :: Error a -> CorePhase a +liftError :: Error b a -> CorePhase b a liftError err = CP (\uniq defs -> do x <- err return (CPState x uniq defs)) @@ -1333,7 +1333,7 @@ depType tp TCon tc -> depName (typeConName tc) TVar _ -> S.empty TApp tp tps -> depsUnions (map depType (tp:tps)) - TSyn syn args tp -> depsUnions (map depType (tp:args)) + TSyn syn args tp -> depsUnions (depName (typesynName syn):(map depType (tp:args))) depDef :: Def -> Deps depDef def = depsUnions [depType (defType def), depExpr (defExpr def)] diff --git a/src/Core/FunLift.hs b/src/Core/FunLift.hs index 25e0c8a41..89ed41bcb 100644 --- a/src/Core/FunLift.hs +++ b/src/Core/FunLift.hs @@ -51,7 +51,7 @@ traceGroups dgs showDG (DefNonRec def) = show (defName def) -liftFunctions :: Pretty.Env -> CorePhase () +liftFunctions :: Pretty.Env -> CorePhase b () liftFunctions penv = liftCorePhaseUniq $ \uniq defs -> runLift penv uniq (liftDefGroups True defs) diff --git a/src/Core/Inline.hs b/src/Core/Inline.hs index be7bb9ce4..f35b101ea 100644 --- a/src/Core/Inline.hs +++ b/src/Core/Inline.hs @@ -49,7 +49,7 @@ trace s x = -inlineDefs :: Pretty.Env -> Int -> Inlines -> CorePhase () +inlineDefs :: Pretty.Env -> Int -> Inlines -> CorePhase b () inlineDefs penv inlineMax inlines = liftCorePhaseUniq $ \uniq defs -> runInl penv inlineMax uniq inlines $ diff --git a/src/Core/Monadic.hs b/src/Core/Monadic.hs index db1e87470..ba8b05241 100644 --- a/src/Core/Monadic.hs +++ b/src/Core/Monadic.hs @@ -47,7 +47,7 @@ trace s x = -- Lib.Trace.trace s x -monTransform :: Pretty.Env -> CorePhase () +monTransform :: Pretty.Env -> CorePhase b () monTransform penv = liftCorePhaseUniq $ \uniq defs -> runMon penv uniq (monDefGroups defs) diff --git a/src/Core/MonadicLift.hs b/src/Core/MonadicLift.hs index 58ab7cb0f..862a8d014 100644 --- a/src/Core/MonadicLift.hs +++ b/src/Core/MonadicLift.hs @@ -40,7 +40,7 @@ trace s x = Lib.Trace.trace s x -monadicLift :: Pretty.Env -> CorePhase () +monadicLift :: Pretty.Env -> CorePhase b () monadicLift penv = liftCorePhaseUniq $ \uniq defs -> runLift penv uniq (liftDefGroups True defs) diff --git a/src/Core/OpenResolve.hs b/src/Core/OpenResolve.hs index 6c7e97157..8796ba7e5 100644 --- a/src/Core/OpenResolve.hs +++ b/src/Core/OpenResolve.hs @@ -46,7 +46,7 @@ trace s x = data Env = Env{ penv :: Pretty.Env, gamma :: Gamma } -openResolve :: Pretty.Env -> Gamma -> CorePhase () +openResolve :: Pretty.Env -> Gamma -> CorePhase b () openResolve penv gamma = liftCorePhase $ \defs -> resDefGroups (Env penv gamma) defs diff --git a/src/Core/Parse.hs b/src/Core/Parse.hs index aa89febbb..b583aff1f 100644 --- a/src/Core/Parse.hs +++ b/src/Core/Parse.hs @@ -41,12 +41,12 @@ import Lib.Trace {-------------------------------------------------------------------------- Parse core interface files --------------------------------------------------------------------------} -type ParseInlines = Gamma -> Error [InlineDef] +type ParseInlines = Gamma -> Error () [InlineDef] -parseCore :: FilePath -> IO (Error (Core, ParseInlines)) +parseCore :: FilePath -> IO (Error b (Core, ParseInlines)) parseCore fname = do input <- readInput fname - return (lexParse False (requalify . allowDotIds) program fname 1 input) + return $ ignoreSyntaxWarnings $ lexParse False (requalify . allowDotIds) program fname 1 input requalify :: [Lexeme] -> [Lexeme] requalify lexs @@ -107,7 +107,7 @@ allowDotIds lexs parseInlines :: Core -> Source -> Env -> [Lexeme] -> ParseInlines parseInlines prog source env inlines gamma - = parseLexemes (pInlines env{ gamma = gamma }) source inlines + = ignoreSyntaxWarnings $ parseLexemes (pInlines env{ gamma = gamma }) source inlines pInlines :: Env -> LexParser [InlineDef] pInlines env @@ -1046,7 +1046,7 @@ envLookupCon :: Env -> Name -> LexParser NameInfo envLookupCon env name = case gammaLookupExactCon name (gamma env) of [con@(InfoCon{})] -> return con - res -> fail $ "unknown constructor: " ++ show name ++ ": " ++ show res -- ++ ":\n" ++ show (gamma env) + res -> fail $ "when parsing " ++ show (modName env) ++ " unknown constructor: " ++ show name ++ ": " ++ show res -- ++ ":\n" ++ show (gamma env) envLookupVar :: Env -> Name -> LexParser Expr envLookupVar env name diff --git a/src/Core/Simplify.hs b/src/Core/Simplify.hs index 1ceb78a72..81a5505c2 100644 --- a/src/Core/Simplify.hs +++ b/src/Core/Simplify.hs @@ -40,7 +40,7 @@ import qualified Data.Set as S -- data Env = Env{ inlineMap :: M.NameMap Expr } -- data Info = Info{ occurrences :: M.NameMap Int } -simplifyDefs :: Pretty.Env -> Bool -> Bool -> Int -> Int -> CorePhase () +simplifyDefs :: Pretty.Env -> Bool -> Bool -> Int -> Int -> CorePhase b () simplifyDefs penv unsafe ndebug nRuns duplicationMax = liftCorePhaseUniq $ \uniq defs -> runSimplify unsafe ndebug duplicationMax uniq penv (simplifyN nRuns (uniquefyDefBodies defs)) diff --git a/src/Core/Specialize.hs b/src/Core/Specialize.hs index 176fd655b..669387595 100644 --- a/src/Core/Specialize.hs +++ b/src/Core/Specialize.hs @@ -87,7 +87,7 @@ runSpecM uniq readState specM = Specialization --------------------------------------------------------------------------} -specialize :: Inlines -> Env -> CorePhase () +specialize :: Inlines -> Env -> CorePhase b () specialize specEnv penv = liftCorePhaseUniq $ \uniq defs -> -- TODO: use uniqe int to generate names and remove call to uniquefyDefGroups? diff --git a/src/Core/UnReturn.hs b/src/Core/UnReturn.hs index 0f18eb58a..31968792d 100644 --- a/src/Core/UnReturn.hs +++ b/src/Core/UnReturn.hs @@ -47,7 +47,7 @@ trace s x = -- Lib.Trace.trace s x -unreturn :: Pretty.Env -> CorePhase () +unreturn :: Pretty.Env -> CorePhase b () unreturn penv = liftCorePhaseUniq $ \uniq defs -> runUR penv uniq (urTopDefGroups defs) diff --git a/src/Core/Unroll.hs b/src/Core/Unroll.hs index 69275b1e2..3b4fc6bcb 100644 --- a/src/Core/Unroll.hs +++ b/src/Core/Unroll.hs @@ -61,7 +61,7 @@ trace s x = -unrollDefs :: Pretty.Env -> Int -> CorePhase () +unrollDefs :: Pretty.Env -> Int -> CorePhase b () unrollDefs penv unrollMax = liftCorePhaseUniq $ \uniq defs -> runUnroll penv unrollMax uniq $ diff --git a/src/Interpreter/Interpret.hs b/src/Interpreter/Interpret.hs index b464bfa35..056a48f84 100644 --- a/src/Interpreter/Interpret.hs +++ b/src/Interpreter/Interpret.hs @@ -126,8 +126,8 @@ command :: State -> Command -> IO () command st cmd = let term = terminal st in do{ case cmd of - Eval line -> do{ err <- compileExpression term (flags st) (loaded st) (Executable nameExpr ()) (program st) bigLine line - ; checkInferWith st line id True err $ \ld -> + Eval line -> do{ err <- compileExpression (const Nothing) term (flags st) (loaded st) (Executable nameExpr ()) (program st) bigLine line + ; checkInferWith st line fst True err $ \(ld, _) -> do if (not (evaluate (flags st))) then let tp = infoType $ gammaFind (qualify nameInteractive nameExpr) (loadedGamma ld) in messageSchemeEffect st tp @@ -136,7 +136,7 @@ command st cmd } Define line -> do err <- compileValueDef term (flags st) (loaded st) (program st) (lineNo st) line - checkInfer2 st True err $ \(defName,ld) -> + checkInfer2Snd st True err $ \(defName,ld) -> do{ let tp = infoType $ gammaFind defName (loadedGamma ld) tpdoc = prettyScheme st tp sig = show defName ++ " :: " ++ show tpdoc @@ -148,8 +148,8 @@ command st cmd } } - TypeOf line -> do err <- compileExpression term (flags st) (loaded st) Object (program st) bigLine line - checkInfer st True err $ \ld -> + TypeOf line -> do err <- compileExpression (const Nothing) term (flags st) (loaded st) Object (program st) bigLine line + checkInfer2Fst st True err $ \(ld, _) -> do{ let tp = infoType $ gammaFind (qualify nameInteractive nameExpr) (loadedGamma ld) ; messageSchemeEffect st tp ; interpreter st{ loaded = ld } -- (loaded st){ loadedModules = loadedModules ld }} @@ -164,7 +164,7 @@ command st cmd TypeDef line-> -- trace ("modules: " ++ show (map (show . modName . loadedModule) (loadedModules st))) $ do err <- compileTypeDef term (flags st) (loaded st) (program st) (lineNo st) line - checkInfer2 st True err $ \(defName, ld) -> + checkInfer2Snd st True err $ \(defName, ld) -> do{ let (qname,kind) = kgammaFind (getName (program st)) defName (loadedKGamma ld) ; messagePrettyLnLn st (text (show defName) <+> text "::" <+> pretty kind) ; interpreter st{ program = maybe (program st) id $ modProgram (loadedModule ld) @@ -273,7 +273,7 @@ loadFilesErr term startSt fileNames force -} walk [] startSt fileNames where - walk :: [Module] -> State -> [FilePath] -> IO (Error State) + walk :: [Module] -> State -> [FilePath] -> IO (Error b State) walk imports st files = case files of [] -> do if (not (null imports) && verbose (flags st) > 0) @@ -292,12 +292,12 @@ loadFilesErr term startSt fileNames force then compileFile term (flags st) (loadedModules (loaded0 st)) Object fname else compileModule term (flags st) (loadedModules (loaded0 st)) (newName fname) -} - compileModuleOrFile term (flags st) [] {- (loadedModules (loaded0 st)) -} fname force + compileModuleOrFile (const Nothing) Nothing term (flags st) [] [] {- (loadedModules (loaded0 st)) -} fname force Object [] ; case checkError err of Left msg -> do messageErrorMsgLnLn st msg return (errorMsg msg) - Right (ld,warnings) + Right ((ld, _), warnings) -> do{ -- let warnings = modWarnings (loadedModule ld) ; err <- if not (null warnings) then do let msg = ErrorWarning warnings ErrorZero @@ -352,14 +352,15 @@ docNotFound cscheme path name {-------------------------------------------------------------------------- Helpers --------------------------------------------------------------------------} -checkInfer :: State -> Bool -> Error Loaded -> (Loaded -> IO ()) -> IO () +checkInfer :: State -> Bool -> Error b Loaded -> (Loaded -> IO ()) -> IO () checkInfer st = checkInferWith st "" id -checkInfer2 st = checkInferWith st "" (\(a,c) -> c) +checkInfer2Snd st = checkInferWith st "" snd +checkInfer2Fst st = checkInferWith st "" fst -checkInfer3 :: State -> String -> Bool -> Error (a,b,Loaded) -> ((a,b,Loaded) -> IO ()) -> IO () +checkInfer3 :: State -> String -> Bool -> Error b (a,b,Loaded) -> ((a,b,Loaded) -> IO ()) -> IO () checkInfer3 st line = checkInferWith st line (\(a,b,c) -> c) -checkInferWith :: State -> String -> (a -> Loaded) -> Bool -> Error a -> (a -> IO ()) -> IO () +checkInferWith :: State -> String -> (a -> Loaded) -> Bool -> Error b a -> (a -> IO ()) -> IO () checkInferWith st line getLoaded showMarker err f = case checkError err of Left msg -> do when showMarker (maybeMessageMarker st (getRange msg)) diff --git a/src/Kind/Constructors.hs b/src/Kind/Constructors.hs index 27ec2ea40..d1d3808ee 100644 --- a/src/Kind/Constructors.hs +++ b/src/Kind/Constructors.hs @@ -15,7 +15,7 @@ module Kind.Constructors( -- * Constructors , constructorsExtend, constructorsLookup, constructorsFind , constructorsIsEmpty , constructorsFindScheme - , constructorsSet + , constructorsSet, constructorsList , constructorsCompose, constructorsFromList , extractConstructors -- * Pretty @@ -78,6 +78,9 @@ constructorsSet :: Constructors -> S.NameSet constructorsSet (Constructors m) = S.fromList (M.keys m) +constructorsList :: Constructors -> [(Name, ConInfo)] +constructorsList (Constructors m) + = M.toList m {-------------------------------------------------------------------------- Pretty printing diff --git a/src/Kind/ImportMap.hs b/src/Kind/ImportMap.hs index c8aaa9f59..a7066ff9c 100644 --- a/src/Kind/ImportMap.hs +++ b/src/Kind/ImportMap.hs @@ -36,7 +36,7 @@ importsExtend name fullName imp = let rpath = reverse $ splitModuleName name in case lookup rpath imp of Nothing -> Just ((rpath,fullName):imp) - Just _ -> Nothing + Just fullName1 -> if fullName == fullName1 then Just imp else Nothing -- | @importsExpand name map@ takes a qualified name (@core/int@) and expands -- it to its real fully qualified name (@std/core/int@). It also returns diff --git a/src/Kind/Infer.hs b/src/Kind/Infer.hs index 63906bd87..6ee46456d 100644 --- a/src/Kind/Infer.hs +++ b/src/Kind/Infer.hs @@ -79,7 +79,7 @@ inferKinds -> Synonyms -- ^ Initial list of synonyms -> Newtypes -- ^ Initial list of data types -> Program UserType UserKind -- ^ Original program - -> Core.CorePhase + -> Core.CorePhase b ( DefGroups Type -- Translated program (containing translated types) -- , Gamma -- Gamma containing generated functions, i.e type scheme for every constructor , KGamma -- updated kind gamma @@ -405,7 +405,7 @@ infExternal names (External name tp pinfos nameRng rng calls vis fip doc) canonicalName n qname if (isHiddenName name) then return () - else do addRangeInfo nameRng (Id qname (NIValue tp') True) + else do addRangeInfo nameRng (Id qname (NIValue tp' True) True) addRangeInfo rng (Decl "external" qname (mangle cname tp')) -- trace ("infExternal: " ++ show cname ++ ": " ++ show (pretty tp')) $ return (Core.External cname tp' pinfos (map (formatCall tp') calls) @@ -966,7 +966,7 @@ resolveConParam idmap (vis,vb) Just e -> {- do e' <- infExpr e return (Just e') -} return (Just (failure "Kind.Infer.resolveConParam: optional parameter expression in constructor")) - addRangeInfo (binderNameRange vb) (Id (binderName vb) (NIValue tp) True) + addRangeInfo (binderNameRange vb) (Id (binderName vb) (NIValue tp True) True) return (vis,vb{ binderType = tp, binderExpr = expr }) -- | @resolveType@ takes: a map from locally quantified type name variables to types, diff --git a/src/Lib/Printer.hs b/src/Lib/Printer.hs index 6f154d06a..c9821966c 100644 --- a/src/Lib/Printer.hs +++ b/src/Lib/Printer.hs @@ -10,28 +10,30 @@ Only the color of 'stdout' is influenced by these functions. -} ----------------------------------------------------------------------------- -module Lib.Printer( +module Lib.Printer( -- * Color Color(..) -- * Printer - , Printer( write, writeText, writeLn, writeTextLn, flush, + , Printer( write, writeText, writeLn, writeTextLn, flush, withColor, withBackColor, withReverse, withUnderline -- ,setColor, setBackColor, setReverse, setUnderline - ) + ) -- * Printers , MonoPrinter, withMonoPrinter - , ColorPrinter, withColorPrinter, withNoColorPrinter, withFileNoColorPrinter, isAnsiPrinter, isConsolePrinter + , ColorPrinter(..), withColorPrinter, withNoColorPrinter, withFileNoColorPrinter, isAnsiPrinter, isConsolePrinter , AnsiPrinter, withAnsiPrinter + , AnsiStringPrinter(..), HtmlTextPrinter(..) , withFilePrinter, withNewFilePrinter - , withHtmlPrinter, withHtmlColorPrinter + , withHtmlPrinter, withHtmlColorPrinter, withHtmlTextPrinter -- * Misc. , ansiWithColor + , ansiDefault , ansiColor ) where import Data.List( intersperse ) -- import Data.Char( toLower ) -import System.IO ( hFlush, stdout, hPutStr, hPutStrLn, openFile, IOMode(..), hClose, Handle ) +import System.IO ( hFlush, stdout, hPutStr, hPutStrLn, openFile, IOMode(..), hClose, Handle ) import Platform.Var( Var, newVar, putVar, takeVar ) import Platform.Runtime( finally ) import Platform.Config( exeExtension ) @@ -47,7 +49,7 @@ import System.Console.Isocline( withTerm, termWriteLn, termWrite, termFlush ) {-------------------------------------------------------------------------- Printer ---------------------------------------------------------------------------} +--------------------------------------------------------------------------} -- | A printer is an abstraction for something where we can send -- character output to. class Printer p where @@ -69,7 +71,7 @@ class Printer p where {-------------------------------------------------------------------------- Interface ---------------------------------------------------------------------------} +--------------------------------------------------------------------------} -- | Available colors on a console. Normally, background colors are -- converted to their /dark/ variant. data Color = Black @@ -95,7 +97,7 @@ data Color = Black {-------------------------------------------------------------------------- Simple monochrome printer ---------------------------------------------------------------------------} +--------------------------------------------------------------------------} -- | On windows, we cannot print unicode characters :-( sanitize :: String -> String @@ -135,7 +137,7 @@ instance Printer MonoPrinter where {-------------------------------------------------------------------------- Simple file printer ---------------------------------------------------------------------------} +--------------------------------------------------------------------------} -- | File printer newtype FilePrinter = FilePrinter Handle @@ -177,7 +179,7 @@ instance Printer FilePrinter where {-------------------------------------------------------------------------- Standard ANSI escape sequences ---------------------------------------------------------------------------} +--------------------------------------------------------------------------} -- | Use a color printer that uses ANSI escape sequences. withAnsiPrinter :: (AnsiPrinter -> IO a) -> IO a withAnsiPrinter f @@ -186,7 +188,7 @@ withAnsiPrinter f finally (f (Ansi ansi)) (do ansiEscapeIO seqReset hFlush stdout) -ansiDefault +ansiDefault = AnsiConsole ColorDefault ColorDefault False False @@ -214,6 +216,47 @@ instance Printer AnsiPrinter where setUnderline p u = unit $ ansiSetConsole p (\con -> con{ underline = u }) +data AnsiStringPrinter = AnsiString (Var AnsiConsole) (Var String) + +instance Printer AnsiStringPrinter where + write (AnsiString c st) s = do + st' <- takeVar st + putVar st (st' ++ s) + writeText (AnsiString c st) s = do + st' <- takeVar st + putVar st (st' ++ T.unpack s) + writeLn (AnsiString c st) s = do + st' <- takeVar st + putVar st (st' ++ s ++ "\n") + writeTextLn (AnsiString c st) s = do + st' <- takeVar st + putVar st (st' ++ T.unpack s ++ "\n") + flush p = return () -- hFlush stdout + withColor p c io = ansiStringWithConsole p (\con -> con{ fcolor = c }) io + withBackColor p c io = ansiStringWithConsole p (\con -> con{ bcolor = c }) io + withReverse p r io = ansiStringWithConsole p (\con -> con{ invert = r }) io + withUnderline p u io = ansiStringWithConsole p (\con -> con{ underline = u }) io + setColor p c = unit $ ansiStringSetConsole p (\con -> con{ fcolor = c }) + setBackColor p c = unit $ ansiStringSetConsole p (\con -> con{ bcolor = c }) + setReverse p r = unit $ ansiStringSetConsole p (\con -> con{ invert = r }) + setUnderline p u = unit $ ansiStringSetConsole p (\con -> con{ underline = u }) + + + +ansiStringWithConsole :: AnsiStringPrinter -> (AnsiConsole -> AnsiConsole) -> IO a -> IO a +ansiStringWithConsole p f io + = do old <- ansiStringSetConsole p f + finally io (ansiStringSetConsole p (const old)) + +ansiStringSetConsole :: AnsiStringPrinter -> (AnsiConsole -> AnsiConsole) -> IO AnsiConsole +ansiStringSetConsole (AnsiString varAnsi varString) f + = do con <- takeVar varAnsi + let new = f con + str <- takeVar varString + putVar varString $ str ++ T.unpack (ansiEscape (seqSetConsole con new)) + putVar varAnsi new + return con + -- | Helper function to put a string into a certain color ansiWithColor :: Color -> String -> String ansiWithColor color s @@ -229,7 +272,7 @@ unit io -- Console code ansiWithConsole :: AnsiPrinter -> (AnsiConsole -> AnsiConsole) -> IO a -> IO a -ansiWithConsole p f io +ansiWithConsole p f io = do old <- ansiSetConsole p f finally io (ansiSetConsole p (const old)) @@ -246,8 +289,8 @@ ansiEscapeIO xs | null xs = return () | otherwise = termWrite (T.unpack {-T.putStr-} (ansiEscape xs)) - - + + ansiEscape :: [T.Text] -> T.Text ansiEscape xs | null xs = T.empty @@ -262,19 +305,19 @@ seqSetConsole old new where reset = concat [seqReset - ,seqReverse (invert new) - ,seqUnderline (underline new) + ,seqReverse (invert new) + ,seqUnderline (underline new) ,seqColor False (fcolor new) ,seqColor True (bcolor new)] - diff = concat + diff = concat [max seqReverse invert ,max seqUnderline underline ,max (seqColor False) fcolor ,max (seqColor True) bcolor ] - max f field + max f field = if (field old /= field new) then f (field new) else [] seqReset :: [T.Text] @@ -300,21 +343,23 @@ seqColor backGround c ansiColor :: Color -> Int -ansiColor c +ansiColor c = let i = fromEnum c - in if (i < 8) then 30 + i + in if (i < 8) then 30 + i else if (i < 16) then 90 + i - 8 else 39 {-------------------------------------------------------------------------- Color console code ---------------------------------------------------------------------------} +--------------------------------------------------------------------------} -- | A color printer supports colored output data ColorPrinter = PCon ConsolePrinter | PAnsi AnsiPrinter + | PAnsiString AnsiStringPrinter | PMono MonoPrinter | PFile FilePrinter | PHTML HtmlPrinter + | PHtmlText HtmlTextPrinter -- | Use a color-enabled printer. withColorPrinter :: (ColorPrinter -> IO b) -> IO b @@ -343,43 +388,46 @@ withFileNoColorPrinter fname f -- | Is this an ANSI printer? isAnsiPrinter :: ColorPrinter -> Bool -isAnsiPrinter cp +isAnsiPrinter cp = case cp of PAnsi ansi -> True + PAnsiString ansi -> True _ -> False isConsolePrinter :: ColorPrinter -> Bool -isConsolePrinter cp +isConsolePrinter cp = case cp of PCon _ -> True _ -> False instance Printer ColorPrinter where - write p s = cmap p write write write write write s - writeLn p s = cmap p writeLn writeLn writeLn writeLn writeLn s - flush p = cmap p flush flush flush flush flush - withColor p c io = cmap p withColor withColor withColor withColor withColor c io - withBackColor p c io = cmap p withBackColor withBackColor withBackColor withBackColor withBackColor c io - withReverse p r io = cmap p withReverse withReverse withReverse withReverse withReverse r io - withUnderline p u io = cmap p withUnderline withUnderline withUnderline withUnderline withUnderline u io - setColor p c = cmap p setColor setColor setColor setColor setColor c - setBackColor p c = cmap p setBackColor setBackColor setBackColor setBackColor setBackColor c - setReverse p r = cmap p setReverse setReverse setReverse setReverse setReverse r - setUnderline p u = cmap p setUnderline setUnderline setUnderline setUnderline setUnderline u - -cmap p f g h i j + write p s = cmap p write write write write write write write s + writeLn p s = cmap p writeLn writeLn writeLn writeLn writeLn writeLn writeLn s + flush p = cmap p flush flush flush flush flush flush flush + withColor p c io = cmap p withColor withColor withColor withColor withColor withColor withColor c io + withBackColor p c io = cmap p withBackColor withBackColor withBackColor withBackColor withBackColor withBackColor withBackColor c io + withReverse p r io = cmap p withReverse withReverse withReverse withReverse withReverse withReverse withReverse r io + withUnderline p u io = cmap p withUnderline withUnderline withUnderline withUnderline withUnderline withUnderline withUnderline u io + setColor p c = cmap p setColor setColor setColor setColor setColor setColor setColor c + setBackColor p c = cmap p setBackColor setBackColor setBackColor setBackColor setBackColor setBackColor setBackColor c + setReverse p r = cmap p setReverse setReverse setReverse setReverse setReverse setReverse setReverse r + setUnderline p u = cmap p setUnderline setUnderline setUnderline setUnderline setUnderline setUnderline setUnderline u + +cmap p f g h i j k l = case p of - PCon cp -> f cp - PAnsi ap -> g ap + PCon cp -> f cp + PAnsi ap -> g ap PMono mp -> h mp PFile fp -> i fp PHTML hp -> j hp + PAnsiString as -> k as + PHtmlText ht -> l ht {-------------------------------------------------------------------------- Windows console code ---------------------------------------------------------------------------} +--------------------------------------------------------------------------} -- | Windows console printer newtype ConsolePrinter = ConsolePrinter () @@ -391,7 +439,7 @@ instance Printer ConsolePrinter where flush p = hFlush stdout withColor p c io = Con.bracketConsole (do Con.setColor c; io) withBackColor p c io = Con.bracketConsole (do Con.setBackColor c; io) - withReverse p r io = Con.bracketConsole (do Con.setReverse r; io) + withReverse p r io = Con.bracketConsole (do Con.setReverse r; io) withUnderline p u io = Con.bracketConsole (do Con.setUnderline u; io) setColor p c = Con.setColor c setBackColor p c = Con.setBackColor c @@ -401,7 +449,7 @@ instance Printer ConsolePrinter where {-------------------------------------------------------------------------- HTML printer ---------------------------------------------------------------------------} +--------------------------------------------------------------------------} data HtmlPrinter = HtmlPrinter () withHtmlPrinter :: (HtmlPrinter -> IO a) -> IO a @@ -423,6 +471,39 @@ instance Printer HtmlPrinter where setReverse p r = return () setUnderline p u = return () + +{-------------------------------------------------------------------------- + HTML Text printer +--------------------------------------------------------------------------} +data HtmlTextPrinter = HtmlTextPrinter (Var T.Text) + +withHtmlTextPrinter :: (HtmlTextPrinter -> IO a) -> IO a +withHtmlTextPrinter f + = do + stringVar <- newVar (T.pack "") + f (HtmlTextPrinter stringVar) + +addHtml :: HtmlTextPrinter -> T.Text -> IO () +addHtml (HtmlTextPrinter stringVar) s = do + old <- takeVar stringVar + putVar stringVar (old <> s) + +instance Printer HtmlTextPrinter where + write p s = addHtml p $ T.pack $ htmlEscape s + writeText p s = addHtml p s + writeLn p s = addHtml p $ T.pack $ htmlEscape (s ++ "\n") + writeTextLn p s = addHtml p (s <> T.pack "\n") + flush p = return () + withColor p c io = htmlTextSpan p (T.pack "color") (htmlColor2 c) io + withBackColor p c io = htmlTextSpan p (T.pack "background-color") (htmlColor2 c) io + withReverse p r io = {- no supported -} io + withUnderline p u io = htmlTextSpan p (T.pack "text-decoration") (T.pack "underline") io + setColor p c = return () + setBackColor p c = return () + setReverse p r = return () + setUnderline p u = return () + + htmlSpan :: T.Text -> T.Text -> IO a -> IO a htmlSpan prop val io = do T.putStr $ T.pack " prop <> T.pack ":" <> val <> T.pack ";'>") + x <- io + addHtml p (T.pack "") + return x + htmlColor :: Color -> T.Text htmlColor c - = case c of + = case c of ColorDefault -> T.pack "black" _ -> T.toLower (T.pack $ show c) +-- VSCode sanitizes spans to only allow colors with hex codes +htmlColor2 :: Color -> T.Text +htmlColor2 c + = case c of + ColorDefault -> T.pack "#000000" + Black -> T.pack "#000000" + White -> T.pack "#ffffff" + DarkRed -> T.pack "#8B0000" + DarkGreen -> T.pack "#006400" + DarkYellow -> T.pack "#8B8000" + DarkBlue -> T.pack "#00008B" + DarkMagenta -> T.pack "#8B008B" + DarkCyan -> T.pack "#008B8B" + Gray -> T.pack "#808080" + DarkGray -> T.pack "#A9A9A9" + Red -> T.pack "#FF0000" + Green -> T.pack "#008000" + Yellow -> T.pack "#FFFF00" + Blue -> T.pack "#0000FF" + Magenta -> T.pack "#FF00FF" + Cyan -> T.pack "#00FFFF" + htmlEscape s = concatMap escape s where diff --git a/src/Main/README.md b/src/Main/README.md new file mode 100644 index 000000000..417464f68 --- /dev/null +++ b/src/Main/README.md @@ -0,0 +1,9 @@ +There are the main front-ends for the Koka compiler: + +- `langserver`: the regular Koka compiler with VS code language server support. + See also `support/vscode` for the VS code extension. + +- `plain`: Koka compiler + interpreter without language server support; this is mainly + to support platforms where the Haskell language server library does not build. + + diff --git a/src/Main/langserver/LanguageServer/Conversions.hs b/src/Main/langserver/LanguageServer/Conversions.hs new file mode 100644 index 000000000..0060ef176 --- /dev/null +++ b/src/Main/langserver/LanguageServer/Conversions.hs @@ -0,0 +1,116 @@ +----------------------------------------------------------------------------- +-- Conversions between LSP types and internal types, e.g. positions/ranges +----------------------------------------------------------------------------- +{-# LANGUAGE OverloadedStrings #-} + +module LanguageServer.Conversions + ( -- * Conversions to LSP types + toLspPos, + toLspRange, + toLspLocation, + toLspLocationLink, + toLspDiagnostics, + toLspErrorDiagnostics, + toLspWarningDiagnostic, + makeDiagnostic, + + -- * Conversions from LSP types + fromLspPos, + fromLspRange, + fromLspLocation + ) +where +import GHC.Generics hiding (UInt) +import qualified Common.Error as E +import qualified Common.Range as R +import qualified Data.Text as T +import qualified Language.LSP.Protocol.Types as J +import Data.Map.Strict as M hiding (map) +import Colog.Core +import Language.LSP.Protocol.Types (UInt) +import Lib.PPrint (Doc) +import qualified Syntax.RangeMap as R +import Compiler.Module (Module (..), Loaded (..)) +import Data.Maybe (fromMaybe) +import Common.File (normalize, realPath) +import Common.Range (sourceNull, Source (sourceName)) + +toLspPos :: R.Pos -> J.Position +toLspPos p = + J.Position (fromIntegral (max 0 (R.posLine p - 1))) (fromIntegral (max 0 (R.posColumn p - 1)))-- LSP positions are zero-based + +toLspRange :: R.Range -> J.Range +toLspRange r = + J.Range (J.Position l1 c1) (J.Position l2 $ c2 + 1) -- LSP range ends are exclusive + where + J.Position l1 c1 = toLspPos $ R.rangeStart r + J.Position l2 c2 = toLspPos $ R.rangeEnd r + +toLspLocation :: R.Range -> J.Location +toLspLocation r = + J.Location uri (toLspRange r) + where + uri = J.filePathToUri $ R.sourceName $ R.rangeSource r + +toLspLocationLink :: R.RangeInfo -> R.Range -> J.LocationLink +toLspLocationLink src r = + J.LocationLink Nothing uri (toLspRange r) (toLspRange r) + where + uri = J.filePathToUri $ R.sourceName $ R.rangeSource r + +toLspDiagnostics :: J.NormalizedUri -> T.Text -> E.Error b a -> M.Map J.NormalizedUri [J.Diagnostic] +toLspDiagnostics uri src err = + case E.checkError err of + Right (_, ws) -> M.fromList $ map (\(r, doc) -> (uriFromRange r uri, [toLspWarningDiagnostic src r doc])) ws + Left e -> toLspErrorDiagnostics uri src e + +toLspErrorDiagnostics :: J.NormalizedUri -> T.Text -> E.ErrorMessage -> M.Map J.NormalizedUri [J.Diagnostic] +toLspErrorDiagnostics uri src e = + case e of + E.ErrorGeneral r doc -> M.singleton (uriFromRange r uri) [makeDiagnostic J.DiagnosticSeverity_Error src r doc] + E.ErrorParse r doc -> M.singleton (uriFromRange r uri) [makeDiagnostic J.DiagnosticSeverity_Error src r doc] + E.ErrorStatic rds -> mapRangeDocs rds + E.ErrorKind rds -> mapRangeDocs rds + E.ErrorType rds -> mapRangeDocs rds + E.ErrorWarning rds e' -> M.unionWith (++) (mapRangeDocs rds) (toLspErrorDiagnostics uri src e') + E.ErrorIO doc -> M.singleton uri [makeDiagnostic J.DiagnosticSeverity_Error src R.rangeNull doc] + E.ErrorZero -> M.empty + where mapRangeDocs rds = M.fromList $ map (\(r, doc) -> (uriFromRange r uri, [makeDiagnostic J.DiagnosticSeverity_Error src r doc])) rds + +uriFromRange :: R.Range -> J.NormalizedUri -> J.NormalizedUri +uriFromRange r uri = + if R.rangeSource r == sourceNull then uri else J.toNormalizedUri $ J.filePathToUri $ sourceName (R.rangeSource r) + +toLspWarningDiagnostic :: T.Text -> R.Range -> Doc -> J.Diagnostic +toLspWarningDiagnostic = + makeDiagnostic J.DiagnosticSeverity_Warning + +makeDiagnostic :: J.DiagnosticSeverity -> T.Text -> R.Range -> Doc -> J.Diagnostic +makeDiagnostic s src r doc = + J.Diagnostic range severity code codeDescription source message tags related dataX + where + range = toLspRange r + source = Just src + severity = Just s + code = Nothing + codeDescription = Nothing + message = T.pack $ show doc + tags + | "is unused" `T.isInfixOf` message = Just [J.DiagnosticTag_Unnecessary] + | otherwise = Nothing + related = Nothing + dataX = Nothing + +fromLspPos :: J.Uri -> J.Position -> R.Pos +fromLspPos uri (J.Position l c) = + R.makePos src (-1) (fromIntegral l + 1) (fromIntegral c + 1) + where + src = case J.uriToFilePath uri of + Just filePath -> R.Source (normalize filePath) R.bstringEmpty -- TODO: Read file here (and compute the offset correctly) + Nothing -> R.sourceNull + +fromLspRange :: J.Uri -> J.Range -> R.Range +fromLspRange uri (J.Range s e) = R.makeRange (fromLspPos uri s) (fromLspPos uri e) + +fromLspLocation :: J.Location -> R.Range +fromLspLocation (J.Location uri rng) = fromLspRange uri rng diff --git a/src/Main/langserver/LanguageServer/Handler/Commands.hs b/src/Main/langserver/LanguageServer/Handler/Commands.hs new file mode 100644 index 000000000..c0c45ed15 --- /dev/null +++ b/src/Main/langserver/LanguageServer/Handler/Commands.hs @@ -0,0 +1,84 @@ +----------------------------------------------------------------------------- +-- The LSP handlers that handles initialization +----------------------------------------------------------------------------- +{-# LANGUAGE OverloadedStrings #-} + +module LanguageServer.Handler.Commands (commandHandler) where + +import Compiler.Options (Flags (outFinalPath), targets, commandLineHelp, updateFlagsFromArgs) +import Language.LSP.Server (Handlers, LspM, notificationHandler, sendNotification, MonadLsp, getVirtualFiles, withIndefiniteProgress, requestHandler) +import qualified Language.LSP.Protocol.Types as J +import qualified Data.Text as T +import LanguageServer.Monad (LSM, getFlags, getTerminal, getModules, getLoaded) +import qualified Language.LSP.Protocol.Message as J +import Data.Aeson as Json +import qualified Language.LSP.Protocol.Lens as J +import Control.Lens ((^.)) +import Data.Maybe (mapMaybe, fromJust, fromMaybe) +import GHC.Base (Type) +import LanguageServer.Handler.TextDocument (recompileFile, compileEditorExpression) +import Compiler.Compile (CompileTarget(..), Terminal (termError, termPhaseDoc), compileExpression, Module (..)) +import Common.Name (newName) +import qualified Language.LSP.Server as J +import Control.Monad.Trans (liftIO) +import Syntax.Syntax (programAddImports, programNull, Import (..)) +import Common.NamePrim (nameInteractiveModule) +import Compiler.Module (Loaded(..)) +import Common.Range (rangeNull) +import Core.Core (Visibility(Private)) + +-- Handles custom commands that we support clients to call +commandHandler :: Handlers LSM +commandHandler = requestHandler J.SMethod_WorkspaceExecuteCommand $ \req resp -> do + let J.ExecuteCommandParams _ command commandParams = req ^. J.params + flags <- getFlags + if command == "koka/genCode" then + case commandParams of + -- koka/genCode filePath "...args to parse" + Just [Json.String filePath, Json.String additionalArgs] -> do + -- Update the flags with the specified arguments + newFlags <- getNewFlags flags additionalArgs + let forceRecompilation = flags /= newFlags + -- Recompile the file, but with executable target + withIndefiniteProgress (T.pack "Compiling " <> filePath) J.NotCancellable $ do + res <- recompileFile (Executable (newName "main") ()) (J.filePathToUri $ T.unpack filePath) Nothing forceRecompilation newFlags + sendNotification J.SMethod_WindowLogMessage $ J.LogMessageParams J.MessageType_Info $ T.pack ("Finished generating code for main file " ++ T.unpack filePath ++ " " ++ fromMaybe "No Compiled File" res) + -- Send the executable file location back to the client in case it wants to run it + resp $ Right $ case res of {Just filePath -> J.InL $ Json.String $ T.pack filePath; Nothing -> J.InR J.Null} + _ -> do + -- Client didn't send the right parameters for this command + sendNotification J.SMethod_WindowLogMessage $ J.LogMessageParams J.MessageType_Error $ T.pack "Invalid parameters for koka/genCode" + resp $ Right $ J.InR J.Null + else if command == "koka/interpretExpression" then + case commandParams of + -- The `filePath` where a top level function is defined by the name `functionName`, and any additional flags + Just [Json.String filePath, Json.String functionName, Json.String additionalArgs] -> do + -- Update the flags with the specified arguments + newFlags <- getNewFlags flags additionalArgs + let forceRecompilation = flags /= newFlags + -- Compile the expression, but with the interpret target + withIndefiniteProgress (T.pack "Interpreting " <> functionName) J.NotCancellable $ do + -- compile the expression + res <- compileEditorExpression (J.filePathToUri $ T.unpack filePath) newFlags forceRecompilation (T.unpack filePath) (T.unpack functionName) + sendNotification J.SMethod_WindowLogMessage $ J.LogMessageParams J.MessageType_Info $ T.pack ("Finished generating code for interpreting function " ++ T.unpack functionName ++ " in file " ++ T.unpack filePath ++ " Result: " ++ fromMaybe "No Compiled File" res) + -- Send the executable file location back to the client in case it wants to run it + resp $ Right $ case res of {Just filePath -> J.InL $ Json.String $ T.pack filePath; Nothing -> J.InR J.Null} + _ -> do + -- Client didn't send the right parameters for this command + sendNotification J.SMethod_WindowLogMessage $ J.LogMessageParams J.MessageType_Error $ T.pack "Invalid parameters for koka/interpretExpression" + resp $ Right $ J.InR J.Null + else + do + sendNotification J.SMethod_WindowLogMessage $ J.LogMessageParams J.MessageType_Error $ T.pack ("Unknown command" ++ show req) + resp $ Right $ J.InR J.Null + +getNewFlags :: Flags -> T.Text -> LSM Flags +getNewFlags flags args = do + term <- getTerminal + case updateFlagsFromArgs flags (T.unpack args) of + Just flags' -> return flags' + Nothing -> do + doc <- liftIO (commandLineHelp flags) + sendNotification J.SMethod_WindowLogMessage $ J.LogMessageParams J.MessageType_Error $ T.pack "Invalid arguments " <> args + liftIO $ termPhaseDoc term doc + return flags \ No newline at end of file diff --git a/src/Main/langserver/LanguageServer/Handler/Completion.hs b/src/Main/langserver/LanguageServer/Handler/Completion.hs new file mode 100644 index 000000000..1f2bf5d7c --- /dev/null +++ b/src/Main/langserver/LanguageServer/Handler/Completion.hs @@ -0,0 +1,449 @@ +----------------------------------------------------------------------------- +-- The LSP handler that provides code completions +----------------------------------------------------------------------------- +{-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE MultiWayIf #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE NamedFieldPuns #-} + +module LanguageServer.Handler.Completion + ( completionHandler, + ) +where + +import Common.Name (Name (..)) +import Compiler.Module (Loaded (..)) +import Control.Lens ((^.)) +import qualified Data.Map as M +import Data.Maybe (maybeToList, fromMaybe, fromJust) +import qualified Data.Text.Utf16.Rope as Rope +import qualified Data.Set as S +import qualified Data.Text as T +import Kind.Constructors (ConInfo (..), Constructors, constructorsList) +import Kind.Synonym (SynInfo (..), Synonyms, synonymsToList) +import Language.LSP.Server (Handlers, getVirtualFile, requestHandler) +import qualified Language.LSP.Protocol.Types as J +import qualified Language.LSP.Protocol.Lens as J +import Language.LSP.VFS (VirtualFile (VirtualFile)) +import LanguageServer.Monad (LSM, getLoaded, getLoadedModule) +import Lib.PPrint (Pretty (..)) +import Syntax.Lexer (reservedNames) +import Type.Assumption + ( Gamma, + NameInfo + ( InfoCon, + InfoExternal, + InfoFun, + InfoImport, + InfoVal, + infoAlias, + infoArity, + infoCName, + infoCon, + infoFormat, + infoFullName, + infoIsVar, + infoRange, + infoType, + infoVis + ), + gammaList, + ) +import qualified Language.LSP.Protocol.Message as J +import Data.Char (isUpper, isAlphaNum) +import Compiler.Compile (Module (..)) +import Type.Type (Type(..), splitFunType, splitFunScheme) +import Syntax.RangeMap (rangeMapFindAt, rangeInfoType) +import LanguageServer.Conversions (fromLspPos) +import Common.Range (makePos, posNull, Range, rangeNull) +import LanguageServer.Handler.Hover (formatRangeInfoHover) +import Type.Unify (runUnify, unify, runUnifyEx, matchArguments) +import Data.Either (isRight) +import Lib.Trace (trace) +import Type.InferMonad (subst, instantiate) +import Type.TypeVar (tvsEmpty) +import Data.ByteString (intercalate) +import Control.Monad.ST (runST) +import Language.LSP.Protocol.Types (InsertTextFormat(InsertTextFormat_Snippet)) +import Control.Monad.IO.Class (liftIO) + +-- Gets tab completion results for a document location +-- This is a pretty complicated handler because it has to do a lot of work +completionHandler :: Handlers LSM +completionHandler = requestHandler J.SMethod_TextDocumentCompletion $ \req responder -> do + let J.CompletionParams doc pos _ _ context = req ^. J.params + uri = doc ^. J.uri + normUri = J.toNormalizedUri uri + loaded <- getLoaded uri + loadedM <- getLoadedModule uri + vfile <- getVirtualFile normUri + let items = do-- list monad + l <- maybeToList loaded + lm <- maybeToList loadedM + vf <- maybeToList vfile + pi <- maybeToList =<< getCompletionInfo pos vf lm uri + findCompletions l lm pi + responder $ Right $ J.InL items + +-- | Describes the line at the current cursor position +-- We need a bit more information than the PositionInfo provided by the LSP library +-- So we duplicate a bit of code from the LSP library here +data PositionInfo = PositionInfo + { fullLine :: !T.Text + -- ^ The full contents of the line the cursor is at + , argument :: !T.Text + , searchTerm :: !T.Text + , cursorPos :: !J.Position + -- ^ The cursor position + , argumentType :: Maybe Type + -- Determines if it is a function completion (. is just prior to the cursor) + , isFunctionCompletion :: Bool + } deriving (Show,Eq) + +getCompletionInfo :: Monad m => J.Position -> VirtualFile -> Module -> J.Uri -> m (Maybe PositionInfo) +getCompletionInfo pos@(J.Position l c) (VirtualFile _ _ ropetext) mod uri = + let rm = (fromJust $ modRangeMap mod) in + let result = Just $ fromMaybe (PositionInfo "" "" "" pos Nothing False) $ do -- Maybe monad + let lastMaybe [] = Nothing + lastMaybe xs = Just $ last xs + + let currentRope = fst $ Rope.splitAtLine 1 $ snd $ Rope.splitAtLine (fromIntegral l) ropetext + beforePos <- Rope.toText . fst <$> Rope.splitAt (fromIntegral c + 1) currentRope + currentWord <- + if | T.null beforePos -> Just "" + | T.last beforePos == ' ' -> Just "" -- Up to whitespace but not including it + | otherwise -> lastMaybe (T.words beforePos) + + let parts = T.split (=='.') -- The () are for operators and / is for qualified names otherwise everything must be adjacent + $ T.takeWhileEnd (\x -> isAlphaNum x || x `elem` ("()-_./'"::String)) currentWord + + case reverse parts of + [] -> Nothing + (x:xs) -> do + -- trace ("parts: " ++ show parts) $ return () + let modName = case filter (not .T.null) xs of {x:xs -> x; [] -> ""} + argumentText <- Rope.toText . fst <$> Rope.splitAt (fromIntegral c) currentRope + let isFunctionCompletion = if | T.null argumentText -> False + | T.findIndex (== '.') argumentText > T.findIndex (== ' ') argumentText -> True + | otherwise -> False + newC = c - fromIntegral (T.length x + (if isFunctionCompletion then 1 else 0)) + let currentType = + if isFunctionCompletion then + let currentRange = fromLspPos uri (J.Position l newC) in + do -- maybe monad + ri <- rangeMapFindAt currentRange rm + case ri of + [(r, rangeInfo)] -> do + t <- rangeInfoType rangeInfo + case splitFunType t of + Just (pars,eff,res) -> Just res + Nothing -> Just t + _ -> Nothing + else Nothing + -- currentRope is already a single line, but it may include an enclosing '\n' + let curLine = T.dropWhileEnd (== '\n') $ Rope.toText currentRope + let pi = PositionInfo curLine modName x pos currentType isFunctionCompletion + return -- $ trace (show pi) + pi + in + -- trace (show result) $ + return result + +-- TODO: Complete local variables +-- TODO: Show documentation comments in completion docs + +filterInfix :: PositionInfo -> T.Text -> Bool +filterInfix pinfo n = (searchTerm pinfo `T.isInfixOf` n) && (('.' /= T.head n) || ".Hnd-" `T.isPrefixOf` n) + +filterInfixConstructors :: PositionInfo -> T.Text -> Bool +filterInfixConstructors pinfo n = (searchTerm pinfo `T.isInfixOf` n) && (('.' /= T.head n) || ".Hnd-" `T.isPrefixOf` n) + +findCompletions :: Loaded -> Module -> PositionInfo -> [J.CompletionItem] +findCompletions loaded mod pinfo@PositionInfo{isFunctionCompletion = fcomplete} = filter (filterInfix pinfo . (^. J.label)) completions + where + curModName = modName mod + search = searchTerm pinfo + gamma = loadedGamma loaded + constrs = loadedConstructors loaded + syns = loadedSynonyms loaded + completions = + if fcomplete then valueCompletions curModName gamma pinfo else keywordCompletions curModName + ++ valueCompletions curModName gamma pinfo + ++ constructorCompletions curModName constrs + ++ synonymCompletions curModName syns + +-- TODO: Type completions, ideally only inside type expressions +-- ++ newtypeCompletions ntypes + +typeUnifies :: Type -> Maybe Type -> Bool +typeUnifies t1 t2 = + case t2 of + Nothing -> True + Just t2 -> let (res, _, _) = (runUnifyEx 0 $ matchArguments True rangeNull tvsEmpty t1 [t2] [] Nothing) in isRight res + +valueCompletions :: Name -> Gamma -> PositionInfo -> [J.CompletionItem] +valueCompletions curModName gamma pinfo@PositionInfo{argumentType=tp, searchTerm=search, isFunctionCompletion} = map toItem . filter matchInfo $ filter (\(n, ni) -> filterInfix pinfo $ T.pack $ nameId n) $ gammaList gamma + where + isHandler n = '.' == T.head n + matchInfo :: (Name, NameInfo) -> Bool + matchInfo (n, ninfo) = case ninfo of + InfoVal {infoType} -> typeUnifies infoType tp + InfoFun {infoType} -> typeUnifies infoType tp + InfoExternal {infoType} -> typeUnifies infoType tp + InfoImport {infoType} -> typeUnifies infoType tp + InfoCon {infoType } -> typeUnifies infoType tp + toItem (n, ninfo) = case ninfo of + InfoCon {infoCon} | isHandler $ T.pack (nameId n) -> makeHandlerCompletionItem curModName infoCon d rng (fullLine pinfo) + InfoFun {infoType} -> makeFunctionCompletionItem curModName n d infoType isFunctionCompletion rng (fullLine pinfo) + InfoVal {infoType} -> case splitFunScheme infoType of + Just (tvars, tpreds, pars, eff, res) -> makeFunctionCompletionItem curModName n d infoType isFunctionCompletion rng (fullLine pinfo) + Nothing -> makeCompletionItem curModName n k d + _ -> makeCompletionItem curModName n k d + where + pos@(J.Position l c) = cursorPos pinfo + rng = J.Range (J.Position l $ c - fromIntegral (T.length search)) pos + k = case ninfo of + InfoVal {..} -> J.CompletionItemKind_Constant + InfoFun {..} -> J.CompletionItemKind_Function + InfoExternal {..} -> J.CompletionItemKind_Reference + InfoImport {..} -> J.CompletionItemKind_Module + InfoCon {infoCon = ConInfo {conInfoParams = ps}} + | not (null ps) -> J.CompletionItemKind_Constructor + | otherwise -> J.CompletionItemKind_EnumMember + d = show $ pretty $ infoType ninfo + +constructorCompletions :: Name -> Constructors -> [J.CompletionItem] +constructorCompletions curModName cstrs = map toItem $ filter (\(n,ci) -> '.' /= T.head (T.pack $ nameId n)) (constructorsList cstrs) + where + toItem (n, cinfo) = makeCompletionItem curModName n k d + where + ps = conInfoParams cinfo + k + | not (null ps) = J.CompletionItemKind_Constructor + | otherwise = J.CompletionItemKind_EnumMember + d = show $ pretty $ conInfoType cinfo + +synonymCompletions :: Name -> Synonyms -> [J.CompletionItem] +synonymCompletions curModName = map toItem . synonymsToList + where + toItem sinfo = makeCompletionItem curModName n J.CompletionItemKind_Interface d + where + n = synInfoName sinfo + d = show $ pretty $ synInfoType sinfo + +keywordCompletions :: Name -> [J.CompletionItem] +keywordCompletions curModName = map toItem $ S.toList reservedNames + where + toItem s = makeSimpleCompletionItem curModName s J.CompletionItemKind_Keyword + +makeCompletionItem :: Name -> Name -> J.CompletionItemKind -> String -> J.CompletionItem +makeCompletionItem curModName n k d = + J.CompletionItem + label + labelDetails + kind + tags + detail + doc + deprecated + preselect + sortText + filterText + insertText + insertTextFormat + insertTextMode + textEdit + textEditText + additionalTextEdits + commitChars + command + xdata + where + label = T.pack $ nameId n + labelDetails = Nothing + kind = Just k + tags = Nothing + detail = Just $ T.pack d + doc = Just $ J.InL $ T.pack $ nameModule n + deprecated = Just False + preselect = Nothing + sortText = Just $ if nameId curModName == nameModule n then T.pack $ "0" ++ nameId n else T.pack $ "2" ++ nameId n + filterText = Nothing + insertText = Nothing + insertTextFormat = Nothing + insertTextMode = Nothing + textEdit = Nothing + textEditText = Nothing + additionalTextEdits = Nothing + commitChars = Just [T.pack "\t"] + command = Nothing + xdata = Nothing + +makeFunctionCompletionItem :: Name -> Name -> String -> Type -> Bool -> J.Range -> T.Text-> J.CompletionItem +makeFunctionCompletionItem curModName funName d funType accessor rng line = + J.CompletionItem + label + labelDetails + kind + tags + detail + doc + deprecated + preselect + sortText + filterText + insertText + insertTextFormat + insertTextMode + textEdit + textEditText + additionalTextEdits + commitChars + command + xdata + where + label = T.pack $ nameId funName + indentation = T.length $ T.takeWhile (== ' ') line + trailingFunIndentation = T.replicate indentation " " + labelDetails = Nothing + kind = Just J.CompletionItemKind_Snippet + tags = Nothing + detail = Just $ T.pack d + doc = Just $ J.InL $ T.pack $ nameModule funName + deprecated = Just False + preselect = Nothing + sortText = Just $ if nameId curModName == nameModule funName then "0" <> label else "2" <> label + filterText = Just label + insertText = Nothing + insertTextFormat = Just InsertTextFormat_Snippet + insertTextMode = Nothing + arguments = case splitFunScheme funType + of Just (tvars, tpreds, pars, eff, res) -> pars + Nothing -> [] + numArgs = length arguments - (if accessor then 1 else 0) + trailingFunArgTp = case arguments + of [] -> Nothing + xs -> let arg = last xs + in case splitFunScheme (snd arg) of + Nothing -> Nothing + Just (_, _, args, _, _) -> Just args + argumentsText = + if numArgs == 0 then -- trace ("No function arguments for " ++ show label) $ + T.pack "" + else case trailingFunArgTp of + Nothing -> "(" <> T.intercalate "," (map (\i -> T.pack $ "$" ++ show i) [1..numArgs]) <> ")" + Just tp -> + let mainArgs = "(" <> T.intercalate "," (map (\i -> T.pack $ "$" ++ show i) [1..numArgs-1]) <> ")" + in mainArgs <> " fn(" <> T.intercalate "," (map (\i -> T.pack $ "$" ++ show i) [numArgs..numArgs+length tp-1]) <> ")\n" <> trailingFunIndentation <> "()" + textEdit = Just $ J.InL $ J.TextEdit rng $ label <> argumentsText + textEditText = Nothing + additionalTextEdits = Nothing + commitChars = Just [T.pack "\t"] + command = Nothing + xdata = Nothing + +makeHandlerCompletionItem :: Name -> ConInfo -> String -> J.Range -> T.Text -> J.CompletionItem +makeHandlerCompletionItem curModName conInfo d r line = + J.CompletionItem + label + labelDetails + kind + tags + detail + doc + deprecated + preselect + sortText + filterText + insertText + insertTextFormat + insertTextMode + textEdit + textEditText + additionalTextEdits + commitChars + command + xdata + where + indentation = T.length $ T.takeWhile (== ' ') line + clauseIndentation = T.replicate indentation " " + clauseBodyIndentation = T.replicate (indentation + 2) " " + typeName = conInfoTypeName conInfo + typeNameId = T.replace ".hnd-" "" $ T.pack $ nameId typeName + label = "handler for " <> typeNameId + labelDetails = Nothing + kind = Just J.CompletionItemKind_Snippet + tags = Nothing + detail = Just $ T.pack d + doc = Just $ J.InL $ T.pack $ nameModule typeName + deprecated = Just False + preselect = Nothing + sortText = Just $ if nameId curModName == nameModule typeName then "0" <> typeNameId else "2" <> typeNameId + filterText = Just typeNameId + insertText = Nothing + insertTextFormat = Just InsertTextFormat_Snippet + insertTextMode = Nothing + handlerClause :: (Int, [T.Text]) -> (Name, Type) -> (Int, [T.Text]) + handlerClause (i, acc) (name, tp) = + -- TODO: Consider adding snippet locations for the body of the handlers as well + if T.isPrefixOf "val" newName then + (i + 1, acc ++ [clauseIndentation <> newName <> " = $" <> T.pack (show (i + 1))]) + else (if not (null funArgs) then fst (last funArgs) + 1 else 1, acc ++ [clauseIndentation <> newName <> "(" <> T.intercalate "," (map snd funArgs) <> ")\n" <> clauseBodyIndentation <> "()"]) + where + funArgs = zipWith (\i s -> (i, T.pack $ "$" ++ show (i + 1))) [i..] (handlerArgs newName tp) + newName = T.replace "brk" "final ctl" $ T.replace "-" " " (T.pack (show name)) + textEdit = Just $ J.InL $ J.TextEdit r $ "handler\n" <> T.intercalate "\n" (snd (foldl handlerClause (1, []) (conInfoParams conInfo))) + textEditText = Nothing + additionalTextEdits = Nothing + commitChars = Just [T.pack "\t"] + command = Nothing + xdata = Nothing + +handlerArgs :: T.Text -> Type -> [Type] +handlerArgs name tp = + case tp of + TApp _ args -> if T.isPrefixOf "val" name then take (length args - 3) args else take (length args - 4) args + _ -> [] + +makeSimpleCompletionItem :: Name -> String -> J.CompletionItemKind -> J.CompletionItem +makeSimpleCompletionItem curModName l k = + J.CompletionItem + label + labelDetails + kind + tags + detail + doc + deprecated + preselect + sortText + filterText + insertText + insertTextFormat + insertTextMode + textEdit + textEditText + additionalTextEdits + commitChars + command + xdata + where + label = T.pack l + labelDetails = Nothing + kind = Just k + tags = Nothing + detail = Nothing + doc = Nothing + deprecated = Just False + preselect = Nothing + sortText = Just $ T.pack $ "1" ++ l + filterText = Nothing + insertText = Nothing + insertTextFormat = Nothing + insertTextMode = Nothing + textEdit = Nothing + textEditText = Nothing + additionalTextEdits = Nothing + commitChars = Just [T.pack "\t"] + command = Nothing + xdata = Nothing diff --git a/src/Main/langserver/LanguageServer/Handler/Definition.hs b/src/Main/langserver/LanguageServer/Handler/Definition.hs new file mode 100644 index 000000000..a6e761258 --- /dev/null +++ b/src/Main/langserver/LanguageServer/Handler/Definition.hs @@ -0,0 +1,76 @@ +----------------------------------------------------------------------------- +-- The LSP handler that provides ctrl-click definitions +----------------------------------------------------------------------------- +{-# LANGUAGE OverloadedStrings #-} + +module LanguageServer.Handler.Definition (definitionHandler) where + +import Compiler.Module (Loaded (..), loadedModule, modRangeMap) +import Control.Lens ((^.)) +import qualified Data.Map as M +import Common.Range as R +import Data.Foldable(maximumBy) +import Data.Maybe (maybeToList) +import Kind.Constructors (conInfoRange, constructorsLookup) +import Kind.Newtypes (dataInfoRange, newtypesLookupAny) +import Kind.Synonym (synInfoRange, synonymsLookup) +import Language.LSP.Server (Handlers, requestHandler) +import qualified Language.LSP.Protocol.Types as J +import qualified Language.LSP.Protocol.Lens as J +import LanguageServer.Conversions (fromLspPos, toLspLocation, toLspLocationLink) +import LanguageServer.Monad (LSM, getLoaded) +import Syntax.RangeMap (RangeInfo (..), rangeMapFindAt, NameInfo (..)) +import Type.Assumption (gammaLookupQ, infoRange) +import qualified Language.LSP.Protocol.Message as J + +-- Finds the definitions of the element under the cursor. +definitionHandler :: Handlers LSM +definitionHandler = requestHandler J.SMethod_TextDocumentDefinition $ \req responder -> do + let J.DefinitionParams doc pos _ _ = req ^. J.params + uri = doc ^. J.uri + loaded <- getLoaded uri + let defs = do -- maybe monad + l <- maybeToList loaded + rmap <- maybeToList $ modRangeMap $ loadedModule l + rm <- maybeToList $ rangeMapFindAt (fromLspPos uri pos) rmap + case rangeMapBestDefinition rm of + Just (r, rinfo) -> findDefinitions l rinfo + Nothing -> [] + responder $ Right $ J.InR $ J.InL defs + +-- Get best rangemap info for a given position +rangeMapBestDefinition rm = + case rm of + [] -> Nothing + [r] -> Just r + xs -> Just $ maximumBy (\a b -> compare (rangeInfoPriority a) (rangeInfoPriority b)) xs + +rangeInfoPriority :: (Range,RangeInfo) -> Int +rangeInfoPriority (r,ri) = + case ri of + Block _ -> -1 + Id _ (NICon{}) True -> 3 + Id _ _ True -> 2 + Id _ _ _ -> 0 + Decl "con" _ _ -> 3 -- Constructors are more important than other decls (such as automatically generated ones) + Decl _ _ _ -> 1 + Warning _ -> 4 + Error _ -> 5 + +-- Finds the definition locations of the element +-- represented by the given range info. +findDefinitions :: Loaded -> RangeInfo -> [J.DefinitionLink] +findDefinitions loaded rinfo = case rinfo of + Id qname _ _ -> + let rngs = + map infoRange (gammaLookupQ qname gamma) + ++ map conInfoRange (maybeToList $ constructorsLookup qname constrs) + ++ map synInfoRange (maybeToList $ synonymsLookup qname synonyms) + ++ map dataInfoRange (maybeToList $ newtypesLookupAny qname newtypes) + in map (J.DefinitionLink . toLspLocationLink rinfo) rngs + _ -> [] + where + gamma = loadedGamma loaded + constrs = loadedConstructors loaded + synonyms = loadedSynonyms loaded + newtypes = loadedNewtypes loaded diff --git a/src/Main/langserver/LanguageServer/Handler/DocumentSymbol.hs b/src/Main/langserver/LanguageServer/Handler/DocumentSymbol.hs new file mode 100644 index 000000000..4458aa6f4 --- /dev/null +++ b/src/Main/langserver/LanguageServer/Handler/DocumentSymbol.hs @@ -0,0 +1,228 @@ +----------------------------------------------------------------------------- +-- The LSP handler that provides a document symbol tree +-- (sometimes presented as 'outline' in the client's GUI) +----------------------------------------------------------------------------- +{-# LANGUAGE OverloadedStrings, FlexibleInstances, RecordWildCards #-} +module LanguageServer.Handler.DocumentSymbol( documentSymbolHandler + ) where + +import qualified Common.Range as R +import Common.Syntax ( DefSort (..), Visibility ) +import Common.Name ( Name (..), isHiddenName ) +import Compiler.Module ( modProgram, loadedModule, Loaded (..) ) +import Control.Lens ( (^.) ) +import qualified Data.Map as M +import Data.Maybe ( maybeToList ) +import qualified Data.Text as T +import Language.LSP.Server ( Handlers, requestHandler ) +import qualified Language.LSP.Protocol.Types as J +import qualified Language.LSP.Protocol.Lens as J +import LanguageServer.Conversions ( toLspRange ) +import LanguageServer.Monad ( LSM, getLoaded ) +import Syntax.Syntax +import qualified Language.LSP.Protocol.Message as J +import Common.NamePrim (nameNull, namePhantom) + +-- The LSP handler that provides the symbol tree of a document +-- Symbols include +-- File / Module / Namespace / Package / Class / Method / Property / Field / Constructor / Enum / Interface / Function / Variable +-- Constant / String / Number / Boolean / Array / Object / Key / Null / EnumMember / Struct / Event / Operator / TypeParameter +-- +-- Koka only reports a subset of these including +-- Interface (for synonyms) +-- Enum (types with more than one constructor) / EnumMember (constructors) / Field (fields) / TypeParameter (type parameters) +-- Struct (types with one constructor) / Constructor (constructor) / Field (fields) / TypeParameter (type parameters) +-- Constant / Function / Variable / Number / String +documentSymbolHandler :: Handlers LSM +documentSymbolHandler = requestHandler J.SMethod_TextDocumentDocumentSymbol $ \req responder -> do + let J.DocumentSymbolParams _ _ doc = req ^. J.params + uri = doc ^. J.uri + loaded <- getLoaded uri + let symbols = findDocumentSymbols =<< maybeToList loaded + responder $ Right $ J.InR $ J.InL symbols + +-- Traverses the syntax tree to find document symbols +findDocumentSymbols :: Loaded -> [J.DocumentSymbol] +findDocumentSymbols loaded = do + prog <- maybeToList $ modProgram $ loadedModule loaded + symbols prog + +class HasSymbols a where + symbols :: a -> [J.DocumentSymbol] + +instance HasSymbols a => HasSymbols (Maybe a) where + symbols = maybe [] symbols + +instance HasSymbols a => HasSymbols [a] where + symbols = (symbols =<<) + +instance HasSymbols () where + symbols = const [] + +instance HasSymbols UserProgram where + symbols prog = symbols (programTypeDefs prog) ++ symbols (programDefs prog) + +-- Type definition instances + +instance HasSymbols UserTypeDefGroup where + symbols tdg = case tdg of + TypeDefRec tds -> symbols tds + TypeDefNonRec td -> symbols td + +instance HasSymbols UserTypeDef where + symbols td = makeSymbolSelect n k r rngSelect cs + where + b = typeDefBinder td + n = tbinderName b + rngSelect = tbinderNameRange b + r = typeDefRange td + k = case td of + Synonym {..} -> J.SymbolKind_Interface + DataType {typeDefConstrs = ctrs} | length ctrs > 1 -> J.SymbolKind_Enum + | otherwise -> J.SymbolKind_Struct + cs = case td of + DataType {typeDefConstrs = ctrs, typeDefParams=params} | length ctrs > 1 -> symbols ctrs ++ symbols params + DataType {typeDefParams=params} -> symbols params + Synonym {typeDefParams = params} -> symbols params + +instance HasSymbols (TypeBinder k) where + symbols b = [] -- makeSymbol n k r [] + where + n = tbinderName b + r = tbinderRange b + k = J.SymbolKind_TypeParameter + +instance HasSymbols UserUserCon where + symbols c = makeSymbolSelect n k r rngSelect cs + where + n = userconName c + rngSelect = userconNameRange c + ps = userconParams c + k | not (null ps) = J.SymbolKind_Constructor + | otherwise = J.SymbolKind_EnumMember + r = userconRange c + cs = symbols ps ++ symbols (userconExists c) + +type UserConParam = (Visibility,ValueBinder UserType (Maybe (Expr UserType))) +instance HasSymbols UserConParam where + symbols (v, b) = makeSymbolSelect n k r rngSelect cs + where + n = binderName b + rngSelect = binderNameRange b + r = binderRange b + k = J.SymbolKind_Field + cs = symbols (binderExpr b) + +-- Value definition instances +instance HasSymbols UserDefGroup where + symbols dg = case dg of + DefRec ds -> symbols ds + DefNonRec d -> symbols d + +instance HasSymbols UserDef where + symbols d = makeSymbolSelect n k r rngSelect cs + where + b = defBinder d + k = case defSort d of + DefFun _ _ -> J.SymbolKind_Function + DefVal -> J.SymbolKind_Constant + DefVar -> J.SymbolKind_Variable + n = binderName b + r = defRange d + rngSelect = binderNameRange b + cs = symbols $ binderExpr b + +instance HasSymbols e => HasSymbols (ValueBinder t e) where + symbols b = makeSymbolSelect n k r rngSelect cs + where + k = J.SymbolKind_Constant + n = binderName b + r = binderRange b + rngSelect = binderNameRange b + cs = symbols $ binderExpr b + +instance HasSymbols UserExpr where + symbols ex = case ex of + Lam bs e _ -> symbols bs ++ symbols e + Let dg e _ -> symbols dg ++ symbols e + Bind d e _ -> symbols d ++ symbols e + App e nes _ -> symbols e ++ symbols (map snd nes) + Ann e _ _ -> symbols e + Case e bs _ -> symbols e ++ symbols bs + Parens e _ _ -> symbols e + Handler _ _ _ _ _ bs e1 e2 e3 hbs _ _ -> symbols bs ++ symbols e1 + ++ symbols e2 + ++ symbols e3 + ++ symbols hbs + Inject _ e _ _ -> symbols e + Var n _ r -> makeSymbol n J.SymbolKind_Variable r [] + Lit l -> symbols l + +instance HasSymbols Lit where + symbols l = + let (s,k) = case l of + LitChar c _ -> (show c, J.SymbolKind_Constant) + LitInt i _ -> (show i, J.SymbolKind_Number) + LitFloat f _ -> (show f, J.SymbolKind_Number) + LitString s _ -> (show s, J.SymbolKind_String) + in [J.DocumentSymbol (T.pack s) Nothing k Nothing Nothing rng rng Nothing ] + where rng = toLspRange $ litRange l + +instance HasSymbols UserHandlerBranch where + symbols hb = makeSymbolSelect n J.SymbolKind_Function r rngSelect cs + where + n = hbranchName hb + rngSelect = hbranchNameRange hb + e = hbranchExpr hb + r = rngSelect `R.combineRange` R.getRange e + ps = hbranchPars hb + cs = symbols ps ++ symbols e + +instance HasSymbols UserBranch where + symbols b = symbols p ++ symbols gs + where + p = branchPattern b + gs = branchGuards b + +instance HasSymbols UserGuard where + symbols g = symbols t ++ symbols e + where + t = guardTest g + e = guardExpr g + +instance HasSymbols UserPattern where + symbols pat = case pat of + PatVar b -> let n = binderName b + r = binderRange b + in makeSymbol n J.SymbolKind_Constant r [] + PatAnn p _ _ -> symbols p + PatCon _ ps _ _ -> symbols $ map snd ps + PatParens p _ -> symbols p + PatLit l -> symbols l + PatWild _ -> [] + +makeSymbolSelect :: Name -> J.SymbolKind -> R.Range -> R.Range -> [J.DocumentSymbol] -> [J.DocumentSymbol] +makeSymbolSelect n k r rngSelect cs = + [J.DocumentSymbol name detail kind tags deprecated range selRange children | nameId n /= "" && not (isHiddenName n) && n /= namePhantom] + where + name = T.pack $ nameId n + detail = Just $ T.pack $ nameModule n + kind = k + tags = Just [] + deprecated = Just False + range = toLspRange (r `R.combineRange` rngSelect) + selRange = toLspRange rngSelect + children = Just cs + +makeSymbol :: Name -> J.SymbolKind -> R.Range -> [J.DocumentSymbol] -> [J.DocumentSymbol] +makeSymbol n k r cs = + [J.DocumentSymbol name detail kind tags deprecated range selRange children | nameId n /= "" && not (isHiddenName n) && n /= namePhantom] + where + name = T.pack $ nameId n + detail = Just $ T.pack $ nameModule n + kind = k + tags = Just [] + deprecated = Just False + range = toLspRange r + selRange = range + children = Just cs diff --git a/src/Main/langserver/LanguageServer/Handler/Folding.hs b/src/Main/langserver/LanguageServer/Handler/Folding.hs new file mode 100644 index 000000000..72e498666 --- /dev/null +++ b/src/Main/langserver/LanguageServer/Handler/Folding.hs @@ -0,0 +1,156 @@ +{-# LANGUAGE RecordWildCards, FlexibleInstances #-} +module LanguageServer.Handler.Folding(foldingHandler) where + +import qualified Common.Range as R +import Compiler.Module (loadedModule, Loaded, Module) +import Control.Lens ((^.)) +import qualified Data.Text as T +import Language.LSP.Server (Handlers, requestHandler) +import qualified Language.LSP.Protocol.Types as J +import qualified Language.LSP.Protocol.Lens as J +import LanguageServer.Conversions (fromLspPos, toLspRange) +import LanguageServer.Monad (LSM, getLoaded) +import qualified Language.LSP.Protocol.Message as J +import Common.Name (nameNil, Name (nameId)) +import Compiler.Compile (modName, Module (modProgram)) +import Data.Maybe (maybeToList) +import Syntax.Syntax +import Common.Syntax +import Language.LSP.Protocol.Types (FoldingRangeKind(FoldingRangeKind_Region)) +import Type.Pretty (ppName) +import Common.Range (Pos(..), Ranged (getRange)) + +-- Handles hover requests +foldingHandler :: Handlers LSM +foldingHandler = requestHandler J.SMethod_TextDocumentFoldingRange $ \req responder -> do + let J.FoldingRangeParams _ _ doc = req ^. J.params + uri = doc ^. J.uri + loaded <- getLoaded uri + let foldings = findFoldingRanges =<< maybeToList loaded + responder $ Right $ J.InL foldings + + +-- Traverses the syntax tree to find document foldings +findFoldingRanges :: Loaded -> [J.FoldingRange] +findFoldingRanges loaded = do + prog <- maybeToList $ modProgram $ loadedModule loaded + foldings prog + + +class HasFoldingRanges a where + foldings :: a -> [J.FoldingRange] + +instance HasFoldingRanges a => HasFoldingRanges (Maybe a) where + foldings = maybe [] foldings + +instance HasFoldingRanges a => HasFoldingRanges [a] where + foldings = (foldings =<<) + +instance HasFoldingRanges () where + foldings = const [] + +instance HasFoldingRanges UserProgram where + foldings prog = foldings (programTypeDefs prog) ++ foldings (programDefs prog) + +-- Type definition instances + +instance HasFoldingRanges UserTypeDefGroup where + foldings tdg = case tdg of + TypeDefRec tds -> foldings tds + TypeDefNonRec td -> foldings td + +instance HasFoldingRanges UserTypeDef where + foldings td = makeFolding r n + where + b = typeDefBinder td + n = tbinderName b + r = typeDefRange td + +instance HasFoldingRanges UserUserCon where + foldings c = makeFolding r n ++ cs + where + n = userconName c + r = userconRange c + cs = foldings (userconParams c) + +type UserConParam = (Visibility,ValueBinder UserType (Maybe (Expr UserType))) +instance HasFoldingRanges UserConParam where + foldings (v, b) = makeFolding r n ++ cs + where + n = binderName b + r = binderRange b + cs = foldings (binderExpr b) + +-- Value definition instances +instance HasFoldingRanges UserDefGroup where + foldings dg = case dg of + DefRec ds -> foldings ds + DefNonRec d -> foldings d + +instance HasFoldingRanges UserDef where + foldings d = makeFolding r n ++ cs + where + b = defBinder d + n = binderName b + r = defRange d + cs = foldings $ binderExpr b + +instance HasFoldingRanges e => HasFoldingRanges (ValueBinder t e) where + foldings b = makeFolding r n ++ cs + where + n = binderName b + r = binderRange b + cs = foldings $ binderExpr b + +instance HasFoldingRanges UserExpr where + foldings ex = case ex of + Lam bs e r -> foldings bs ++ foldings e ++ makeFoldingNoName r + Let (DefRec dfs) e r -> concatMap foldings dfs ++ foldings e + Let (DefNonRec df) e r -> foldings df ++ foldings e + Bind d e r -> foldings d ++ foldings e ++ makeFolding r (getName d) + App e nes _ -> foldings e ++ foldings (map snd nes) + Ann e _ r -> foldings e ++ makeFoldingNoName r + Case e bs r -> foldings e ++ foldings bs ++ makeFoldingNoName r + Parens e _ _ -> foldings e + Handler _ _ _ _ _ bs e1 e2 e3 hbs _ r -> foldings bs ++ foldings e1 + ++ foldings e2 + ++ foldings e3 + ++ foldings hbs ++ makeFoldingNoName r + Inject _ e _ _ -> foldings e + _ -> [] + +instance HasFoldingRanges UserHandlerBranch where + foldings hb = makeFolding r n ++ cs + where + n = hbranchName hb + e = hbranchExpr hb + r = R.getRange (hbranchNameRange hb) `R.combineRange` R.getRange e + ps = hbranchPars hb + cs = foldings ps ++ foldings e + +instance HasFoldingRanges UserBranch where + foldings b = foldings gs + where + p = branchPattern b + gs = branchGuards b + +instance HasFoldingRanges UserGuard where + foldings g = foldings t ++ foldings e + where + t = guardTest g + e = guardExpr g + +makeFoldingNoName :: R.Range -> [J.FoldingRange] +makeFoldingNoName r = [J.FoldingRange lineStart (Just charStart) lineEnd (Just charEnd) (Just J.FoldingRangeKind_Region) Nothing | rangeSpansLine r] + where J.Range {_start=J.Position{_line=lineStart, _character=charStart}, _end=J.Position{_line=lineEnd, _character=charEnd}} = toLspRange r + +makeFolding :: R.Range -> Name -> [J.FoldingRange] +makeFolding r n = + [J.FoldingRange lineStart (Just charStart) lineEnd (Just charEnd) (Just J.FoldingRangeKind_Region) (Just (T.pack $ nameId n)) | rangeSpansLine r] + where J.Range {_start=J.Position{_line=lineStart, _character=charStart}, _end=J.Position{_line=lineEnd, _character=charEnd}} = toLspRange r + + +rangeSpansLine :: R.Range -> Bool +rangeSpansLine r = lineStart /= lineEnd + where lineStart = posLine $ R.rangeStart r + lineEnd = posLine $ R.rangeEnd r diff --git a/src/Main/langserver/LanguageServer/Handler/Hover.hs b/src/Main/langserver/LanguageServer/Handler/Hover.hs new file mode 100644 index 000000000..934e02313 --- /dev/null +++ b/src/Main/langserver/LanguageServer/Handler/Hover.hs @@ -0,0 +1,96 @@ +----------------------------------------------------------------------------- +-- The LSP handler that provides hover tooltips +----------------------------------------------------------------------------- +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE RankNTypes #-} + +module LanguageServer.Handler.Hover (hoverHandler, formatRangeInfoHover) where + +import Compiler.Module (loadedModule, modRangeMap, Loaded (loadedModules, loadedImportMap), Module (modPath, modSourcePath)) +import Compiler.Options (Flags, colorSchemeFromFlags, prettyEnvFromFlags) +import Compiler.Compile (modName) +import Data.Foldable(maximumBy) +import Control.Lens ((^.)) +import Control.Monad.Cont (liftIO) +import Common.Range as R +import Common.Name (nameNil) +import Common.ColorScheme (ColorScheme (colorNameQual, colorSource), Color (Gray)) +import qualified Data.Text as T +import qualified Language.LSP.Protocol.Types as J +import qualified Language.LSP.Protocol.Lens as J +import qualified Language.LSP.Protocol.Message as J +import Syntax.RangeMap (NameInfo (..), RangeInfo (..), rangeMapFindAt) +import Language.LSP.Server (Handlers, sendNotification, requestHandler) +import LanguageServer.Conversions (fromLspPos, toLspRange) +import LanguageServer.Monad (LSM, getLoaded, getLoadedModule, getHtmlPrinter, getFlags) +import Lib.PPrint (Pretty (..), Doc, text, (<+>), color) +import Type.Pretty (ppScheme, defaultEnv, Env(..), ppName) +import Kind.Pretty (prettyKind) +import Kind.ImportMap (importsEmpty, ImportMap) +import Type.Type (Name) +import Debug.Trace (trace) + +-- Handles hover requests +hoverHandler :: Handlers LSM +hoverHandler = requestHandler J.SMethod_TextDocumentHover $ \req responder -> do + let J.HoverParams doc pos _ = req ^. J.params + uri = doc ^. J.uri + loadedMod <- getLoadedModule uri + loaded <- getLoaded uri + let res = do -- maybe monad + mod <- loadedMod + l <- loaded + rmap <- modRangeMap mod + -- Find the range info at the given position + rm <- rangeMapFindAt (fromLspPos uri pos) rmap + trace (show rm) $ return () + (r, rinfo) <- rangeMapBestHover rm + return (modName mod, loadedImportMap l, r, rinfo) + case res of + Just (mName, imports, r, rinfo) -> do + -- Get the html-printer and flags + print <- getHtmlPrinter + flags <- getFlags + let env = (prettyEnvFromFlags flags){ context = mName, importsMap = imports } + colors = colorSchemeFromFlags flags + x <- liftIO $ print $ formatRangeInfoHover env colors rinfo + let hc = J.InL $ J.mkMarkdown x + rsp = J.Hover hc $ Just $ toLspRange r + responder $ Right $ J.InL rsp + Nothing -> responder $ Right $ J.InR J.Null + +-- Get best rangemap info for a given position +rangeMapBestHover rm = + case rm of + [] -> Nothing + [r] -> Just r + xs -> Just $ maximumBy (\a b -> compare (rangeInfoPriority a) (rangeInfoPriority b)) xs + +rangeInfoPriority :: (Range,RangeInfo) -> Int +rangeInfoPriority (r,ri) = + case ri of + Block _ -> -1 + Id _ (NICon{}) True -> 3 + Id _ _ True -> 2 + Id _ _ _ -> 0 + Decl "con" _ _ -> 3 -- Constructors are more important than other decls (such as automatically generated ones) + Decl _ _ _ -> 1 + Warning _ -> 4 + Error _ -> 5 + +-- Pretty-prints type/kind information to a hover tooltip given a type pretty environment, color scheme +formatRangeInfoHover :: Env -> ColorScheme -> RangeInfo -> Doc +formatRangeInfoHover env colors rinfo = + case rinfo of + Id qname info isdef -> + ppName env qname <+> text " : " <+> case info of + NIValue tp _ -> ppScheme env tp + NICon tp -> ppScheme env tp + NITypeCon k -> prettyKind colors k + NITypeVar k -> prettyKind colors k + NIModule -> text "module" + NIKind -> text "kind" + Decl s name mname -> text s <+> text " " <+> pretty name + Block s -> text s + Error doc -> text "Error: " <+> doc + Warning doc -> text "Warning: " <+> doc diff --git a/src/Main/langserver/LanguageServer/Handler/InlayHints.hs b/src/Main/langserver/LanguageServer/Handler/InlayHints.hs new file mode 100644 index 000000000..bc3e7174b --- /dev/null +++ b/src/Main/langserver/LanguageServer/Handler/InlayHints.hs @@ -0,0 +1,76 @@ +----------------------------------------------------------------------------- +-- The LSP handler that provides hover tooltips +----------------------------------------------------------------------------- +{-# LANGUAGE OverloadedStrings #-} + +module LanguageServer.Handler.InlayHints (inlayHintsHandler) where + +import qualified Language.LSP.Protocol.Types as J +import qualified Language.LSP.Protocol.Message as J +import qualified Language.LSP.Protocol.Lens as J +import Language.LSP.Server (Handlers, sendNotification, requestHandler) +import LanguageServer.Monad (LSM, getLoaded, getLoadedModule, getFlags) +import LanguageServer.Conversions (fromLspPos, toLspRange, toLspPos, fromLspRange) +import LanguageServer.Handler.Hover (formatRangeInfoHover) +import qualified Data.Text as T +import Common.Range (Range (..), rangeEnd, Pos(..), rangeNull, posNull) +import Syntax.RangeMap (NameInfo (..), RangeInfo (..), rangeMapFindIn) +import Control.Lens ((^.)) +import Data.Maybe (mapMaybe) +import Type.Pretty (ppType, Env (..), defaultEnv, ppScheme) +import Common.Name (Name) +import Compiler.Compile (Module(..), Loaded (..)) +import Kind.ImportMap (ImportMap) +import Compiler.Options (prettyEnvFromFlags, Flags) +-- import Debug.Trace (trace) + +-- The LSP handler that provides inlay hints (inline type annotations etc) +inlayHintsHandler :: Handlers LSM +inlayHintsHandler = requestHandler J.SMethod_TextDocumentInlayHint $ \req responder -> do + let J.InlayHintParams prog doc rng = req ^. J.params + uri = doc ^. J.uri + newRng = fromLspRange uri rng + loadedMod <- getLoadedModule uri + loaded <- getLoaded uri + flags <- getFlags + let rsp = do -- maybe monad + l <- loaded + lm <- loadedMod + rmap <- modRangeMap lm + -- trace (show $ rangeMapFindIn newRng rmap) $ return () + let env = (prettyEnvFromFlags flags){ context = modName lm, importsMap = loadedImportMap l, showFlavours=False } + return $ mapMaybe (toInlayHint env (modName lm)) $ rangeMapFindIn newRng rmap + case rsp of + Nothing -> responder $ Right $ J.InR J.Null + Just rsp -> responder $ Right $ J.InL rsp + +-- Takes a range and range info and returns an inlay hint if it should be shown +toInlayHint :: Env -> Name -> (Range, RangeInfo) -> Maybe J.InlayHint +toInlayHint env modName (rng, rngInfo) = do + let rngEnd = rangeEnd rng + -- should show identifier hint if it's not annotated already + shouldShow = + (rngEnd /= posNull) && + case rngInfo of + Id _ info _ -> case info of + NIValue _ isAnnotated -> not isAnnotated + _ -> False + _ -> False + if shouldShow then + let position = toLspPos rngEnd{posColumn = posColumn rngEnd + 1} in + let info = T.pack <$> formatInfo env modName rngInfo in + case info of + Just typeString -> + -- If there is a type to show, show it along with a text edit to accept the type suggestion + Just $ J.InlayHint position (J.InL typeString) (Just J.InlayHintKind_Type) (Just [J.TextEdit (J.Range position position) typeString]) Nothing (Just True) (Just True) Nothing + Nothing -> Nothing + else Nothing + +-- Pretty-prints type information for an inlay hint +formatInfo :: Env -> Name -> RangeInfo -> Maybe String +formatInfo env modName rinfo = case rinfo of + Id qname info isdef -> + case info of + NIValue tp _ -> Just $ " : " ++ show (ppScheme env tp) + _ -> Nothing + _ -> Nothing \ No newline at end of file diff --git a/src/Main/langserver/LanguageServer/Handler/TextDocument.hs b/src/Main/langserver/LanguageServer/Handler/TextDocument.hs new file mode 100644 index 000000000..85502a4dd --- /dev/null +++ b/src/Main/langserver/LanguageServer/Handler/TextDocument.hs @@ -0,0 +1,278 @@ +----------------------------------------------------------------------------- +-- The LSP handlers that handle changes to the document +----------------------------------------------------------------------------- +{-# LANGUAGE OverloadedStrings #-} + +module LanguageServer.Handler.TextDocument + ( didOpenHandler, + didChangeHandler, + didSaveHandler, + didCloseHandler, + recompileFile, + compileEditorExpression, + persistModules, + ) +where + +import Common.Error (Error, checkPartial) +import Compiler.Compile (Terminal (..), compileModuleOrFile, Loaded (..), CompileTarget (..), compileFile, codeGen, compileExpression) +import Control.Lens ((^.)) +import Control.Monad.Trans (liftIO) +import qualified Data.Map as M +import Data.Maybe (fromJust, fromMaybe) +import qualified Data.Text as T +import Language.LSP.Diagnostics (partitionBySource) +import Language.LSP.Server (Handlers, flushDiagnosticsBySource, publishDiagnostics, sendNotification, getVirtualFile, getVirtualFiles, notificationHandler) +import qualified Language.LSP.Protocol.Types as J +import qualified Language.LSP.Protocol.Lens as J +import LanguageServer.Conversions (toLspDiagnostics, makeDiagnostic) +import LanguageServer.Monad (LSM, getLoaded, putLoaded, getTerminal, getFlags, LSState (documentInfos), getLSState, modifyLSState, removeLoaded, getModules, putDiagnostics, getDiagnostics, clearDiagnostics, removeLoadedUri) +import Language.LSP.VFS (virtualFileText, VFS(..), VirtualFile, file_version, virtualFileVersion) +import qualified Data.Text.Encoding as T +import Data.Functor ((<&>)) +import qualified Language.LSP.Protocol.Message as J +import Data.ByteString (ByteString) +import Data.Map (Map) +import Text.Read (readMaybe) +import Debug.Trace (trace) +import Control.Exception (try) +import qualified Control.Exception as Exc +import Compiler.Options (Flags) +import Common.File (getFileTime, FileTime, getFileTimeOrCurrent, getCurrentTime, normalize, realPath) +import GHC.IO (unsafePerformIO) +import Compiler.Module (Module(..), initialLoaded) +import Control.Monad (when, foldM) +import Data.Time (addUTCTime, addLocalTime) +import qualified Data.ByteString as J +import Syntax.Syntax ( programNull, programAddImports, Import(..) ) +import Common.Range (rangeNull) +import Core.Core (Visibility(Private)) +import Common.NamePrim (nameInteractiveModule, nameExpr, nameSystemCore) +import Common.Name (newName) +import Lib.PPrint (text) + +-- Compile the file on opening +didOpenHandler :: Handlers LSM +didOpenHandler = notificationHandler J.SMethod_TextDocumentDidOpen $ \msg -> do + let uri = msg ^. J.params . J.textDocument . J.uri + let version = msg ^. J.params . J.textDocument . J.version + flags <- getFlags + _ <- recompileFile InMemory uri (Just version) False flags + return () + +-- Recompile the file on changes +didChangeHandler :: Handlers LSM +didChangeHandler = notificationHandler J.SMethod_TextDocumentDidChange $ \msg -> do + let uri = msg ^. J.params . J.textDocument . J.uri + let version = msg ^. J.params . J.textDocument . J.version + flags <- getFlags + _ <- recompileFile InMemory uri (Just version) False flags + return () + +-- Saving a file just recompiles it +didSaveHandler :: Handlers LSM +didSaveHandler = notificationHandler J.SMethod_TextDocumentDidSave $ \msg -> do + let uri = msg ^. J.params . J.textDocument . J.uri + flags <- getFlags + _ <- recompileFile InMemory uri Nothing False flags + return () + +-- Closing the file +didCloseHandler :: Handlers LSM +didCloseHandler = notificationHandler J.SMethod_TextDocumentDidClose $ \msg -> do + let uri = msg ^. J.params . J.textDocument . J.uri + removeLoadedUri uri + -- Don't remove diagnostics so the file stays red in the editor, and problems are shown, but do remove the compilation state + return () + +-- Retreives a file from the virtual file system, returning the contents and the last modified time +maybeContents :: Map FilePath (ByteString, FileTime, J.Int32) -> FilePath -> Maybe (ByteString, FileTime) +maybeContents vfs uri = do + -- trace ("Maybe contents " ++ show uri ++ " " ++ show (M.keys vfs)) $ return () + (text, ftime, vers) <- M.lookup uri vfs + return (text, ftime) + +-- Creates a diff of the virtual file system including keeping track of version numbers and last modified times +-- Modified times are not present in the LSP libraris's virtual file system, so we do it ourselves +diffVFS :: Map FilePath (ByteString, FileTime, J.Int32) -> Map J.NormalizedUri VirtualFile -> LSM (Map FilePath (ByteString, FileTime, J.Int32)) +diffVFS oldvfs vfs = + -- Fold over the new map, creating a new map that has the same keys as the new map + foldM (\acc (k, v) -> do + -- Get the key as a normalized file path + path0 <- liftIO $ realPath $ J.fromNormalizedFilePath $ fromJust $ J.uriToNormalizedFilePath k + let newK = normalize path0 + -- New file contents & verson + let text = T.encodeUtf8 $ virtualFileText v + vers = virtualFileVersion v + case M.lookup newK oldvfs of + Just old@(_, _, vOld) -> + -- If the key is in the old map, and the version number is the same, keep the old value + if vOld == vers then + return $ M.insert newK old acc + else do + -- Otherwise update the value with a new timestamp + time <- liftIO getCurrentTime + return $ M.insert newK (text, time, vers) acc + Nothing -> do + -- If the key wasn't already present in the map, get it's file time from disk (since it was just opened / created) + time <- liftIO $ getFileTimeOrCurrent newK + -- trace ("New file " ++ show newK ++ " " ++ show time) $ return () + return $ M.insert newK (text, time, vers) acc) + M.empty (M.toList vfs) + +-- Updates the virtual file system in the LSM state +updateVFS :: LSM (Map FilePath (ByteString, FileTime, J.Int32)) +updateVFS = do + -- Get the virtual files + vFiles <- getVirtualFiles + -- Get the full map + let vfs = _vfsMap vFiles + -- Get the old virtual files we have stored + oldvfs <- documentInfos <$> getLSState + -- Diff the virtual files + newvfs <- diffVFS oldvfs vfs + -- Update the virtual files in the state + modifyLSState (\old -> old{documentInfos = newvfs}) + return newvfs + +-- Compiles a single expression (calling a top level function with no arguments) - such as a test method +compileEditorExpression :: J.Uri -> Flags -> Bool -> String -> String -> LSM (Maybe FilePath) +compileEditorExpression uri flags force filePath functionName = do + loaded <- getLoaded uri + case loaded of + Just loaded -> do + let mod = loadedModule loaded + -- Get the virtual files + vfs <- documentInfos <$> getLSState + -- Set up the imports for the expression (core and the module) + let imports = [Import nameSystemCore nameSystemCore rangeNull Private, Import (modName mod) (modName mod) rangeNull Private] + program = programAddImports (programNull nameInteractiveModule) imports + term <- getTerminal + -- reusing interpreter compilation entry point + let resultIO = compileExpression (maybeContents vfs) term flags (if force then initialLoaded else loaded) (Executable nameExpr ()) program 0 (functionName ++ "()") + processCompilationResult normUri filePath False resultIO + Nothing -> do + return Nothing + where normUri = J.toNormalizedUri uri + +-- Recompiles the given file, stores the compilation result in +-- LSM's state and emits diagnostics +recompileFile :: CompileTarget () -> J.Uri -> Maybe J.Int32 -> Bool -> Flags -> LSM (Maybe FilePath) +recompileFile compileTarget uri version force flags = + case J.uriToFilePath uri of + Just filePath0 -> do + -- Get the file path + path <- liftIO $ realPath filePath0 + let filePath = normalize path + -- Update the virtual file system + newvfs <- updateVFS + -- Get the file contents + let contents = fst <$> maybeContents newvfs filePath + modules <- getModules + term <- getTerminal + sendNotification J.SMethod_WindowLogMessage $ J.LogMessageParams J.MessageType_Info $ T.pack $ "Recompiling " ++ filePath + -- Don't use the cached modules as regular modules (they may be out of date, so we want to resolveImports fully over again) + let resultIO = compileFile (maybeContents newvfs) contents term flags [] (if force then [] else modules) compileTarget [] filePath + processCompilationResult normUri filePath True resultIO + Nothing -> return Nothing + where + normUri = J.toNormalizedUri uri + +-- Processes the result of a compilation, updating the loaded state and emitting diagnostics +-- Returns the executable file path if compilation succeeded +processCompilationResult :: J.NormalizedUri -> FilePath -> Bool -> IO (Error Loaded (Loaded, Maybe FilePath)) -> LSM (Maybe FilePath) +processCompilationResult normUri filePath update doIO = do + let ioResult :: IO (Either Exc.SomeException (Error Loaded (Loaded, Maybe FilePath))) + ioResult = try doIO + result <- liftIO ioResult + case result of + Left e -> do + -- Compilation threw an exception, put it in the log, as well as a notification + sendNotification J.SMethod_WindowLogMessage $ J.LogMessageParams J.MessageType_Error $ "When compiling file " <> T.pack filePath <> T.pack (" compiler threw exception " ++ show e) + sendNotification J.SMethod_WindowShowMessage $ J.ShowMessageParams J.MessageType_Error $ "When compiling file " <> T.pack filePath <> T.pack (" compiler threw exception " ++ show e) + let diagSrc = T.pack "koka" + maxDiags = 100 + diags = M.fromList [(normUri, [makeDiagnostic J.DiagnosticSeverity_Error diagSrc rangeNull (text $ show e)])] + putDiagnostics diags + diags <- getDiagnostics + let diagsBySrc = M.map partitionBySource diags + flushDiagnosticsBySource maxDiags (Just diagSrc) + mapM_ (\(uri, diags) -> publishDiagnostics maxDiags uri Nothing diags) (M.toList diagsBySrc) + return Nothing + Right res -> do + -- No exception - so check the result of the compilation + outFile <- case checkPartial res of + Right ((l, outFile), _, _) -> do + -- Compilation succeeded + when update $ putLoaded l -- update the loaded state for this file + sendNotification J.SMethod_WindowLogMessage $ J.LogMessageParams J.MessageType_Info $ "Successfully compiled " <> T.pack filePath + return outFile -- return the executable file path + Left (e, m) -> do + -- Compilation failed + case m of + Nothing -> + trace ("Error when compiling, no cached modules " ++ show e) $ + return () + Just l -> do + trace ("Error when compiling have cached" ++ show (map modSourcePath $ loadedModules l)) $ return () + when update $ putLoaded l + removeLoaded (loadedModule l) + sendNotification J.SMethod_WindowLogMessage $ J.LogMessageParams J.MessageType_Error $ T.pack ("Error when compiling " ++ show e) <> T.pack filePath + return Nothing + -- Emit the diagnostics (errors and warnings) + let diagSrc = T.pack "koka" + diags = toLspDiagnostics normUri diagSrc res + maxDiags = 100 + -- Union with the current file mapped to an empty list, since we want to clear diagnostics for this file when it is an error in another file + diags' = M.union diags (M.fromList [(normUri, [])]) + -- Clear diagnostics for this file if there are no errors / warnings + if null diags then clearDiagnostics normUri else putDiagnostics diags' + -- Get all the diagnostics for all files (language server doesn't support updating diagnostics for a single file) + diags <- getDiagnostics + -- Partition them by source (koka, typescript, linterx, etc.) -- we should only have koka for now + let diagsBySrc = M.map partitionBySource diags + if null diags + -- If there are no diagnostics clear all koka diagnostics + then flushDiagnosticsBySource maxDiags (Just diagSrc) + -- Otherwise report all diagnostics + else do + flushDiagnosticsBySource maxDiags (Just diagSrc) + mapM_ (\(uri, diags) -> publishDiagnostics maxDiags uri Nothing diags) (M.toList diagsBySrc) + return outFile + +-- Persists all modules to disk +persistModules :: LSM () +persistModules = do + mld <- getModules + mapM_ persistModule mld -- TODO: Dependency ordering + +-- Persist a single module to disk (not yet implemented) +persistModule :: Module -> LSM () +persistModule m = do + return () + -- TODO: This works, but needs to check that the dependencies are persisted first. + -- let generate = do + -- -- trace "Generating" $ return () + -- mld <- getLoaded + -- case mld of + -- Just loaded -> do + -- term <- getTerminal + -- flags <- getFlags + -- (loaded, file) <- liftIO $ codeGen term flags Object loaded{loadedModule = m} + -- putLoaded loaded + -- return () + -- Nothing -> return () + -- -- trace ("Module " ++ show (modName m)) $ + -- case modOutputTime m of + -- Nothing -> do + -- -- trace "No output time" $ return () + -- generate + -- -- If it has been 5 seconds since the last time the module was changed + -- -- and it isn't updated on disk persist again. + -- -- We don't do it all the time, because with virtual files and editor changes it would be too much + -- Just t -> do + -- ct <- liftIO getCurrentTime + -- when ((ct > addUTCTime 5 (modTime m)) && (modTime m > t)) $ do + -- -- trace ("Last output time" ++ show t) $ return () + -- generate + -- return () \ No newline at end of file diff --git a/src/Main/langserver/LanguageServer/Handlers.hs b/src/Main/langserver/LanguageServer/Handlers.hs new file mode 100644 index 000000000..c8ca42fe1 --- /dev/null +++ b/src/Main/langserver/LanguageServer/Handlers.hs @@ -0,0 +1,148 @@ +----------------------------------------------------------------------------- +-- The request handlers used by the language server +----------------------------------------------------------------------------- +{-# LANGUAGE RankNTypes #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE NamedFieldPuns #-} +{-# LANGUAGE DuplicateRecordFields #-} +{-# LANGUAGE PolyKinds #-} +{-# LANGUAGE GADTs #-} + +module LanguageServer.Handlers (ReactorInput(..), lspHandlers) where + +import Compiler.Options (Flags) +import Language.LSP.Server (Handlers, notificationHandler, sendNotification, Handler, mapHandlers, MonadLsp (..)) +import LanguageServer.Handler.Completion (completionHandler) +import LanguageServer.Handler.Definition (definitionHandler) +import LanguageServer.Handler.DocumentSymbol (documentSymbolHandler) +import LanguageServer.Handler.Hover (hoverHandler) +import LanguageServer.Handler.InlayHints (inlayHintsHandler) +import LanguageServer.Handler.Commands (commandHandler) +import LanguageServer.Handler.Folding (foldingHandler) +import LanguageServer.Handler.TextDocument (didChangeHandler, didCloseHandler, didOpenHandler, didSaveHandler) +import LanguageServer.Monad (LSM, runLSM, LSState (..), updateConfig) +import Language.LSP.Protocol.Message (TRequestMessage(..), TNotificationMessage(..), Method, MessageDirection(..), MessageKind(..), SMethod (..), SomeLspId (SomeLspId), LspId (..), NotificationMessage (..), ResponseError (..)) +import Control.Monad.Trans (lift) +import Control.Monad.Reader (MonadReader(ask)) + +import GHC.Conc (atomically) +import Control.Monad.IO.Class (liftIO) + +import Control.Concurrent.STM.TChan +import Control.Concurrent.MVar (readMVar) +import Control.Lens ((^.)) +import Control.Concurrent (modifyMVar) +import Control.Concurrent.Async +import Control.Concurrent.STM +import qualified Data.Map as M +import qualified Data.Set as S +import Language.LSP.Protocol.Lens hiding (retry) +import Prelude hiding (id) +import qualified Language.LSP.Protocol.Types as J +import qualified Language.LSP.Protocol.Message as J +import Language.LSP.Protocol.Types (DidChangeTextDocumentParams(..), VersionedTextDocumentIdentifier (..)) + +import Control.Monad (when, unless) +import qualified Data.Text as T +import qualified Debug.Trace as Debug + +newtype ReactorInput = ReactorAction (IO ()) + +-- A list of all the handlers we support +handlers :: Handlers LSM +handlers = + mconcat + [ initializedHandler, + didOpenHandler, + didChangeHandler, + didSaveHandler, + didCloseHandler, + hoverHandler, + definitionHandler, + documentSymbolHandler, + completionHandler, + cancelHandler, + commandHandler, + inlayHintsHandler, + foldingHandler, + configurationChangeHandler + ] + +configurationChangeHandler :: Handlers LSM +configurationChangeHandler = notificationHandler J.SMethod_WorkspaceDidChangeConfiguration $ \_not -> do + let J.DidChangeConfigurationParams{_settings} = _not ^. params + updateConfig _settings + return () + +-- Handles the initialized notification +initializedHandler :: Handlers LSM +initializedHandler = notificationHandler J.SMethod_Initialized $ \_not -> sendNotification J.SMethod_WindowLogMessage $ J.LogMessageParams J.MessageType_Info (T.pack "Initialized language server.") + +-- Handles cancel requests +cancelHandler :: Handlers LSM +cancelHandler = + notificationHandler SMethod_CancelRequest $ \msg -> + do + let id_ = msg ^. params ^. id + state <- lift ask + stateV <- liftIO $ readMVar state + -- Add the request id to the cancelled requests set + _ <- liftIO $ atomically $ modifyTVar (cancelledRequests stateV) $ \t -> S.insert (SomeLspId (toLspId id_)) t + return () + where toLspId (J.InL x) = IdInt x + toLspId (J.InR y) = IdString y + +-- Wraps the normal handler with a function that runs a request in a separate thread and races it with a cancel +lspHandlers rin = mapHandlers goReq goNot handlers where + -- For requests (which can be canceled, and the client expects a response) + goReq :: forall (a :: Method ClientToServer Request). Handler LSM a -> Handler LSM a + goReq f msg@TRequestMessage{_id} k = do + env <- getLspEnv + state <- lift ask + let newId = SomeLspId _id + stVal <- liftIO $ readMVar state + -- Inserts the request into the pending requests set + liftIO $ atomically $ modifyTVar (pendingRequests stVal) $ \t -> S.insert newId t + + -- Spins in a loop waiting for changes to the cancelled requests set and if the request is in there it finishes the thread + let waitForCancel reqId = atomically $ do + cancelled <- readTVar (cancelledRequests stVal) + unless (reqId `S.member` cancelled) retry + -- adds a task to the reactor to run the request in a separate thread + liftIO $ atomically $ writeTChan rin $ -- check if canceled and if so don't run + ReactorAction $ do + -- To run it we race against the cancel + cancelOrRes <- race (waitForCancel newId) $ do + cancelled <- readTVarIO (cancelledRequests stVal) + -- If the request is cancelled before we start we return a cancelled error + if newId `S.member` cancelled then runLSM (k $ Left $ ResponseError (J.InL J.LSPErrorCodes_RequestCancelled) (T.pack "") Nothing) state env + -- Otherwise we run the request + else runLSM (f msg k) state env + liftIO $ atomically $ do -- After it finishes we remove it from the pending requests set and canceled set + modifyTVar (pendingRequests stVal) $ \t -> S.delete newId t + modifyTVar (cancelledRequests stVal) $ \t -> S.delete newId t + case cancelOrRes of -- Finally we return the result of the request + Left () -> return () + Right res -> pure res + + -- For notifications from the client (which are just fire and forget for the client) + goNot :: forall (a :: Method ClientToServer Notification). Handler LSM a -> Handler LSM a + goNot f msg = do + env <- getLspEnv + state <- lift ask + stVal <- liftIO $ readMVar state + let mtd = msg ^. method + case mtd of + SMethod_TextDocumentDidChange -> do + -- If text document change command, and a new change comes in with a newer version for the same file, cancel the old one + let TNotificationMessage{_params=DidChangeTextDocumentParams{_textDocument=VersionedTextDocumentIdentifier{_uri, _version}}} = msg + stateV <- liftIO $ readMVar state + liftIO $ atomically $ modifyTVar (documentVersions stateV) $ \t -> M.insert _uri _version t + liftIO $ atomically $ writeTChan rin $ + ReactorAction $ do + -- When running the request we check if the version is the same as the latest version, if not we don't run the change handler + versions <- readTVarIO (documentVersions stVal) + when (M.lookup _uri versions == Just _version) $ runLSM (f msg) state env + _ -> + liftIO $ atomically $ writeTChan rin $ + ReactorAction (runLSM (f msg) state env) diff --git a/src/Main/langserver/LanguageServer/Monad.hs b/src/Main/langserver/LanguageServer/Monad.hs new file mode 100644 index 000000000..129ce8943 --- /dev/null +++ b/src/Main/langserver/LanguageServer/Monad.hs @@ -0,0 +1,259 @@ +----------------------------------------------------------------------------- +-- The language server's monad that holds state (e.g. loaded/compiled modules) +----------------------------------------------------------------------------- +{-# LANGUAGE RankNTypes #-} +{-# LANGUAGE KindSignatures #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE OverloadedStrings #-} + +module LanguageServer.Monad + ( LSState (..), + defaultLSState, + newLSStateVar, + LSM, + getTerminal,getFlags,getColorScheme,getHtmlPrinter, + getLSState,modifyLSState, + getLoaded,putLoaded,removeLoaded,removeLoadedUri,getLoadedModule, + getModules, + updateConfig, + getDiagnostics,putDiagnostics,clearDiagnostics, + runLSM, + ) +where + +import Control.Concurrent.MVar (MVar, modifyMVar, newMVar, putMVar, readMVar, newEmptyMVar) +import Control.Monad.Reader (ReaderT, ask, runReaderT) +import Control.Monad.Trans (lift, liftIO) +import qualified Data.Map.Strict as M +import qualified Data.Text as T +import Language.LSP.Server (LanguageContextEnv, LspT, runLspT, sendNotification, Handlers) +import qualified Language.LSP.Protocol.Types as J +import qualified Language.LSP.Protocol.Message as J + +import Compiler.Compile (Terminal (..), Loaded (..), Module (..)) +import Lib.PPrint (Pretty(..), asString, writePrettyLn, Doc) +import Control.Concurrent.Chan (readChan) +import Type.Pretty (ppType, defaultEnv, Env (context, importsMap), ppScheme) +import qualified Language.LSP.Server as J +import GHC.Base (Type, Alternative (..)) +import Lib.Printer (withColorPrinter, withColor, writeLn, ansiDefault, AnsiStringPrinter (AnsiString), Color (Red), ColorPrinter (PAnsiString, PHtmlText), withHtmlTextPrinter, HtmlTextPrinter (..)) +import Compiler.Options (Flags (..), prettyEnvFromFlags, verbose) +import Common.Error (ppErrorMessage) +import Common.ColorScheme (colorSource, ColorScheme) +import Common.Name (nameNil) +import Kind.ImportMap (importsEmpty) +import Platform.Var (newVar, takeVar) +import Debug.Trace (trace) + +import Control.Monad.STM +import Control.Concurrent.STM.TChan +import Control.Concurrent +import GHC.Conc (atomically) +import Control.Concurrent.STM (newTVarIO, TVar) +import qualified Data.Set as Set +import Control.Concurrent.STM.TMVar (TMVar) +import qualified Data.ByteString as D +import Platform.Filetime (FileTime) +import Common.File (realPath,normalize) +import Compiler.Module (Modules) +import Data.Maybe (fromMaybe, isJust) +import Data.List (find) +import qualified Data.Aeson as A +import Data.Aeson.Types +import Common.ColorScheme (darkColorScheme, lightColorScheme) + +-- The language server's state, e.g. holding loaded/compiled modules. +data LSState = LSState { + lsModules :: ![Module], + lsLoaded :: !(M.Map FilePath Loaded), + messages :: !(TChan (String, J.MessageType)), + flags:: !Flags, + terminal:: !Terminal, + htmlPrinter :: Doc -> IO T.Text, + pendingRequests :: !(TVar (Set.Set J.SomeLspId)), + cancelledRequests :: !(TVar (Set.Set J.SomeLspId)), + documentVersions :: !(TVar (M.Map J.Uri J.Int32)), + documentInfos :: !(M.Map FilePath (D.ByteString, FileTime, J.Int32)), + diagnostics :: !(M.Map J.NormalizedUri [J.Diagnostic]), + config :: Config +} + +-- The monad holding (thread-safe) state used by the language server. +type LSM = LspT () (ReaderT (MVar LSState) IO) + +-- Runs the language server's state monad. +runLSM :: LSM a -> MVar LSState -> LanguageContextEnv () -> IO a +runLSM lsm stVar cfg = runReaderT (runLspT cfg lsm) stVar + +newLSStateVar :: Flags -> IO (MVar LSState) +newLSStateVar flags = defaultLSState flags >>= newMVar + +-- Fetches the language server's state inside the LSM monad +getLSState :: LSM LSState +getLSState = do + stVar <- lift ask + liftIO $ readMVar stVar + +-- Updates the language server's state inside the LSM monad +modifyLSState :: (LSState -> LSState) -> LSM () +modifyLSState m = do + stVar <- lift ask + liftIO $ modifyMVar stVar $ \s -> return (m s, ()) + +defaultLSState :: Flags -> IO LSState +defaultLSState flags = do + msgChan <- atomically newTChan :: IO (TChan (String, J.MessageType)) + pendingRequests <- newTVarIO Set.empty + cancelledRequests <- newTVarIO Set.empty + fileVersions <- newTVarIO M.empty + -- Trim trailing whitespace and newlines from the end of a string + let trimnl :: [Char] -> [Char] + trimnl str = reverse $ dropWhile (`T.elem` "\n\r\t ") $ reverse str + let withNewPrinter f = do + ansiConsole <- newVar ansiDefault + stringVar <- newVar "" + let p = AnsiString ansiConsole stringVar + tp <- (f . PAnsiString) p + ansiString <- takeVar stringVar + atomically $ writeTChan msgChan (trimnl ansiString, tp) + let cscheme = colorScheme flags + prettyEnv flags ctx imports = (prettyEnvFromFlags flags){ context = ctx, importsMap = imports } + term = Terminal (\err -> withNewPrinter $ \p -> do putErrorMessage p (showSpan flags) cscheme err; return J.MessageType_Error) + (if verbose flags > 1 then (\msg -> withNewPrinter $ \p -> do withColor p (colorSource cscheme) (writeLn p msg); return J.MessageType_Info) + else (\_ -> return ())) + (if verbose flags > 0 then (\msg -> withNewPrinter $ \p -> do writePrettyLn p msg; return J.MessageType_Info) else (\_ -> return ())) + (\tp -> withNewPrinter $ \p -> do putScheme p (prettyEnv flags nameNil importsEmpty) tp; return J.MessageType_Info) + (\msg -> withNewPrinter $ \p -> do writePrettyLn p msg; return J.MessageType_Info) + return LSState { + lsLoaded = M.empty, lsModules=[], + messages = msgChan, pendingRequests=pendingRequests, cancelledRequests=cancelledRequests, config=Config{colors=Colors{mode="dark"}}, + terminal = term, htmlPrinter = htmlTextColorPrinter, flags = flags, + documentInfos = M.empty, documentVersions = fileVersions, diagnostics = M.empty} + +htmlTextColorPrinter :: Doc -> IO T.Text +htmlTextColorPrinter doc + = do + stringVar <- newVar (T.pack "") + let printer = PHtmlText (HtmlTextPrinter stringVar) + writePrettyLn printer doc + takeVar stringVar + +putScheme p env tp + = writePrettyLn p (ppScheme env tp) + +putErrorMessage p endToo cscheme err + = writePrettyLn p (ppErrorMessage endToo cscheme err) + +data Config = Config { + colors :: Colors +} +data Colors = Colors { + mode :: String +} + +instance FromJSON Colors where + parseJSON (A.Object v) = Colors <$> v .: "mode" + parseJSON _ = empty + +instance FromJSON Config where + parseJSON (A.Object v) = Config <$> v .: "colors" + parseJSON _ = empty + +updateConfig :: A.Value -> LSM () +updateConfig cfg = + case fromJSON cfg of + A.Success cfg -> do + modifyLSState $ \s -> + let s' = s{config=cfg} in + if mode (colors cfg) == "dark" then + trace "setting color scheme to dark" $ + s'{flags=(flags s'){colorScheme=darkColorScheme}} + else + trace "setting color scheme to light" $ + s'{flags=(flags s'){colorScheme=lightColorScheme}} + + +-- Fetches the terminal used for printing messages +getTerminal :: LSM Terminal +getTerminal = terminal <$> getLSState + +-- Fetches the loaded state holding compiled modules +getFlags :: LSM Flags +getFlags = flags <$> getLSState + +-- Fetches the html printer used for printing markdown compatible text +getHtmlPrinter :: LSM (Doc -> IO T.Text) +getHtmlPrinter = htmlPrinter <$> getLSState + +-- Fetches the color scheme used for coloring markdown compatible text +getColorScheme :: LSM ColorScheme +getColorScheme = colorScheme <$> getFlags + + +-- Diagnostics +getDiagnostics :: LSM (M.Map J.NormalizedUri [J.Diagnostic]) +getDiagnostics = diagnostics <$> getLSState + +-- Clear diagnostics for a file +clearDiagnostics :: J.NormalizedUri -> LSM () +clearDiagnostics uri = modifyLSState $ \s -> s {diagnostics = M.delete uri (diagnostics s)} + +putDiagnostics :: M.Map J.NormalizedUri [J.Diagnostic] -> LSM () +putDiagnostics diags = -- Left biased union prefers more recent diagnostics + modifyLSState $ \s -> s {diagnostics = M.union diags (diagnostics s)} + + +-- Fetches all the most recent succesfully compiled modules (for incremental compilation) +getModules :: LSM Modules +getModules = lsModules <$> getLSState + +mergeModules :: Modules -> Modules -> Modules +mergeModules newModules oldModules = + let nModValid = filter (\m -> isJust (modCompiled m)) newModules -- only add modules that sucessfully compiled + newModNames = map modName nModValid + in nModValid ++ filter (\m -> modName m `notElem` newModNames) oldModules + +-- Replaces the loaded state holding compiled modules +putLoaded :: Loaded -> LSM () +putLoaded l = modifyLSState $ \s -> s {lsModules = mergeModules (loadedModule l:loadedModules l) (lsModules s), lsLoaded = M.insert (modSourcePath $ loadedModule l) l (lsLoaded s)} + +removeLoaded :: Module -> LSM () +removeLoaded m = modifyLSState $ \s -> s {lsModules = filter (\m1 -> modName m1 /= modName m) (lsModules s), lsLoaded = M.delete (modSourcePath m) (lsLoaded s)} + +getLoadedModule :: J.Uri -> LSM (Maybe Module) +getLoadedModule uri = do + lmaybe <- getLoaded uri + liftIO $ loadedModuleFromUri lmaybe uri + +loadedModuleFromUri :: Maybe Loaded -> J.Uri -> IO (Maybe Module) +loadedModuleFromUri l uri = + case l of + Nothing -> return Nothing + Just l -> + case J.uriToFilePath uri of + Nothing -> return Nothing + Just uri -> do + path <- realPath uri + let p = normalize path + return $ find (\m -> p == modSourcePath m) $ loadedModules l + +-- Removes a loaded module from the loaded state holding compiled modules +removeLoadedUri :: J.Uri -> LSM () +removeLoadedUri uri = do + case J.uriToFilePath uri of + Nothing -> return () + Just path -> do + path0 <- liftIO $ realPath path + let path = normalize path0 + modifyLSState (\st -> st {lsLoaded = M.delete path (lsLoaded st)}) + +-- Fetches the loaded state holding compiled modules +getLoaded :: J.Uri -> LSM (Maybe Loaded) +getLoaded uri = do + st <- getLSState + case J.uriToFilePath uri of + Nothing -> return Nothing + Just uri -> do + path <- liftIO $ realPath uri + let p = normalize path + return $ M.lookup p (lsLoaded st) \ No newline at end of file diff --git a/src/Main/langserver/LanguageServer/Run.hs b/src/Main/langserver/LanguageServer/Run.hs new file mode 100644 index 000000000..9bac99b7f --- /dev/null +++ b/src/Main/langserver/LanguageServer/Run.hs @@ -0,0 +1,116 @@ +----------------------------------------------------------------------------- +-- The language server's main module +----------------------------------------------------------------------------- +{-# LANGUAGE RankNTypes #-} +{-# LANGUAGE KindSignatures #-} +{-# LANGUAGE DataKinds #-} +module LanguageServer.Run (runLanguageServer) where + +import System.Exit ( exitFailure ) +import Compiler.Options (Flags (languageServerPort)) +import Control.Monad (void, forever) +import Control.Monad.IO.Class (liftIO) +import Control.Monad.STM +import Control.Concurrent.STM.TChan +import Control.Concurrent +import Language.LSP.Server +import qualified Language.LSP.Protocol.Types as J +import qualified Language.LSP.Protocol.Message as J +import qualified Language.LSP.Server as J +import LanguageServer.Handlers +import LanguageServer.Monad (newLSStateVar, runLSM, LSM, getLSState, LSState (messages)) +import Colog.Core (LogAction, WithSeverity) +import qualified Colog.Core as L +import qualified Data.Text as T +import qualified Data.Text.Encoding as T +import Language.LSP.Logging (defaultClientLogger) +import Network.Simple.TCP +import Network.Socket hiding (connect) +import GHC.IO.IOMode (IOMode(ReadWriteMode)) +import GHC.Conc (atomically) +import LanguageServer.Handler.TextDocument (persistModules) +import GHC.IO.Handle (BufferMode(LineBuffering), hSetBuffering) +import GHC.IO.StdHandles (stdout, stderr) + +runLanguageServer :: Flags -> [FilePath] -> IO () +runLanguageServer flags files = do + if languageServerPort flags == -1 then do + putStr "No port specified for language server\n. Use --lsport= to specify a port." + exitFailure + else return () + -- Have to set line buffering, otherwise the client doesn't receive data until buffers fill up + hSetBuffering stdout LineBuffering + hSetBuffering stderr LineBuffering + -- Connect to localhost on the port given by the client + connect "127.0.0.1" (show $ languageServerPort flags) (\(socket, _) -> do + -- Create a handle to the client from the socket + handle <- socketToHandle socket ReadWriteMode + -- Create a new language server state + state <- newLSStateVar flags + -- Get the message channel + messageChan <- liftIO $ messages <$> readMVar state + -- Create a new channel for the reactor to receive messages on + rin <- atomically newTChan :: IO (TChan ReactorInput) + void $ + runServerWithHandles + ioLogger + lspLogger + handle + handle + $ + ServerDefinition + { parseConfig = const $ const $ Right (), + onConfigChange = const $ pure (), + defaultConfig = (), + configSection = T.pack "koka", + -- Two threads, the request thread and the message thread (so we can send messages to the client, while the compilation is happening) + doInitialize = \env _ -> forkIO (reactor rin) >> forkIO (messageHandler messageChan env state) >> pure (Right env), + staticHandlers = \_caps -> lspHandlers rin, + interpretHandler = \env -> Iso (\lsm -> runLSM lsm state env) liftIO, + options = + defaultOptions + { optTextDocumentSync = Just syncOptions, + optExecuteCommandCommands = Just [T.pack "koka/genCode", T.pack "koka/interpretExpression"] + -- optCompletionTriggerCharacters = Just ['.', ':', '/'] + -- TODO: ? https://www.stackage.org/haddock/lts-18.21/lsp-1.2.0.0/src/Language.LSP.Server.Core.html#Options + } + }) + where + prettyMsg l = "[" <> show (L.getSeverity l) <> "] " <> show (L.getMsg l) <> "\n\n" + -- io logger, prints all log level messages to stdout + ioLogger :: LogAction IO (WithSeverity LspServerLog) + ioLogger = L.cmap prettyMsg L.logStringStdout + stderrLogger :: LogAction IO (WithSeverity T.Text) + stderrLogger = L.cmap show L.logStringStderr + -- lsp logger, prints all messages to stdout and to the client + lspLogger :: LogAction (LspM config) (WithSeverity LspServerLog) + lspLogger = + let clientLogger = L.cmap (fmap (T.pack . show)) defaultClientLogger + in clientLogger <> L.hoistLogAction liftIO ioLogger + syncOptions = + J.TextDocumentSyncOptions + (Just True) -- open/close notifications + (Just J.TextDocumentSyncKind_Incremental) -- changes + (Just False) -- will save + (Just False) -- will save (wait until requests are sent to server) + (Just $ J.InR $ J.SaveOptions $ Just False) -- trigger on save, but dont send document + +-- Handles messages to send to the client, just spins and sends +messageHandler :: TChan (String, J.MessageType) -> LanguageContextEnv () -> MVar LSState -> IO () +messageHandler msgs env state = do + forever $ do + (msg, msgType) <- atomically $ readTChan msgs + runLSM (sendNotification J.SMethod_WindowLogMessage $ J.LogMessageParams msgType $ T.pack msg) state env + +-- Runs in a loop, getting the next queued request and executing it +reactor :: TChan ReactorInput -> IO () +reactor inp = do + forever $ do + ReactorAction act <- atomically $ readTChan inp + act + +-- TODO: Finish persisting modules in a separate thread +doPersist state env = + forever $ do + threadDelay 1000000 + runLSM persistModules state env diff --git a/src/Main.hs b/src/Main/langserver/Main.hs similarity index 79% rename from src/Main.hs rename to src/Main/langserver/Main.hs index 80914e08e..833855f58 100644 --- a/src/Main.hs +++ b/src/Main/langserver/Main.hs @@ -12,7 +12,7 @@ module Main where import System.Exit ( exitFailure ) -import Control.Monad ( when ) +import Control.Monad ( when, foldM ) import Platform.Config import Lib.PPrint ( Pretty(pretty), writePrettyLn ) @@ -29,9 +29,11 @@ import Interpreter.Interpret ( interpret ) import Kind.ImportMap ( importsEmpty ) import Kind.Synonym ( synonymsIsEmpty, ppSynonyms, synonymsFilter ) import Kind.Assumption ( kgammaFilter ) +import LanguageServer.Run ( runLanguageServer ) import Type.Assumption ( ppGamma, ppGammaHidden, gammaFilter, createNameInfoX, gammaNew ) import Type.Pretty ( ppScheme, Env(context,importsMap) ) - +import System.IO (hPutStrLn, stderr) +import Data.List (intercalate) -- compiled entry main = mainArgs "" @@ -53,7 +55,7 @@ mainArgs args = do (flags,flags0,mode) <- getOptions args let with = if (not (null (redirectOutput flags))) then withFileNoColorPrinter (redirectOutput flags) - else if (console flags == "html") + else if (console flags == "html") then withHtmlColorPrinter else if (console flags == "ansi") then withColorPrinter @@ -73,26 +75,38 @@ mainMode flags flags0 mode p ModeHelp -> showHelp flags p ModeVersion - -> withNoColorPrinter (\monop -> showVersion flags monop) + -> withNoColorPrinter (showVersion flags) ModeCompiler files - -> mapM_ (compile p flags) files + -> do + errFiles <- foldM (\errfiles file -> + do + res <- compile p flags file + if res then return errfiles + else return (file:errfiles) + ) [] files + if null errFiles then return () + else do + hPutStrLn stderr ("Failed to compile " ++ intercalate "," files) + exitFailure ModeInteractive files -> interpret p flags flags0 files + ModeLanguageServer files + -> runLanguageServer flags files -compile :: ColorPrinter -> Flags -> FilePath -> IO () +compile :: ColorPrinter -> Flags -> FilePath -> IO Bool compile p flags fname = do let exec = Executable (newName "main") () - err <- compileFile term flags [] - (if (not (evaluate flags)) then (if library flags then Library else exec) else exec) fname + err <- compileFile (const Nothing) Nothing term flags [] [] + (if (not (evaluate flags)) then (if library flags then Library else exec) else exec) [] fname case checkError err of Left msg -> do putPrettyLn p (ppErrorMessage (showSpan flags) cscheme msg) -- exitFailure -- don't fail for tests - - Right (Loaded gamma kgamma synonyms newtypes constructors _ imports _ - (Module modName _ _ _ _ _warnings rawProgram core _ _ modTime) _ _ _ - , warnings) + return False + Right ((Loaded gamma kgamma synonyms newtypes constructors _ imports _ + (Module modName _ _ _ _ _ rawProgram core _ _ _ _ modTime _ _) _ _ _ + , _), warnings) -> do when (not (null warnings)) (let msg = ErrorWarning warnings ErrorZero in putPrettyLn p (ppErrorMessage (showSpan flags) cscheme msg)) @@ -105,9 +119,11 @@ compile p flags fname if showHiddenTypeSigs flags then do -- workaround since private defs aren't in gamma putPrettyLn p $ ppGammaHidden (prettyEnv flags modName imports) $ gammaFilter modName $ gammaFromDefGroups $ coreProgDefs core - else if showTypeSigs flags then + return True + else if showTypeSigs flags then do putPrettyLn p $ ppGamma (prettyEnv flags modName imports) $ gammaFilter modName gamma - else pure () + return True + else return True where term = Terminal (putErrorMessage p (showSpan flags) cscheme) diff --git a/src/Main/plain/Main.hs b/src/Main/plain/Main.hs new file mode 100644 index 000000000..4f0f4488b --- /dev/null +++ b/src/Main/plain/Main.hs @@ -0,0 +1,158 @@ +------------------------------------------------------------------------------ +-- Copyright 2012-2021, Microsoft Research, Daan Leijen. +-- +-- This is free software; you can redistribute it and/or modify it under the +-- terms of the Apache License, Version 2.0. A copy of the License can be +-- found in the LICENSE file at the root of this distribution. +----------------------------------------------------------------------------- +{- + Main module. +-} +----------------------------------------------------------------------------- +module Main where + +import System.Exit ( exitFailure ) +import Control.Monad ( when, foldM ) + +import Platform.Config +import Lib.PPrint ( Pretty(pretty), writePrettyLn ) +import Lib.Printer +import Common.ColorScheme +import Common.Failure ( catchIO ) +import Common.Error +import Common.Name +import Common.File ( joinPath ) +import Compiler.Options +import Compiler.Compile ( compileFile, CompileTarget(..), Module(..), Loaded(..), Terminal(..) ) +import Core.Core ( coreProgDefs, flattenDefGroups, defType, Def(..) ) +import Interpreter.Interpret ( interpret ) +import Kind.ImportMap ( importsEmpty ) +import Kind.Synonym ( synonymsIsEmpty, ppSynonyms, synonymsFilter ) +import Kind.Assumption ( kgammaFilter ) +import Type.Assumption ( ppGamma, ppGammaHidden, gammaFilter, createNameInfoX, gammaNew ) +import Type.Pretty ( ppScheme, Env(context,importsMap) ) +import System.IO (hPutStrLn, stderr) +import Data.List (intercalate) + +-- compiled entry +main = mainArgs "" + +-- ghci entry +maing = maingg "" +maindoc = maingg "--html" +mainjs = maingg "--target=js" +maincs = maingg "--target=cs" + +maingg extraOptions + = mainArgs ("-ilib -itest --verbose " ++ extraOptions) + +-- hugs entry +mainh = mainArgs "-ilib -itest --console=raw" + + +mainArgs args + = do (flags,flags0,mode) <- getOptions args + let with = if (not (null (redirectOutput flags))) + then withFileNoColorPrinter (redirectOutput flags) + else if (console flags == "html") + then withHtmlColorPrinter + else if (console flags == "ansi") + then withColorPrinter + else withNoColorPrinter + with (mainMode flags flags0 mode) + `catchIO` \err -> + do if ("ExitFailure" `isPrefix` err) + then return () + else putStr err + exitFailure + where + isPrefix s t = (s == take (length s) t) + +mainMode :: Flags -> Flags -> Mode -> ColorPrinter -> IO () +mainMode flags flags0 mode p + = case mode of + ModeHelp + -> showHelp flags p + ModeVersion + -> withNoColorPrinter (showVersion flags) + ModeCompiler files + -> do + errFiles <- foldM (\errfiles file -> + do + res <- compile p flags file + if res then return errfiles + else return (file:errfiles) + ) [] files + if null errFiles then return () + else do + hPutStrLn stderr ("Failed to compile " ++ intercalate "," files) + exitFailure + ModeInteractive files + -> interpret p flags flags0 files + ModeLanguageServer files + -> do + putStr "Language server mode not supported in this build.\n" + exitFailure + + +compile :: ColorPrinter -> Flags -> FilePath -> IO Bool +compile p flags fname + = do let exec = Executable (newName "main") () + err <- compileFile (const Nothing) Nothing term flags [] [] + (if (not (evaluate flags)) then (if library flags then Library else exec) else exec) [] fname + case checkError err of + Left msg + -> do putPrettyLn p (ppErrorMessage (showSpan flags) cscheme msg) + -- exitFailure -- don't fail for tests + return False + Right ((Loaded gamma kgamma synonyms newtypes constructors _ imports _ + (Module modName _ _ _ _ _ rawProgram core _ _ _ _ modTime _ _) _ _ _ + , _), warnings) + -> do when (not (null warnings)) + (let msg = ErrorWarning warnings ErrorZero + in putPrettyLn p (ppErrorMessage (showSpan flags) cscheme msg)) + when (showKindSigs flags) $ do + putPrettyLn p (pretty (kgammaFilter modName kgamma)) + let localSyns = synonymsFilter modName synonyms + when (not (synonymsIsEmpty localSyns)) + (putPrettyLn p (ppSynonyms (prettyEnv flags modName imports) localSyns)) + + if showHiddenTypeSigs flags then do + -- workaround since private defs aren't in gamma + putPrettyLn p $ ppGammaHidden (prettyEnv flags modName imports) $ gammaFilter modName $ gammaFromDefGroups $ coreProgDefs core + return True + else if showTypeSigs flags then do + putPrettyLn p $ ppGamma (prettyEnv flags modName imports) $ gammaFilter modName gamma + return True + else return True + where + term + = Terminal (putErrorMessage p (showSpan flags) cscheme) + (if (verbose flags > 1) then (\msg -> withColor p (colorSource cscheme) (writeLn p msg)) + else (\_ -> return ())) + (if (verbose flags > 0) then writePrettyLn p else (\_ -> return ())) + (putScheme p (prettyEnv flags nameNil importsEmpty)) + (writePrettyLn p) + + cscheme + = colorSchemeFromFlags flags + + prettyEnv flags ctx imports + = (prettyEnvFromFlags flags){ context = ctx, importsMap = imports } + +gammaFromDefGroups groups = gammaNew $ map defToGammaEntry $ flattenDefGroups groups + where + defToGammaEntry def = (defName def, createNameInfoX (defVis def) (defName def) (defSort def) (defNameRange def) (defType def)) + +putScheme p env tp + = putPrettyLn p (ppScheme env tp) + +putErrorMessage p endToo cscheme err + = putPrettyLn p (ppErrorMessage endToo cscheme err) + +putPhase p cscheme msg + = withColor p (colorInterpreter cscheme) (writeLn p msg) + +putPrettyLn p doc + = do writePrettyLn p doc + writeLn p "" diff --git a/src/Static/FixityResolve.hs b/src/Static/FixityResolve.hs index 04ca9c65f..bf8d4c302 100644 --- a/src/Static/FixityResolve.hs +++ b/src/Static/FixityResolve.hs @@ -31,7 +31,7 @@ import Common.Range import Common.Syntax import Syntax.Syntax -fixityResolve :: ColorScheme -> Fixities -> UserProgram -> Error (UserProgram,Fixities) +fixityResolve :: ColorScheme -> Fixities -> UserProgram -> Error b (UserProgram,Fixities) fixityResolve cscheme fixMap (Program source modName nameRange tdgroups defs importdefs externals fixdefs doc) = let fixMap1 = fixitiesCompose fixMap (extractFixMap fixdefs) in do defs1 <- runFixM fixMap1 (resolveDefs defs) @@ -164,7 +164,7 @@ fixitiesNew fs data FixM a = FixM (Fixities -> Res a) data Res a = Res !a ![(Range,Doc)] -runFixM :: Fixities -> FixM a -> Error a +runFixM :: Fixities -> FixM a -> Error b a runFixM fixities (FixM f) = case f fixities of Res x errors -> if null errors then return x else errorMsg (ErrorStatic errors) diff --git a/src/Syntax/Colorize.hs b/src/Syntax/Colorize.hs index 39f3cff62..75ab84139 100644 --- a/src/Syntax/Colorize.hs +++ b/src/Syntax/Colorize.hs @@ -152,7 +152,7 @@ transform isLiterate rng rangeMap env lexeme content in (ranges, case info of - NIValue tp -> signature env toLit isLiterate "type" qname (mangle qname tp) (showType env tp) $ + NIValue tp _ -> signature env toLit isLiterate "type" qname (mangle qname tp) (showType env tp) $ (case lexeme of (Lexeme _ (LexKeyword _ _)) -> cspan "keyword" pcontent -- for 'return' _ -> pcontent) NICon tp -> signature env toLit isLiterate "type" qname (mangleConName qname) (showType env tp) $ cspan "constructor" pcontent diff --git a/src/Syntax/Lexer.hs b/src/Syntax/Lexer.hs index 947014f72..9c01b16c5 100644 --- a/src/Syntax/Lexer.hs +++ b/src/Syntax/Lexer.hs @@ -7,6 +7,7 @@ module Syntax.Lexer( lexing, lexer , module Syntax.Lexeme , readInput, extractLiterate + , reservedNames ) where import Lib.Trace @@ -30,11 +31,11 @@ import Data.Word( Word8 ) #endif #if __GLASGOW_HASKELL__ >= 503 import Data.Array -import Data.Array.Base (unsafeAt) #else import Array #endif #if __GLASGOW_HASKELL__ >= 503 +import Data.Array.Base (unsafeAt) import GHC.Exts #else import GlaExts @@ -43,21 +44,21 @@ alex_tab_size :: Int alex_tab_size = 8 alex_base :: AlexAddr alex_base = AlexA# - "\xf8\xff\xff\xff\x6e\x00\x00\x00\x5a\x01\x00\x00\x46\x02\x00\x00\x31\x03\x00\x00\x1d\x04\x00\x00\xea\x04\x00\x00\x44\x05\x00\x00\xda\xff\xff\xff\x67\x05\x00\x00\xdb\xff\xff\xff\xdf\xff\xff\xff\xe0\xff\xff\xff\xe1\xff\xff\xff\x56\x05\x00\x00\xe2\xff\xff\xff\x5d\x00\x00\x00\xd4\x01\x00\x00\x68\x05\x00\x00\x2a\x02\x00\x00\xa8\x05\x00\x00\x21\x06\x00\x00\x61\x06\x00\x00\xf6\x00\x00\x00\x00\x07\x00\x00\xa9\x01\x00\x00\x80\x03\x00\x00\x6c\x04\x00\x00\xe4\x04\x00\x00\x19\x06\x00\x00\x30\x06\x00\x00\x10\x07\x00\x00\xef\x06\x00\x00\x9e\x00\x00\x00\x2f\x07\x00\x00\x5f\x07\x00\x00\x6a\x02\x00\x00\x9f\x07\x00\x00\xcf\x07\x00\x00\xbf\x02\x00\x00\x0f\x08\x00\x00\x3f\x08\x00\x00\x47\x03\x00\x00\x7f\x08\x00\x00\x0f\x09\x00\x00\xe6\x08\x00\x00\xab\x03\x00\x00\x26\x09\x00\x00\x66\x09\x00\x00\xf6\x09\x00\x00\x0d\x0a\x00\x00\xd4\x09\x00\x00\x14\x0a\x00\x00\x34\x0a\x00\x00\x54\x0a\x00\x00\x94\x0a\x00\x00\xb4\x0a\x00\x00\xd4\x0a\x00\x00\x14\x0b\x00\x00\x34\x0b\x00\x00\x54\x0b\x00\x00\x94\x0b\x00\x00\xb4\x0b\x00\x00\x44\x0c\x00\x00\x0b\x0c\x00\x00\x4b\x0c\x00\x00\x6b\x0c\x00\x00\xab\x0c\x00\x00\x3b\x0d\x00\x00\x52\x0d\x00\x00\x43\x0d\x00\x00\x8a\xff\xff\xff\x83\x0d\x00\x00\x8b\xff\xff\xff\xc3\x0d\x00\x00\x8c\xff\xff\xff\x03\x00\x00\x00\x03\x0e\x00\x00\x8e\xff\xff\xff\x05\x00\x00\x00\x93\x0e\x00\x00\x7a\x0e\x00\x00\x90\xff\xff\xff\x0a\x0f\x00\x00\x3b\x01\x00\x00\xc0\x01\x00\x00\xcf\x01\x00\x00\xe0\x01\x00\x00\xca\x02\x00\x00\xf1\xff\xff\xff\x00\x00\x00\x00\x37\x0f\x00\x00\x5a\x0f\x00\x00\x7d\x0f\x00\x00\x9b\x0f\x00\x00\xeb\xff\xff\xff\xef\x0f\x00\x00\x52\x00\x00\x00\x00\x00\x00\x00\x43\x10\x00\x00\x53\x00\x00\x00\x97\x10\x00\x00\xec\xff\xff\xff\xe5\x10\x00\x00\x3f\x11\x00\x00\x00\x00\x00\x00\x4f\x11\x00\x00\xa7\x03\x00\x00\xb7\x03\x00\x00\x74\x11\x00\x00\x97\x11\x00\x00\xb5\x11\x00\x00\xda\x11\x00\x00\xfd\x11\x00\x00\x00\x00\x00\x00\x20\x12\x00\x00\x43\x12\x00\x00\x66\x12\x00\x00\xa2\x12\x00\x00\x54\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xed\xff\xff\xff\x00\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x01\x13\x00\x00\xf4\xff\xff\xff\x0d\x00\x00\x00\xd6\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0\x12\x00\x00\x33\x04\x00\x00\xd5\x13\x00\x00\x2b\x14\x00\x00\x6b\x14\x00\x00\x8b\x14\x00\x00\x4e\x00\x00\x00\x62\x05\x00\x00\xcb\x14\x00\x00\xfc\xff\xff\xff\x82\x15\x00\x00\x00\x00\x00\x00\x5b\x00\x00\x00\x00\x00\x00\x00\x71\x15\x00\x00\xdf\x06\x00\x00\xf7\x15\x00\x00\x17\x16\x00\x00\x57\x16\x00\x00\x77\x16\x00\x00\xb7\x16\x00\x00\xff\xff\xff\xff\x76\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x6e\x17\x00\x00\x56\x00\x00\x00\x5c\x00\x00\x00\x00\x00\x00\x00\x5d\x17\x00\x00\xd6\x08\x00\x00\xe3\x17\x00\x00\x03\x18\x00\x00\x43\x18\x00\x00\x63\x18\x00\x00\xa3\x18\x00\x00\x07\x00\x00\x00\x7e\x00\x00\x00\x5a\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x49\x19\x00\x00\xdd\x09\x00\x00\xcf\x19\x00\x00\xef\x19\x00\x00\x2f\x1a\x00\x00\x4f\x1a\x00\x00\x7f\x00\x00\x00\x8f\x1a\x00\x00\x0a\x00\x00\x00\x46\x1b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x35\x1b\x00\x00\x0c\x0c\x00\x00\xbb\x1b\x00\x00\xdb\x1b\x00\x00\x1b\x1c\x00\x00\x3b\x1c\x00\x00\x81\x00\x00\x00\x7b\x1c\x00\x00\xaf\x00\x00\x00"# + "\xf8\xff\xff\xff\x6e\x00\x00\x00\x5a\x01\x00\x00\x46\x02\x00\x00\x31\x03\x00\x00\x1d\x04\x00\x00\xea\x04\x00\x00\x44\x05\x00\x00\xda\xff\xff\xff\x67\x05\x00\x00\xdb\xff\xff\xff\xdf\xff\xff\xff\xe0\xff\xff\xff\xe1\xff\xff\xff\x56\x05\x00\x00\xe2\xff\xff\xff\x5d\x00\x00\x00\xd4\x01\x00\x00\x68\x05\x00\x00\x2a\x02\x00\x00\xa8\x05\x00\x00\x21\x06\x00\x00\x61\x06\x00\x00\x00\x07\x00\x00\xa9\x01\x00\x00\x80\x03\x00\x00\x6c\x04\x00\x00\xe4\x04\x00\x00\x19\x06\x00\x00\x30\x06\x00\x00\x10\x07\x00\x00\xef\x06\x00\x00\x9d\x00\x00\x00\x2f\x07\x00\x00\x5f\x07\x00\x00\xe8\x00\x00\x00\x9f\x07\x00\x00\xcf\x07\x00\x00\x6a\x02\x00\x00\x0f\x08\x00\x00\x3f\x08\x00\x00\xbf\x02\x00\x00\x7f\x08\x00\x00\x0f\x09\x00\x00\xe6\x08\x00\x00\x47\x03\x00\x00\x26\x09\x00\x00\x66\x09\x00\x00\xf6\x09\x00\x00\xbd\x09\x00\x00\xfd\x09\x00\x00\x1d\x0a\x00\x00\x3d\x0a\x00\x00\x7d\x0a\x00\x00\x9d\x0a\x00\x00\xbd\x0a\x00\x00\xfd\x0a\x00\x00\x1d\x0b\x00\x00\x3d\x0b\x00\x00\x7d\x0b\x00\x00\x9d\x0b\x00\x00\x2d\x0c\x00\x00\xf4\x0b\x00\x00\x34\x0c\x00\x00\x54\x0c\x00\x00\x94\x0c\x00\x00\x24\x0d\x00\x00\x0b\x0d\x00\x00\x4b\x0d\x00\x00\x8b\x0d\x00\x00\x01\x00\x00\x00\xcb\x0d\x00\x00\x02\x00\x00\x00\x5b\x0e\x00\x00\x42\x0e\x00\x00\xeb\xff\xff\xff\xd2\x0e\x00\x00\xc0\x01\x00\x00\xe9\x0e\x00\x00\xcf\x01\x00\x00\xe0\x01\x00\x00\xfe\x03\x00\x00\xca\x02\x00\x00\xa7\x03\x00\x00\xea\xff\xff\xff\xec\xff\xff\xff\x18\x0f\x00\x00\x3b\x0f\x00\x00\x5e\x0f\x00\x00\x7c\x0f\x00\x00\xe9\xff\xff\xff\xd0\x0f\x00\x00\x52\x00\x00\x00\x00\x00\x00\x00\x24\x10\x00\x00\x7d\x10\x00\x00\x53\x00\x00\x00\xd1\x10\x00\x00\xed\xff\xff\xff\x1f\x11\x00\x00\x79\x11\x00\x00\x00\x00\x00\x00\x89\x11\x00\x00\xb7\x03\x00\x00\xae\x11\x00\x00\x83\x04\x00\x00\x42\x05\x00\x00\xef\x11\x00\x00\x12\x12\x00\x00\xdc\x11\x00\x00\x3f\x12\x00\x00\x00\x00\x00\x00\x62\x12\x00\x00\x85\x12\x00\x00\xa8\x12\x00\x00\xe4\x12\x00\x00\xe7\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xee\xff\xff\xff\x00\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x43\x13\x00\x00\x0d\x00\x00\x00\x18\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x32\x13\x00\x00\x3d\x04\x00\x00\x17\x14\x00\x00\x6d\x14\x00\x00\xad\x14\x00\x00\xcd\x14\x00\x00\x2e\x00\x00\x00\x62\x05\x00\x00\x0d\x15\x00\x00\xc4\x15\x00\x00\xf0\xff\xff\xff\x00\x00\x00\x00\xb3\x15\x00\x00\xdf\x06\x00\x00\x39\x16\x00\x00\x59\x16\x00\x00\x99\x16\x00\x00\xb9\x16\x00\x00\xf9\x16\x00\x00\x4e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0\x17\x00\x00\x4d\x00\x00\x00\x54\x00\x00\x00\x00\x00\x00\x00\x9f\x17\x00\x00\xd6\x08\x00\x00\x25\x18\x00\x00\x45\x18\x00\x00\x85\x18\x00\x00\xa5\x18\x00\x00\xe5\x18\x00\x00\x73\x00\x00\x00\x9c\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8b\x19\x00\x00\xbe\x09\x00\x00\x11\x1a\x00\x00\x31\x1a\x00\x00\x71\x1a\x00\x00\x91\x1a\x00\x00\x75\x00\x00\x00\xd1\x1a\x00\x00\x88\x1b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x77\x1b\x00\x00\xf5\x0b\x00\x00\xfd\x1b\x00\x00\x1d\x1c\x00\x00\x5d\x1c\x00\x00\x7d\x1c\x00\x00\x76\x00\x00\x00\xbd\x1c\x00\x00"# alex_table :: AlexAddr alex_table = AlexA# - "\x00\x00\x7f\x00\x5a\x00\x62\x00\x72\x00\x83\x00\x7a\x00\x7b\x00\x7c\x00\x7e\x00\xbc\x00\xb0\x00\xa3\x00\xa3\x00\x94\x00\x94\x00\x84\x00\x59\x00\x5f\x00\x66\x00\x7a\x00\x7f\x00\x79\x00\x5a\x00\x59\x00\x73\x00\x78\x00\x5d\x00\x73\x00\x73\x00\x73\x00\x81\x00\x68\x00\x69\x00\x73\x00\x73\x00\x69\x00\x76\x00\x73\x00\x77\x00\x6f\x00\x6e\x00\x6e\x00\x6e\x00\x6e\x00\x6e\x00\x6e\x00\x6e\x00\x6e\x00\x6e\x00\x73\x00\x69\x00\x74\x00\x73\x00\x74\x00\x73\x00\x82\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x69\x00\x73\x00\x69\x00\x73\x00\x67\x00\x88\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x69\x00\x75\x00\x69\x00\x73\x00\xa3\x00\xa3\x00\x61\x00\x64\x00\xaf\x00\x84\x00\x95\x00\x5b\x00\x94\x00\x94\x00\x06\x00\x06\x00\x5c\x00\x7e\x00\xa1\x00\xa2\x00\xa3\x00\xa3\x00\xb1\x00\xb0\x00\xbd\x00\x00\x00\x00\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa4\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa5\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x7e\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\xae\x00\xbc\x00\xad\x00\xad\x00\xad\x00\xad\x00\xad\x00\xad\x00\xad\x00\xad\x00\xad\x00\xad\x00\xad\x00\xad\x00\xad\x00\xad\x00\xad\x00\xad\x00\xad\x00\xad\x00\xad\x00\xad\x00\xad\x00\xad\x00\xad\x00\xad\x00\xad\x00\xad\x00\xad\x00\xad\x00\xad\x00\xad\x00\xaa\x00\xac\x00\xac\x00\xac\x00\xac\x00\xac\x00\xac\x00\xac\x00\xac\x00\xac\x00\xac\x00\xac\x00\xac\x00\xab\x00\xac\x00\xac\x00\xa7\x00\xa9\x00\xa9\x00\xa9\x00\xa8\x00\xb0\x00\xb1\x00\x00\x00\x55\x00\xb9\x00\x55\x00\x00\x00\x00\x00\x6c\x00\x6c\x00\x6c\x00\x6c\x00\x6c\x00\x6c\x00\x6c\x00\x6c\x00\x6c\x00\x6c\x00\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x6c\x00\x6c\x00\x6c\x00\x6c\x00\x6c\x00\x6c\x00\x6c\x00\x6c\x00\x6c\x00\x6c\x00\x57\x00\x7e\x00\x57\x00\x00\x00\x00\x00\x6b\x00\x6b\x00\x6b\x00\x6b\x00\x6b\x00\x6b\x00\x6b\x00\x6b\x00\x6b\x00\x6b\x00\x00\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x6b\x00\x6b\x00\x6b\x00\x6b\x00\x6b\x00\x6b\x00\x6b\x00\x6b\x00\x6b\x00\x6b\x00\xbb\x00\x00\x00\xba\x00\xba\x00\xba\x00\xba\x00\xba\x00\xba\x00\xba\x00\xba\x00\xba\x00\xba\x00\xba\x00\xba\x00\xba\x00\xba\x00\xba\x00\xba\x00\xba\x00\xba\x00\xba\x00\xba\x00\xba\x00\xba\x00\xba\x00\xba\x00\xba\x00\xba\x00\xba\x00\xba\x00\xba\x00\xba\x00\xb6\x00\xb8\x00\xb8\x00\xb8\x00\xb8\x00\xb8\x00\xb8\x00\xb8\x00\xb8\x00\xb8\x00\xb8\x00\xb8\x00\xb8\x00\xb7\x00\xb8\x00\xb8\x00\xb3\x00\xb5\x00\xb5\x00\xb5\x00\xb4\x00\xbc\x00\xbd\x00\x7e\x00\x00\x00\xc5\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x00\x00\x00\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\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\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x6a\x00\x6a\x00\x6a\x00\x6a\x00\x6a\x00\x6a\x00\x6a\x00\x6a\x00\x6a\x00\x6a\x00\x00\x00\x00\x00\xc7\x00\x00\x00\xc6\x00\xc6\x00\xc6\x00\xc6\x00\xc6\x00\xc6\x00\xc6\x00\xc6\x00\xc6\x00\xc6\x00\xc6\x00\xc6\x00\xc6\x00\xc6\x00\xc6\x00\xc6\x00\xc6\x00\xc6\x00\xc6\x00\xc6\x00\xc6\x00\xc6\x00\xc6\x00\xc6\x00\xc6\x00\xc6\x00\xc6\x00\xc6\x00\xc6\x00\xc6\x00\xc2\x00\xc4\x00\xc4\x00\xc4\x00\xc4\x00\xc4\x00\xc4\x00\xc4\x00\xc4\x00\xc4\x00\xc4\x00\xc4\x00\xc4\x00\xc3\x00\xc4\x00\xc4\x00\xbf\x00\xc1\x00\xc1\x00\xc1\x00\xc0\x00\x88\x00\x00\x00\x00\x00\x90\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x00\x00\x00\x00\x84\x00\x84\x00\x87\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x91\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x1c\x00\x1c\x00\x1c\x00\x1c\x00\x1c\x00\x1c\x00\x1c\x00\x1c\x00\x1c\x00\x1c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c\x00\x1c\x00\x1c\x00\x1c\x00\x1c\x00\x1c\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\x6b\x00\x6b\x00\x6b\x00\x6b\x00\x6b\x00\x6b\x00\x6b\x00\x6b\x00\x6b\x00\x6b\x00\x1c\x00\x1c\x00\x1c\x00\x1c\x00\x1c\x00\x1c\x00\x6c\x00\x6c\x00\x6c\x00\x6c\x00\x6c\x00\x6c\x00\x6c\x00\x6c\x00\x6c\x00\x6c\x00\x93\x00\x00\x00\x92\x00\x92\x00\x92\x00\x92\x00\x92\x00\x92\x00\x92\x00\x92\x00\x92\x00\x92\x00\x92\x00\x92\x00\x92\x00\x92\x00\x92\x00\x92\x00\x92\x00\x92\x00\x92\x00\x92\x00\x92\x00\x92\x00\x92\x00\x92\x00\x92\x00\x92\x00\x92\x00\x92\x00\x92\x00\x92\x00\x8d\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8e\x00\x8f\x00\x8f\x00\x8a\x00\x8c\x00\x8c\x00\x8c\x00\x8b\x00\x94\x00\x94\x00\x00\x00\x00\x00\xa0\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\x00\x00\x00\x00\x94\x00\x94\x00\x96\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x1d\x00\x1d\x00\x1d\x00\x1d\x00\x1d\x00\x1d\x00\x1d\x00\x1d\x00\x1d\x00\x1d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d\x00\x1d\x00\x1d\x00\x1d\x00\x1d\x00\x1d\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\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d\x00\x1d\x00\x1d\x00\x1d\x00\x1d\x00\x1d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f\x00\x00\x00\x9e\x00\x9e\x00\x9e\x00\x9e\x00\x9e\x00\x9e\x00\x9e\x00\x9e\x00\x9e\x00\x9e\x00\x9e\x00\x9e\x00\x9e\x00\x9e\x00\x9e\x00\x9e\x00\x9e\x00\x9e\x00\x9e\x00\x9e\x00\x9e\x00\x9e\x00\x9e\x00\x9e\x00\x9e\x00\x9e\x00\x9e\x00\x9e\x00\x9e\x00\x9e\x00\x9b\x00\x9d\x00\x9d\x00\x9d\x00\x9d\x00\x9d\x00\x9d\x00\x9d\x00\x9d\x00\x9d\x00\x9d\x00\x9d\x00\x9d\x00\x9c\x00\x9d\x00\x9d\x00\x98\x00\x9a\x00\x9a\x00\x9a\x00\x99\x00\x18\x00\x00\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x07\x00\x00\x00\x07\x00\x07\x00\x07\x00\x07\x00\x00\x00\x00\x00\x62\x00\x07\x00\x07\x00\x00\x00\x07\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7d\x00\x07\x00\x00\x00\x07\x00\x07\x00\x07\x00\x07\x00\x85\x00\x00\x00\x00\x00\x00\x00\x09\x00\x85\x00\x09\x00\x09\x00\x09\x00\x09\x00\x00\x00\x7e\x00\x72\x00\x09\x00\x09\x00\x00\x00\x09\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x09\x00\x07\x00\x09\x00\x09\x00\x09\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x85\x00\x00\x00\x07\x00\x00\x00\x07\x00\x09\x00\x0b\x00\x09\x00\x00\x00\x00\x00\x0b\x00\x00\x00\x0b\x00\x1d\x00\x00\x00\x00\x00\x31\x00\x7e\x00\x85\x00\x00\x00\x00\x00\x00\x00\x85\x00\x00\x00\x85\x00\x1e\x00\x00\x00\x00\x00\x3f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x09\x00\x00\x00\x09\x00\x00\x00\x00\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\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\x43\x00\x7e\x00\x1f\x00\x1f\x00\x1f\x00\x1f\x00\x1f\x00\x1f\x00\x1f\x00\x1f\x00\x1f\x00\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1f\x00\x1f\x00\x1f\x00\x1f\x00\x1f\x00\x1f\x00\x2c\x00\x2c\x00\x2c\x00\x2c\x00\x2c\x00\x2c\x00\x2c\x00\x2c\x00\x2c\x00\x2c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2c\x00\x2c\x00\x2c\x00\x2c\x00\x2c\x00\x2c\x00\x00\x00\x00\x00\x00\x00\x1f\x00\x1f\x00\x1f\x00\x1f\x00\x1f\x00\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2c\x00\x2c\x00\x2c\x00\x2c\x00\x2c\x00\x2c\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\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\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x07\x00\x00\x00\x07\x00\x07\x00\x07\x00\x07\x00\x00\x00\x00\x00\x00\x00\x07\x00\x07\x00\x00\x00\x07\x00\x07\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x07\x00\x07\x00\x07\x00\x07\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x07\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\x00\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x07\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\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\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\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\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\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x3e\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\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\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\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\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\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\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\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\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\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\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\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\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x00\x00\x00\x00\x00\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x00\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x50\x00\x50\x00\x50\x00\x50\x00\x50\x00\x50\x00\x50\x00\x50\x00\x50\x00\x50\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x50\x00\x50\x00\x50\x00\x50\x00\x50\x00\x50\x00\x00\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x50\x00\x50\x00\x50\x00\x50\x00\x50\x00\x50\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\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\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x00\x00\x00\x00\x00\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x54\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\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\x00\x00\x00\x00\x54\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x86\x00\x86\x00\x86\x00\x86\x00\x86\x00\x86\x00\x86\x00\x86\x00\x86\x00\x86\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x86\x00\x86\x00\x86\x00\x86\x00\x86\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\x86\x00\x86\x00\x86\x00\x86\x00\x86\x00\x86\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x6d\x00\x6d\x00\x6d\x00\x6d\x00\x6d\x00\x6d\x00\x6d\x00\x6d\x00\x6d\x00\x6d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x6d\x00\x6d\x00\x6d\x00\x6d\x00\x6d\x00\x6d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5b\x00\x00\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x00\x00\x00\x00\x00\x00\x5b\x00\x5b\x00\x00\x00\x5b\x00\x5b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x6d\x00\x6d\x00\x6d\x00\x6d\x00\x6d\x00\x6d\x00\x5b\x00\x00\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5c\x00\x00\x00\x5c\x00\x5c\x00\x5c\x00\x5c\x00\x00\x00\x00\x00\x00\x00\x5c\x00\x5c\x00\x00\x00\x5c\x00\x5c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5b\x00\x5c\x00\x5b\x00\x5c\x00\x5c\x00\x5c\x00\x5c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5d\x00\x00\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x00\x00\x00\x00\x00\x00\x5d\x00\x5d\x00\x00\x00\x5d\x00\x5d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5b\x00\x00\x00\x5b\x00\x5c\x00\x5d\x00\x5c\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5e\x00\x00\x00\x00\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x00\x00\x5c\x00\x00\x00\x5c\x00\x5d\x00\x00\x00\x5d\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x00\x00\x00\x00\x00\x00\x5d\x00\x5e\x00\x5d\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x61\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x00\x00\x06\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\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\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x64\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x63\x00\x00\x00\x06\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x00\x00\x00\x00\x00\x00\x00\x00\x63\x00\x00\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x66\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x65\x00\x00\x00\x00\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x00\x00\x00\x00\x00\x00\x00\x00\x65\x00\x00\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x65\x00\x67\x00\x00\x00\x00\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x00\x00\x00\x00\x00\x00\x00\x00\x67\x00\x00\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x09\x00\x00\x00\x09\x00\x09\x00\x09\x00\x09\x00\x00\x00\x00\x00\x00\x00\x09\x00\x09\x00\x00\x00\x09\x00\x09\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x09\x00\x00\x00\x09\x00\x09\x00\x09\x00\x09\x00\x6a\x00\x6a\x00\x6a\x00\x6a\x00\x6a\x00\x6a\x00\x6a\x00\x6a\x00\x6a\x00\x6a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x56\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x09\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x32\x00\x00\x00\x6d\x00\x6d\x00\x6d\x00\x6d\x00\x6d\x00\x6d\x00\x6d\x00\x6d\x00\x6d\x00\x6d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x56\x00\x6d\x00\x6d\x00\x6d\x00\x6d\x00\x6d\x00\x6d\x00\x09\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x54\x00\x58\x00\x00\x00\x6e\x00\x6e\x00\x6e\x00\x6e\x00\x6e\x00\x6e\x00\x6e\x00\x6e\x00\x6e\x00\x6e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x6d\x00\x6d\x00\x6d\x00\x6d\x00\x6d\x00\x6d\x00\x00\x00\x56\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\x00\x54\x00\x6e\x00\x6e\x00\x6e\x00\x6e\x00\x6e\x00\x6e\x00\x6e\x00\x6e\x00\x6e\x00\x6e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x56\x00\x73\x00\x56\x00\x73\x00\x73\x00\x73\x00\x73\x00\x00\x00\x00\x00\x00\x00\x73\x00\x73\x00\x00\x00\x73\x00\x73\x00\x00\x00\x00\x00\x00\x00\x00\x00\x53\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x73\x00\x00\x00\x71\x00\x73\x00\x71\x00\x73\x00\x56\x00\x00\x00\x00\x00\x00\x00\x73\x00\x00\x00\x73\x00\x73\x00\x73\x00\x73\x00\x00\x00\x00\x00\x00\x00\x73\x00\x73\x00\x00\x00\x73\x00\x73\x00\x00\x00\x53\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x73\x00\x73\x00\x73\x00\x71\x00\x73\x00\x71\x00\x73\x00\x00\x00\x00\x00\x00\x00\x00\x00\x73\x00\x00\x00\x73\x00\x73\x00\x73\x00\x73\x00\x00\x00\x00\x00\x00\x00\x73\x00\x73\x00\x00\x00\x73\x00\x73\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x71\x00\x00\x00\x73\x00\x73\x00\x73\x00\x73\x00\x73\x00\x73\x00\x73\x00\x73\x00\x00\x00\x00\x00\x00\x00\x00\x00\x73\x00\x00\x00\x73\x00\x73\x00\x73\x00\x73\x00\x00\x00\x00\x00\x00\x00\x73\x00\x73\x00\x00\x00\x73\x00\x73\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x71\x00\x00\x00\x73\x00\x73\x00\x73\x00\x73\x00\x71\x00\x73\x00\x71\x00\x73\x00\x00\x00\x00\x00\x00\x00\x00\x00\x73\x00\x00\x00\x73\x00\x73\x00\x73\x00\x73\x00\x00\x00\x00\x00\x00\x00\x73\x00\x73\x00\x00\x00\x73\x00\x73\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x73\x00\x00\x00\x73\x00\x73\x00\x73\x00\x73\x00\x71\x00\x73\x00\x71\x00\x73\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x71\x00\x00\x00\x73\x00\x73\x00\x73\x00\x73\x00\x73\x00\x73\x00\x73\x00\x73\x00\x00\x00\x00\x00\x00\x00\x73\x00\x73\x00\x00\x00\x73\x00\x73\x00\x00\x00\x6f\x00\x6e\x00\x6e\x00\x6e\x00\x6e\x00\x6e\x00\x6e\x00\x6e\x00\x6e\x00\x6e\x00\x73\x00\x00\x00\x73\x00\x73\x00\x73\x00\x73\x00\x70\x00\x00\x00\x73\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x73\x00\x00\x00\x73\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\x73\x00\x00\x00\x73\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x00\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0e\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\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\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\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17\x00\x00\x00\x16\x00\x16\x00\x16\x00\x16\x00\x16\x00\x16\x00\x16\x00\x16\x00\x16\x00\x16\x00\x16\x00\x16\x00\x16\x00\x16\x00\x16\x00\x16\x00\x16\x00\x16\x00\x16\x00\x16\x00\x16\x00\x16\x00\x16\x00\x16\x00\x16\x00\x16\x00\x16\x00\x16\x00\x16\x00\x16\x00\x13\x00\x15\x00\x15\x00\x15\x00\x15\x00\x15\x00\x15\x00\x15\x00\x15\x00\x15\x00\x15\x00\x15\x00\x15\x00\x14\x00\x15\x00\x15\x00\x10\x00\x12\x00\x12\x00\x12\x00\x11\x00\x84\x00\x84\x00\x00\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x00\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\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\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\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x00\x00\x52\x00\x00\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x40\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\x41\x00\x42\x00\x42\x00\x2d\x00\x2f\x00\x2f\x00\x2f\x00\x2e\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x51\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x94\x00\x94\x00\x00\x00\x00\x00\x4f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x94\x00\x94\x00\x00\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\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\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\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x4e\x00\x00\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x3c\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\x3d\x00\x3e\x00\x3e\x00\x29\x00\x2b\x00\x2b\x00\x2b\x00\x2a\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\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\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x3e\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\x94\x00\xa3\x00\xa3\x00\x00\x00\x00\x00\x4c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\x00\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\x00\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x4b\x00\x00\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x39\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3a\x00\x3b\x00\x3b\x00\x26\x00\x28\x00\x28\x00\x28\x00\x27\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xa3\x00\xb0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x49\x00\x00\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x36\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x37\x00\x38\x00\x38\x00\x23\x00\x25\x00\x25\x00\x25\x00\x24\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xbc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x47\x00\x00\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x33\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x34\x00\x35\x00\x35\x00\x20\x00\x22\x00\x22\x00\x22\x00\x21\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\x46\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\xbc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"# + "\x00\x00\x7c\x00\x55\x00\x5d\x00\x6f\x00\x7f\x00\x77\x00\x78\x00\x79\x00\x7b\x00\x54\x00\x9c\x00\x8f\x00\x76\x00\x4b\x00\x58\x00\x5a\x00\x56\x00\x7c\x00\x90\x00\x62\x00\x77\x00\x57\x00\x55\x00\x54\x00\x70\x00\x75\x00\x70\x00\x70\x00\x70\x00\x70\x00\x7e\x00\x64\x00\x65\x00\x70\x00\x70\x00\x65\x00\x73\x00\x70\x00\x74\x00\x6a\x00\x6c\x00\x6c\x00\x6c\x00\x6c\x00\x6c\x00\x6c\x00\x6c\x00\x6c\x00\x6c\x00\x70\x00\x65\x00\x71\x00\x70\x00\x71\x00\x70\x00\x84\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x65\x00\x70\x00\x65\x00\x70\x00\x63\x00\x8f\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5f\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x65\x00\x72\x00\x65\x00\x70\x00\x9c\x00\x9c\x00\x5c\x00\x60\x00\xa7\x00\x9a\x00\x9c\x00\x9b\x00\xa9\x00\xb4\x00\x06\x00\x06\x00\x00\x00\x7b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9d\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9e\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x00\x00\x00\x00\x00\x00\xa6\x00\xa6\x00\xa6\x00\xa6\x00\xa6\x00\xa6\x00\xa6\x00\xa6\x00\xa6\x00\xa6\x00\xa6\x00\xa6\x00\xa6\x00\xa6\x00\xa6\x00\xa6\x00\xa6\x00\xa6\x00\xa6\x00\xa6\x00\xa6\x00\xa6\x00\xa6\x00\xa6\x00\xa6\x00\xa6\x00\xa6\x00\xa6\x00\xa6\x00\xa6\x00\xa3\x00\xa5\x00\xa5\x00\xa5\x00\xa5\x00\xa5\x00\xa5\x00\xa5\x00\xa5\x00\xa5\x00\xa5\x00\xa5\x00\xa5\x00\xa4\x00\xa5\x00\xa5\x00\xa0\x00\xa2\x00\xa2\x00\xa2\x00\xa1\x00\xa8\x00\xa9\x00\x00\x00\x00\x00\xb1\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x00\x00\x00\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\x1a\x00\x1a\x00\x1a\x00\x1a\x00\x1a\x00\x1a\x00\x1a\x00\x1a\x00\x1a\x00\x1a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1a\x00\x1a\x00\x1a\x00\x1a\x00\x1a\x00\x1a\x00\x6c\x00\x6c\x00\x6c\x00\x6c\x00\x6c\x00\x6c\x00\x6c\x00\x6c\x00\x6c\x00\x6c\x00\x50\x00\x7b\x00\x50\x00\x00\x00\x00\x00\x69\x00\x69\x00\x69\x00\x69\x00\x69\x00\x69\x00\x69\x00\x69\x00\x69\x00\x69\x00\x00\x00\x1a\x00\x1a\x00\x1a\x00\x1a\x00\x1a\x00\x1a\x00\x69\x00\x69\x00\x69\x00\x69\x00\x69\x00\x69\x00\x69\x00\x69\x00\x69\x00\x69\x00\x00\x00\x00\x00\xb2\x00\xb2\x00\xb2\x00\xb2\x00\xb2\x00\xb2\x00\xb2\x00\xb2\x00\xb2\x00\xb2\x00\xb2\x00\xb2\x00\xb2\x00\xb2\x00\xb2\x00\xb2\x00\xb2\x00\xb2\x00\xb2\x00\xb2\x00\xb2\x00\xb2\x00\xb2\x00\xb2\x00\xb2\x00\xb2\x00\xb2\x00\xb2\x00\xb2\x00\xb2\x00\xae\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xb0\x00\xaf\x00\xb0\x00\xb0\x00\xab\x00\xad\x00\xad\x00\xad\x00\xac\x00\xb3\x00\xb4\x00\x7b\x00\x00\x00\xbc\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x00\x00\x00\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x66\x00\x66\x00\x66\x00\x66\x00\x66\x00\x66\x00\x66\x00\x66\x00\x66\x00\x66\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbd\x00\xbd\x00\xbd\x00\xbd\x00\xbd\x00\xbd\x00\xbd\x00\xbd\x00\xbd\x00\xbd\x00\xbd\x00\xbd\x00\xbd\x00\xbd\x00\xbd\x00\xbd\x00\xbd\x00\xbd\x00\xbd\x00\xbd\x00\xbd\x00\xbd\x00\xbd\x00\xbd\x00\xbd\x00\xbd\x00\xbd\x00\xbd\x00\xbd\x00\xbd\x00\xb9\x00\xbb\x00\xbb\x00\xbb\x00\xbb\x00\xbb\x00\xbb\x00\xbb\x00\xbb\x00\xbb\x00\xbb\x00\xbb\x00\xbb\x00\xba\x00\xbb\x00\xbb\x00\xb6\x00\xb8\x00\xb8\x00\xb8\x00\xb7\x00\x84\x00\x00\x00\x00\x00\x8c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x00\x00\x00\x00\x80\x00\x80\x00\x83\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x8d\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\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\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x00\x00\x00\x00\x8e\x00\x8e\x00\x8e\x00\x8e\x00\x8e\x00\x8e\x00\x8e\x00\x8e\x00\x8e\x00\x8e\x00\x8e\x00\x8e\x00\x8e\x00\x8e\x00\x8e\x00\x8e\x00\x8e\x00\x8e\x00\x8e\x00\x8e\x00\x8e\x00\x8e\x00\x8e\x00\x8e\x00\x8e\x00\x8e\x00\x8e\x00\x8e\x00\x8e\x00\x8e\x00\x89\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8a\x00\x8b\x00\x8b\x00\x86\x00\x88\x00\x88\x00\x88\x00\x87\x00\x8f\x00\x8f\x00\x00\x00\x53\x00\x99\x00\x53\x00\x00\x00\x00\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x67\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8f\x00\x8f\x00\x90\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x1c\x00\x1c\x00\x1c\x00\x1c\x00\x1c\x00\x1c\x00\x1c\x00\x1c\x00\x1c\x00\x1c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c\x00\x1c\x00\x1c\x00\x1c\x00\x1c\x00\x1c\x00\x69\x00\x69\x00\x69\x00\x69\x00\x69\x00\x69\x00\x69\x00\x69\x00\x69\x00\x69\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\x1c\x00\x1c\x00\x1c\x00\x1c\x00\x1c\x00\x1c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x98\x00\x98\x00\x98\x00\x98\x00\x98\x00\x98\x00\x98\x00\x98\x00\x98\x00\x98\x00\x98\x00\x98\x00\x98\x00\x98\x00\x98\x00\x98\x00\x98\x00\x98\x00\x98\x00\x98\x00\x98\x00\x98\x00\x98\x00\x98\x00\x98\x00\x98\x00\x98\x00\x98\x00\x98\x00\x98\x00\x95\x00\x97\x00\x97\x00\x97\x00\x97\x00\x97\x00\x97\x00\x97\x00\x97\x00\x97\x00\x97\x00\x97\x00\x97\x00\x96\x00\x97\x00\x97\x00\x92\x00\x94\x00\x94\x00\x94\x00\x93\x00\x17\x00\x00\x00\x1d\x00\x1d\x00\x1d\x00\x1d\x00\x1d\x00\x1d\x00\x1d\x00\x1d\x00\x1d\x00\x1d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d\x00\x1d\x00\x1d\x00\x1d\x00\x1d\x00\x1d\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x1d\x00\x1d\x00\x1d\x00\x1d\x00\x1d\x00\x1d\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x07\x00\x00\x00\x07\x00\x07\x00\x07\x00\x07\x00\x00\x00\x00\x00\x5d\x00\x07\x00\x07\x00\x52\x00\x07\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7a\x00\x07\x00\x00\x00\x07\x00\x07\x00\x07\x00\x07\x00\x81\x00\x00\x00\x00\x00\x51\x00\x09\x00\x81\x00\x09\x00\x09\x00\x09\x00\x09\x00\x00\x00\x7b\x00\x6f\x00\x09\x00\x09\x00\x00\x00\x09\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x4c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x09\x00\x07\x00\x09\x00\x09\x00\x09\x00\x09\x00\x51\x00\x00\x00\x00\x00\x00\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x19\x00\x00\x00\x00\x00\x4c\x00\x00\x00\x00\x00\x00\x00\x81\x00\x00\x00\x07\x00\x00\x00\x07\x00\x09\x00\x0b\x00\x09\x00\x00\x00\x00\x00\x0b\x00\x00\x00\x0b\x00\x1c\x00\x00\x00\x00\x00\x30\x00\x7b\x00\x81\x00\x00\x00\x00\x00\x00\x00\x81\x00\x00\x00\x81\x00\x1d\x00\x00\x00\x00\x00\x3d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x09\x00\x00\x00\x09\x00\x00\x00\x00\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x7b\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x2b\x00\x2b\x00\x2b\x00\x2b\x00\x2b\x00\x2b\x00\x2b\x00\x2b\x00\x2b\x00\x2b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2b\x00\x2b\x00\x2b\x00\x2b\x00\x2b\x00\x2b\x00\x00\x00\x00\x00\x00\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2b\x00\x2b\x00\x2b\x00\x2b\x00\x2b\x00\x2b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x07\x00\x00\x00\x07\x00\x07\x00\x07\x00\x07\x00\x00\x00\x00\x00\x00\x00\x07\x00\x07\x00\x00\x00\x07\x00\x07\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x07\x00\x07\x00\x07\x00\x07\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x07\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x00\x00\x00\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x07\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3d\x00\x3d\x00\x3d\x00\x3d\x00\x3d\x00\x3d\x00\x3d\x00\x3d\x00\x3d\x00\x3d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3d\x00\x3d\x00\x3d\x00\x3d\x00\x3d\x00\x3d\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3d\x00\x3d\x00\x3d\x00\x3d\x00\x3d\x00\x3d\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\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\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\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\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x00\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\x00\x42\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\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\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\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\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\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x49\x00\x49\x00\x49\x00\x49\x00\x49\x00\x49\x00\x49\x00\x49\x00\x49\x00\x49\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x49\x00\x49\x00\x49\x00\x49\x00\x49\x00\x49\x00\x00\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x49\x00\x49\x00\x49\x00\x49\x00\x49\x00\x49\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\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\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\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x6b\x00\x6b\x00\x6b\x00\x6b\x00\x6b\x00\x6b\x00\x6b\x00\x6b\x00\x6b\x00\x6b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x6b\x00\x6b\x00\x6b\x00\x6b\x00\x6b\x00\x6b\x00\x68\x00\x68\x00\x68\x00\x68\x00\x68\x00\x68\x00\x68\x00\x68\x00\x68\x00\x68\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x68\x00\x68\x00\x68\x00\x68\x00\x68\x00\x68\x00\x00\x00\x00\x00\x00\x00\x6b\x00\x6b\x00\x6b\x00\x6b\x00\x6b\x00\x6b\x00\x56\x00\x00\x00\x56\x00\x56\x00\x56\x00\x56\x00\x00\x00\x00\x00\x00\x00\x56\x00\x56\x00\x00\x00\x56\x00\x56\x00\x00\x00\x00\x00\x00\x00\x68\x00\x68\x00\x68\x00\x68\x00\x68\x00\x68\x00\x00\x00\x00\x00\x56\x00\x00\x00\x56\x00\x56\x00\x56\x00\x56\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x56\x00\x57\x00\x56\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x58\x00\x58\x00\x58\x00\x58\x00\x00\x00\x00\x00\x00\x00\x58\x00\x58\x00\x00\x00\x58\x00\x58\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x56\x00\x00\x00\x56\x00\x57\x00\x58\x00\x57\x00\x58\x00\x58\x00\x58\x00\x58\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x59\x00\x00\x00\x00\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x00\x00\x57\x00\x00\x00\x57\x00\x58\x00\x00\x00\x58\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x00\x00\x00\x00\x00\x00\x58\x00\x59\x00\x58\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x59\x00\x5c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5b\x00\x00\x00\x06\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5b\x00\x00\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x5b\x00\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5e\x00\x00\x00\x06\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5e\x00\x00\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x76\x00\x4b\x00\x00\x00\x00\x00\x00\x00\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5e\x00\x00\x00\x06\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5e\x00\x00\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x5e\x00\x62\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x61\x00\x00\x00\x00\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x00\x00\x00\x00\x00\x00\x00\x00\x61\x00\x00\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x61\x00\x63\x00\x00\x00\x00\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x00\x00\x00\x00\x00\x00\x00\x00\x63\x00\x00\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x63\x00\x09\x00\x00\x00\x09\x00\x09\x00\x09\x00\x09\x00\x00\x00\x00\x00\x00\x00\x09\x00\x09\x00\x00\x00\x09\x00\x09\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x09\x00\x00\x00\x09\x00\x09\x00\x09\x00\x09\x00\x66\x00\x66\x00\x66\x00\x66\x00\x66\x00\x66\x00\x66\x00\x66\x00\x66\x00\x66\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x51\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x09\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x68\x00\x68\x00\x68\x00\x68\x00\x68\x00\x68\x00\x68\x00\x68\x00\x68\x00\x68\x00\x52\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x51\x00\x68\x00\x68\x00\x68\x00\x68\x00\x68\x00\x68\x00\x09\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x70\x00\x4f\x00\x70\x00\x70\x00\x70\x00\x70\x00\x00\x00\x00\x00\x00\x00\x70\x00\x70\x00\x00\x00\x70\x00\x70\x00\x00\x00\x00\x00\x4e\x00\x00\x00\x68\x00\x68\x00\x68\x00\x68\x00\x68\x00\x68\x00\x00\x00\x70\x00\x00\x00\x6e\x00\x70\x00\x6e\x00\x70\x00\x00\x00\x4e\x00\x4f\x00\x6b\x00\x6b\x00\x6b\x00\x6b\x00\x6b\x00\x6b\x00\x6b\x00\x6b\x00\x6b\x00\x6b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x6b\x00\x6b\x00\x6b\x00\x6b\x00\x6b\x00\x6b\x00\x00\x00\x00\x00\x70\x00\x00\x00\x70\x00\x00\x00\x00\x00\x00\x00\x00\x00\x4f\x00\x52\x00\x00\x00\x6c\x00\x6c\x00\x6c\x00\x6c\x00\x6c\x00\x6c\x00\x6c\x00\x6c\x00\x6c\x00\x6c\x00\x00\x00\x00\x00\x4c\x00\x00\x00\x6b\x00\x6b\x00\x6b\x00\x6b\x00\x6b\x00\x6b\x00\x00\x00\x51\x00\x6e\x00\x00\x00\x70\x00\x00\x00\x00\x00\x00\x00\x00\x00\x4f\x00\x70\x00\x00\x00\x70\x00\x70\x00\x70\x00\x70\x00\x00\x00\x00\x00\x00\x00\x70\x00\x70\x00\x00\x00\x70\x00\x70\x00\x00\x00\x00\x00\x00\x00\x4d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x51\x00\x00\x00\x70\x00\x00\x00\x6e\x00\x70\x00\x6e\x00\x70\x00\x00\x00\x00\x00\x00\x00\x00\x00\x70\x00\x00\x00\x70\x00\x70\x00\x70\x00\x70\x00\x00\x00\x00\x00\x00\x00\x70\x00\x70\x00\x00\x00\x70\x00\x70\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x70\x00\x70\x00\x70\x00\x70\x00\x70\x00\x70\x00\x70\x00\x00\x00\x00\x00\x00\x00\x00\x00\x70\x00\x00\x00\x70\x00\x70\x00\x70\x00\x70\x00\x00\x00\x00\x00\x00\x00\x70\x00\x70\x00\x00\x00\x70\x00\x70\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x6e\x00\x00\x00\x70\x00\x70\x00\x70\x00\x70\x00\x6e\x00\x70\x00\x6e\x00\x70\x00\x00\x00\x00\x00\x00\x00\x00\x00\x70\x00\x00\x00\x70\x00\x70\x00\x70\x00\x70\x00\x00\x00\x00\x00\x00\x00\x70\x00\x70\x00\x00\x00\x70\x00\x70\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x70\x00\x00\x00\x70\x00\x70\x00\x70\x00\x70\x00\x6e\x00\x70\x00\x6e\x00\x70\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x6e\x00\x00\x00\x70\x00\x70\x00\x70\x00\x70\x00\x70\x00\x70\x00\x70\x00\x70\x00\x00\x00\x00\x00\x00\x00\x70\x00\x70\x00\x00\x00\x70\x00\x70\x00\x00\x00\x6a\x00\x6c\x00\x6c\x00\x6c\x00\x6c\x00\x6c\x00\x6c\x00\x6c\x00\x6c\x00\x6c\x00\x70\x00\x00\x00\x70\x00\x70\x00\x70\x00\x70\x00\x6d\x00\x00\x00\x70\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x70\x00\x00\x00\x70\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\x70\x00\x00\x00\x70\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x00\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0e\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\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\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\x16\x00\x16\x00\x16\x00\x16\x00\x16\x00\x16\x00\x16\x00\x16\x00\x16\x00\x16\x00\x16\x00\x16\x00\x16\x00\x16\x00\x16\x00\x16\x00\x16\x00\x16\x00\x16\x00\x16\x00\x16\x00\x16\x00\x16\x00\x16\x00\x16\x00\x16\x00\x16\x00\x16\x00\x16\x00\x16\x00\x13\x00\x15\x00\x15\x00\x15\x00\x15\x00\x15\x00\x15\x00\x15\x00\x15\x00\x15\x00\x15\x00\x15\x00\x15\x00\x14\x00\x15\x00\x15\x00\x10\x00\x12\x00\x12\x00\x12\x00\x11\x00\x80\x00\x80\x00\x00\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x00\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\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\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\x40\x00\x40\x00\x00\x00\x00\x00\x00\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\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\x3f\x00\x40\x00\x40\x00\x2c\x00\x2e\x00\x2e\x00\x2e\x00\x2d\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x8f\x00\x8f\x00\x00\x00\x00\x00\x48\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8f\x00\x8f\x00\x00\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x3a\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3b\x00\x3c\x00\x3c\x00\x28\x00\x2a\x00\x2a\x00\x2a\x00\x29\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x8f\x00\x9c\x00\x9c\x00\x00\x00\x00\x00\x46\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x00\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x00\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x37\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x38\x00\x39\x00\x39\x00\x25\x00\x27\x00\x27\x00\x27\x00\x26\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x39\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x45\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\x9c\x00\xa8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\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\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x34\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x35\x00\x36\x00\x36\x00\x22\x00\x24\x00\x24\x00\x24\x00\x23\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\x44\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xa8\x00\xb3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\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\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x43\x00\x31\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x32\x00\x33\x00\x33\x00\x1f\x00\x21\x00\x21\x00\x21\x00\x20\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\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\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\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\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\x43\x00\x43\x00\x43\x00\x43\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\xb3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\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\x29\x00\x29\x00\x0d\x00\x27\x00\x27\x00\x27\x00\x27\x00\x80\x00\x80\x00\x80\x00\x0a\x00\x80\x00\x0a\x00\x80\x00\x20\x00\x27\x00\x27\x00\x27\x00\x09\x00\x22\x00\x0a\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\x0a\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\x27\x00\x27\x00\x0d\x00\x80\x00\x22\x00\x2a\x00\x80\x00\x0a\x00\x2f\x00\x2f\x00\x2f\x00\x27\x00\x2f\x00\x2a\x00\x80\x00\x0a\x00\x0a\x00\x80\x00\x0a\x00\xff\xff\xff\xff\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\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\x27\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\xc0\x00\x80\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\xd7\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\x09\x00\x0a\x00\xff\xff\x2b\x00\x0d\x00\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\x80\x00\xff\xff\xff\xff\xff\xff\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\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\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\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\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xc0\x00\xff\xff\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\xd7\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\x09\x00\x0a\x00\x27\x00\xff\xff\x0d\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\xff\xff\xff\xff\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\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\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\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\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xc0\x00\xff\xff\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\xd7\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\x0a\x00\xff\xff\xff\xff\x0d\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\xff\xff\xff\xff\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\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\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\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xc0\x00\xff\xff\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\xd7\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\x09\x00\x0a\x00\xff\xff\xff\xff\x0d\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\xff\xff\xff\xff\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\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\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\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\xff\xff\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\xd7\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\x28\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\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\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\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\x21\x00\xff\xff\x23\x00\x24\x00\x25\x00\x26\x00\xff\xff\xff\xff\x29\x00\x2a\x00\x2b\x00\xff\xff\x2d\x00\x2e\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x22\x00\xff\xff\xff\xff\xff\xff\xff\xff\x27\x00\x3a\x00\xff\xff\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x22\x00\xff\xff\xff\xff\xff\xff\x21\x00\x27\x00\x23\x00\x24\x00\x25\x00\x26\x00\xff\xff\x27\x00\x29\x00\x2a\x00\x2b\x00\xff\xff\x2d\x00\x2e\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5c\x00\x3a\x00\x5e\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\xff\xff\xff\xff\xff\xff\xff\xff\x55\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5c\x00\xff\xff\xff\xff\xff\xff\xff\xff\x55\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5c\x00\xff\xff\x7c\x00\xff\xff\x7e\x00\x5c\x00\x6e\x00\x5e\x00\xff\xff\xff\xff\x72\x00\xff\xff\x74\x00\x75\x00\xff\xff\xff\xff\x78\x00\x27\x00\x6e\x00\xff\xff\xff\xff\xff\xff\x72\x00\xff\xff\x74\x00\x75\x00\xff\xff\xff\xff\x78\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7c\x00\xff\xff\x7e\x00\xff\xff\xff\xff\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\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\x27\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\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\xff\xff\xff\xff\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x27\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\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\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\x2a\x00\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\xff\xff\xff\xff\x3a\x00\xff\xff\x3c\x00\x3d\x00\x3e\x00\x3f\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\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5c\x00\xff\xff\x5e\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\xff\xff\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7c\x00\xff\xff\x7e\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\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\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\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\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\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\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\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\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\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\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\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\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\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\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\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\xff\xff\xff\xff\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\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\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\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\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\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\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\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\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\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\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\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\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\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\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\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\xff\xff\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\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\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\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\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\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\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\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\xff\xff\xff\xff\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x50\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\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x70\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\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\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\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\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\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\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\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\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x21\x00\xff\xff\x23\x00\x24\x00\x25\x00\x26\x00\xff\xff\xff\xff\xff\xff\x2a\x00\x2b\x00\xff\xff\x2d\x00\x2e\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x3a\x00\xff\xff\x3c\x00\x3d\x00\x3e\x00\x3f\x00\xff\xff\xff\xff\xff\xff\xff\xff\x21\x00\xff\xff\x23\x00\x24\x00\x25\x00\x26\x00\xff\xff\xff\xff\xff\xff\x2a\x00\x2b\x00\xff\xff\x2d\x00\x2e\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5c\x00\x3a\x00\x5e\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\xff\xff\xff\xff\xff\xff\xff\xff\x21\x00\xff\xff\x23\x00\x24\x00\x25\x00\x26\x00\xff\xff\xff\xff\xff\xff\x2a\x00\x2b\x00\xff\xff\x2d\x00\x2e\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7c\x00\xff\xff\x7e\x00\x5c\x00\x3a\x00\x5e\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x27\x00\xff\xff\xff\xff\xff\xff\xff\xff\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\x7c\x00\xff\xff\x7e\x00\x5c\x00\xff\xff\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\xff\xff\xff\xff\xff\xff\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\x27\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x2d\x00\xff\xff\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\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\x27\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x2d\x00\xff\xff\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\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\x27\x00\xff\xff\xff\xff\xff\xff\xff\xff\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\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\x21\x00\xff\xff\x23\x00\x24\x00\x25\x00\x26\x00\xff\xff\xff\xff\xff\xff\x2a\x00\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\xff\xff\xff\xff\x3a\x00\xff\xff\x3c\x00\x3d\x00\x3e\x00\x3f\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\xff\xff\xff\xff\xff\xff\xff\xff\x45\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5c\x00\xff\xff\x5e\x00\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\x65\x00\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x7c\x00\xff\xff\x7e\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x50\x00\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\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\xff\xff\x45\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x2e\x00\x70\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\xff\xff\xff\xff\xff\xff\xff\xff\x45\x00\x21\x00\x65\x00\x23\x00\x24\x00\x25\x00\x26\x00\xff\xff\xff\xff\xff\xff\x2a\x00\x2b\x00\xff\xff\x2d\x00\x2e\x00\xff\xff\xff\xff\xff\xff\xff\xff\x58\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x3a\x00\xff\xff\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x65\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\x2a\x00\x2b\x00\xff\xff\x2d\x00\x2e\x00\xff\xff\x78\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5c\x00\x3a\x00\x5e\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\xff\xff\xff\xff\xff\xff\xff\xff\x21\x00\xff\xff\x23\x00\x24\x00\x25\x00\x26\x00\xff\xff\xff\xff\xff\xff\x2a\x00\x2b\x00\xff\xff\x2d\x00\x2e\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7c\x00\xff\xff\x7e\x00\x5c\x00\x3a\x00\x5e\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\xff\xff\xff\xff\xff\xff\xff\xff\x21\x00\xff\xff\x23\x00\x24\x00\x25\x00\x26\x00\xff\xff\xff\xff\xff\xff\x2a\x00\x2b\x00\xff\xff\x2d\x00\x2e\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7c\x00\xff\xff\x7e\x00\x5c\x00\x3a\x00\x5e\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\xff\xff\xff\xff\xff\xff\xff\xff\x21\x00\xff\xff\x23\x00\x24\x00\x25\x00\x26\x00\xff\xff\xff\xff\xff\xff\x2a\x00\x2b\x00\xff\xff\x2d\x00\x2e\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7c\x00\xff\xff\x7e\x00\x5c\x00\x3a\x00\x5e\x00\x3c\x00\x3d\x00\x3e\x00\x3f\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\x7c\x00\xff\xff\x7e\x00\x5c\x00\x21\x00\x5e\x00\x23\x00\x24\x00\x25\x00\x26\x00\xff\xff\xff\xff\xff\xff\x2a\x00\x2b\x00\xff\xff\x2d\x00\x2e\x00\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x3a\x00\xff\xff\x3c\x00\x3d\x00\x3e\x00\x3f\x00\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\x5c\x00\xff\xff\x5e\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0a\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\x7c\x00\xff\xff\x7e\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\xff\xff\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\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\xc0\x00\xff\xff\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\xd7\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\x20\x00\x21\x00\xff\xff\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\xff\xff\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\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\xc0\x00\xff\xff\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\xd7\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\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\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\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\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\xff\xff\xff\xff\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\x20\x00\x21\x00\xff\xff\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\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\xc0\x00\xff\xff\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\xd7\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\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\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\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\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\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\xff\xff\xff\xff\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\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\xff\xff\x2b\x00\x2c\x00\x2d\x00\x2e\x00\xff\xff\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\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\xc0\x00\xff\xff\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\xd7\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\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\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\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\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\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\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\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\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\xc0\x00\xff\xff\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\xd7\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\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\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\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\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\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\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\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\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\xc0\x00\xff\xff\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\xd7\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\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\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\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\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\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\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\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\x29\x00\x29\x00\x0d\x00\x27\x00\x27\x00\x27\x00\x27\x00\x20\x00\x0a\x00\x0a\x00\x22\x00\x23\x00\x23\x00\x27\x00\x2a\x00\x09\x00\x23\x00\x27\x00\x27\x00\x2f\x00\x0a\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\x0a\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\x0a\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\x27\x00\x27\x00\x0d\x00\x2f\x00\x0a\x00\x2a\x00\x0a\x00\x0a\x00\x2f\x00\x2f\x00\xff\xff\x27\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\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\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\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\xff\xff\xff\xff\xff\xff\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\xd7\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\x09\x00\x0a\x00\xff\xff\xff\xff\x0d\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\xff\xff\xff\xff\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\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\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\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\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\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\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\xd7\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\x09\x00\x0a\x00\x27\x00\xff\xff\x0d\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\xff\xff\xff\xff\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\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\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\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\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\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\xd7\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\x0a\x00\xff\xff\xff\xff\x0d\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\xff\xff\xff\xff\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\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\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\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\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\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\xd7\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\x09\x00\x0a\x00\xff\xff\x2b\x00\x0d\x00\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\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\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\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\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\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\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\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\xd7\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\x28\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\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\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\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\x21\x00\xff\xff\x23\x00\x24\x00\x25\x00\x26\x00\xff\xff\xff\xff\x29\x00\x2a\x00\x2b\x00\x2e\x00\x2d\x00\x2e\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x22\x00\xff\xff\xff\xff\xff\xff\xff\xff\x27\x00\x3a\x00\xff\xff\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x22\x00\xff\xff\xff\xff\x45\x00\x21\x00\x27\x00\x23\x00\x24\x00\x25\x00\x26\x00\xff\xff\x27\x00\x29\x00\x2a\x00\x2b\x00\xff\xff\x2d\x00\x2e\x00\xff\xff\xff\xff\xff\xff\xff\xff\x58\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5c\x00\x3a\x00\x5e\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x65\x00\xff\xff\xff\xff\xff\xff\x55\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5c\x00\xff\xff\xff\xff\xff\xff\xff\xff\x55\x00\xff\xff\xff\xff\x78\x00\xff\xff\xff\xff\xff\xff\x5c\x00\xff\xff\x7c\x00\xff\xff\x7e\x00\x5c\x00\x6e\x00\x5e\x00\xff\xff\xff\xff\x72\x00\xff\xff\x74\x00\x75\x00\xff\xff\xff\xff\x78\x00\x27\x00\x6e\x00\xff\xff\xff\xff\xff\xff\x72\x00\xff\xff\x74\x00\x75\x00\xff\xff\xff\xff\x78\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7c\x00\xff\xff\x7e\x00\xff\xff\xff\xff\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\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\x27\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\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\xff\xff\xff\xff\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x27\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\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\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\x2a\x00\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\xff\xff\xff\xff\x3a\x00\xff\xff\x3c\x00\x3d\x00\x3e\x00\x3f\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\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5c\x00\xff\xff\x5e\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\xff\xff\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7c\x00\xff\xff\x7e\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\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\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\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\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\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\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\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\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\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\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\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\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\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\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\xff\xff\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\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\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\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\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\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\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\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\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\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\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\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\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\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\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\xff\xff\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\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\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\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\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\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\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\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\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\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\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\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\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\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\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\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\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\xff\xff\xff\xff\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x21\x00\xff\xff\x23\x00\x24\x00\x25\x00\x26\x00\xff\xff\xff\xff\xff\xff\x2a\x00\x2b\x00\xff\xff\x2d\x00\x2e\x00\xff\xff\xff\xff\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\xff\xff\xff\xff\x3a\x00\xff\xff\x3c\x00\x3d\x00\x3e\x00\x3f\x00\xff\xff\xff\xff\xff\xff\xff\xff\x21\x00\xff\xff\x23\x00\x24\x00\x25\x00\x26\x00\xff\xff\xff\xff\xff\xff\x2a\x00\x2b\x00\xff\xff\x2d\x00\x2e\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5c\x00\x3a\x00\x5e\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\xff\xff\xff\xff\xff\xff\xff\xff\x21\x00\xff\xff\x23\x00\x24\x00\x25\x00\x26\x00\xff\xff\xff\xff\xff\xff\x2a\x00\x2b\x00\xff\xff\x2d\x00\x2e\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7c\x00\xff\xff\x7e\x00\x5c\x00\x3a\x00\x5e\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x27\x00\xff\xff\xff\xff\xff\xff\xff\xff\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\x7c\x00\xff\xff\x7e\x00\x5c\x00\xff\xff\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\xff\xff\xff\xff\xff\xff\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\x27\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x2d\x00\xff\xff\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\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\x27\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x2d\x00\xff\xff\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\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\x22\x00\x23\x00\xff\xff\xff\xff\xff\xff\x27\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x2d\x00\xff\xff\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\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\x27\x00\xff\xff\xff\xff\xff\xff\xff\xff\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\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\x21\x00\xff\xff\x23\x00\x24\x00\x25\x00\x26\x00\xff\xff\xff\xff\xff\xff\x2a\x00\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\xff\xff\xff\xff\x3a\x00\xff\xff\x3c\x00\x3d\x00\x3e\x00\x3f\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\xff\xff\xff\xff\xff\xff\xff\xff\x45\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5c\x00\xff\xff\x5e\x00\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\x5f\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x65\x00\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x7c\x00\xff\xff\x7e\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x21\x00\x50\x00\x23\x00\x24\x00\x25\x00\x26\x00\xff\xff\xff\xff\xff\xff\x2a\x00\x2b\x00\xff\xff\x2d\x00\x2e\x00\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\xff\xff\x3a\x00\xff\xff\x3c\x00\x3d\x00\x3e\x00\x3f\x00\xff\xff\x2e\x00\x70\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\xff\xff\xff\xff\x5c\x00\xff\xff\x5e\x00\xff\xff\xff\xff\xff\xff\xff\xff\x50\x00\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\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\xff\xff\x45\x00\x7c\x00\xff\xff\x7e\x00\xff\xff\xff\xff\xff\xff\xff\xff\x70\x00\x21\x00\xff\xff\x23\x00\x24\x00\x25\x00\x26\x00\xff\xff\xff\xff\xff\xff\x2a\x00\x2b\x00\xff\xff\x2d\x00\x2e\x00\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x65\x00\xff\xff\x3a\x00\xff\xff\x3c\x00\x3d\x00\x3e\x00\x3f\x00\xff\xff\xff\xff\xff\xff\xff\xff\x21\x00\xff\xff\x23\x00\x24\x00\x25\x00\x26\x00\xff\xff\xff\xff\xff\xff\x2a\x00\x2b\x00\xff\xff\x2d\x00\x2e\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5c\x00\x3a\x00\x5e\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\xff\xff\xff\xff\xff\xff\xff\xff\x21\x00\xff\xff\x23\x00\x24\x00\x25\x00\x26\x00\xff\xff\xff\xff\xff\xff\x2a\x00\x2b\x00\xff\xff\x2d\x00\x2e\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7c\x00\xff\xff\x7e\x00\x5c\x00\x3a\x00\x5e\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\xff\xff\xff\xff\xff\xff\xff\xff\x21\x00\xff\xff\x23\x00\x24\x00\x25\x00\x26\x00\xff\xff\xff\xff\xff\xff\x2a\x00\x2b\x00\xff\xff\x2d\x00\x2e\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7c\x00\xff\xff\x7e\x00\x5c\x00\x3a\x00\x5e\x00\x3c\x00\x3d\x00\x3e\x00\x3f\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\x7c\x00\xff\xff\x7e\x00\x5c\x00\x21\x00\x5e\x00\x23\x00\x24\x00\x25\x00\x26\x00\xff\xff\xff\xff\xff\xff\x2a\x00\x2b\x00\xff\xff\x2d\x00\x2e\x00\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x3a\x00\xff\xff\x3c\x00\x3d\x00\x3e\x00\x3f\x00\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\x5c\x00\xff\xff\x5e\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0a\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\x7c\x00\xff\xff\x7e\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\xff\xff\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\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\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\xd7\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\x20\x00\x21\x00\xff\xff\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\xff\xff\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\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\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\xd7\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\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\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\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\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\xff\xff\xff\xff\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\x20\x00\x21\x00\xff\xff\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\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\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\xd7\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\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\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\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\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\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\xff\xff\xff\xff\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\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\xff\xff\x2b\x00\x2c\x00\x2d\x00\x2e\x00\xff\xff\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\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\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\xd7\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\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\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\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\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\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\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\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\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\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\xd7\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\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\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\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\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\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\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\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\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\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\xd7\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\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\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\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\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\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\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\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# - "\x80\x00\xa6\x00\xb2\x00\xbe\x00\x89\x00\x97\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\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0f\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"# + "\x7d\x00\x9f\x00\xaa\x00\xb5\x00\x85\x00\x91\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\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0f\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"# -alex_accept = listArray (0 :: Int, 199) +alex_accept = listArray (0 :: Int, 189) [ AlexAccNone , AlexAccNone , AlexAccNone @@ -142,16 +143,6 @@ alex_accept = listArray (0 :: Int, 199) , AlexAccNone , AlexAccNone , AlexAccNone - , AlexAccNone - , AlexAccNone - , AlexAccNone - , AlexAccNone - , AlexAccNone - , AlexAcc 111 - , AlexAcc 110 - , AlexAcc 109 - , AlexAcc 108 - , AlexAccPred 107 (alexPrevCharMatches(\c -> c >= '\n' && c <= '\n' || False))(AlexAcc 106) , AlexAcc 105 , AlexAcc 104 , AlexAcc 103 @@ -260,122 +251,116 @@ alex_accept = listArray (0 :: Int, 199) , AlexAcc 0 ] -alex_actions = array (0 :: Int, 112) - [ (111,alex_action_0) - , (110,alex_action_1) - , (109,alex_action_2) - , (108,alex_action_3) - , (107,alex_action_4) - , (106,alex_action_19) - , (105,alex_action_5) - , (104,alex_action_5) - , (103,alex_action_6) - , (102,alex_action_6) - , (101,alex_action_7) - , (100,alex_action_8) - , (99,alex_action_8) - , (98,alex_action_9) - , (97,alex_action_9) - , (96,alex_action_10) - , (95,alex_action_11) - , (94,alex_action_11) - , (93,alex_action_12) - , (92,alex_action_12) - , (91,alex_action_13) - , (90,alex_action_14) - , (89,alex_action_15) - , (88,alex_action_15) - , (87,alex_action_16) - , (86,alex_action_17) - , (85,alex_action_18) - , (84,alex_action_19) - , (83,alex_action_19) - , (82,alex_action_19) - , (81,alex_action_19) - , (80,alex_action_19) - , (79,alex_action_20) - , (78,alex_action_21) - , (77,alex_action_22) - , (76,alex_action_23) - , (75,alex_action_24) - , (74,alex_action_25) - , (73,alex_action_25) - , (72,alex_action_26) - , (71,alex_action_27) - , (70,alex_action_27) - , (69,alex_action_27) - , (68,alex_action_27) - , (67,alex_action_28) - , (66,alex_action_29) - , (65,alex_action_30) - , (64,alex_action_31) - , (63,alex_action_32) - , (62,alex_action_33) - , (61,alex_action_33) - , (60,alex_action_33) - , (59,alex_action_33) - , (58,alex_action_33) - , (57,alex_action_33) - , (56,alex_action_33) - , (55,alex_action_33) - , (54,alex_action_33) - , (53,alex_action_33) - , (52,alex_action_33) - , (51,alex_action_34) - , (50,alex_action_35) - , (49,alex_action_36) - , (48,alex_action_37) - , (47,alex_action_37) - , (46,alex_action_37) - , (45,alex_action_37) - , (44,alex_action_37) - , (43,alex_action_37) - , (42,alex_action_37) - , (41,alex_action_37) - , (40,alex_action_37) - , (39,alex_action_37) - , (38,alex_action_38) - , (37,alex_action_39) - , (36,alex_action_40) - , (35,alex_action_41) - , (34,alex_action_41) - , (33,alex_action_42) - , (32,alex_action_42) - , (31,alex_action_42) - , (30,alex_action_42) - , (29,alex_action_42) - , (28,alex_action_42) - , (27,alex_action_42) - , (26,alex_action_42) - , (25,alex_action_42) - , (24,alex_action_42) - , (23,alex_action_43) - , (22,alex_action_44) - , (21,alex_action_45) - , (20,alex_action_45) - , (19,alex_action_45) - , (18,alex_action_45) - , (17,alex_action_45) - , (16,alex_action_45) - , (15,alex_action_45) - , (14,alex_action_45) - , (13,alex_action_45) - , (12,alex_action_45) - , (11,alex_action_46) - , (10,alex_action_47) - , (9,alex_action_48) - , (8,alex_action_48) - , (7,alex_action_48) - , (6,alex_action_48) - , (5,alex_action_48) - , (4,alex_action_48) - , (3,alex_action_48) - , (2,alex_action_48) - , (1,alex_action_48) - , (0,alex_action_48) +alex_actions = array (0 :: Int, 106) + [ (105,alex_action_0) + , (104,alex_action_1) + , (103,alex_action_2) + , (102,alex_action_3) + , (101,alex_action_4) + , (100,alex_action_5) + , (99,alex_action_5) + , (98,alex_action_6) + , (97,alex_action_6) + , (96,alex_action_7) + , (95,alex_action_8) + , (94,alex_action_8) + , (93,alex_action_8) + , (92,alex_action_9) + , (91,alex_action_9) + , (90,alex_action_10) + , (89,alex_action_11) + , (88,alex_action_11) + , (87,alex_action_12) + , (86,alex_action_12) + , (85,alex_action_13) + , (84,alex_action_13) + , (83,alex_action_14) + , (82,alex_action_14) + , (81,alex_action_14) + , (80,alex_action_15) + , (79,alex_action_16) + , (78,alex_action_17) + , (77,alex_action_18) + , (76,alex_action_18) + , (75,alex_action_18) + , (74,alex_action_18) + , (73,alex_action_18) + , (72,alex_action_19) + , (71,alex_action_20) + , (70,alex_action_21) + , (69,alex_action_22) + , (68,alex_action_23) + , (67,alex_action_24) + , (66,alex_action_24) + , (65,alex_action_25) + , (64,alex_action_26) + , (63,alex_action_26) + , (62,alex_action_26) + , (61,alex_action_27) + , (60,alex_action_28) + , (59,alex_action_29) + , (58,alex_action_30) + , (57,alex_action_31) + , (56,alex_action_32) + , (55,alex_action_32) + , (54,alex_action_32) + , (53,alex_action_32) + , (52,alex_action_32) + , (51,alex_action_32) + , (50,alex_action_32) + , (49,alex_action_32) + , (48,alex_action_32) + , (47,alex_action_32) + , (46,alex_action_33) + , (45,alex_action_34) + , (44,alex_action_35) + , (43,alex_action_35) + , (42,alex_action_35) + , (41,alex_action_35) + , (40,alex_action_35) + , (39,alex_action_35) + , (38,alex_action_35) + , (37,alex_action_35) + , (36,alex_action_35) + , (35,alex_action_36) + , (34,alex_action_37) + , (33,alex_action_38) + , (32,alex_action_39) + , (31,alex_action_39) + , (30,alex_action_40) + , (29,alex_action_40) + , (28,alex_action_40) + , (27,alex_action_40) + , (26,alex_action_40) + , (25,alex_action_40) + , (24,alex_action_40) + , (23,alex_action_40) + , (22,alex_action_40) + , (21,alex_action_41) + , (20,alex_action_42) + , (19,alex_action_43) + , (18,alex_action_43) + , (17,alex_action_43) + , (16,alex_action_43) + , (15,alex_action_43) + , (14,alex_action_43) + , (13,alex_action_43) + , (12,alex_action_43) + , (11,alex_action_43) + , (10,alex_action_44) + , (9,alex_action_45) + , (8,alex_action_46) + , (7,alex_action_46) + , (6,alex_action_46) + , (5,alex_action_46) + , (4,alex_action_46) + , (3,alex_action_46) + , (2,alex_action_46) + , (1,alex_action_46) + , (0,alex_action_46) ] -{-# LINE 203 "src/Syntax/Lexer.x" #-} +{-# LINE 216 "src/Syntax/Lexer.x" #-} ----------------------------------------------------------- -- helpers @@ -414,6 +399,11 @@ fromHexEsc :: String -> Char fromHexEsc s = toEnum $ digitsToNum 16 s +startsWith :: String -> String -> Bool +startsWith s [] = True +startsWith [] _ = False +startsWith (c:cs) (p:ps) = if (p==c) then startsWith cs ps else False + ----------------------------------------------------------- -- Reserved ----------------------------------------------------------- @@ -433,26 +423,26 @@ reservedNames , "type", "alias" , "struct", "enum", "con" , "val", "fun", "fn", "extern", "var" - , "control", "rcontrol", "except" + , "ctl", "final", "raw" , "if", "then", "else", "elif" , "return", "match", "with", "in" , "forall", "exists", "some" - , "private", "public", "abstract" + , "pub", "abstract" , "module", "import", "as" - -- alternatives - , "pub" - -- effect handlers , "handler", "handle" , "effect", "receffect" , "named" , "mask" - , "override" - , "unsafe" -- future + , "override" -- deprecated + , "private", "public" -- use pub + , "rawctl", "brk" -- use raw ctl, and final ctl + -- alternative names for backwards paper compatability + , "control", "rcontrol", "except" , "ambient", "context" -- use effcet , "inject" -- use mask , "use", "using" -- use with instead @@ -468,6 +458,7 @@ reservedNames , "." , ":" , "->" + , "<-" , ":=" , "|" ] @@ -557,6 +548,7 @@ data State = State { pos :: !Pos -- current position , previous :: !Char , current :: !BString , previousLex :: Lex + , rawEnd :: String } type Action = BString -> State -> State -> (Maybe Lex, State) @@ -604,6 +596,16 @@ withmore action = \bs st0 st1 -> action (B.concat (reverse (bs : retained st1))) st0 st1{ retained = [] } +rawdelim :: Action -> Action +rawdelim action + = \bs st0 st1 -> let s = bstringToString bs + delim = "\"" ++ replicate (length s - 2) '#' + in -- trace ("raw delim: " ++ show delim) $ + action bs st0 st1{ rawEnd = delim } + +withRawDelim :: (String -> String -> Action) -> Action +withRawDelim f + = \bs st0 st1 -> (f (bstringToString bs) (rawEnd st1)) bs st0 st1 constant x = token (\_ -> x) @@ -637,10 +639,10 @@ lexer sourceName lineNo input lexing :: Source -> Int -> BString -> [Lexeme] lexing source lineNo input = let initPos = makePos source 0 lineNo 1 - initSt = State initPos initPos [0] [] '\n' input (LexWhite "") + initSt = State initPos initPos [0] [] '\n' input (LexWhite "") "\"" in go initSt where go st = - -- trace ("scan: " ++ show (pos st) ++ ": <" ++ show (head (states st)) ++ ">: " ++ show (BC.take 5 (current st))) $ + -- trace ("scan: start: " ++ show (startPos st) ++ ", " ++ show (pos st) ++ ": <" ++ show (head (states st)) ++ ">: " ++ show (BC.take 5 (current st))) $ let idx0 = B.length (current st) in case alexScan st (head (states st)) of AlexEOF -> [] @@ -661,7 +663,7 @@ lexing source lineNo input Nothing -> go st2 -- more Just token -> let range = makeRange (startPos st) (before (pos st2)) ltoken = lparen token (previousLex st1) - in -- trace ("result: " ++ showFullRange range ++ ": " ++ show ltoken) $ + in -- trace ("token: " ++ showFullRange range ++ ": " ++ show ltoken) $ seq range $ Lexeme range ltoken : go st2{ startPos = pos st2, previousLex = ltoken } lparen token prev @@ -710,48 +712,56 @@ alex_action_8 = string $ \s -> if isReserved s alex_action_9 = string $ LexCons . newName alex_action_10 = string $ LexWildCard . newName alex_action_11 = string $ LexSpecial -alex_action_12 = string $ \s -> LexFloat (read s) s -alex_action_13 = string $ \s -> LexFloat (parseHexFloat s) s -alex_action_14 = string $ \s -> LexInt (parseNum s) s -alex_action_15 = string $ \s -> LexInt (parseNum s) s -alex_action_16 = string $ LexOp . newName -alex_action_17 = less 1 $ string $ \s -> if (s=="|") then LexKeyword s "" else LexOp (newName s) -alex_action_18 = string $ LexIdOp . newName . stripParens -alex_action_19 = string $ \s -> if isReserved s +alex_action_12 = string $ \s -> LexFloat (read (filter (/='_') s)) s +alex_action_13 = string $ \s -> LexFloat (parseHexFloat (filter (/='_') s)) s +alex_action_14 = string $ \s -> LexInt (parseNum (filter (/='_') s)) s +alex_action_15 = string $ LexOp . newName +alex_action_16 = less 1 $ string $ \s -> if (s=="|") then LexKeyword s "" else LexOp (newName s) +alex_action_17 = string $ LexIdOp . newName . stripParens +alex_action_18 = string $ \s -> if isReserved s then LexKeyword s "" else if isPrefixOp s then LexPrefix (newName s) else LexOp (newName s) -alex_action_20 = next stringlit $ more (const B.empty) -alex_action_21 = next stringraw $ more (const B.empty) -alex_action_22 = string $ LexChar . fromCharEsc . head . drop 2 -alex_action_23 = string $ LexChar . fromHexEsc . init . drop 3 -alex_action_24 = string $ LexChar . head . tail -alex_action_25 = string $ \s -> LexError ("illegal character literal: " ++ show (head (tail s))) -alex_action_26 = string $ \s -> LexError ("tab characters: configure your editor to use spaces instead (soft tab)") -alex_action_27 = string $ \s -> LexError ("illegal character: " ++ show s ++ (if (s=="\t") then " (replace tabs with spaces)" else "")) -alex_action_28 = more id -alex_action_29 = more fromCharEscB -alex_action_30 = more fromHexEscB -alex_action_31 = pop $ \_ -> withmore (string LexString . B.init) -alex_action_32 = pop $ \_ -> constant (LexError "string literal ended by a new line") -alex_action_33 = string $ \s -> LexError ("illegal character in string: " ++ show s) -alex_action_34 = more id -alex_action_35 = more B.tail -alex_action_36 = pop $ \_ -> withmore (string LexString . B.init) -alex_action_37 = string $ \s -> LexError ("illegal character in raw string: " ++ show s) -alex_action_38 = pop $ \state -> if state==comment then more id +alex_action_19 = next stringlit $ more (const B.empty) +alex_action_20 = next stringraw $ rawdelim $ more (const B.empty) +alex_action_21 = string $ LexChar . fromCharEsc . head . drop 2 +alex_action_22 = string $ LexChar . fromHexEsc . init . drop 3 +alex_action_23 = string $ LexChar . head . tail +alex_action_24 = string $ \s -> LexError ("illegal character literal: " ++ show (head (tail s))) +alex_action_25 = string $ \s -> LexError ("tab characters: configure your editor to use spaces instead (soft tab)") +alex_action_26 = string $ \s -> LexError ("illegal character: " ++ show s ++ (if (s=="\t") then " (replace tabs with spaces)" else "")) +alex_action_27 = more id +alex_action_28 = more fromCharEscB +alex_action_29 = more fromHexEscB +alex_action_30 = pop $ \_ -> withmore (string LexString . B.init) +alex_action_31 = pop $ \_ -> constant (LexError "string literal ended by a new line") +alex_action_32 = string $ \s -> LexError ("illegal character in string: " ++ show s) +alex_action_33 = more id +alex_action_34 = withRawDelim $ \s delim -> + if (s == delim) + then -- done + pop $ \_ -> less (length delim) $ withmore $ + string (LexString . reverse . drop (length delim) . reverse) + else if (length s > length delim) + then -- too many terminating hashse + string $ \s -> LexError ("raw string: too many '#' terminators in raw string (expecting " ++ show (length delim - 1) ++ ")") + else -- continue + more id + +alex_action_35 = string $ \s -> LexError ("illegal character in raw string: " ++ show s) +alex_action_36 = pop $ \state -> if state==comment then more id else withmore (string $ LexComment . filter (/='\r')) -alex_action_39 = push $ more id -alex_action_40 = more id +alex_action_37 = push $ more id +alex_action_38 = more id +alex_action_39 = more id +alex_action_40 = string $ \s -> LexError ("illegal character in comment: " ++ show s) alex_action_41 = more id -alex_action_42 = string $ \s -> LexError ("illegal character in comment: " ++ show s) -alex_action_43 = more id -alex_action_44 = pop $ \_ -> withmore (string $ LexComment . filter (/='\r')) -alex_action_45 = string $ \s -> LexError ("illegal character in line comment: " ++ show s) -alex_action_46 = more id -alex_action_47 = pop $ \_ -> withmore (string $ LexComment . filter (/='\r')) -alex_action_48 = string $ \s -> LexError ("illegal character in line directive: " ++ show s) +alex_action_42 = pop $ \_ -> withmore (string $ LexComment . filter (/='\r')) +alex_action_43 = string $ \s -> LexError ("illegal character in line comment: " ++ show s) +alex_action_44 = more id +alex_action_45 = pop $ \_ -> withmore (string $ LexComment . filter (/='\r')) +alex_action_46 = string $ \s -> LexError ("illegal character in line directive: " ++ show s) {-# LINE 1 "templates/GenericTemplate.hs" #-} -- ----------------------------------------------------------------------------- -- ALEX TEMPLATE @@ -778,6 +788,7 @@ alex_action_48 = string $ \s -> LexError ("illegal character in line directive: + -- Do not remove this comment. Required to fix CPP parsing when using GCC and a clang-compiled alex. #if __GLASGOW_HASKELL__ > 706 #define GTE(n,m) (tagToEnum# (n >=# m)) @@ -812,6 +823,7 @@ uncheckedShiftL# = shiftL# #endif {-# INLINE alexIndexInt16OffAddr #-} +alexIndexInt16OffAddr :: AlexAddr -> Int# -> Int# alexIndexInt16OffAddr (AlexA# arr) off = #ifdef WORDS_BIGENDIAN narrow16Int# i @@ -821,7 +833,10 @@ alexIndexInt16OffAddr (AlexA# arr) off = low = int2Word# (ord# (indexCharOffAddr# arr off')) off' = off *# 2# #else - indexInt16OffAddr# arr off +#if __GLASGOW_HASKELL__ >= 901 + int16ToInt# +#endif + (indexInt16OffAddr# arr off) #endif @@ -829,6 +844,7 @@ alexIndexInt16OffAddr (AlexA# arr) off = {-# INLINE alexIndexInt32OffAddr #-} +alexIndexInt32OffAddr :: AlexAddr -> Int# -> Int# alexIndexInt32OffAddr (AlexA# arr) off = #ifdef WORDS_BIGENDIAN narrow32Int# i @@ -842,7 +858,10 @@ alexIndexInt32OffAddr (AlexA# arr) off = b0 = int2Word# (ord# (indexCharOffAddr# arr off')) off' = off *# 4# #else - indexInt32OffAddr# arr off +#if __GLASGOW_HASKELL__ >= 901 + int32ToInt# +#endif + (indexInt32OffAddr# arr off) #endif @@ -939,16 +958,16 @@ alex_scan_tkn user__ orig_input len input__ s 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)) - | otherwise - = check_accs rest - check_accs (AlexAccSkipPred predx rest) - | predx user__ orig_input (I# (len)) input__ - = AlexLastSkip input__ (I# (len)) - | otherwise - = check_accs rest + + + + + + + + + + data AlexLastAcc @@ -961,31 +980,31 @@ data AlexAcc user | AlexAcc Int | AlexAccSkip - | AlexAccPred Int (AlexAccPred user) (AlexAcc user) - | AlexAccSkipPred (AlexAccPred user) (AlexAcc 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__ -alexPrevCharMatches f _ input__ _ _ = f (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. + + + + + + + + + + + + + + + + + + + + diff --git a/src/Syntax/Lexer.x b/src/Syntax/Lexer.x index 380d1ce59..38d2bfdf6 100644 --- a/src/Syntax/Lexer.x +++ b/src/Syntax/Lexer.x @@ -11,6 +11,7 @@ module Syntax.Lexer( lexing, lexer , module Syntax.Lexeme , readInput, extractLiterate + , reservedNames ) where import Lib.Trace diff --git a/src/Syntax/Parse.hs b/src/Syntax/Parse.hs index 215530c55..6aac5cf79 100644 --- a/src/Syntax/Parse.hs +++ b/src/Syntax/Parse.hs @@ -9,14 +9,14 @@ Parse concrete syntax. -} ----------------------------------------------------------------------------- -module Syntax.Parse( parseProgramFromFile +module Syntax.Parse( parseProgramFromFile, parseProgramFromString , parseValueDef , parseTypeDef , parseExpression , parseType -- used by the core parser - , lexParse, parseLex, LexParser, parseLexemes, parseInline + , lexParse, parseLex, LexParser, parseLexemes, parseInline, ignoreSyntaxWarnings , visibility, modulepath, importAlias, parseFip , tbinderId, constructorId, funid, paramid @@ -44,6 +44,7 @@ import Text.Parsec hiding (space,tab,lower,upper,alphaNum,sourceName,optional) import Text.Parsec.Error import Text.Parsec.Pos (newPos) +import Common.Error as Err import Common.Name import Common.NamePrim import Common.Range hiding (after) @@ -60,12 +61,13 @@ import Syntax.Lexeme import Syntax.Lexer ( lexing ) import Syntax.Layout ( layout ) import Syntax.Promote ( promote, promoteType, quantify, promoteFree ) +import Common.ColorScheme (defaultColorScheme) ----------------------------------------------------------- -- Parser on token stream ----------------------------------------------------------- -type LexParser a = Parsec [Lexeme] () a -- GenParser Lexeme () a +type LexParser a = Parsec [Lexeme] [(String, Range)] a -- GenParser Lexeme () a parseLex :: Lex -> LexParser Lexeme parseLex lex @@ -82,50 +84,81 @@ optional p = do { p; return True } <|> return False ----------------------------------------------------------- -- Parse varieties ----------------------------------------------------------- -parseProgramFromFile :: Bool -> FilePath -> IO (Error UserProgram) +parseProgramFromFile :: Bool -> FilePath -> IO (Error a UserProgram) parseProgramFromFile semiInsert fname = do input <- readInput fname - return (lexParse semiInsert id program fname 1 input) - - -parseValueDef :: Bool -> FilePath -> Int -> String -> Error UserDef + let result = parseProgramFromString semiInsert input fname + case checkError result of + Right (a, warnings) -> + do + logSyntaxWarnings warnings + return result + Left err -> return result + +logSyntaxWarnings :: [(Range, Doc)] -> IO () +logSyntaxWarnings warnings + = putPretty (prettyWarnings True defaultColorScheme warnings) + +parseProgramFromString :: Bool -> BString -> FilePath -> Error a UserProgram +parseProgramFromString semiInsert input fname + = do (result, syntaxWarnings) <- lexParse semiInsert id program fname 1 input + addWarnings (map (\(s, r) -> (r, text s)) syntaxWarnings) $ return result + +parseValueDef :: Bool -> FilePath -> Int -> String -> Error () UserDef parseValueDef semiInsert sourceName line input = lexParseS semiInsert (const valueDefinition) sourceName line input -parseTypeDef :: Bool -> FilePath -> Int -> String -> Error (UserTypeDef,[UserDef]) +parseTypeDef :: Bool -> FilePath -> Int -> String -> Error () (UserTypeDef,[UserDef]) parseTypeDef semiInsert sourceName line input = lexParseS semiInsert (const typeDefinition) sourceName line input -parseType :: Bool -> FilePath -> Int -> Name -> String -> Error UserTypeDef +parseType :: Bool -> FilePath -> Int -> Name -> String -> Error () UserTypeDef parseType semiInsert sourceName line name input = lexParseS semiInsert (const (userType name)) sourceName line input -parseExpression :: Bool -> FilePath -> Int -> Name -> String -> Error UserDef +parseExpression :: Bool -> FilePath -> Int -> Name -> String -> Error () UserDef parseExpression semiInsert sourceName line name input = lexParseS semiInsert (const (expression name)) sourceName line input -lexParseS semiInsert p sourceName line str - = lexParse semiInsert id p sourceName line (stringToBString str) +ignoreSyntaxWarnings :: Error b (a, [(String, Range)]) -> Error b a +ignoreSyntaxWarnings result = + do (x, syntaxWarnings) <- result + return x -lexParse :: Bool -> ([Lexeme]-> [Lexeme]) -> (Source -> LexParser a) -> FilePath -> Int -> BString -> Error a +lexParseS :: Bool -> (Source -> LexParser b) -> FilePath -> Int -> String -> Error a b +lexParseS semiInsert p sourceName line str + = do + (result, syntaxWarnings) <- (lexParse semiInsert id p sourceName line (stringToBString str)) + return $ trace (concat (intersperse "\n" (map fst syntaxWarnings))) $ result + +runStateParser :: LexParser a -> SourceName -> [Lexeme] -> Either ParseError (a, [(String, Range)]) +runStateParser p sourceName lex = + runParser (pp p) [] sourceName lex + where + pp p = + do r <- p + s <- getState + return (r, s) + +lexParse :: Bool -> ([Lexeme]-> [Lexeme]) -> (Source -> LexParser a) -> FilePath -> Int -> BString -> Error b (a, [(String, Range)]) lexParse semiInsert preprocess p sourceName line rawinput = let source = Source sourceName rawinput input = if (isLiteralDoc sourceName) then extractLiterate rawinput else rawinput xs = lexing source line input lexemes = preprocess $ layout semiInsert xs in -- trace (unlines (map show lexemes)) $ - case (parse (p source) sourceName lexemes) of + case (runStateParser (p source) sourceName lexemes) of Left err -> makeParseError (errorRangeLexeme xs source) err Right x -> return x -parseLexemes :: LexParser a -> Source -> [Lexeme] -> Error a +parseLexemes :: LexParser a -> Source -> [Lexeme] -> Error () (a, [(String, Range)]) parseLexemes p source@(Source sourceName _) lexemes - = case (parse p sourceName lexemes) of + = case (runStateParser p sourceName lexemes) of Left err -> makeParseError (errorRangeLexeme lexemes source) err Right x -> return x -makeParseError :: (ParseError -> Range) -> ParseError -> Error a +makeParseError :: (ParseError -> Range) -> ParseError -> Error b a makeParseError toRange perr = errorMsg (ErrorParse (toRange perr) errorDoc) where @@ -296,7 +329,7 @@ visibility vis = do rng <- keywordOr "pub" ["public"] return (Public,rng) <|> do rng <- keyword "private" - pwarningMessage "using 'private' is deprecated, only use 'pub' to make declarations public" + pwarningMessage "using 'private' is deprecated, only use 'pub' to make declarations public" rng return (Private,rng) <|> return (vis,rangeNull) @@ -318,7 +351,7 @@ externDecl dvis <|> try ( do (krng,_) <- dockeyword "extern" specialId "include" - warnDeprecated "include" "import" + warnDeprecated "include" "import" krng return (Left (externalImport krng))) <|> try ( do (vis,vrng) <- visibility dvis @@ -1182,9 +1215,9 @@ parseFip = do isTail <- do specialId "tail" return True <|> return False - ( do specialId "fip" + ( do rng <- specialId "fip" alloc <- parseFipAlloc - when isTail $ pwarningMessage "a 'fip' function implies already 'tail'" + when isTail $ pwarningMessage "a 'fip' function implies already 'tail'" rng return (Fip alloc) <|> do specialId "fbip" @@ -1528,13 +1561,13 @@ lambda alts return (ann fun) ifexpr - = do rng <- keyword "if" + = do rng <- do keyword "if" tst <- ntlexpr (texpr,eexprs,eexpr) <- do texpr <- returnexpr return (texpr, [], Var nameUnit False (after (getRange texpr))) <|> - do texpr <- thenexpr + do texpr <- thenexpr rng eexprs <- many elif eexpr <- do keyword "else" blockexpr @@ -1554,18 +1587,18 @@ ifexpr return fullMatch where elif - = do keyword "elif" + = do rng <- keyword "elif" tst <- ntlexpr -- parens expr - texpr <- thenexpr + texpr <- thenexpr rng return (tst,texpr) - thenexpr + thenexpr rng = do keyword "then" blockexpr <|> do pos <- getPosition expr <- blockexpr - pwarning $ "warning " ++ show pos ++ ": using an 'if' without 'then' is deprecated.\n hint: add the 'then' keyword." + pwarning ("warning " ++ show pos ++ ": using an 'if' without 'then' is deprecated.\n hint: add the 'then' keyword.") rng return expr returnexpr @@ -1730,7 +1763,7 @@ handlerOp :: LexParser (Clause, Maybe (UserExpr -> UserExpr)) handlerOp = do rng <- keyword "return" (name,prng,tp) <- do (name,prng) <- paramid - pwarningMessage "'return x' is deprecated; use 'return(x)' instead." + pwarningMessage "'return x' is deprecated; use 'return(x)' instead." prng tp <- optionMaybe typeAnnotPar return (name,prng,tp) <|> @@ -1772,9 +1805,11 @@ handlerOp <|> -- deprecated do lookAhead qidentifier - pwarningMessage "using a bare operation is deprecated.\n hint: start with 'val', 'fun', 'brk', or 'ctl' instead." - return OpControl + return OpControlErr (name, nameRng) <- qidentifier + if opSort == OpControlErr then + pwarningMessage "using a bare operation is deprecated.\n hint: start with 'val', 'fun', 'brk', or 'ctl' instead." nameRng + else return () (oppars,prng) <- opParams expr <- bodyexpr let rexpr = expr -- if (resumeKind /= ResumeTail) then expr else resumeCall expr pars nameRng @@ -1824,7 +1859,7 @@ guards return [Guard guardTrue exp] <|> do exp <- block - pwarningMessage "use '->' for pattern matches" + pwarningMessage "use '->' for pattern matches" (getRange exp) return [Guard guardTrue exp] guardBar @@ -2841,7 +2876,7 @@ specialIdOr kw deprecated = choice (specialId kw : map deprecate deprecated) where deprecate k = do rng <- specialId k - warnDeprecated k kw + warnDeprecated k kw rng return rng @@ -2851,7 +2886,7 @@ keywordOr kw deprecated = choice (keyword kw : map deprecate deprecated) where deprecate k = do rng <- keyword k - warnDeprecated k kw + warnDeprecated k kw rng return rng dockeywordOr :: String -> [String] -> LexParser (Range,String) @@ -2860,7 +2895,7 @@ dockeywordOr kw deprecated = choice (dockeyword kw : map deprecate deprecated) where deprecate k = do x <- dockeyword k - warnDeprecated k kw + warnDeprecated k kw (fst x) return x @@ -2877,18 +2912,17 @@ dockeyword s show s -warnDeprecated dep new +warnDeprecated dep new rng = do pos <- getPosition - pwarning $ "warning " ++ show pos ++ ": keyword \"" ++ dep ++ "\" is deprecated. Consider using \"" ++ new ++ "\" instead." + pwarning ("warning " ++ show pos ++ ": keyword \"" ++ dep ++ "\" is deprecated. Consider using \"" ++ new ++ "\" instead.") rng -pwarningMessage msg +pwarningMessage msg rng = do pos <- getPosition - pwarning $ "warning " ++ show pos ++ ": " ++ msg - -pwarning :: String -> LexParser () -pwarning msg = traceM msg + pwarning ("warning " ++ show pos ++ ": " ++ msg) rng +pwarning :: String -> Range -> LexParser () +pwarning msg rng = modifyState (\prev -> prev ++ [(msg, rng)]) uniqueRngHiddenName :: Range -> String -> Name diff --git a/src/Syntax/RangeMap.hs b/src/Syntax/RangeMap.hs index d1b259200..b85c1f936 100644 --- a/src/Syntax/RangeMap.hs +++ b/src/Syntax/RangeMap.hs @@ -10,7 +10,10 @@ module Syntax.RangeMap( RangeMap, RangeInfo(..), NameInfo(..) , rangeMapInsert , rangeMapSort , rangeMapLookup + , rangeMapFindAt + , rangeMapFindIn , rangeMapAppend + , rangeInfoType , mangle , mangleConName , mangleTypeName @@ -19,7 +22,7 @@ module Syntax.RangeMap( RangeMap, RangeInfo(..), NameInfo(..) -- import Lib.Trace import Data.Char ( isSpace ) import Common.Failure -import Data.List (sortBy, groupBy) +import Data.List (sortBy, groupBy, minimumBy, foldl') import Lib.PPrint import Common.Range import Common.Name @@ -29,8 +32,10 @@ import Type.Type import Kind.Kind import Type.TypeVar import Type.Pretty() +import Data.Maybe (fromMaybe) newtype RangeMap = RM [(Range,RangeInfo)] + deriving Show mangleConName :: Name -> Name mangleConName name @@ -61,7 +66,7 @@ data RangeInfo | Id Name NameInfo Bool -- qualified name, info, is the definition data NameInfo - = NIValue Type + = NIValue Type Bool -- Has annotated type already | NICon Type | NITypeCon Kind | NITypeVar Kind @@ -98,7 +103,7 @@ penalty name instance Enum NameInfo where fromEnum ni = case ni of - NIValue _ -> 1 + NIValue _ _ -> 1 NICon _ -> 2 NITypeCon _ -> 3 NITypeVar _ -> 4 @@ -161,6 +166,39 @@ rangeMapLookup r (RM rm) eq (_,ri1) (_,ri2) = (EQ == compare ((fromEnum ri1) `div` 10) ((fromEnum ri2) `div` 10)) cmp (_,ri1) (_,ri2) = compare (fromEnum ri1) (fromEnum ri2) +rangeMapFindIn :: Range -> RangeMap -> [(Range, RangeInfo)] +rangeMapFindIn rng (RM rm) + = filter (\(rng, info) -> rangeStart rng >= start || rangeEnd rng <= end) rm + where start = rangeStart rng + end = rangeEnd rng + +rangeMapFindAt :: Pos -> RangeMap -> Maybe [(Range, RangeInfo)] +rangeMapFindAt pos (RM rm) + = shortestRange $ filter (containsPos . fst) rm + where + containsPos rng = rangeStart rng <= pos && rangeEnd rng >= pos + shortestRange [] = Nothing + shortestRange rs = Just $ minimumByList cmp rs + cmp (r1,_) (r2,_) = compare (rangeLength r1) (rangeLength r2) + +minimumByList :: Foldable t => (a -> a -> Ordering) -> t a -> [a] +minimumByList cmp la = fromMaybe [] (foldl' min' Nothing la) + where + min' mx y = Just $! case mx of + Nothing -> [y] + Just (x:xs) -> case cmp x y of + GT -> [y] + EQ -> y:x:xs + _ -> x:xs + +rangeInfoType :: RangeInfo -> Maybe Type +rangeInfoType ri + = case ri of + Id _ info _ -> case info of + NIValue tp _ -> Just tp + NICon tp -> Just tp + _ -> Nothing + _ -> Nothing instance HasTypeVar RangeMap where sub `substitute` (RM rm) @@ -185,18 +223,18 @@ instance HasTypeVar RangeInfo where instance HasTypeVar NameInfo where sub `substitute` ni = case ni of - NIValue tp -> NIValue (sub `substitute` tp) + NIValue tp annotated -> NIValue (sub `substitute` tp) annotated NICon tp -> NICon (sub `substitute` tp) _ -> ni ftv ni = case ni of - NIValue tp -> ftv tp + NIValue tp _ -> ftv tp NICon tp -> ftv tp _ -> tvsEmpty btv ni = case ni of - NIValue tp -> btv tp + NIValue tp _ -> btv tp NICon tp -> btv tp _ -> tvsEmpty diff --git a/src/Syntax/Syntax.hs b/src/Syntax/Syntax.hs index f7e8fc1d6..709f5d458 100644 --- a/src/Syntax/Syntax.hs +++ b/src/Syntax/Syntax.hs @@ -284,6 +284,13 @@ data Lit | LitString String Range deriving (Show) +litRange :: Lit -> Range +litRange lit + = case lit of + LitInt _ range -> range + LitFloat _ range -> range + LitChar _ range -> range + LitString _ range -> range stripExpr :: Expr t -> Expr t stripExpr (Parens e _ _) = stripExpr e diff --git a/src/Type/Infer.hs b/src/Type/Infer.hs index c1ce327e3..a909ccde5 100644 --- a/src/Type/Infer.hs +++ b/src/Type/Infer.hs @@ -82,7 +82,7 @@ traceDoc fdoc = do penv <- getPrettyEnv Infer Types --------------------------------------------------------------------------} inferTypes :: Env -> Maybe RM.RangeMap -> Synonyms -> Newtypes -> Constructors -> ImportMap -> Gamma -> Name -> DefGroups Type - -> Core.CorePhase (Gamma, Core.DefGroups, Maybe RM.RangeMap ) + -> Core.CorePhase b (Gamma, Core.DefGroups, Maybe RM.RangeMap ) inferTypes prettyEnv mbRangeMap syns newTypes cons imports gamma0 context defs = -- error "Type.Infer.inferTypes: not yet implemented" -- return (gamma0,[],uniq0) @@ -273,7 +273,7 @@ addRangeInfoCoreDef topLevel mod def coreDef = let qname = if (topLevel && not (isQualified (Core.defName coreDef))) then qualify mod (Core.defName coreDef) else Core.defName coreDef - in do addRangeInfo (Core.defNameRange coreDef) (RM.Id qname (RM.NIValue (Core.defType coreDef)) True) + in do addRangeInfo (Core.defNameRange coreDef) (RM.Id qname (RM.NIValue (Core.defType coreDef) True) True) addRangeInfo (defRange def) (RM.Decl (if defIsVal def then "val" else "fun") qname (RM.mangle qname (Core.defType coreDef))) @@ -460,6 +460,10 @@ inferDef expect (Def (ValueBinder name mbTp expr nameRng vrng) rng vis sort inl else return () subst (Core.Def name resTp resCore vis sort inl nameRng doc) -- must 'subst' since the total unification can cause substitution. (see test/type/hr1a) +isAnnotatedBinder :: ValueBinder (Maybe Type) x -> Bool +isAnnotatedBinder (ValueBinder _ Just{} _ _ _) = True +isAnnotatedBinder _ = False + inferBindDef :: Def Type -> Inf (Effect,Core.Def) inferBindDef (Def (ValueBinder name () expr nameRng vrng) rng vis sort inl doc) = -- trace ("infer bind def: " ++ show name ++ ", var?:" ++ show (sort==DefVar)) $ @@ -478,7 +482,7 @@ inferBindDef (Def (ValueBinder name () expr nameRng vrng) rng vis sort inl doc) return (Core.Def name refTp refExpr vis sort inl nameRng doc) if (not (isWildcard name)) - then addRangeInfo nameRng (RM.Id name (RM.NIValue (Core.defType coreDef)) True) + then addRangeInfo nameRng (RM.Id name (RM.NIValue (Core.defType coreDef) (isAnnot expr)) True) else if (isTypeUnit (Core.typeOf coreDef)) then return () else do seff <- subst eff @@ -608,7 +612,7 @@ inferExpr propagated expect (Lam binders body rng) else let b = head polyBinders in typeError (rng) (binderNameRange b) (text "unannotated parameters cannot be polymorphic") (binderType b) [(text "hint",text "annotate the parameter with a polymorphic type")] - mapM_ (\(binder,tp) -> addRangeInfo (binderNameRange binder) (RM.Id (binderName binder) (RM.NIValue tp) True)) (zip binders1 parTypes2) + mapM_ (\(arg,binder,tp) -> addRangeInfo (binderNameRange binder) (RM.Id (binderName binder) (RM.NIValue tp (case arg of {Just s -> True; Nothing -> False})) True)) (zip3 propArgs binders1 parTypes2) eff <- freshEffect return (ftp, eff, fcore ) @@ -640,7 +644,7 @@ inferExpr propagated expect (App (Var name _ nameRng) [(_,expr)] rng) | name == -> do inferUnify (checkReturn rng) (getRange expr) retTp tp resTp <- Op.freshTVar kindStar Meta let typeReturn = typeFun [(nameNil,tp)] typeTotal resTp - addRangeInfo nameRng (RM.Id (newName "return") (RM.NIValue tp) False) + addRangeInfo nameRng (RM.Id (newName "return") (RM.NIValue tp True) False) return (resTp, eff, Core.App (Core.Var (Core.TName nameReturn typeReturn) (Core.InfoExternal [(Default,"return #1")])) [core]) -- | Assign expression @@ -907,7 +911,7 @@ inferExpr propagated expect (Lit lit) inferExpr propagated expect (Parens expr name rng) = do (tp,eff,core) <- inferExpr propagated expect expr if (name /= nameNil) - then do addRangeInfo rng (RM.Id name (RM.NIValue tp) True) + then do addRangeInfo rng (RM.Id name (RM.NIValue tp True) True) else return () return (tp,eff,core) @@ -1022,6 +1026,7 @@ inferHandler propagated expect handlerSort handlerScoped allowMask OpControlRaw -> let eff0 = effectExtend heff eff resumeContextTp = typeResumeContext resumeArg eff eff0 res in (nameClause "control-raw" (length pars), pars ++ [ValueBinder (newName "rcontext") (Just resumeContextTp) () hrng patRng]) + OpControlErr -> failure "Type.Infer.inferHandler: using a bare operation is deprecated.\n hint: start with 'val', 'fun', 'brk', or 'ctl' instead." -- _ -> failure $ "Type.Infer.inferHandler: unexpected resume kind: " ++ show rkind -- traceDoc $ \penv -> text "resolving:" <+> text (showPlain opName) <+> text ", under effect:" <+> text (showPlain effectName) (_,gtp,_) <- resolveFunName (if isQualified opName then opName else qualify (qualifier effectName) opName) @@ -1331,7 +1336,7 @@ inferApp propagated expect fun nargs rng cargs = [Core.Var (Core.TName var (Core.typeOf arg)) Core.InfoNone | (var,(_,arg)) <- vargs] if (Core.isTotal fcore) then return (Core.makeLet defs (coreApp fcore cargs)) - else do fname <- uniqueName "fun" + else do fname <- uniqueName "fct" let fdef = Core.DefNonRec (Core.Def fname ftp fcore Core.Private (defFun [] {-all own, TODO: maintain borrow annotations?-}) InlineAuto rangeNull "") fvar = Core.Var (Core.TName fname ftp) Core.InfoNone return (Core.Let (fdef:defs) (coreApp fvar cargs)) @@ -1440,21 +1445,21 @@ inferVar propagated expect name rng isRhs [(Nothing,App (Var nameByref False irng) [(Nothing,Var name False irng)] irng)] irng) name rng) - addRangeInfo rng (RM.Id qname (RM.NIValue tp1) False) + addRangeInfo rng (RM.Id qname (RM.NIValue tp1 True) False) -- traceDoc $ \env -> text " deref" <+> pretty name <+> text "to" <+> ppType env tp1 return (tp1,eff1,core1) else case info of InfoVal{ infoIsVar = True } | isRhs -- is it a right-hand side variable? -> do (tp1,eff1,core1) <- inferExpr propagated expect (App (Var nameDeref False rng) [(Nothing,App (Var nameByref False rng) [(Nothing,Var name False rng)] rng)] rng) - addRangeInfo rng (RM.Id qname (RM.NIValue tp1) False) + addRangeInfo rng (RM.Id qname (RM.NIValue tp1 True) False) return (tp1,eff1,core1) InfoVal{} | isValueOperation tp - -> do addRangeInfo rng (RM.Id qname (RM.NIValue tp) True) + -> do addRangeInfo rng (RM.Id qname (RM.NIValue tp True) True) inferExpr propagated expect (App (Var (toValueOperationName qname) False rangeNull) [] rangeNull) _ -> -- inferVarX propagated expect name rng qname1 tp1 info1 do let coreVar = coreExprFromNameInfo qname info -- traceDoc $ \env -> text "inferVar:" <+> pretty name <+> text ":" <+> text (show info) <.> text ":" <+> ppType env tp - addRangeInfo rng (RM.Id (infoCanonicalName qname info) (RM.NIValue tp) False) + addRangeInfo rng (RM.Id (infoCanonicalName qname info) (RM.NIValue tp True) False) (itp,coref) <- maybeInstantiate rng expect tp sitp <- subst itp -- traceDoc $ \env -> (text " Type.Infer.Var: " <+> pretty name <.> colon <+> ppType env{showIds=True} sitp) @@ -1637,7 +1642,7 @@ inferPattern matchType branchRange (PatVar binder) withPattern inferPart Nothing -- it is a variable indeed -> -} - do addRangeInfo (binderNameRange binder) (RM.Id (binderName binder) (RM.NIValue matchType) True) + do addRangeInfo (binderNameRange binder) (RM.Id (binderName binder) (RM.NIValue matchType (isAnnotatedBinder binder)) True) case (binderType binder) of Just tp -> inferUnify (checkAnn (getRange binder)) (binderNameRange binder) matchType tp Nothing -> return () diff --git a/src/Type/InferMonad.hs b/src/Type/InferMonad.hs index 3b51aaa4f..6c4ab520b 100644 --- a/src/Type/InferMonad.hs +++ b/src/Type/InferMonad.hs @@ -851,7 +851,7 @@ data Env = Env{ prettyEnv :: !Pretty.Env data St = St{ uniq :: !Int, sub :: !Sub, preds :: ![Evidence], holeAllowed :: !Bool, mbRangeMap :: Maybe RangeMap } -runInfer :: Pretty.Env -> Maybe RangeMap -> Synonyms -> Newtypes -> ImportMap -> Gamma -> Name -> Int -> Inf a -> Error (a,Int,Maybe RangeMap) +runInfer :: Pretty.Env -> Maybe RangeMap -> Synonyms -> Newtypes -> ImportMap -> Gamma -> Name -> Int -> Inf a -> Error b (a,Int,Maybe RangeMap) runInfer env mbrm syns newTypes imports assumption context unique (Inf f) = case f (Env env context (newName "") False newTypes syns assumption infgammaEmpty imports False False) (St unique subNull [] False mbrm) of diff --git a/src/Type/Pretty.hs b/src/Type/Pretty.hs index 82b075f74..b10e6c71e 100644 --- a/src/Type/Pretty.hs +++ b/src/Type/Pretty.hs @@ -126,6 +126,7 @@ type TvScheme = M.Map TypeVar (Prec -> Doc) -- | Pretty print environment for types. data Env = Env{ showKinds :: Bool , showIds :: Bool -- show id numbers + , showFlavours :: Bool , expandSynonyms :: Bool , colors :: ColorScheme , nice :: Nice @@ -156,7 +157,7 @@ data Env = Env{ showKinds :: Bool -- | Default pretty print environment defaultEnv :: Env defaultEnv - = Env False False False + = Env False False False False defaultColorScheme niceEmpty (precTop-1) M.empty (newName "Main") (importsEmpty) False False [] @@ -192,8 +193,9 @@ ppSchemeEffect env tp prettyDefFunType :: Env -> [ParamInfo] -> Scheme -> Doc prettyDefFunType env pinfos tp - = let (Just params,pre,post) = ppDeclType env pinfos tp - in pre <.> parens (commaSep (map ppParam params)) <+> text "->" <+> post + = case ppDeclType env pinfos tp of + (Just params,pre,post) -> pre <.> parens (commaSep (map ppParam params)) <+> text "->" <+> post + (Nothing,pre,post) -> pre <+> text "()" <+> text "->" <+> post where ppParam (name,pinfo,tpDoc) = (case pinfo of Borrow -> text "^" <+> (if nameNil == name then text "_" else ppName env name) <+> text ": " @@ -460,10 +462,11 @@ ppTypeVar :: Env -> TypeVar -> Doc ppTypeVar env (TypeVar id kind flavour) = colorByKindDef env kind colorTypeVar $ wrapKind (showKinds env) env kind $ - (case flavour of - Meta -> text "_" - Skolem -> if (coreIface env) then text "__" else text "$" - _ -> empty) <.> nicePretty (nice env) id <.> (if (showIds env) then text ("=" ++ show id) else empty) + let flav = case flavour of + Meta -> text "_" + Skolem -> if (coreIface env) then text "__" else text "$" + _ -> empty in + (if showFlavours env then flav else empty) <.> nicePretty (nice env) id <.> (if (showIds env) then text ("=" ++ show id) else empty) ppTypeCon :: Env -> TypeCon -> Doc ppTypeCon env (TypeCon name kind) diff --git a/stack.yaml b/stack.yaml index b805dfb2c..f16179709 100644 --- a/stack.yaml +++ b/stack.yaml @@ -29,6 +29,10 @@ extra-deps: - regex-compat-0.95.2.1 # only needed for koka-test (use 0.95.1.4 for pre lts-21.0) - json-0.10 # only needed for koka-test - isocline-1.0.7 +- lsp-2.3.0.0 # only needed for language server +- lsp-types-2.1.0.0 # only needed for language server +- text-rope-0.2 # needed for lsp +- co-log-core-0.3.2.0 # needed for lsp rebuild-ghc-options: true allow-newer: true diff --git a/support/vscode/README.md b/support/vscode/README.md new file mode 100644 index 000000000..2c58fd422 --- /dev/null +++ b/support/vscode/README.md @@ -0,0 +1,20 @@ +This contains the sources for building the VS code extension (VSIX). + +To build the extension first install nodejs/npm: + +> cd support/vscode/koka.language-koka +> npm run build +> npm run package + +and install the resulting `.vsix` extension either by right-clicking in VS code and select `install extension`, +or run: + +> code --install-extension language-koka-.vsix + +In the extension you may need to go to the settings and set the path +to the Koka executable. If you like to use the build version use: + +> stack path --local-install-root + +to get the local install root directory where `/bin/koka` is +the path to local executable. diff --git a/support/vscode/koka.language-koka/README.md b/support/vscode/koka.language-koka/README.md index ba1a1323e..d0e3fc2af 100644 --- a/support/vscode/koka.language-koka/README.md +++ b/support/vscode/koka.language-koka/README.md @@ -1,10 +1,86 @@ -# Koka Syntax Highlighting +# Koka Syntax Highlighting and Language Server -Syntax highlighting support for the +Syntax highlighting and language server support for the Koka programming language in Visual Studio Code. +Also includes language server support, and easy installation of the latest Koka SDK. + Visit for more information. +## Language Server + +The language server continously analyses the code to show +parse- and type errors, complete identifiers, +show type information on hover, and +can execute `main`, `test-xxx`, and `example-xxx` functions +directly in the debug console. + +### Easy SDK Installation +Open the command panel in VSCode `(Ctrl/Cmd+Shift+P)` and run the `Koka: Download and Install Latest Version` command. (Start typing the command and it should surface to the top.) + +If Koka doesn't detect an existing installation, it will prompt to run this command automatically. + +### Customize + +The extension shows "inlay hints" for inferred types of parameters +and local declarations. You can toggle inlay hints on- and +off in the editor inlay hints settings. +In the extension settings, you can also set the Koka compiler +path and specific compiler flags manually. + +### Running Files + +You can create custom run configurations in your `launch.json` file, just like any other programming language. +For koka you have the following options: +```json +{ + "type": "koka", + "request": "launch", + "program": "", // The path to the file you want to run + "name": "", // The name as you want it to appear in the run configurations dropdown + "functionName": "", // optional function name to run (must be a function that doesn't use any effects other than io effects and returns a showable value) + "programArgs": [], // optional arguments you want to give to the compiled program + "compilerArgs": "", // optional arguments you want to give to the compiler (e.g. --verbose or -O2) +} +``` + +Although it pulls up the debug panels, it doesn't support debugging yet. + +Compilation progress will be shown in the language server Terminal window, but the debug console will be used to show the output of the program. + + +### Language Server Configuration + +By default the language server support is enabled. To disable it, add the following to your `settings.json` file: +```json +{ + "koka.languageServer.enabled": false, +} +``` + +If you would like additional arguments to all invocations of the compiler, you can add them to your `settings.json` file: +```json +{ + "koka.languageServer.compilerArgs": ["--verbose"], +} +``` + +To change the current working directory for the language server (by default the first workspace folder), add the following to your `settings.json` file: +```json +{ + "koka.languageServer.cwd": "/path/to/working/directory", +} +``` + +### Supported Language Server Aspects +- [x] Diagnostics +- [x] Code completion +- [x] Hover information +- [x] Find definitions +- [x] Inlay hints +- [x] Document outline +- [x] Code folding ranges + ## Token Classes * `koka.conid`: constructors. @@ -24,12 +100,12 @@ Visit for more information. * `koka.comment`(`.line`|`.block`): comments. * `koka.comment.doc`(`.emph`|`.pre`|`.pre.type`|`.pre.block`): documentation inside a comment. -## Customize +### Customize You can customize the Koka syntax highlighting by editing -the `settings.json` file of VS Code (press `Ctrl/Cmd+Shift+P` and +the `settings.json` file of VS Code (press `Ctrl/Cmd+Shift+P` and select "Open Settings (JSON)" to open it). -Then add a [editor.tokenColorCustomizations](https://code.visualstudio.com/docs/getstarted/themes#_editor-syntax-highlighting) +Then add a [editor.tokenColorCustomizations](https://code.visualstudio.com/docs/getstarted/themes#_editor-syntax-highlighting) entry, for example: ```json "editor.tokenColorCustomizations": { @@ -45,8 +121,15 @@ entry, for example: }, { "scope": "koka.id.decl.function", "settings": { "foreground": "#cac199" } - }, + }, ] } ``` +## Extension Commands + +The language server opens an extra terminal which shows the output of the compiler. +This can be closed, but a new terminal will be opened whenever the language server is restarted. +You can also reopen it by running the `Koka: Show Language Server Output` command in the vscode command panel `(Ctrl/Cmd+Shift+P)`. + +To uninstall the Koka SDK run the `Koka: Uninstall System SDK` command in the vscode command panel `(Ctrl/Cmd+Shift+P)`. diff --git a/support/vscode/koka.language-koka/images/koka-logo-filled-dark.svg b/support/vscode/koka.language-koka/images/koka-logo-filled-dark.svg new file mode 100644 index 000000000..087ee37cc --- /dev/null +++ b/support/vscode/koka.language-koka/images/koka-logo-filled-dark.svg @@ -0,0 +1,61 @@ + + + + + + + + + + + diff --git a/support/vscode/koka.language-koka/images/koka-logo-filled-light.svg b/support/vscode/koka.language-koka/images/koka-logo-filled-light.svg new file mode 100644 index 000000000..bbc7a80cd --- /dev/null +++ b/support/vscode/koka.language-koka/images/koka-logo-filled-light.svg @@ -0,0 +1,62 @@ + + + + + + + + + + + diff --git a/support/vscode/koka.language-koka/images/koka-logo-filled.svg b/support/vscode/koka.language-koka/images/koka-logo-filled.svg new file mode 100644 index 000000000..b48860a9e --- /dev/null +++ b/support/vscode/koka.language-koka/images/koka-logo-filled.svg @@ -0,0 +1,59 @@ + + + + + + + + + + + diff --git a/support/vscode/koka.language-koka/package.json b/support/vscode/koka.language-koka/package.json index 38f9d28e3..3bca00f86 100644 --- a/support/vscode/koka.language-koka/package.json +++ b/support/vscode/koka.language-koka/package.json @@ -1,84 +1,241 @@ { - "name": "language-koka", - "displayName": "Koka Syntax Highlighting", - "description": "Official syntax support for the Koka programming language.", - "version": "2.0.5", - "publisher": "koka", - "engines": { - "vscode": "^1.0.0" - }, - "icon": "images/koka-logo-filled.png", - "galleryBanner": { - "color": "#293845", - "theme": "dark" - }, - "files": [ - "syntaxes/*.json", - "images/", - "README.md" - ], - "keywords": [ - "koka", - "effect", - "handler", + "name": "language-koka", + "displayName": "Koka Language", + "description": "The official Koka programming language extension.", + "version": "2.4.3", + "publisher": "koka", + "engines": { + "vscode": ">=1.81.0" + }, + "icon": "images/koka-logo-filled.png", + "galleryBanner": { + "color": "#293845", + "theme": "dark" + }, + "files": [ + "syntaxes/*.json", + "images/", + "README.md" + ], + "keywords": [ + "koka", + "effect", + "handler", "koka-lang" - ], - "license": "MIT", - "homepage": "https://koka-lang.github.io", - "repository": { - "type": "git", - "url": "https://github.com/koka-lang/koka" - }, - "bugs": { - "url": "https://github.com/koka-lang/koka/issues" - }, - "categories": [ - "Programming Languages" - ], + ], + "license": "MIT", + "homepage": "https://koka-lang.github.io", + "repository": { + "type": "git", + "url": "https://github.com/koka-lang/koka" + }, + "bugs": { + "url": "https://github.com/koka-lang/koka/issues" + }, + "categories": [ + "Programming Languages", + "Debuggers" + ], + "main": "./out/extension", + "activationEvents": [ + "workspaceContains:**/*.kk" + ], "contributes": { - "configuration": { - "type": "object", - "title": "Koka configuration", - "properties": { - "koka.indentationRules.enabled": { - "type": "boolean", - "default": true, - "description": "Set to 'false' to disable automatically increasing indent on newlines after '{', 'match' etc." - } - } - }, + "languages": [ + { + "id": "koka", + "aliases": [ + "Koka", + "koka-lang" + ], + "extensions": [ + ".kk", + ".kki", + ".kkc" + ], + "configuration": "./koka-configuration.json", + "icon": { + "light": "./images/koka-logo-filled-light.svg", + "dark": "./images/koka-logo-filled-dark.svg" + } + } + ], + "grammars": [ + { + "language": "koka", + "scopeName": "source.koka", + "path": "./syntaxes/koka.json" + } + ], + "configuration": { + "type": "object", + "title": "Koka", + "properties": { + "koka.indentationRules.enabled": { + "type": "boolean", + "default": true, + "description": "Automatically increase indentation after '{', 'match' etc." + }, + "koka.languageServer.enabled": { + "type": "boolean", + "default": true, + "description": "Enable the Koka language server (e.g. parse errors, hover, code completion, etc.) for Koka.\nMay require specifying the path to the Koka compiler under 'koka.languageServer.compiler'." + }, + "koka.languageServer.compiler": { + "type": "string", + "default": null, + "description": "The path of the Koka compiler. By default the extension assumes that 'koka' is on your PATH" + }, + "koka.languageServer.compilerArgs": { + "type": "array", + "items": { + "type": "string" + }, + "default": null, + "description": "Additional arguments used for compilation from the language server" + }, + "koka.languageServer.cwd": { + "type": "string", + "default": "", + "description": "If specified, the directory in which the language server executes. Uses by default the current workspace root directory." + }, + "koka.debugExtension": { + "type": "boolean", + "default": true, + "description": "Log trace information from the language server subprocess." + }, + "koka.languageServer.trace.server": { + "scope": "window", + "type": "string", + "enum": [ + "off", + "messages", + "verbose" + ], + "default": "off", + "description": "Trace messages between VS Code and the language server." + } + } + }, "configurationDefaults": { "[koka]": { "editor.tabSize": 2, "editor.insertSpaces": true } }, - "languages": [ - { - "id": "koka", - "aliases": [ - "Koka", - "koka-lang" - ], - "extensions": [ - ".kk", - ".kki", - ".kkc" - ], - "configuration": "./koka-configuration.json" - } - ], - "grammars": [ - { - "language": "koka", - "scopeName": "source.koka", - "path": "./syntaxes/koka.json" - } - ] - }, - "scripts": { - }, - "devDependencies": { - "vscode": "^1.0.0" - } -} + "commands": [ + { + "command": "koka.restartLanguageServer", + "title": "Koka: Restart Language Server" + }, + { + "command": "koka.downloadLatest", + "title": "Koka: Download and Install Latest Version" + }, + { + "command": "koka.uninstall", + "title": "Koka: Uninstall System SDK" + }, + { + "command": "koka.startWithoutDebugging", + "title": "Koka: Run current file" + }, + { + "command": "koka.selectTarget", + "title": "Koka: Set compilation target" + }, + { + "command": "koka.selectSDK", + "title": "Koka: Set sdk path" + }, + { + "command": "koka.showLSPOutput", + "title": "Koka: Show Language Server Output" + } + ], + "debuggers": [ + { + "type": "koka", + "label": "Koka Debugger", + "runtime": "node", + "languages": [ + "koka" + ], + "configurationAttributes": { + "launch": { + "required": [ + "program" + ], + "properties": { + "program": { + "type": "string", + "description": "File to run the main function from", + "default": "${workspaceFolder}/${command:AskForProgramName}" + }, + "functionName": { + "type": "string", + "description": "Name of the function to run", + "default": "main" + }, + "compilerArgs": { + "type": "string", + "description": "Additional arguments to pass to the compiler\nArguments that are intended to be passed to the compiled program should be specified in programArgs\n (e.g. `--kktime`)" + }, + "programArgs": { + "type": "array", + "items": { + "type": "string" + }, + "default": null, + "description": "Additional arguments to pass to the program" + } + } + } + }, + "initialConfigurations": [ + { + "name": "Debug Koka Program", + "type": "koka", + "request": "launch", + "program": "" + } + ], + "configurationSnippets": [ + { + "label": "Koka: Run", + "description": "Compile and run a Koka program", + "body": { + "type": "koka", + "request": "launch", + "program": "${0}", + "name": "${0}" + } + } + ], + "variables": { + "AskForProgramName": "extension.language-koka.getProgramName" + } + } + ] + }, + "scripts": { + "build": "tsc", + "watch": "tsc -w", + "package": "vsce package", + "publish": "vsce publish" + }, + "devDependencies": { + "@types/node": "^20.5.6", + "@types/vscode": "1.81.0", + "@vscode/vsce": "^2.22.0", + "@types/semver": "^7.5.6", + "typescript": "^5.2.2" + }, + "dependencies": { + "@vscode/debugadapter": "^1.61.0", + "@vscode/debugprotocol": "^1.61.0", + "semver": "^7.5.4", + "await-notify": "1.0.1", + "vscode-languageclient": "^8.1.0" + } +} \ No newline at end of file diff --git a/support/vscode/koka.language-koka/src/code-lens.ts b/support/vscode/koka.language-koka/src/code-lens.ts new file mode 100644 index 000000000..30fd44f89 --- /dev/null +++ b/support/vscode/koka.language-koka/src/code-lens.ts @@ -0,0 +1,90 @@ +import path = require("path"); +import * as vscode from "vscode" +import { KokaConfig } from "./workspace"; + +export class MainCodeLensProvider implements vscode.CodeLensProvider { + private onDidChangeCodeLensesEmitter: vscode.EventEmitter = new vscode.EventEmitter() + + constructor(private readonly config: KokaConfig) { } + + public async provideCodeLenses(document: vscode.TextDocument, token: vscode.CancellationToken): Promise { + const doc = document.getText() + const re_main = /((?<=\n)|^)((pub\s+)?fun\s+main\(\))/g; + const re_test = /((?<=\n)|^)((pub\s+)?fun\s+(test[\w-]*)\(\))/g; + const re_example = /((?<=\n)|^)((pub\s+)?fun\s+(example[\w-]*)\(\))/g; + let lenses = []; + let match = null; + let has_main = false; + console.log("Koka: Scanning document for main and test function"); + while (match = re_main.exec(doc)) { + if (has_main) { + console.log("Koka: Found multiple main functions. This is not supported in the compiler.") + return []; + } + has_main = true; + lenses.push(...this.createMainCodeLens(document, match.index, match[0].length)) + } + while (match = re_test.exec(doc)) { + if (has_main) { + console.log("Koka: Found both a main and a test function. Only the main function will be runnable via code lens.") + break; + } + lenses.push(...this.createTestCodeLens(document, match.index, match[4], match[0].length)) + } + while (match = re_example.exec(doc)) { + if (has_main) { + console.log("Koka: Found both a main and an example function. Only the main function will be runnable via code lens.") + break; + } + lenses.push(...this.createTestCodeLens(document, match.index, match[4], match[0].length)) + } + return lenses + } + + private createMainCodeLens(document: vscode.TextDocument, offset: number, len: number): vscode.CodeLens[] { + return [new vscode.CodeLens( + toRange(document, offset, len), + { + arguments: [document.uri], + command: "koka.startWithoutDebugging", + title: "run debug", // `Run ${path.relative(this.config.cwd, document.uri.fsPath)} (debug)`, + tooltip: "Compile and run in debug mode" + }, + ), new vscode.CodeLens( + toRange(document, offset, len), + { + arguments: [document.uri, "-O2", ["--kktime"]], + command: "koka.startWithoutDebugging", + title: `optimized`, // `Run ${path.relative(this.config.cwd, document.uri.fsPath)} (release)`, + tooltip: "Compile with flag -O2\nRun executable with flag --kktime" + }, + ), + ] + } + + private createTestCodeLens(document: vscode.TextDocument, offset: number, functionName: string, len: number): vscode.CodeLens[] { + return [new vscode.CodeLens( + toRange(document, offset, len), + { + arguments: [document.uri, functionName], + command: "koka.interpretExpression", + title: "run debug", //`Run ${functionName} (debug)`, + tooltip: "Compile and run in debug mode" + } + ), + new vscode.CodeLens( + toRange(document, offset, len), + { + arguments: [document.uri, functionName, "-O2", ["--kktime"]], + command: "koka.interpretExpression", + title: `optimized`, // `Run ${functionName} (release)`, + tooltip: "Compile with flag -O2\nRun executable with flag --kktime" + } + ) + ] + } +} + +function toRange(document: vscode.TextDocument, offset: number, length: number): vscode.Range { + return new vscode.Range(document.positionAt(offset), document.positionAt(offset + length)) +} \ No newline at end of file diff --git a/support/vscode/koka.language-koka/src/debugger.ts b/support/vscode/koka.language-koka/src/debugger.ts new file mode 100644 index 000000000..690be2aa3 --- /dev/null +++ b/support/vscode/koka.language-koka/src/debugger.ts @@ -0,0 +1,277 @@ +import * as child_process from 'child_process' +import * as fs from "fs" + +import { + Logger, logger, + LoggingDebugSession, + InitializedEvent, TerminatedEvent, OutputEvent, + Thread, +} from '@vscode/debugadapter' +import { DebugProtocol } from '@vscode/debugprotocol' +import { EventEmitter } from 'events' +import { KokaConfig } from './workspace' +import { Subject } from 'await-notify' +import * as path from 'path' +import { + LanguageClient, + ExecuteCommandRequest, + ExecuteCommandParams, +} from 'vscode-languageclient/node' + +/* + * This interface describes the mock-debug specific launch attributes + * (which are not part of the Debug Adapter Protocol). + * The schema for these attributes lives in the package.json of the mock-debug extension. + * The interface should always match this schema. + */ +interface LaunchRequestArguments extends DebugProtocol.LaunchRequestArguments { + /** An absolute path to the "program" to debug. */ + program: string + /** Additional arguments */ + compilerArgs?: string + /** Additional arguments */ + programArgs?: string[] + /** enable logging the Debug Adapter Protocol */ + trace?: boolean + /** A single function to run (must have no effects and return a type that is showable)*/ + functionName?: string +} + +export class KokaDebugSession extends LoggingDebugSession { + + // we don't support multiple threads, so we can use a hardcoded ID for the default thread + private static THREAD_ID = 1 + + private _configurationDone = new Subject() + + private _runtime: KokaRuntime + /** + * Creates a new debug adapter that is used for one debug session. + * We configure the default implementation of a debug adapter here. + */ + + + public constructor(private readonly config: KokaConfig, private readonly client: LanguageClient) { + super("koka-debug.txt") + + // this debugger uses zero-based lines and columns + this.setDebuggerLinesStartAt1(false) + this.setDebuggerColumnsStartAt1(false) + + this._runtime = new KokaRuntime(config, client) + + // setup event handlers + this._runtime.on('output', (text, category) => { + const e: DebugProtocol.OutputEvent = new OutputEvent(`${text}\n`) + e.body.category = category + + this.sendEvent(e) + }) + this._runtime.on('end', () => { + this.sendEvent(new TerminatedEvent()) + }) + } + + /** + * The 'initialize' request is the first request called by the frontend + * to interrogate the features the debug adapter provides. + */ + protected initializeRequest(response: DebugProtocol.InitializeResponse, args: DebugProtocol.InitializeRequestArguments): void { + + // build and return the capabilities of this debug adapter: + response.body = response.body || {} + + // the adapter implements the configurationDoneRequest. + response.body.supportsConfigurationDoneRequest = true + + // make VS Code not use 'evaluate' when hovering over source + response.body.supportsEvaluateForHovers = false + + // make VS Code not show a 'step back' button + response.body.supportsStepBack = false + + // make VS Code not support data breakpoints + response.body.supportsDataBreakpoints = false + + // make VS Code not support completion in REPL + response.body.supportsCompletionsRequest = false + response.body.completionTriggerCharacters = [] + + // make VS Code send cancelRequests + response.body.supportsCancelRequest = true + response.body.supportsTerminateRequest = true + + // make VS Code not send the breakpointLocations request + response.body.supportsBreakpointLocationsRequest = false + + this.sendResponse(response) + + // we request configurations early by sending an 'initializeRequest' to the frontend. + // The frontend will end the configuration sequence by calling 'configurationDone' request. + this.sendEvent(new InitializedEvent()) + } + + /** + * Called at the end of the configuration sequence. + * Indicates that all breakpoints etc. have been sent to the DA and that the 'launch' can start. + */ + protected configurationDoneRequest(response: DebugProtocol.ConfigurationDoneResponse, args: DebugProtocol.ConfigurationDoneArguments): void { + super.configurationDoneRequest(response, args) + + // notify the launchRequest that configuration has finished + this._configurationDone.notify() + } + + protected async launchRequest(response: DebugProtocol.LaunchResponse, args: LaunchRequestArguments) { + + // make sure to 'Stop' the buffered logging if 'trace' is not set + logger.setup(args.trace ? Logger.LogLevel.Verbose : Logger.LogLevel.Stop, false) + + // wait until configuration has finished (and configurationDoneRequest has been called) + // No configuration of breakpoints etc is currently supported so set a low timeout + await this._configurationDone.wait(1) + + // start the program in the runtime + this._runtime.start(args) + + this.sendResponse(response) + } + + protected threadsRequest(response: DebugProtocol.ThreadsResponse): void { + + // debug runtime supports no threads so just return a default thread. + response.body = { + threads: [ + new Thread(KokaDebugSession.THREAD_ID, "main thread") + ] + } + this.sendResponse(response) + } + + protected async terminateRequest(response: DebugProtocol.TerminateResponse, args: DebugProtocol.TerminateArguments, request?: DebugProtocol.Request) { + await this._runtime.cancel() + response.success = true + response.message = "terminated" + this.sendResponse(response) + } + + protected async cancelRequest(response: DebugProtocol.CancelResponse, args: DebugProtocol.CancelArguments) { + await this._runtime.cancel() + response.success = true + response.message = "cancelled" + this.sendResponse(response) + } +} + +class KokaRuntime extends EventEmitter { + + constructor(private readonly config: KokaConfig, private readonly client: LanguageClient) { + super() + } + ps?: child_process.ChildProcess | null + + + public async start(args: LaunchRequestArguments) { + const target = this.config.target + let compilerTarget + switch (target) { + case 'C': + compilerTarget = 'c' + break + case 'JS': + compilerTarget = 'js' + break + case 'WASM': + compilerTarget = 'wasm' + break + case 'C#': + compilerTarget = 'cs' + break + default: + compilerTarget = 'c' + break + } + // Args that are parsed by the compiler are in the args field. This leaves the rest of the object open for + let additionalArgs = "--target=" + compilerTarget + if (args.compilerArgs) { + additionalArgs = additionalArgs + " " + args.compilerArgs + } + try { + let resp = null + if (args.functionName) { + resp = await this.client.sendRequest(ExecuteCommandRequest.type, { command: 'koka/interpretExpression', arguments: [args.program, args.functionName, additionalArgs] }) + } else { + resp = await this.client.sendRequest(ExecuteCommandRequest.type, { command: 'koka/genCode', arguments: [args.program, additionalArgs] }) + } + console.log(`Generated code at ${resp}`) + if (!resp) { + this.emit('output', `Error generating code, see language server output for specifics`, 'stderr') + this.emit('end', -1) + return; + } + if (!fs.existsSync(path.join(this.config.cwd, resp))) { + console.log(`Error finding code at ${resp}`) + this.emit('end', -1) + return; + } + if (target == 'C') { + console.log(`Executing ${resp} ${args.programArgs ?? []}`) + this.ps = child_process.spawn(resp, args.programArgs ?? [], { cwd: this.config.cwd, env: process.env }) + this.ps.stdout?.on('data', (data) => { + this.emit('output', data.toString().trim(), 'stdout') + }) + this.ps.stderr?.on('data', (data) => { + this.emit('output', data.toString().trim(), 'stderr') + }) + this.ps.on('close', (code) => { + this.emit('end', code) + this.ps = null + }) + } + // else if (target == 'JS' || target == 'WASM') { + // const realTarget = target == 'JS' ? 'jsweb' : 'wasmweb' + // // TODO: Better configuration for wasm / js build outputs + // const webBuildDir = path.join(this.config.cwd, 'web', 'build') + // console.log(`Executing ${this.config.command} --target=${realTarget} ${file} -i${this.config.cwd} --outputdir=${webBuildDir}`) + // this.ps = child_process.exec(`${this.config.command} --target=${realTarget} ${file} -i${this.config.cwd} --outputdir=${webBuildDir}`, (exitCode, stdout, stderr) => { + // // TODO: separate output streams for compile versus running? + // if (stdout) { + // this.emit('output', stdout, 'stdout') + // } + // if (stderr) { + // this.emit('output', stderr, 'stderr') + // } + // if (exitCode) { + // this.emit('output', `Compiler exited with error status ${exitCode}`, 'stderr') + // this.emit('end') + // } else { + // this.emit('output', `Compiler exited succesfully`, 'stdout') + // this.emit('end') + // } + // }) + // } else { + // // TODO: Support C# + // this.emit('end') + // } + + } catch (e) { + this.emit('output', `Error generating code: ${e}`, 'stderr') + this.emit('end', -1) + } + } + + public async cancel() { + if (this.ps) { + const result = await this.ps.kill() + if (!result) { + console.log("Escalating process kill to SIGKILL") + await this.ps.kill(9) + } + this.ps = null + this.emit('output', `Compile was cancelled`, 'stdout') + this.emit('end', 1) + } else { + console.log("No process to cancel?") + } + } +} \ No newline at end of file diff --git a/support/vscode/koka.language-koka/src/extension.ts b/support/vscode/koka.language-koka/src/extension.ts new file mode 100644 index 000000000..f3f989860 --- /dev/null +++ b/support/vscode/koka.language-koka/src/extension.ts @@ -0,0 +1,232 @@ +import * as vscode from 'vscode' +import * as path from 'path' + +import { KokaConfig, downloadSDK, scanForSDK, uninstallSDK } from './workspace' +import { CancellationToken, DebugConfiguration, DebugConfigurationProvider, ProviderResult, WorkspaceFolder } from 'vscode' +import { KokaDebugSession } from './debugger' +import { KokaLanguageServer } from './lang-server' +import { MainCodeLensProvider } from './code-lens' + +let languageServer: KokaLanguageServer; + +export async function deactivate() { } + +export async function activate(context: vscode.ExtensionContext) { + const vsConfig = vscode.workspace.getConfiguration('koka') // All configuration parameters are prefixed with koka + console.log(`Koka: language server enabled ${vsConfig.get('languageServer.enabled')}`) + + // Create commands that do not depend on the language server + createBasicCommands(context, vsConfig); + console.log(context.globalStorageUri); + if (!vsConfig.get('languageServer.enabled')) { + return + } + + const sdk = await scanForSDK(context, vsConfig) + if (!sdk){ + return; + } + const { sdkPath, allSDKs } = sdk + const kokaConfig = new KokaConfig(vsConfig, sdkPath, allSDKs) + if (!kokaConfig.command) { + vscode.window.showInformationMessage(`Koka SDK not functional: tried initializing from path: ${kokaConfig.sdkPath}\n All SDKs: ${allSDKs}`) + return // No use initializing the rest of the extension's features + } + + languageServer = new KokaLanguageServer(context) + await languageServer.start(kokaConfig, context) + + // create a new status bar item that we can now manage + const selectSDKMenuItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, 100) + selectSDKMenuItem.command = 'koka.selectSDK' + context.subscriptions.push(selectSDKMenuItem) + selectSDKMenuItem.show() + selectSDKMenuItem.text = `Koka SDK` + selectSDKMenuItem.tooltip = `${kokaConfig.sdkPath}` + + // create a new status bar item that we can now manage + const selectCompileTarget = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, 100) + selectCompileTarget.command = 'koka.selectTarget' + context.subscriptions.push(selectCompileTarget) + selectCompileTarget.show() + selectCompileTarget.text = `Koka Backend: ${kokaConfig.target}` + + // Register debug adapter + registerDebugConfiguration(context, kokaConfig) + // Initialize commands + createCommands(context, vsConfig, kokaConfig, selectSDKMenuItem, selectCompileTarget) + // Code lens (run and test) + context.subscriptions.push( + vscode.languages.registerCodeLensProvider({ language: "koka", scheme: "file" }, new MainCodeLensProvider(kokaConfig)) + ) +} + +// These commands do not depend on the language server +function createBasicCommands(context: vscode.ExtensionContext, config: vscode.WorkspaceConfiguration) { + context.subscriptions.push( + // SDK management + vscode.commands.registerCommand('koka.downloadLatest', async () => { + // Reset the download flag + await context.globalState.update('koka-download', true) + downloadSDK(context, config, true, undefined) + }), + vscode.commands.registerCommand('koka.uninstall', () => { + uninstallSDK(context) + }) + ) +} + +// Register's some things that are needed for debugging +function registerDebugConfiguration(context: vscode.ExtensionContext, kokaConfig: KokaConfig) { + context.subscriptions.push( + // register a configuration provider for 'koka' debug type + vscode.debug.registerDebugConfigurationProvider('koka', new KokaRunConfigurationProvider()), + // run tests / run main + vscode.debug.registerDebugAdapterDescriptorFactory('koka', new InlineDebugAdapterFactory(kokaConfig)) + ) +} + +// Create all of the commands that can be used via the vscode api +function createCommands( + context: vscode.ExtensionContext, + config: vscode.WorkspaceConfiguration, + kokaConfig: KokaConfig, + selectSDKMenuItem: vscode.StatusBarItem, + selectCompileTarget: vscode.StatusBarItem, +) { + context.subscriptions.push( + vscode.commands.registerCommand('koka.selectSDK', async () => { + const sdk = await scanForSDK(context, config) + if (!sdk) { + return; + } + const { sdkPath, allSDKs } = sdk + kokaConfig.allSDKs = allSDKs + const result = await vscode.window.showQuickPick(kokaConfig.allSDKs) + if (result) kokaConfig.selectSDK(result) + selectSDKMenuItem.tooltip = `${kokaConfig.sdkPath}` + await vscode.commands.executeCommand('koka.restartLanguageServer') + }), + // Language Server management + vscode.commands.registerCommand('koka.showLSPOutput', async () => { + languageServer.showOutputChannel() + }), + vscode.commands.registerCommand('koka.restartLanguageServer', () => { + if (!config.get('languageServer.enabled')) + return vscode.window.showErrorMessage('Language server is not enabled') + vscode.window.withProgress( + { + location: vscode.ProgressLocation.Notification, + title: 'Koka', + cancellable: false, + }, + async (progress, token) => { + progress.report({ message: 'Restarting language server' }) + await languageServer.dispose() + const languageServerIdx = context.subscriptions.indexOf(languageServer) + if (languageServerIdx != -1) { + context.subscriptions.splice(languageServerIdx, 1) + } + const sdk = await scanForSDK(context, config) + if (!sdk) { + return; + } + const { sdkPath, allSDKs } = sdk + const newConfig = new KokaConfig(config, sdkPath, allSDKs) + languageServer = new KokaLanguageServer(context) + await languageServer.start(newConfig, context) + + progress.report({ + message: 'Language server restarted', + increment: 100, + }) + // Wait 2 seconds to allow user to read message + await new Promise((resolve) => setTimeout(resolve, 2000)) + }, + ) + }), + // Configuration + vscode.commands.registerCommand('koka.selectTarget', async () => { + const result = await vscode.window.showQuickPick(['C', 'WASM', 'JS', 'C#']) + if (result) kokaConfig.selectTarget(result) + selectCompileTarget.text = `Koka Backend: ${kokaConfig.target}` + }), + // Debug Adaptor stuff + vscode.commands.registerCommand('extension.language-koka.getProgramName', c => { + return vscode.window.showInputBox({ + placeHolder: "Please enter the name of a koka file in the workspace folder", + value: path.relative(config.cwd, vscode.window.activeTextEditor?.document.fileName || '') || 'test.kk' + }) + }), + // Start a program given just a path + vscode.commands.registerCommand('koka.startWithoutDebugging', (resource: vscode.Uri, compilerArgs?: string, programArgs?: string[]) => { + const launchConfig = + { + name: `koka run: ${resource.path}`, + request: "launch", + type: "koka", + program: resource.fsPath, + compilerArgs, + programArgs + } + console.log(`Launch config ${launchConfig}`) + vscode.debug.startDebugging(vscode.workspace.getWorkspaceFolder(resource), launchConfig as vscode.DebugConfiguration) + }), + // Start a program given a path and a function name + vscode.commands.registerCommand('koka.interpretExpression', (resource: vscode.Uri, functionName: string, compilerArgs?: string, programArgs?: string[]) => { + const launchConfig = + { + name: `koka run: ${resource.path}`, + request: "launch", + type: "koka", + program: resource.fsPath, + functionName, + compilerArgs, + programArgs + } + console.log(`Launch config ${launchConfig}`) + vscode.debug.startDebugging(vscode.workspace.getWorkspaceFolder(resource), launchConfig as vscode.DebugConfiguration) + }), + ) + +} + + +class KokaRunConfigurationProvider implements DebugConfigurationProvider { + + /** + * Massage a debug configuration just before a debug session is being launched, + * e.g. add all missing attributes to the debug configuration. + */ + resolveDebugConfiguration(folder: WorkspaceFolder | undefined, config: DebugConfiguration, token?: CancellationToken): ProviderResult { + // if launch.json is missing or empty + if (!config.type && !config.request && !config.name) { + const editor = vscode.window.activeTextEditor + if (editor && editor.document.languageId === 'koka') { + config.type = 'koka' + config.name = 'Launch' + config.request = 'launch' + config.program = '${file}' + config.stopOnEntry = true + } + } + + if (!config.program) { + return vscode.window.showInformationMessage("Cannot find a program to debug").then(_ => { + return undefined // abort launch + }) + } + + return config + } +} + +class InlineDebugAdapterFactory implements vscode.DebugAdapterDescriptorFactory { + + constructor(private readonly config: KokaConfig) { } + + createDebugAdapterDescriptor(_session: vscode.DebugSession): ProviderResult { + if (languageServer.languageClient) + return new vscode.DebugAdapterInlineImplementation(new KokaDebugSession(this.config, languageServer.languageClient)) + } +} \ No newline at end of file diff --git a/support/vscode/koka.language-koka/src/lang-server.ts b/support/vscode/koka.language-koka/src/lang-server.ts new file mode 100644 index 000000000..74019c992 --- /dev/null +++ b/support/vscode/koka.language-koka/src/lang-server.ts @@ -0,0 +1,155 @@ + +import * as vscode from "vscode" +import * as child_process from "child_process" +import { AddressInfo, Server, createServer } from 'net' + +import { + DidChangeConfigurationNotification, + LanguageClient, + LanguageClientOptions, + RevealOutputChannelOn, + StreamInfo, +} from 'vscode-languageclient/node' +import { KokaConfig } from "./workspace" + +let stderrOutputChannel: vscode.OutputChannel +let stdoutOutputChannel: vscode.OutputChannel +let firstRun = true + +export class KokaLanguageServer { + languageClient?: LanguageClient + languageServerProcess?: child_process.ChildProcess + socketServer?: Server + outputChannel?: vscode.OutputChannel + lspWriteEmitter: vscode.EventEmitter = new vscode.EventEmitter(); + lspPty?: vscode.Pseudoterminal + lspTerminal?: vscode.Terminal + + constructor(context: vscode.ExtensionContext) { + if (firstRun) { + stderrOutputChannel = vscode.window.createOutputChannel('Koka Language Server Stderr') + stdoutOutputChannel = vscode.window.createOutputChannel('Koka Language Server Stdout') + context.subscriptions.push(stderrOutputChannel) + context.subscriptions.push(stdoutOutputChannel) + firstRun = false; + } + } + + showOutputChannel() { + if (!this.lspTerminal?.exitStatus) { + this.outputChannel?.show() + } else if (this.lspPty) { + this.lspTerminal = vscode.window.createTerminal({ + name: 'Koka Language Server', + pty: this.lspPty, + isTransient: true + }) + this.lspTerminal.show() + } + } + + async start(config: KokaConfig, context: vscode.ExtensionContext) { + console.log(`Koka: Language Server ${config.command} ${config.langServerArgs.join(" ")} Workspace: ${config.cwd}`) + let self = this; + function serverOptions(): Promise { + return new Promise((resolve, reject) => { + let timeout = setTimeout(() => { + reject("Server took too long to connect") + }, 3000) + self.socketServer = createServer((s) => { + console.log("Got Connection to Client") + clearTimeout(timeout) + resolve({ writer: s, reader: s }) + }).listen(0, "127.0.0.1", () => { + const port = (self.socketServer!.address() as AddressInfo).port + console.log(`Starting language server in ${config.cwd} on port ${port}`) + self.languageServerProcess = child_process.spawn(config.command, [...config.langServerArgs, `--lsport=${port}`], { + cwd: config.cwd, + env: process.env, + }) + if (config.debugExtension) { + self.languageServerProcess?.stderr?.on('data', (data) => { + // console.log(data.toString()) + stderrOutputChannel.append(`${data.toString()}`) + }) + self.languageServerProcess?.stdout?.on('data', (data) => { + // console.log(data.toString()) + stdoutOutputChannel.append(`${data.toString()}`) + }) + } + }) + }) + } + // This issue: https://github.com/microsoft/vscode/issues/571 + // This sample: https://github.com/ShMcK/vscode-pseudoterminal/blob/master/src/extension.ts + this.lspPty = { + onDidWrite: (listener) => this.lspWriteEmitter.event((e) => listener(e.replace('\r\n', '\n').replace('\n', '\r\n'))), + open: () => { }, + close: () => { } + }; + this.lspTerminal = vscode.window.createTerminal({ + name: 'Koka Language Server', + pty: this.lspPty, + isTransient: true + }) + this.outputChannel = { + name: 'Koka Language Server', + append: (value: string) => this.lspWriteEmitter.fire(value), + appendLine: (value: string) => { + this.lspWriteEmitter.fire(value) + this.lspWriteEmitter.fire('\r\n') + }, + clear: () => { + this.lspWriteEmitter.fire("\x1b[2J\x1b[3J\x1b[;H") + }, + show: () => this.lspTerminal?.show(), + hide: () => this.lspTerminal?.hide(), + dispose: () => { + this.lspTerminal?.dispose() + this.lspWriteEmitter.dispose() + this.lspPty?.close() + }, + replace: (v) => { + this.lspWriteEmitter.fire("\x1b[2J\x1b[3J\x1b[;H") + this.lspWriteEmitter.fire(v) + }, + + }; + const clientOptions: LanguageClientOptions = { + documentSelector: [{ language: 'koka', scheme: 'file' }], + outputChannel: this.outputChannel, + revealOutputChannelOn: RevealOutputChannelOn.Never, + markdown: { + isTrusted: true, + supportHtml: true, + } + } + this.languageClient = new LanguageClient( + 'Koka Language Client', + serverOptions, + clientOptions, + ) + context.subscriptions.push(this) + + await this.languageClient.start() + let isDark = vscode.window.activeColorTheme.kind == vscode.ColorThemeKind.Dark + this.languageClient.sendNotification(DidChangeConfigurationNotification.type, { settings: { colors: { mode: isDark ? "dark" : "light" } } }) + return this.languageClient + } + + async dispose() { + try { + await this.languageClient?.stop() + await this.languageClient?.dispose() + const result = this.languageServerProcess?.kill('SIGINT') + if (!result) { + console.log("Failed to end language server with SIGINT, trying SIGTERM") + this.languageServerProcess?.kill() + } + this.socketServer?.close() + // TODO: Does the terminal need to be disposed or is that handled by disposing the client + } catch { + // Ignore for now, the process should automatically die when the server / client closes the connection + } + } +} \ No newline at end of file diff --git a/support/vscode/koka.language-koka/src/workspace.ts b/support/vscode/koka.language-koka/src/workspace.ts new file mode 100644 index 000000000..9ae2d6a6b --- /dev/null +++ b/support/vscode/koka.language-koka/src/workspace.ts @@ -0,0 +1,220 @@ +import * as path from "path" +import * as fs from "fs" +import * as vs from "vscode" +import * as os from "os" +import * as vscode from "vscode" +import * as child_process from "child_process" +import * as semver from "semver" + +interface SDKs { sdkPath: string, allSDKs: string[] } +const kokaExeName = os.platform() === "win32" ? "koka.exe" : "koka" +const latestVersion = "2.4.3" + +const home = os.homedir(); +export async function scanForSDK(context: vscode.ExtensionContext, config: vscode.WorkspaceConfiguration): Promise { + const processPath = (process.env.PATH as string) || "" + const paths = processPath.split(path.delimiter).filter((p) => p) + + const dev = path.join(home, 'koka') + let defaultSDK = "" + let allSDKs = [] + if (fs.existsSync(dev)) { + + let command = 'stack path --local-install-root' + const ghc = `${home}/.ghcup/env` + if (fs.existsSync(ghc)) { + // Linux ghcup installation does not show up in vscode's process.PATH, + // ensure stack uses the correct ghc by sourcing the ghcup env script + command = `${process.env.SHELL} -c "source ${ghc} && stack path --local-install-root"` + } + + const options = { cwd: dev, env: process.env } + const result = child_process.execSync(command, options) + const devPath = result.toString().trim(); + // Prioritize dev + const sdkPath = path.join(devPath, 'bin', kokaExeName) + if (fs.existsSync(sdkPath)) { + vs.window.showInformationMessage("Koka dev SDK found!") + console.log("Koka: Using dev build of koka at " + devPath) + defaultSDK = sdkPath + allSDKs.push(defaultSDK) + } else { + vs.window.showInformationMessage("Koka dev environment found, but no built SDK") + } + } + + const local = path.join(home, '.local/bin') + for (const p of [local].concat(paths)) { + if (fs.existsSync(path.join(p, kokaExeName))) { + console.log("Koka: Found build of koka at " + p) + const sdkPath = path.join(p, kokaExeName) + allSDKs.push(sdkPath) + if (defaultSDK === "") { + vs.window.showInformationMessage(`Using Koka SDK at ${p}`) + defaultSDK = sdkPath + } + } + } + defaultSDK = config.get('languageServer.compiler') as string || defaultSDK + if (defaultSDK === "" && !config.get('languageServer.compiler')) { + console.log('Koka: No Koka SDK found') + vs.window.showWarningMessage("Koka SDK not found on path or in ~/.local/bin") + return await downloadSDK(context, config, false, undefined) + } else if (semver.lt(getSDKVersion(defaultSDK), latestVersion) ) { + return await downloadSDK(context, config, true, {sdkPath: defaultSDK, allSDKs: allSDKs }) + } + return { sdkPath: defaultSDK, allSDKs: allSDKs } +} + +function getSDKVersion(sdkPath: string): string { + const options = { env: process.env } + const result = child_process.execSync(`${sdkPath} --version`, options) + const versionRegex = /version: ([0-9]+\.[0-9]+.[0-9]+)/g; + const match = versionRegex.exec(result.toString()) + console.log("Koka: Found version " + match[1].toString()) + return match[1].toString(); +} + +export async function downloadSDK(context: vscode.ExtensionContext, config: vscode.WorkspaceConfiguration, upgrade: boolean, old: (SDKs|undefined)): Promise { + const response = context.globalState.get('koka-download') + if (response === false){ + return old; + } + const decision = await vscode.window.showInformationMessage( + `${upgrade ? "There is an update for koka available\n\n" : ""}Download and Install Koka, continue?`, + { modal: true }, + 'Yes', + 'No' + ) + if (decision == 'No') { + await context.globalState.update('koka-download', false) + return old; + } + let command = "curl -sSL https://github.com/koka-lang/koka/releases/latest/download/install.sh | sh && exit" + if (os.platform() === "win32") { + command = "curl -sSL -o %tmp%\install-koka.bat https://github.com/koka-lang/koka/releases/latest/download/install.bat && %tmp%\install-koka.bat && exit" + } + const term = vscode.window.createTerminal({ name: "Install Koka", cwd: home, shellPath: DefaultShellPath, isTransient: true, message: "Installing Koka" }) + term.sendText(command) + term.show() + let dispose: vscode.Disposable | undefined = undefined; + const result = await new Promise((resolve, reject) => { + let finished = false; + // Race between a 30 second timeout on watching terminals + // and the terminal finishing installation + setTimeout(() => { + if (!finished){ + console.log("Koka: Installation timed out") + resolve(undefined); + finished = true; + } + }, 30000); + dispose = vscode.window.onDidCloseTerminal(async (t) => { + console.log("Terminal closed") + if (t === term) { + console.log("Koka: Installation finished") + const sdk = await scanForSDK(context, config); + if (!finished){ + const {sdkPath, allSDKs} = sdk + if (sdkPath){ + console.log(path.join(sdkPath)) + const sdkRoot = path.dirname(path.dirname(sdkPath)) + const examples = path.join(sdkRoot, "share", "koka", `v${latestVersion}`, "lib", "samples") + if (fs.existsSync(examples)) { + let dest = path.join(context.globalStorageUri.fsPath, "samples") + fs.cp(examples, dest, {recursive:true}, async (err) => { + if (!err){ + const decision = await vscode.window.showInformationMessage( + `Open Koka's latest samples folder?`, + { modal: true }, + 'Yes', + 'Yes (new window)', + 'No' + ) + if (decision == 'No') { + return; + } + const examplesUri = vscode.Uri.file(dest) + vscode.commands.executeCommand('vscode.openFolder', examplesUri, {forceNewWindow : decision == 'Yes (new window)'}) + } + }) + + } + console.log(examples) + resolve(sdk); + } else { + resolve(undefined) + } + finished = true; + } + } + }) + }) + dispose?.dispose() + return result; +} + +export async function uninstallSDK(context: vscode.ExtensionContext) { + const decision = await vscode.window.showInformationMessage( + `Uninstall the system Koka installation, continue?`, + { modal: true }, + 'Yes', + 'No' + ) + if (decision == 'No') { + return + } + let command = "curl -sSL https://github.com/koka-lang/koka/releases/latest/download/install.sh | sh -s -- -u -f" + if (os.platform() === "win32") { + command = "curl -sSL -o %tmp%\install-koka.bat https://github.com/koka-lang/koka/releases/latest/download/install.bat && %tmp%\install-koka.bat -u -f" + } + const term = vscode.window.createTerminal({ name: "Uninstall Koka", cwd: home, shellPath: DefaultShellPath, isTransient: true, message: "Uninstalling Koka, you can close the terminal when done" }) + term.sendText(command) + term.show() +} + +const DefaultShellPath = os.platform() === "win32" ? "C:\\Windows\\System32\\cmd.exe" : null + +export class KokaConfig { + constructor(config: vscode.WorkspaceConfiguration, sdkPath: string, allSDKs: string[]) { + this.config = config + this.debugExtension = config.get('debugExtension') as boolean + this.defaultSDK = sdkPath + this.sdkPath = sdkPath + this.allSDKs = allSDKs + this.cwd = config.get('languageServer.cwd') as string || vscode.workspace.workspaceFolders![0].uri.fsPath + this.langServerArgs = [] + this.additionalArgs = config.get('languageServer.compilerArgs') as string[] || [] + this.selectSDK(this.sdkPath) + this.target = "C" + } + defaultSDK: string + sdkPath: string + allSDKs: string[] + config: vscode.WorkspaceConfiguration + debugExtension: boolean + command?: string | null + langServerArgs: string[] + additionalArgs: string[] + target: string + cwd: string + + selectSDK(path: string) { + if (!fs.existsSync(path)) { + console.log(`Koka compiler not found at this location ${path}`) + this.command = null + return + } + // Test we can execute the sdk command + fs.accessSync(path, fs.constants.X_OK) + this.command = this.sdkPath + this.langServerArgs = ["--language-server", `-i${this.cwd}`, ...this.additionalArgs] + } + + selectTarget(t: string) { + if (!["C", "JS", "WASM", "C#"].includes(t)) { + return + } + this.target = t + } +} \ No newline at end of file diff --git a/support/vscode/koka.language-koka/tsconfig.json b/support/vscode/koka.language-koka/tsconfig.json new file mode 100644 index 000000000..3cae2e758 --- /dev/null +++ b/support/vscode/koka.language-koka/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "es2020", + "lib": [ + "es2020" + ], + "outDir": "out", + "sourceMap": true, + "strict": false, + "rootDir": "src" + }, + "exclude": [ + "node_modules", + ".vscode-test" + ] +} \ No newline at end of file diff --git a/util/install.bat b/util/install.bat index d337f5331..7f52eb483 100644 --- a/util/install.bat +++ b/util/install.bat @@ -4,7 +4,7 @@ rem Installation script for Koka; use -h to see command line options. rem ------------------------------------------------------------------ setlocal -set KOKA_VERSION=v2.4.2 +set KOKA_VERSION=v2.4.3 set KOKA_PREFIX=%LOCALAPPDATA%\koka set KOKA_UNINSTALL=N set KOKA_HELP=N diff --git a/util/install.sh b/util/install.sh index 0e3e5ddfc..80e9de862 100755 --- a/util/install.sh +++ b/util/install.sh @@ -4,7 +4,7 @@ # Installation script for Koka; use -h to see command line options. #----------------------------------------------------------------------------- -VERSION="v2.4.2" +VERSION="v2.4.3" MODE="install" # or uninstall PREFIX="/usr/local" QUIET=""