Compare commits

...

414 Commits

Author SHA1 Message Date
onryo fe04ef3095 Merge branch 'dev' 1 month ago
onryo 23e3e3899a Add release name before merging 1 month ago
Duke 23813ae00e Update relnotes 1 month ago
Duke d8e528f696 Bump version to 1.4.2 1 month ago
Duke 5610d6c572 Update relnotes for 1.4.2 1 month ago
Duke 3a6f632b9b Try to prevent #155 2 months ago
Duke 2754629a95 Do not log sensitive data to STDOUT 2 months ago
Duke eea2a9a6bf Choose number of compile jobs in build.sh #156 2 months ago
duke e6195fd918 Merge pull request 'Replace old graphics with new' (#147) from onryo into dev 3 months ago
Duke b3f195432e Merge branch 'dev' 3 months ago
Duke 02325ad7ae relnotes 3 months ago
Duke 0c9a3f43ad linguist 3 months ago
Duke 00b143e04f Create relnotes for 1.4.1 3 months ago
Duke c442377473 bump version 3 months ago
duke 5659a2a725 Merge pull request 'Debug tab' (#148) from debuglog into dev 3 months ago
Duke 702619a8e0 Support dragonx debug log and custom number of lines 3 months ago
onryo ee5e94cfd0 fix build when removing old files 3 months ago
onryo 8119c5b6e3 fix 146 3 months ago
Duke da3fb9c8a4 Add refresh button for debug log 3 months ago
Duke 0f45b3fe5b Add tab for viewing the debug log 3 months ago
Duke 05790935ba Revert "change gif when sending" 3 months ago
duke 203c23dad2 Merge pull request 'Allow custom rescan height on privkey import' (#145) from import into dev 3 months ago
Duke 1b10aefbe8 Cleanup 3 months ago
Duke d35a601dcc verify that taddr privkeys are base58 3 months ago
Duke b52c7bc151 Remove isSproutAddress 3 months ago
Duke a0cc4184bc Trim leading and trailing whitespace from rescan height when importing a privkey 3 months ago
Duke 8b41a3b0f4 Disable rescanfrom input if rescan is unchecked 3 months ago
Duke 68bd0db44c Only import valid zaddr+taddr privkeys and only rescan if there was at least 1 valid privkey 3 months ago
Duke 2000377783 Too bad this code does not seem to work 3 months ago
Duke e042c1fb09 We do not support sprout privkeys that begin with SK 3 months ago
Duke 7db95fbf49 Support disabling rescan or a custom rescan height when importing privkeys 3 months ago
Duke 8bb0b3df5c Make import popup look nicer 3 months ago
Duke f689547a36 Add basic rescan options to import popup 3 months ago
onryo f50ccd78b5 change gif when sending 3 months ago
onryo 219e41ccb5 dialog text 3 months ago
Duke ec6327a6b0 Add function to validate taddr privkeys 3 months ago
Duke 227dcaddbb Slightly better zaddr privkey validation 3 months ago
onryo 868bf83155 add rescanfrom 3 months ago
onryo 4ef65d1a3f add chkrescan 3 months ago
Duke 17c44521be Use takeFirst() instead of first() and pop_front() 3 months ago
Duke c5ceac8443 View transparent spends and shielded outputs in txs; Allow double clicking on a tx in tx tab to view tx 3 months ago
Duke 8b8bca02ac Add View transaction as right menu option in tx tab 3 months ago
Duke 81702d25c1 Add view transaction ui file 3 months ago
Duke fb67b86d0d View Transaction 3 months ago
Duke f914f6d61a Just say Error, since we show this error for all errors, not just transaction errors 3 months ago
Duke a18014b6d4 Render valuePools json and each tx in their own property 3 months ago
Duke 1e4095651a Allow items to be selected 4 months ago
Duke 946ed661e9 Tor v3 has been supported for a while 4 months ago
Duke 9e4c26ccd2 Show transaction list in CSV format when viewing a block; allow viewing block 0 4 months ago
Duke 5dc1944084 More debugging about block properties 4 months ago
Duke 9187f3c620 Add getrawtransaction RPC method 4 months ago
Duke 4d28ac2969 Add z_viewtransaction RPC method 4 months ago
Duke d3846c7bdf Merge branch 'master' into dev 4 months ago
Duke 775581f942 Merge branch 'dev' 4 months ago
Duke 0c70550080 update relnotes 4 months ago
Duke e7d46d9a95 update translations 4 months ago
Duke 9bf04778bd bump version to 1.4.0 4 months ago
fekt 427c960546 Require int for block height 7 months ago
Duke b8955b176f Render integer values correctly in Get Block Info 7 months ago
fekt 25630d75df Merge branch 'dev' of https://git.hush.is/hush/SilentDragon into dev 7 months ago
fekt dee213dc5a Adding missing getblock.ui 7 months ago
fekt ed22b79957 Update 'doc/relnotes/README.md' 8 months ago
fekt ba2f322124 Initial commit for viewing getblock info 8 months ago
fekt 64f32cac57 Update 'doc/relnotes/README.md' 8 months ago
fekt d06cc5af81 Allow setting IP for tor proxy 8 months ago
fekt ffb12e0adf Update 'doc/relnotes/README.md' 9 months ago
fekt dbc34dde12 Specify count for listtransactions 9 months ago
fekt cf5c369de3 Update relnotes 9 months ago
fekt ed1fab8550 Use single set of translation resources 1 year ago
fekt 41f18d76ee Revert "Update 'application-sdx.qrc'" 1 year ago
fekt d96fa89e02 Update 'application-sdx.qrc' 1 year ago
fekt 2834abcbc6 derp fix 1 year ago
fekt 03fc69d001 Added DragonX file names 1 year ago
fekt 8cfb0b4ec6 Fix for saving on Windows 1 year ago
Duke 1d2e7007fb Fix compiler errors and warnings 1 year ago
Jonathan "Duke" Leto 403b29ec2e Remove websocket junk 1 year ago
onryo 7fe00b6b46 Fix Lack of Q_OBJECT macros for #120 1 year ago
fekt 5c9cc656f0 Update 'README.md' 1 year ago
fekt 4bb1d98ecd Fixing SDX .wxs file 1 year ago
fekt b4400e3ac8 Wixl files for .msi 1 year ago
fekt fb07f11fd2 Update application-sdx.qrc 1 year ago
fekt 8d3fce909d DragonX info tab logo 1 year ago
Duke 047c2a0682 Merge branch 'dev' 1 year ago
Duke dbbcbf0407 Update relnotes 1 year ago
Duke 565344ff42 Update relnotes 1 year ago
Duke 1149e38b11 Update relnotes 1 year ago
Duke ee0fb815b9 update relnotes 1 year ago
Duke 9b2133a78a Cleanup 1 year ago
Duke 3cac061de9 linguist 1 year ago
Duke 486d363f99 sdx linguist docs 1 year ago
Duke d563c3e37d German translation of mining tab 1 year ago
Duke 3af25822ba remove websockets translation 1 year ago
Duke c333017e29 Remove wormhole translation strings 1 year ago
Duke a7df6b1117 Slightly improve translating mining tab when lang changes. Currently it only works once for some reason 1 year ago
Duke 7f41eb2944 Update mining thread combobox when lang changes 1 year ago
Duke 284f1cd80a Update text of start/stop mining buttons when language changes 1 year ago
Duke 63f431dfe8 linguist 1 year ago
Duke 7fd782ab93 Retranslate the tab text of the Mining tab when language changes at run-time 1 year ago
Duke 1cf1bb17dd Add qmake and make versions to build.sh output 1 year ago
Duke 9712ef59e5 UK translation updates 1 year ago
Duke 977f42e918 Translate some missing ZH strings 1 year ago
Duke ce447dbd5c Translate some missing ZH strings 1 year ago
Duke 784681d94c update translations 1 year ago
Duke aba447a829 Do not render lag/etc 1 year ago
Duke 56e7a70db2 update translations 1 year ago
duke 0a80801173 Update 'doc/relnotes/README.md' 1 year ago
duke 360bfb30db Update 'doc/relnotes/README.md' 1 year ago
fekt cab39801e7 UI tweaks 1 year ago
Duke 4d667fe6b2 Update Chinese translation of Mining Tab 1 year ago
Duke 766842176f Russian translation for Mining Tab 1 year ago
Duke c175b303bf Update Spanish translations 1 year ago
Duke c363a458b7 Add Spanish translation for mining tab 1 year ago
Duke dca66b70ed Integrate Tor explorer 1 year ago
Duke 08f2865c9a Clean out junk from translations 1 year ago
Duke 3062e67c74 SDX translations 1 year ago
Duke 3c9d22a754 Remove more SDA stuff 1 year ago
Duke 7ec220a9c3 Update translations 1 year ago
Duke a573794b1a Remove SDA stuff 1 year ago
Duke 31eb59c378 update .gitignore 1 year ago
Duke 82f2438533 Update translations 1 year ago
Duke 380e1193d3 Remove websockets from Dockerfile 1 year ago
Duke a3a85c4395 Remove websockets from SDX build project 1 year ago
Duke 3474360182 update docs re websockets 1 year ago
Duke bb8317ddfd Much rejoicing at the deletion of websockets 1 year ago
Duke 5729584be3 Remove mobile app code 1 year ago
Duke adc999e98f Remove mobile app menu item 1 year ago
Duke f591fe332b Allow custom tor port 1 year ago
Duke df27872363 ignore generated c++ file 1 year ago
Duke d2f648fe0f Add compiled SDX translations 1 year ago
Duke 4671fb0a8a Do not ignore compiled translations 1 year ago
Duke 5b175cd7a7 update SD translations 1 year ago
Duke fb7cbee741 update SDX translations 1 year ago
duke 52cba688ec Merge pull request 'DragonX support in SilentDragon (SilentDragonX)' (#112) from dragonx into dev 1 year ago
Duke 0b7c908c6e Render netsol in Node Info tab in SD 1 year ago
Duke e23c845f7d Prevent coredump in SD which should not call getmininginfo 1 year ago
Duke c4d9f4e6c5 toLower() 1 year ago
Duke b0292ff403 Try to fix SDX bug on Mac when running from an .app file 1 year ago
fekt 48bf0fe342 DragonX icons 1 year ago
fekt 2f099b3ebb SDX sapling param paths on OSX 1 year ago
fekt 080ac87cf5 Update dragonx.css 1 year ago
fekt 426d38b59d Update Info.plist 1 year ago
Duke a557e25b61 Attempt to fix short passwords on mac+win 1 year ago
fekt 9c946f82ea Resized DragonX startup animations 1 year ago
Duke f0beedd304 Instantly update the mining GUI when number of threads changes 1 year ago
Duke c065d253a0 If currently mining, automatically change number of threads when combobox changes 1 year ago
Duke 7a04a245b0 Show the word 'thread' or 'threads' when selecting number of mining threads 1 year ago
Duke 3da01807e5 SDX talks to dragonxd 1 year ago
Duke 36f50965f4 Use correct window title when shutting down SDX 1 year ago
Duke a7cd1d938f Use correct window title for startup connection dialog 1 year ago
Duke 5f28567cc9 Better estimated luck with less numerical error 1 year ago
fekt 0de898bcc3 Additional DragonX resources and modified to use single set of themes 1 year ago
fekt dfd45a4235 DragonX CSS tweaks 1 year ago
fekt 08485e10ad Setting DragonX default theme for additional exception 1 year ago
fekt ed2e08244f Set default theme for DragonX 1 year ago
fekt 2733c1bacc DragonX theme 1 year ago
fekt 765b768f14 Updated logo for QR code overlay 1 year ago
fekt 04093b0382 Reverting some previous modifications to fix cross-compiling wind0ze 1 year ago
fekt 38380980e3 Theme-based BG color fix behind image on Node info tab 1 year ago
fekt 31b549e0e3 Resource changes for DragonX 1 year ago
Duke 32b08ff83a Mining tab 1 year ago
Duke 3b521bdcf3 update sdx build 1 year ago
onryo e3ca42eac2 Update 'res/silentdragon_be.ts' 1 year ago
Duke c267f7d7e7 add some SDX images 1 year ago
Duke 723eabcecb Use the correct config file on mac+win 1 year ago
fekt f514551c7d wind0ze build script mods for SDX 1 year ago
Duke c6268fc3f2 Fix bugs in autogenerated dragonx confs 1 year ago
Duke aa019f1fe8 No trailing space in dragonx param list 1 year ago
Duke 26c665594e Try to make build-sdx.sh work on windoze 1 year ago
Duke 03c1133dee SDX build tweaks and translations 1 year ago
Duke 50882c6cc5 fix broken BE translation file 1 year ago
Duke 443a07e676 SilentDragonX 1 year ago
Duke a223d7f226 update translations 1 year ago
onryo 1c3a77e829 Updated Belarusian translation 1 year ago
Duke f9f88c6a66 Disable price feed by default 1 year ago
Duke 25acf96cf2 Merge branch 'dev' of https://git.hush.is/hush/SilentDragon into dev 1 year ago
Duke 0048ed3d7e Change rescan info poll to 10s 1 year ago
onryo e05c6b696f Updated Russian translation 1 year ago
onryo b53b39a1ae Updated Polish translation 1 year ago
Duke Leto 5f3fecc496 update issue template 1 year ago
Jonathan "Duke" Leto a00b1d604a More release process notes 1 year ago
Jonathan "Duke" Leto 5c76b656b5 Document static build for release bins 1 year ago
Jonathan "Duke" Leto 72516aea6b update release process 1 year ago
Jonathan "Duke" Leto eb2411594d Update relnotes 1 year ago
Jonathan "Duke" Leto e653d38577 SD release process 1 year ago
Jonathan "Duke" Leto dd249a6315 SD release process 1 year ago
Jonathan "Duke" Leto d041e6d8b6 issue template 1 year ago
Jonathan "Duke" Leto fc4a4c9e21 Merge branch 'dev' of https://git.hush.is/hush/SilentDragon into dev 1 year ago
Jonathan "Duke" Leto 261831291c issue template 1 year ago
Duke Leto a23169729a Update 'doc/release-process.md' 1 year ago
Duke Leto 8f3f2a339d Remove migration stuff 1 year ago
Duke Leto 91c78e176c linguist for NL 1 year ago
onryo 86ca4e140b NL translation 1 year ago
Jonathan "Duke" Leto 6cba952211 Remove vanished translation entries 1 year ago
Jonathan "Duke" Leto 5c4c4af25a Rename to createhushconfdialog.ui 1 year ago
Jonathan "Duke" Leto 3ca6f349e8 Remove vanished translation junk 1 year ago
Jonathan "Duke" Leto 88d29104e6 Remove unused translation entries 1 year ago
Jonathan "Duke" Leto ff423ac311 Clean up 1 year ago
Jonathan "Duke" Leto f96cc4d1fe Delete unused file 1 year ago
Jonathan "Duke" Leto 179dea40a6 Update translations 1 year ago
Jonathan "Duke" Leto b5b1732454 Remove junk 1 year ago
Jonathan "Duke" Leto 08c18db6fd Update copyright year to 2022 1 year ago
Jonathan "Duke" Leto 68256aab70 Update release process 1 year ago
Jonathan "Duke" Leto 0316f0f4f2 Document git merge --abort 1 year ago
Jonathan "Duke" Leto 74a65f514e Update release process 1 year ago
Jonathan "Duke" Leto 08ac88d2cd Merge branch 'master' into dev 1 year ago
Jonathan "Duke" Leto a9467af35e Clarify that the fixes are actually in the embedded hushd 1 year ago
Jonathan "Duke" Leto de3bfba7a0 Update release notes 1 year ago
Duke Leto c8c26b12df Use PreciseTimer for main timer and rescanTimer 1 year ago
Duke Leto 706689f86b Check if getrescaninfo exists and improved error handling 1 year ago
Duke Leto e81eb093b1 Fix compile 1 year ago
fekt 8a0cffba67 Update midnight.css 1 year ago
fekt 9c1db5ff8b getrescaninfo and other tweaks 1 year ago
Duke Leto 2f40a16665 Update 'doc/relnotes/README.md' 1 year ago
Duke Leto 2cfd0865b7 Update 'doc/relnotes/README.md' 1 year ago
fekt 064b6202fb Icon for generate/mined 1 year ago
fekt c3c7f5161a QR code and memo tweaks 1 year ago
fekt eb42261908 GUI tweaks for dark themes 1 year ago
fekt 6b6c04404f Minor changes to messages and translation support 1 year ago
fekt 8f79558881 Status bar changes when loading txs 1 year ago
fekt 0f4c91397f Reverting inadvertent change 1 year ago
fekt 25d3c9dc34 Banning/unbanning improvements 1 year ago
fekt 8565bc266a Changes for icons 1 year ago
fekt dc5f3c3a11 Fix for settings/connection info 1 year ago
fekt f8dbc9da7a silentdragon.pro changes 1 year ago
fekt 06e5e851a2 Revert "Missing ui_rescandialog.h" 1 year ago
fekt 19567dd144 Missing ui_rescandialog.h 1 year ago
fekt 7eea0fc743 Missing header for rescandialog 1 year ago
Duke Leto 6b4aa2e38d update relnotes 1 year ago
fekt c435a818b4 Test reading debug.log 1 year ago
fekt af98833558 Icons in tx table and memo improvement 1 year ago
fekt 6fc4e3731c Icons for tx table and settings core dump fix 1 year ago
fekt f9b98b733f WIP: Rescan changes 1 year ago
fekt e59c0737ea QR code changes 1 year ago
fekt ab17a1012e Fix for memo not showing in GUI for sender 1 year ago
fekt 19fc806fad Adding back inadvertent changes 1 year ago
fekt d3638b3320 UI tweaks to send tab 1 year ago
fekt 26a9788f7f Fixes for timer to not constantly poll z_getoperationstatus 1 year ago
fekt 39a9bf2526 Unban all peers missing header change 1 year ago
fekt 186d865b22 Unban all peers 1 year ago
fekt a236d83322 Adding ban/unban to peers list 2 years ago
Duke Leto ae284ee32c Add methods for z_sweepstatus and z_consolidationstatus 2 years ago
Duke Leto dcd3f43d0f Add method for setban RPC 2 years ago
Duke Leto 81c3aca28d Method to call clearbanned rpc 2 years ago
Duke Leto 24364cfba0 Allow rescan RPC to take an optional height 2 years ago
Duke Leto b5f0eee1ff Add method to call the rescan RPC 2 years ago
Duke Leto e0ca6da85b The Answer 2 years ago
Duke Leto bef407a6db Change report bug link to TG support, since only logged in users can make Gitea issues 2 years ago
Jonathan "Duke" Leto 2f8c2b0537 Clean up 2 years ago
Jonathan "Duke" Leto f21475deb4 Update relnotes and add release-process.md 2 years ago
jahway603 7ca4533ab4 added wallet location info 2 years ago
Duke Leto 8e2bf50081 This text only confuses users 2 years ago
Duke Leto 702ec7a72d ignore core files 2 years ago
Duke Leto b276a42ab0 Remove unused translation stuff 2 years ago
Duke Leto 0427088084 Merge NL translation updates 2 years ago
Duke Leto cc656e6d39 update translations 2 years ago
onryo 8ea6ea3ed2 Upload files to 'res' 2 years ago
onryo af6245a599 Upload files to 'res' 2 years ago
Duke Leto 68246f5b6d Merge branch 'dev' of https://git.hush.is/hush/SilentDragon into dev 2 years ago
Duke Leto e5b795597c Merge branch 'language' into dev 2 years ago
Duke Leto bc2757300e more websocket debugz 2 years ago
Duke Leto 9d67619569 Merge pull request 'Polished make-deb.sh + polished silentdragon icon' (#82) from odinzu-dev into dev 2 years ago
oDinZu a4932f71d3 update make-deb.sh for silentdragon bin only and updated silentdragon icon again 2 years ago
oDinZu dee7636c9f updated script for .deb files with SD, including new sd.xpm 2 years ago
Duke Leto 69119491f7 add more debug to wormhole logging, because coredumps 2 years ago
Duke Leto 9a960c697d Prevent the translation of theme names, which causes problems 2 years ago
Duke Leto 1d05221ac9 Report currency changes in status bar 2 years ago
Duke Leto 20ce45f754 Prevent coredumps from invalid languages in config file 2 years ago
Duke Leto ea1b0d75b0 Use the default system language and render en_US as English 2 years ago
Duke Leto e889668d4e Write the selected language to our config file and read it in and use it when SD starts 2 years ago
Duke Leto c3ea342c7c Replace old malicious explorer URLs if they are found in a config file 2 years ago
Duke Leto f4043ec439 Show properly uppercased language name in statusBar 2 years ago
Duke Leto e9195e78d4 Uppercase the first letter of all languages 2 years ago
Duke Leto 4b35ff58dc Prevent invalid theme names and use dark theme if one is found 2 years ago
Duke Leto 82ef15ea75 Show language list in native language 2 years ago
Duke Leto 1267988ab4 Theme change debugging and set to dark in exceptions 2 years ago
Duke Leto 17337585a3 Sort languages in alphabetical order 2 years ago
Duke Leto ff522eff27 Retranslate the settings modal when language changes 2 years ago
Duke Leto 3a17596931 Attempt to modify changeEvent for our dialogs, but not quite 2 years ago
Duke Leto 1bdb948a3c Show currently selected language in combobox 2 years ago
Duke Leto 1a9569cf50 Make Filipino and all 3 letter language codes work 2 years ago
Duke Leto d16b35d7c1 cleanup 2 years ago
Duke Leto 1712fc1d5c Allow changing language at run-time to any supported language 2 years ago
Duke Leto 391f330044 Render language list as a QComboBox 2 years ago
Duke Leto 2bbab2b675 Plumbing for selecting language at run-time 2 years ago
Duke Leto d407d7aff3 Fix animations on send and shutdown 2 years ago
Duke Leto ba73876f59 bump version to 1.3.1 2 years ago
Duke Leto dc4f03a483 remove duplicate qmake check, fixes #74 2 years ago
Duke Leto 60b1dc77f7 Update mkrelease.sh 2 years ago
Duke Leto 0a1a4efb40 update names 2 years ago
Duke Leto b8a3707475 update name 2 years ago
Duke Leto 1d70d7c8f6 update .gitignore 2 years ago
Duke Leto aa78e4faea Merge branch 'dev' of https://git.hush.is/hush/SilentDragon into dev 2 years ago
Duke Leto 6f86c5dde9 Update release scripts 2 years ago
Duke Leto f6237dcfa9 Merge pull request 'One startup screen for all themes' (#73) from onryo/SilentDragon:dev into dev 2 years ago
Duke Leto b04b3b5927 Merge branch 'dev' into dev 2 years ago
onryo 1fc0204f8a Update 'src/connection.cpp' 2 years ago
Duke Leto 7f3041dd09 Merge branch 'dev' 2 years ago
Duke Leto c3ba68cabd reorder relnotes 2 years ago
Duke Leto 66955b6457 Update relnotes 2 years ago
Duke Leto 4e7da355f5 relnotes formatting 2 years ago
Duke Leto 3cfc398682 update 2 years ago
Duke Leto 2d7974da60 Update our readme with some gems; delete twitter badge 2 years ago
Duke Leto fcee06a5c3 Fix autostart of hushd 2 years ago
Duke Leto 968dfef194 Show version of SD that generates a config file 2 years ago
Duke Leto 11783730a4 Merge branch 'dev' 2 years ago
Duke Leto 193181d2c7 Credit for animation 2 years ago
Duke Leto 0e4ebd0a84 Berserk Bonnacon 2 years ago
Duke Leto 4aa2fc4cec linguist 2 years ago
Duke Leto 52ade59e22 Merge branch 'master' into dev 2 years ago
Duke Leto cc20883fbf Add 1.3.0 relnotes 2 years ago
Duke Leto 64f9d1067b Add relnotes 2 years ago
Duke Leto 0d1c6048e4 Clean up 2 years ago
Duke Leto 7275099e3b HUSH 2 years ago
Duke Leto 32b142ff95 More logging for refreshPrice 2 years ago
Duke Leto e7d11b3644 In case of exception, use BTC instead of USD as default currency 2 years ago
Duke Leto b669d405c0 Merge pull request 'New animated startup GIF' (#69) from onryo/SilentDragon:dev into dev 2 years ago
onryo a3b27af2fa Upload files to 'res' 2 years ago
Duke Leto 80f82fd965 Merge branch 'dev' of https://git.hush.is/hush/silentdragon into dev 2 years ago
Duke Leto 4ca02f3f73 Look for qmake+make in build.sh 2 years ago
Duke Leto 8caee21ccd Update translations 2 years ago
Duke Leto 14e2ed59c2 Add PL 2 years ago
Duke Leto 44cce4a364 Merge pull request 'pl' (#67) from onryo/SilentDragon:dev into dev 2 years ago
onryo d78de68f9f Upload files to 'res' 2 years ago
onryo cc23a3fb7b Update 'silentdragon.pro' 2 years ago
onryo b6d347fbea no translation for commands 2 years ago
jahway603 0864656e90 added linux .desktop file 2 years ago
onryo 4ed7462f70 BE translation update 2 years ago
onryo bbc9091ba8 RU translation update 2 years ago
Duke Leto c6979bd845 update translations 2 years ago
Duke Leto 32e4f06646 hushDir 2 years ago
Duke Leto 324efe7373 It is a hushd version 2 years ago
Duke Leto 57e1876daa Hush allows duplicate zaddr recipients 2 years ago
Duke Leto 3268ba8619 It is a hush conf 2 years ago
Duke Leto d374c74f00 Clean up 2 years ago
Duke Leto 2cded5d345 Update ES translation 2 years ago
Duke Leto a3a78bccff Update German translation 2 years ago
Duke Leto f8d353f4b6 Update German translation 2 years ago
Duke Leto 8718b3d183 update translations 2 years ago
Duke Leto 99a38133c1 Merge branch 'dev' of https://git.hush.is/hush/SilentDragon into dev 2 years ago
Duke Leto b7eb93ec7c Report QT version in About 2 years ago
jahway603 88b0f5d145 minor change to README.md so users will stop running the comment as part of the command 2 years ago
Duke Leto e63171562e It is a Hush wallet dir 2 years ago
Duke Leto fdf853269a Merge branch 'master' into dev 2 years ago
Duke Leto f624aa4be4 Update deb package script 2 years ago
Duke Leto 75c89c4be4 Update binary tarball script for new binary names 2 years ago
Duke Leto 8228015946 Update version to 1.3.0 2 years ago
Duke Leto 293f505e69 Update code for our new binary names 2 years ago
Duke Leto 0f46ec2305 This is no longer a script 2 years ago
Duke Leto eb660bd2ee update dev docs 2 years ago
Duke Leto d562fc6b16 Give SD users an easy way to send taddr funds to a zaddr 3 years ago
Duke Leto b15444cbdb Start adding GUI for z_mergetoaddress 3 years ago
Duke Leto dfb69d5095 Basic shielding of coinbase funds 3 years ago
Duke Leto d9a5f57da2 z_shieldcoinbase plumbing 3 years ago
Duke Leto 2ea1ee9385 Teach SD about ~/.hush/ 3 years ago
Duke Leto db5b0e94ee Merge pull request 'added opengl error solution to readme' (#19) from oDinZu/SilentDragon:master into master 3 years ago
oDinZu 15652dbc4b added opengl error solution to readme 3 years ago
Duke Leto 20e900bd98 update image when making HUSH3.conf 3 years ago
Duke Leto 8520a50fb9 update about tab image 3 years ago
Duke Leto 4e13de530f Upload files to 'res' 3 years ago
Duke Leto 0a4af21801 . 3 years ago
Duke Leto a5cc5a1c9c update mac build instructions 3 years ago
Duke Leto 8331250dde Merge branch 'master' into dev 3 years ago
Duke Leto efa4c73724 Merge pull request 'sapling files now included' (#14) from sapling-params into dev 3 years ago
Duke Leto df640ccf39 Merge branch 'master' of https://git.hush.is/hush/SilentDragon 3 years ago
jahway603 150c2559ce sapling files now included 3 years ago
Duke Leto e21c52aec9 Merge pull request 'new screenshots' (#13) from screenshots into master 3 years ago
jahway603 ebf364a4bc minor README.md change 3 years ago
jahway603 4f0f6b3dd6 added screenshots for each tab 3 years ago
Duke Leto 8a985aead6 Merge branch 'dev' of https://git.hush.is/hush/SilentDragon into dev 3 years ago
Duke Leto 0a742e7438 Bump version to 1.2.0 3 years ago
Duke Leto 7035787708 Merge pull request 'updated BE and RU langs' (#9) from onryo/SilentDragon:onryo into dev 3 years ago
onryo 6a5be2edba RU lang 3 years ago
onryo c7db5ff099 BE lang 3 years ago
Duke Leto 042caa1c8f linguist updates 3 years ago
Duke Leto 0cee12d854 Merge remote-tracking branch 'onryo/dev' into dev 3 years ago
onryo e3a1221a10 updated BE lang 3 years ago
onryo 51059aa6c3 updated RU lang for the upcoming release 3 years ago
Duke Leto 46ad8b6611 linguist 3 years ago
Duke Leto e58484231f Render banned peers in the peers tab 3 years ago
Duke Leto e1d6b8a98c Add GUI for disconnected/banned peers 3 years ago
Duke Leto 9f32f3e04f Peers tab tweaks 3 years ago
Duke Leto 81fa019a3f Right click menu and tooltips for peers tab 3 years ago
Duke Leto b055613e89 Peers tab 3 years ago
Duke Leto aa1cab39ff Add tls=only just in case 3 years ago
Duke Leto 1c8f9e592b Merge branch 'master' into dev 3 years ago
Duke Leto 1569303620 Refactor 3 years ago
Duke Leto f8b87c3572 Refactor 3 years ago
Duke Leto 11f24b7e43 Use absolute paths to avoid Great Sadness 3 years ago
Duke Leto 22f6fa490f Automagically use asmap.dat for ASN data, if it exists in PWD 3 years ago
Duke Leto 388cd4a7e4 Update ignored files 3 years ago
Duke Leto 8d1b4d0a0c Updated Russian (RU) translation 3 years ago
Duke Leto 1a6365db47 Add Belarusian (BE) translation 3 years ago
Duke Leto 36b4bad7dd Polish comes from the cities; wisdom from the desert. 3 years ago
Duke Leto 3a9f098caa New params 3 years ago
Duke Leto 4be49d607a update hush-cli 3 years ago
Duke Leto e34b5b0d3b Merge pull request 'minor UI updates & minor build.sh change' (#3) from jahway603/SilentDragon:dev into dev 3 years ago
jahway603 f54eb22d74 added qmake check in build.sh 3 years ago
jahway603 a5b204079b swapped About and Help on menu toolbar & updated logo to reflect SD instead of SDL 3 years ago
Duke Leto 892d0339f6 updates 3 years ago
Duke Leto 5d6cc9ff48 We do not download junk like other coins 3 years ago
Duke Leto 1a684ddee6 Fuck github some more 3 years ago
Duke Leto 8265334b64 Disable checking cunty github for updates 3 years ago
Duke Leto b7ac09bd71 2021 3 years ago
Duke Leto b4cf171515 ch-ch-changes 3 years ago
Duke Leto dce8f2838c bump dat version 3 years ago
Djozeff 317d8d52aa Update 'README.md' 3 years ago
Djozeff cf16139f80 Update 'README.md' 3 years ago
Djozeff 2f2b0ab702 Update 'README.md' 3 years ago
Duke Leto 478479e70a Replace github links with gitea links 3 years ago
Duke Leto a339b237e8 No more github badges 3 years ago
Duke Leto 4190aa7405 Update support links 3 years ago
Duke Leto 50eae156d7
Merge pull request #208 from gilardh/master 4 years ago
gilardh a4db8e47b1 Put all theme name to 'unfinished' 4 years ago
Duke Leto 96fe5aa1c1 Make older systems happy by making sure shared_ptr is available 4 years ago
  1. 20
      .gitignore
  2. 2
      .travis.yml
  3. 5
      AUTHORS
  4. 131
      README.md
  5. 71
      SilentDragon-1.3.1.wxs
  6. 87
      SilentDragonX-1.3.1.wxs
  7. 73
      application-sdx.qrc
  8. 97
      application.qrc
  9. BIN
      asmap.dat
  10. 24
      build-sdx.sh
  11. 42
      build.sh
  12. 64
      doc/release-process.md
  13. 109
      doc/relnotes/README.md
  14. 6
      docs/index.html
  15. 21
      hush-cli
  16. BIN
      images/sd-hushd-tab.png
  17. BIN
      images/sd-main-window.png
  18. BIN
      images/sd-market-tab.png
  19. BIN
      images/sd-peers-tab.png
  20. BIN
      images/sd-receive-tab.png
  21. BIN
      images/sd-send-tab.png
  22. BIN
      images/sd-transactions-tab.png
  23. 31
      issue_template.md
  24. 42
      res-drgx/Info.plist
  25. BIN
      res-drgx/Ubuntu-R.ttf
  26. 13
      res-drgx/appdmg.json
  27. BIN
      res-drgx/connected.gif
  28. BIN
      res-drgx/connectoverinternetcheckbox.png
  29. BIN
      res-drgx/dmgbg.png
  30. BIN
      res-drgx/hush-3.6.0.png
  31. BIN
      res-drgx/hush-dark.png
  32. BIN
      res-drgx/hushdlogo.png
  33. BIN
      res-drgx/icon.ico
  34. BIN
      res-drgx/liblibsodium.a
  35. BIN
      res-drgx/libsodium.a
  36. BIN
      res-drgx/libsodium.lib
  37. 64
      res-drgx/libsodium/buildlibsodium.sh
  38. BIN
      res-drgx/libsodiumd.lib
  39. BIN
      res-drgx/loading.gif
  40. BIN
      res-drgx/lock_closed.png
  41. BIN
      res-drgx/lock_open.png
  42. BIN
      res-drgx/logo.icns
  43. BIN
      res-drgx/logobig.gif
  44. 38
      res-drgx/mkicns.sh
  45. BIN
      res-drgx/paymentreq.gif
  46. 712
      res-drgx/qt5.natvis
  47. BIN
      res-drgx/remove.png
  48. 6
      res-drgx/resize.sh
  49. BIN
      res-drgx/send.png
  50. BIN
      res-drgx/silentdragon-animated-dark.gif
  51. BIN
      res-drgx/silentdragon-animated-loop-dark.gif
  52. BIN
      res-drgx/silentdragon-animated-loop.gif
  53. BIN
      res-drgx/silentdragon-animated-startup-dark.gif
  54. BIN
      res-drgx/silentdragon-animated-startup.gif
  55. BIN
      res-drgx/silentdragon-animated.gif
  56. 385
      res-drgx/silentdragon.xpm
  57. 1779
      res-drgx/silentdragon_template.ts
  58. BIN
      res-drgx/synced.png
  59. BIN
      res-drgx/transaction0.png
  60. BIN
      res-drgx/transaction2.png
  61. BIN
      res-drgx/transaction_abandoned.png
  62. BIN
      res-drgx/transaction_conflicted.png
  63. BIN
      res-drgx/tx_inout.png
  64. BIN
      res-drgx/tx_input.png
  65. BIN
      res-drgx/tx_mined.png
  66. BIN
      res-drgx/tx_output.png
  67. BIN
      res-drgx/verify.png
  68. BIN
      res-drgx/warning.png
  69. 0
      res-drgx/wormholeconnect.png
  70. BIN
      res-drgx/wxsbanner.bmp
  71. BIN
      res-drgx/wxsdialog.bmp
  72. BIN
      res-drgx/zcashdlogo.gif
  73. 2
      res/Info.plist
  74. 13
      res/SIGNATURES_README
  75. 2
      res/css/dark.css
  76. 114
      res/css/dragonx.css
  77. 2
      res/css/light.css
  78. 21
      res/css/midnight.css
  79. BIN
      res/hushdlogo.png
  80. 2
      res/libsodium/buildlibsodium.sh
  81. BIN
      res/lock_closed.png
  82. BIN
      res/lock_open.png
  83. BIN
      res/remove.png
  84. BIN
      res/send.png
  85. BIN
      res/silentdragon-animated-dark.gif
  86. BIN
      res/silentdragon-animated-startup-dark.gif
  87. BIN
      res/silentdragon-animated-startup.gif
  88. BIN
      res/silentdragon-animated.gif
  89. 811
      res/silentdragon.xpm
  90. BIN
      res/silentdragon_be.qm
  91. 2811
      res/silentdragon_be.ts
  92. 1636
      res/silentdragon_bg.ts
  93. BIN
      res/silentdragon_de.qm
  94. 1852
      res/silentdragon_de.ts
  95. BIN
      res/silentdragon_es.qm
  96. 1800
      res/silentdragon_es.ts
  97. BIN
      res/silentdragon_fi.qm
  98. 1779
      res/silentdragon_fi.ts
  99. BIN
      res/silentdragon_fil.qm
  100. 1700
      res/silentdragon_fil.ts
  101. BIN
      res/silentdragon_fr.qm
  102. 1789
      res/silentdragon_fr.ts
  103. BIN
      res/silentdragon_hr.qm
  104. 1720
      res/silentdragon_hr.ts
  105. BIN
      res/silentdragon_id.qm
  106. 1239
      res/silentdragon_id.ts
  107. BIN
      res/silentdragon_it.qm
  108. 1764
      res/silentdragon_it.ts
  109. BIN
      res/silentdragon_nl.qm
  110. 2414
      res/silentdragon_nl.ts
  111. BIN
      res/silentdragon_pl.qm
  112. 2810
      res/silentdragon_pl.ts
  113. BIN
      res/silentdragon_pt.qm
  114. 1759
      res/silentdragon_pt.ts
  115. BIN
      res/silentdragon_ro.qm
  116. 1706
      res/silentdragon_ro.ts
  117. BIN
      res/silentdragon_ru.qm
  118. 2336
      res/silentdragon_ru.ts
  119. BIN
      res/silentdragon_sr.qm
  120. 1720
      res/silentdragon_sr.ts
  121. 109
      res/silentdragon_template.ts
  122. BIN
      res/silentdragon_tr.qm
  123. 1775
      res/silentdragon_tr.ts
  124. BIN
      res/silentdragon_uk.qm
  125. 1837
      res/silentdragon_uk.ts
  126. BIN
      res/silentdragon_zh.qm
  127. 1771
      res/silentdragon_zh.ts
  128. BIN
      res/synced.png
  129. BIN
      res/transaction0.png
  130. BIN
      res/transaction2.png
  131. BIN
      res/transaction_abandoned.png
  132. BIN
      res/transaction_conflicted.png
  133. BIN
      res/tx_inout.png
  134. BIN
      res/tx_input.png
  135. BIN
      res/tx_mined.png
  136. BIN
      res/tx_output.png
  137. BIN
      res/verify.png
  138. BIN
      res/warning.png
  139. BIN
      res/zcashdlogo.gif
  140. 4
      run-after-build-sdx.sh
  141. 2
      run-after-build.sh
  142. BIN
      sapling-output.params
  143. BIN
      sapling-spend.params
  144. BIN
      silentdragon.png
  145. 27
      silentdragon.pro
  146. 164
      silentdragonx.pro
  147. 3
      src/3rdparty/sodium.h
  148. 10
      src/about.ui
  149. 13
      src/addressbook.cpp
  150. 6
      src/addressbook.h
  151. 4
      src/addresscombo.cpp
  152. 2
      src/addresscombo.h
  153. 28
      src/balancestablemodel.cpp
  154. 10
      src/balancestablemodel.h
  155. 135
      src/bannedpeerstablemodel.cpp
  156. 37
      src/bannedpeerstablemodel.h
  157. 511
      src/connection.cpp
  158. 32
      src/connection.h
  159. 32
      src/connection.ui
  160. 292
      src/createhushconfdialog.ui
  161. 212
      src/createzcashconfdialog.ui
  162. 25
      src/fillediconlabel.cpp
  163. 4
      src/fillediconlabel.h
  164. 85
      src/getblock.ui
  165. 20
      src/guiconstants.h
  166. 4
      src/logger.cpp
  167. 4
      src/logger.h
  168. 41
      src/main.cpp
  169. 1675
      src/mainwindow.cpp
  170. 56
      src/mainwindow.h
  171. 811
      src/mainwindow.ui
  172. 4
      src/memoedit.cpp
  173. 10
      src/memoedit.h
  174. 14
      src/mobileappconnector.cpp
  175. 22
      src/mobileappconnector.h
  176. 214
      src/mobileappconnector.ui
  177. 185
      src/peerstablemodel.cpp
  178. 44
      src/peerstablemodel.h
  179. 3
      src/precompiled.h
  180. 34
      src/privkey.ui
  181. 90
      src/qrcode.ui
  182. 12
      src/qrcodelabel.cpp
  183. 2
      src/qrcodelabel.h
  184. 4
      src/recurring.cpp
  185. 4
      src/recurring.h
  186. 23
      src/requestdialog.cpp
  187. 2
      src/requestdialog.h
  188. 2
      src/requestdialog.ui
  189. 91
      src/rescandialog.ui
  190. 678
      src/rpc.cpp
  191. 80
      src/rpc.h
  192. 2
      src/scripts/docker/Dockerfile
  193. 2
      src/scripts/dotranslations.sh
  194. 64
      src/scripts/dounifiedbuild.ps1
  195. 11
      src/scripts/make-binary-tarball.sh
  196. 102
      src/scripts/make-deb.sh
  197. 2
      src/scripts/make-only-deb.sh
  198. 4
      src/scripts/mkmacdmg.sh
  199. 48
      src/scripts/mkrelease.sh
  200. 16
      src/scripts/mkwininstaller.ps1
  201. 2
      src/scripts/signbinaries.sh
  202. 10
      src/scripts/silentdragon.wxs
  203. 5
      src/sd.h
  204. 97
      src/sendtab.cpp
  205. 12
      src/senttxstore.cpp
  206. 2
      src/senttxstore.h
  207. 138
      src/settings.cpp
  208. 40
      src/settings.h
  209. 413
      src/settings.ui
  210. 127
      src/txtablemodel.cpp
  211. 8
      src/txtablemodel.h
  212. 5
      src/validateaddress.cpp
  213. 6
      src/validateaddress.h
  214. 2
      src/version.h
  215. 2
      src/viewalladdresses.cpp
  216. 6
      src/viewalladdresses.h
  217. 85
      src/viewtransaction.ui
  218. 908
      src/websockets.cpp
  219. 177
      src/websockets.h
  220. 170
      src/zboard.ui
  221. 9
      util/silentdragon.desktop
  222. 24
      win-build-sdx.sh
  223. 38
      win-build.sh

20
.gitignore

@ -6,8 +6,8 @@ docs/website/public
.DS_Store .DS_Store
hushd hushd
IDEWorkspaceChecks.plist IDEWorkspaceChecks.plist
komodo-cli hush-cli
komodod dragonxd
*.mak *.mak
Makefile Makefile
Makefile.* Makefile.*
@ -17,8 +17,11 @@ release/
res/libsodium.a res/libsodium.a
res/libsodium.a res/libsodium.a
res/libsodium/libsodium* res/libsodium/libsodium*
res-drgx/libsodium.a
res-drgx/libsodium.a
res-drgx/libsodium/libsodium*
silentdragon silentdragon
silentdragon silentdragonx
silentdragon.pro.user silentdragon.pro.user
*.sln *.sln
src/precompiled.h.cpp src/precompiled.h.cpp
@ -29,12 +32,7 @@ src/ui_*.h
workspace.code-workspace workspace.code-workspace
x64/ x64/
*.xcsettings *.xcsettings
zec-qt-wallet-mingw*
zec-qt-wallet_plugin_import.cpp
zec-qt-wallet_resource*
zec-qt-wallet.sln
zec-qt-wallet.vcxproj*
zecwallet_plugin_import.cpp
zecwallet_resource*
zecwallet.vcxproj*
*.zip *.zip
core
qrc_application-sdx.cpp
silentdragon_plugin_import.cpp

2
.travis.yml

@ -14,7 +14,7 @@ before_install:
# TODO: I usually make builds with 5.14 - Duke # TODO: I usually make builds with 5.14 - Duke
- sudo add-apt-repository ppa:beineri/opt-qt591-trusty -y - sudo add-apt-repository ppa:beineri/opt-qt591-trusty -y
- sudo apt-get update -qq - sudo apt-get update -qq
- sudo apt-get install qt59base qt59websockets - sudo apt-get install qt59base
- source /opt/qt59/bin/qt59-env.sh - source /opt/qt59/bin/qt59-env.sh
- chmod +x res/libsodium/buildlibsodium.sh - chmod +x res/libsodium/buildlibsodium.sh

5
AUTHORS

@ -0,0 +1,5 @@
# The Hush Developers
Duke Leto https://git.hush.is/duke https://github.com/leto
Jane Mercer https://git.hush.is/radix42 https://github.com/radix42

131
README.md

@ -1,15 +1,6 @@
# SilentDragon # SilentDragon
[![GitHub license](https://img.shields.io/badge/License-GPL%20v3-yellow.svg)](https://github.com/MyHush/SilentDragon/blob/master/LICENSE)
[![GitHub version](https://badge.fury.io/gh/MyHush%2FSilentDragon.svg)](https://badge.fury.io/gh/MyHush%2FSilentDragon)
[![Github All Releases](https://img.shields.io/github/downloads/MyHush/SilentDragon/total.svg)](https://img.shields.io/github/downloads/MyHush/SilentDragon/total.svg)
<p align="left"> <p align="left">
<a href="https://twitter.com/MyHushTeam">
<img src="https://img.shields.io/twitter/url?style=social&url=https%3A%2F%2Ftwitter.com%2Fmyhushteam"
alt="MyHushTeam's Twitter"></a>
<a href="https://twitter.com/intent/follow?screen_name=MyHushTeam">
<img src="https://img.shields.io/twitter/follow/MyHushTeam?style=social&logo=twitter"
alt="follow on Twitter"></a>
<a href="https://fosstodon.org/@myhushteam"> <a href="https://fosstodon.org/@myhushteam">
<img src="https://img.shields.io/badge/Mastodon-MyHushTeam-blue" <img src="https://img.shields.io/badge/Mastodon-MyHushTeam-blue"
alt="follow on Mastodon"></a> alt="follow on Mastodon"></a>
@ -19,30 +10,42 @@
</p> </p>
SilentDragon desktop wallet for HUSH runs on Linux, Windows and macOS. SilentDragon desktop wallet for HUSH runs on Linux, Windows and macOS.
This is experimental software under active development! This is experimental software under active development! Get real-time
support on [our Telegram support group](https://hush.is/tg_support) and
feel free to join the [main Telegram group](https://hush.is/tg) as well.
![Screenshots](silentdragon.png?raw=true) ![Screenshots](images/sd-receive-tab.png?raw=true)
The following are screenshots for each SilentDragon tab:
* [Main Window](images/sd-main-window.png)
* [Send Tab](images/sd-send-tab.png)
* [Transactions Tab](images/sd-transactions-tab.png)
* [Peers Tab](images/sd-peers-tab.png)
* [Market Tab](images/sd-market-tab.png)
* [Hushd Tab](images/sd-hushd-tab.png)
## PRIVACY NOTICE ## PRIVACY NOTICE
SilentDragon contacts a few different external websites to get various SilentDragon contacts a few different external websites to get various
bits of data. bits of data.
* coingecko.com for price data API * coingecko.com for price data API (defaults to on, optional)
* explorer.myhush.org for explorer links * explorer.hush.is for explorer links (optional)
* dexstats.info for address utilities * dexstats.info for address utilities
* wormhole.myhush.org for Wormhole services * Address Asset Viewer menu action (optional)
* Convert Address menu action (optional)
This means your IP address is known to these servers. Enable Tor setting This means your IP address is known to these servers. Enable Tor setting
in SilentDragon to prevent this, or better yet, use TAILS: https://tails.boum.org/ in SilentDragon to prevent this, or better yet, use TAILS: https://tails.boum.org/
# Installation # Installation
Go to the releases page and grab the latest installers or binary. https://github.com/MyHush/SilentDragon/releases Go to the [releases page](https://git.hush.is/hush/SilentDragon/releases) and grab the latest installers or binary.
For Arch Linux users, this is available from the AUR.
## hushd ## hushd
SilentDragon needs a Hush full node running [hushd](https://github.com/MyHush/hush3/). If you already have a hushd node running, SilentDragon will connect to it. SilentDragon needs a Hush full node running [hushd](https://git.hush.is/hush/hush3/). If you already have a hushd node running, SilentDragon will connect to it.
If you don't have one, SilentDragon will start its embedded hushd node. If you don't have one, SilentDragon will start its embedded hushd node.
@ -50,44 +53,64 @@ Additionally, if this is the first time you're running SilentDragon or a hushd d
Pass `--no-embedded` to disable the embedded hushd and force SilentDragon to connect to an external node. Pass `--no-embedded` to disable the embedded hushd and force SilentDragon to connect to an external node.
If SD crashes when autostarting hushd, you may have run out of memory. This could happen with very large wallets. Try closing unnecessary applications and/or browser tabs and retry.
Another method is to start hushd first, then start SD, which will connect to the existing hushd.
## Compiling from source ## Compiling from source
SilentDragon is written in C++ 14, and can be compiled with g++/clang++/visual SilentDragon is written in C++ 14, and can be compiled with g++/clang++/visual
c++. It also depends on Qt5, which you can get from c++. It also depends on Qt5, which you can get from [here](https://www.qt.io/download)
[here](https://www.qt.io/download). Note that if you are compiling from source, or within your operating system package manager. Note that if you are compiling
you won't get the embedded hushd by default. You can either run an external from source, you won't get the embedded hushd by default. You can either run an external
hushd, or compile hushd as well. hushd, or compile hushd as well.
### Building on Linux ### Building on Linux
#### Ubuntu 18.04 and 20.04: #### Linux Troubleshooting
If you run into an error with OpenGL, you may need to install extra deps. More details [here](https://gist.github.com/shamiul94/a632f7ab94cf389e08efd7174335df1c)
**Error**
```
/usr/bin/ld: cannot find -lGL
clang: error: linker command failed with exit code 1 (use -v to see invocation)
```
**Solution**
``` ```
sudo apt-get -y install qt5-default qt5-qmake libqt5websockets5-dev qtcreator sudo apt-get -y install libglu1-mesa-dev freeglut3-dev mesa-common-dev
git clone https://github.com/MyHush/SilentDragon.git ```
#### Ubuntu 18.04 and 20.04
You can install the pre-reqs and build on Ubuntu 18.04 & 20.04 with:
```shell script
sudo apt-get -y install qt5-default qt5-qmake qtcreator
git clone https://git.hush.is/hush/SilentDragon
cd SilentDragon cd SilentDragon
./build.sh linguist # compile translations ./build.sh linguist
./build.sh ./build.sh
./silentdragon ./silentdragon
``` ```
#### Arch Linux: #### Arch Linux
``` You can install the pre-reqs and build on Arch Linux with:
sudo pacman -S qt5-base qt5-tools qtcreator qt5-websockets rust
git clone https://github.com/MyHush/SilentDragon.git ```shell script
sudo pacman -S qt5-base qt5-tools qtcreator rust
git clone https://git.hush.is/hush/SilentDragon
cd SilentDragon cd SilentDragon
./build.sh linguist # compile translations ./build.sh linguist
./build.sh release ./build.sh release
./silentdragon ./silentdragon
``` ```
### Building on Windows ### Building on Windows
You need Visual Studio 2017 (The free C++ Community Edition works just fine). You need Visual Studio 2017 (The free C++ Community Edition works just fine).
From the VS Tools command prompt From the VS Tools command prompt
``` ```shell script
git clone https://github.com/MyHush/SilentDragon.git git clone https://git.hush.is/hush/SilentDragon
cd SilentDragon cd SilentDragon
c:\Qt5\bin\qmake.exe silentdragon.pro -spec win32-msvc CONFIG+=debug c:\Qt5\bin\qmake.exe silentdragon.pro -spec win32-msvc CONFIG+=debug
nmake nmake
@ -96,7 +119,7 @@ debug\SilentDragon.exe
``` ```
To create the Visual Studio project files so you can compile and run from Visual Studio: To create the Visual Studio project files so you can compile and run from Visual Studio:
``` ```shell script
c:\Qt5\bin\qmake.exe silentdragon.pro -tp vc CONFIG+=debug c:\Qt5\bin\qmake.exe silentdragon.pro -tp vc CONFIG+=debug
``` ```
@ -104,30 +127,56 @@ c:\Qt5\bin\qmake.exe silentdragon.pro -tp vc CONFIG+=debug
You need to install the Xcode app or the Xcode command line tools first, and then install Qt. You need to install the Xcode app or the Xcode command line tools first, and then install Qt.
``` TODO: Suggestions on installing qt5 deps on a Mac
git clone https://github.com/MyHush/SilentDragon.git
```shell script
git clone https://git.hush.is/hush/SilentDragon
cd SilentDragon cd SilentDragon
qmake silentdragon.pro CONFIG+=debug # These commands require qmake to be installed
./build.sh linguist
./build.sh
make make
./SilentDragon.app/Contents/MacOS/SilentDragon ./SilentDragon.app/Contents/MacOS/SilentDragon
``` ```
### Building SilentDragonX
```
git clone https://git.hush.is/hush/SilentDragon
cd SilentDragon
./build-sdx.sh
./build-sdx.sh linguist # update translations, might not be needed
```
The binary will be called `silentdragonx`
### Emulating the embedded node ### Emulating the embedded node
In binary releases, SilentDragon will use node binaries in the current directory to sync a node from scratch. In binary releases, SilentDragon will use node binaries in the current directory to sync a node from scratch.
It does not attempt to download them, it bundles them. To simulate this from a developer setup, you can symlink It does not attempt to download them, it bundles them. To simulate this from a developer setup, you can symlink
these four files in your Git repo: these four files in your Git repo:
``` ```shell script
ln -s ../hush3/src/hushd ln -s ../hush3/src/hushd
ln -s ../hush3/src/komodod ln -s ../hush3/src/hush-cli
ln -s ../hush3/src/komodo-cli
``` ```
The above assumes silentdragon and hush3 git repos are in the same directory. File names on Windows will need to be tweaked. The above assumes silentdragon and hush3 git repos are in the same directory. File names on Windows will need to be tweaked.
### Support ## Where is my wallet stored?
Linux: `~/.hush/HUSH3`
Windows 10: `C:\Documents and Settings\%user\Application Data\Hush` or `C:\Users\%user\AppData\Roaming\Hush`
Mac : `~/Library/Application Support/Hush/HUSH3`
## Support
For support or other questions, join us on [Telegram](https://hush.is/telegram), or toot at our [Mastodon](https://fosstodon.org/@myhushteam) or join [Telegram Support](https://hush.is/telegram_support) or [file an issue](https://git.hush.is/hush/SilentDragon/issues).
For support or other questions, join us on [Discord](https://myhush.org/discord), or tweet at [@MyHushTeam](https://twitter.com/MyHushTeam), or toot at our [Mastodon](https://fosstodon.org/@myhushteam) or join [Telegram](http://myhush.org/telegram) or [file an issue](https://github.com/MyHush/SilentDragon/issues). ## License
GPLv3 or later

71
SilentDragon-1.3.1.wxs

@ -0,0 +1,71 @@
<?xml version='1.0' encoding='windows-1252'?>
<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>
<Product Name='SilentDragon' Id='a2e4bc6c-5911-4a07-a05c-d2fec0a44a7f' UpgradeCode='a41d7a93-a6cb-41fb-89d2-706a8c22bc99'
Language='1033' Codepage='1252' Version='1.3.1' Manufacturer='HUSH'>
<Package Id='*' Keywords='Installer' Description="HUSH SilentDragon Installer"
Comments='' Manufacturer='HUSH'
InstallerVersion='100' Languages='1033' Compressed='yes' SummaryCodepage='1252' />
<Media Id='1' Cabinet='SilentDragon.cab' EmbedCab='yes' DiskPrompt="CD-ROM #1" />
<Property Id='DiskPrompt' Value="HUSH SilentDragon 1.3.1 Installation [1]" />
<Directory Id='TARGETDIR' Name='SourceDir'>
<Directory Id='ProgramFilesFolder' Name='PFiles'>
<Directory Id='HUSH' Name='HUSH'>
<Directory Id='INSTALLDIR' Name='SilentDragon'>
<Component Id='MainExecutable' Guid='56443570-635d-48e4-8448-8ffd0d7c415a'>
<File Id='SilentDragonEXE' Name='silentdragon.exe' DiskId='1' Source='silentdragon.exe' KeyPath='yes'>
<Shortcut Id="startmenuSilentDragon" Directory="ProgramMenuDir" Name="SilentDragon" WorkingDirectory='INSTALLDIR' Icon="silentdragon.exe" IconIndex="0" Advertise="yes" />
<Shortcut Id="desktopSilentDragon" Directory="DesktopFolder" Name="SilentDragon" WorkingDirectory='INSTALLDIR' Icon="silentdragon.exe" IconIndex="0" Advertise="yes" />
</File>
</Component>
<Component Id="asmap" Guid="190ad39b-44fa-4b22-94ee-d42aca7acc7b">
<File Id="asmap.dat" DiskId='1' Source="asmap.dat" KeyPath="yes"/>
</Component>
<Component Id="hush-cli" Guid="e19e8fd8-aeb9-4dad-99bd-70da0a0aa92c2">
<File Id="hush-cli.exe" DiskId='1' Source="hush-cli.exe" KeyPath="yes"/>
</Component>
<Component Id="hush-tx" Guid="f96b2a39-4734-4a8d-abc3-895006052e97">
<File Id="hush-tx.exe" DiskId='1' Source="hush-tx.exe" KeyPath="yes"/>
</Component>
<Component Id="hushd" Guid="fa66588f-8788-4b29-b6d6-c4a903e49d79">
<File Id="hushd.exe" DiskId='1' Source="hushd.exe" KeyPath="yes"/>
</Component>
<Component Id="sapling-output" Guid="1ecc1590-ddf3-4f6d-94c5-6bf091aef77a">
<File Id="sapling-output.params" DiskId='1' Source="sapling-output.params" KeyPath="yes"/>
</Component>
<Component Id="sapling-spend" Guid="828d3827-5f2b-47c6-8717-8a664054a2af">
<File Id="sapling-spend.params" DiskId='1' Source="sapling-spend.params" KeyPath="yes"/>
</Component>
</Directory>
</Directory>
</Directory>
<Directory Id="ProgramMenuFolder" Name="Programs">
<Directory Id="ProgramMenuDir" Name="SilentDragon">
<Component Id="ProgramMenuDir" Guid="7ac6af1f-1377-4158-915f-c410cc5cd2a9">
<RemoveFolder Id='ProgramMenuDir' On='uninstall' />
<RegistryValue Root='HKCU' Key='Software\[Manufacturer]\[ProductName]' Type='string' Value='' KeyPath='yes' />
</Component>
</Directory>
</Directory>
<Directory Id="DesktopFolder" Name="Desktop" />
</Directory>
<Feature Id='Complete' Level='1'>
<ComponentRef Id='MainExecutable' />
<ComponentRef Id='ProgramMenuDir' />
<ComponentRef Id='asmap' />
<ComponentRef Id='hush-cli' />
<ComponentRef Id='hush-tx' />
<ComponentRef Id='hushd' />
<ComponentRef Id='sapling-output' />
<ComponentRef Id='sapling-spend' />
</Feature>
<Icon Id="silentdragon.exe" SourceFile="silentdragon.ico" />
</Product>
</Wix>

87
SilentDragonX-1.3.1.wxs

@ -0,0 +1,87 @@
<?xml version='1.0' encoding='windows-1252'?>
<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>
<Product Name='SilentDragonX' Id='c2083d6a-4511-4c37-b23c-6699badb781f' UpgradeCode='0877ea1a-0662-48a2-8512-b5868f0a40a6'
Language='1033' Codepage='1252' Version='1.3.1' Manufacturer='HUSH'>
<Package Id='*' Keywords='Installer' Description="HUSH SilentDragonX Installer"
Comments='' Manufacturer='HUSH'
InstallerVersion='100' Languages='1033' Compressed='yes' SummaryCodepage='1252' />
<Media Id='1' Cabinet='SilentDragonX.cab' EmbedCab='yes' DiskPrompt="CD-ROM #1" />
<Property Id='DiskPrompt' Value="HUSH SilentDragonX 1.3.1 Installation [1]" />
<Directory Id='TARGETDIR' Name='SourceDir'>
<Directory Id='ProgramFilesFolder' Name='PFiles'>
<Directory Id='HUSH' Name='HUSH'>
<Directory Id='INSTALLDIR' Name='SilentDragonX'>
<Component Id='MainExecutable' Guid='e96fa770-8ac4-4e69-85b0-1d5b97d658f1'>
<File Id='SilentDragonXEXE' Name='silentdragonx.exe' DiskId='1' Source='silentdragonx.exe' KeyPath='yes'>
<Shortcut Id="startmenuSilentDragonX" Directory="ProgramMenuDir" Name="SilentDragonX" WorkingDirectory='INSTALLDIR' Icon="silentdragonx.exe" IconIndex="0" Advertise="yes" />
<Shortcut Id="desktopSilentDragonX" Directory="DesktopFolder" Name="SilentDragonX" WorkingDirectory='INSTALLDIR' Icon="silentdragonx.exe" IconIndex="0" Advertise="yes" />
</File>
</Component>
<Component Id="asmap" Guid="1e7a811c-6076-4046-b592-3aebf31961c4">
<File Id="asmap.dat" DiskId='1' Source="asmap.dat" KeyPath="yes"/>
</Component>
<Component Id="dragonx-cli" Guid="5b648615-b957-470e-9ec0-777b8896e913">
<File Id="dragonx-cli.bat" DiskId='1' Source="dragonx-cli.bat" KeyPath="yes"/>
</Component>
<Component Id="dragonxd" Guid="779810d3-b092-4349-940b-03ba73ec556d">
<File Id="dragonxd.bat" DiskId='1' Source="dragonxd.bat" KeyPath="yes"/>
</Component>
<Component Id="hush-cli" Guid="305d8117-5685-4d06-b0be-a7cd176f8111">
<File Id="hush-cli.exe" DiskId='1' Source="hush-cli.exe" KeyPath="yes"/>
</Component>
<Component Id="hushd" Guid="5024eceb-fba3-48d8-9ab5-e61ae5c1964d">
<File Id="hushd.exe" DiskId='1' Source="hushd.exe" KeyPath="yes"/>
</Component>
<Component Id="hush-smart-chain" Guid="c66ffa5c-02ae-42e0-bbca-8cc71a4e92e9">
<File Id="hush-smart-chain.bat" DiskId='1' Source="hush-smart-chain.bat" KeyPath="yes"/>
</Component>
<Component Id="hush-tx" Guid="7baac56a-8bf4-4bb2-b97d-a59da5c0edd6">
<File Id="hush-tx.exe" DiskId='1' Source="hush-tx.exe" KeyPath="yes"/>
</Component>
<Component Id="readme" Guid="5edea091-83d0-4f1c-a84f-298e4e8e61e9">
<File Id="README.txt" DiskId='1' Source="README.txt" KeyPath="yes"/>
</Component>
<Component Id="sapling-output" Guid="dddc6a47-8a26-49ec-b5a8-e38a06e11000">
<File Id="sapling-output.params" DiskId='1' Source="sapling-output.params" KeyPath="yes"/>
</Component>
<Component Id="sapling-spend" Guid="42edd54d-b480-4aaa-a976-ec305127dbbb">
<File Id="sapling-spend.params" DiskId='1' Source="sapling-spend.params" KeyPath="yes"/>
</Component>
</Directory>
</Directory>
</Directory>
<Directory Id="ProgramMenuFolder" Name="Programs">
<Directory Id="ProgramMenuDir" Name="SilentDragonX">
<Component Id="ProgramMenuDir" Guid="2ac41712-9a5d-48d6-9ca9-fe31bad57153">
<RemoveFolder Id='ProgramMenuDir' On='uninstall' />
<RegistryValue Root='HKCU' Key='Software\[Manufacturer]\[ProductName]' Type='string' Value='' KeyPath='yes' />
</Component>
</Directory>
</Directory>
<Directory Id="DesktopFolder" Name="Desktop" />
</Directory>
<Feature Id='Complete' Level='1'>
<ComponentRef Id='MainExecutable' />
<ComponentRef Id='ProgramMenuDir' />
<ComponentRef Id='asmap' />
<ComponentRef Id='dragonx-cli' />
<ComponentRef Id='dragonxd' />
<ComponentRef Id='hush-cli' />
<ComponentRef Id='hushd' />
<ComponentRef Id='hush-smart-chain' />
<ComponentRef Id='hush-tx' />
<ComponentRef Id='readme' />
<ComponentRef Id='sapling-output' />
<ComponentRef Id='sapling-spend' />
</Feature>
<Icon Id="silentdragonx.exe" SourceFile="silentdragonx.ico" />
</Product>
</Wix>

73
application-sdx.qrc

@ -0,0 +1,73 @@
<RCC>
<qresource prefix="/fonts">
<file alias="Ubuntu-R.ttf">res-drgx/Ubuntu-R.ttf</file>
</qresource>
<qresource prefix="/icons">
<file alias="connected.gif">res-drgx/connected.gif</file>
<file alias="loading.gif">res-drgx/loading.gif</file>
<file alias="paymentreq.gif">res-drgx/paymentreq.gif</file>
<file alias="icon.ico">res-drgx/icon.ico</file>
<file alias="warning.png">res-drgx/warning.png</file>
<file alias="verify.png">res-drgx/verify.png</file>
<file alias="tx_output.png">res-drgx/tx_output.png</file>
<file alias="tx_mined.png">res-drgx/tx_mined.png</file>
<file alias="tx_input.png">res-drgx/tx_input.png</file>
<file alias="transaction_conflicted.png">res-drgx/transaction_conflicted.png</file>
<file alias="transaction_abandoned.png">res-drgx/transaction_abandoned.png</file>
<file alias="transaction2.png">res-drgx/transaction2.png</file>
<file alias="transaction0.png">res-drgx/transaction0.png</file>
<file alias="synced.png">res-drgx/synced.png</file>
<file alias="send.png">res-drgx/send.png</file>
<file alias="remove.png">res-drgx/remove.png</file>
<file alias="lock_open.png">res-drgx/lock_open.png</file>
<file alias="tx_inout.png">res-drgx/tx_inout.png</file>
<file alias="lock_closed.png">res-drgx/lock_closed.png</file>
</qresource>
<qresource prefix="/img">
<file alias="hushdlogo.png">res-drgx/hushdlogo.png</file>
<file alias="logobig.gif">res-drgx/logobig.gif</file>
<file alias="silentdragon-animated.gif">res-drgx/silentdragon-animated.gif</file>
<file alias="silentdragon-animated-dark.gif">res-drgx/silentdragon-animated-dark.gif</file>
<file alias="silentdragon-animated-startup.gif">res-drgx/silentdragon-animated-startup.gif</file>
<file alias="silentdragon-animated-startup-dark.gif">res-drgx/silentdragon-animated-startup-dark.gif</file>
</qresource>
<qresource prefix="/translations">
<file alias="silentdragon_be.qm">res/silentdragon_be.qm</file>
<file alias="silentdragon_bg.qm">res/silentdragon_bg.qm</file>
<file alias="silentdragon_de.qm">res/silentdragon_de.qm</file>
<file alias="silentdragon_es.qm">res/silentdragon_es.qm</file>
<file alias="silentdragon_fi.qm">res/silentdragon_fi.qm</file>
<file alias="silentdragon_fil.qm">res/silentdragon_fil.qm</file>
<file alias="silentdragon_fr.qm">res/silentdragon_fr.qm</file>
<file alias="silentdragon_hr.qm">res/silentdragon_hr.qm</file>
<file alias="silentdragon_it.qm">res/silentdragon_it.qm</file>
<file alias="silentdragon_id.qm">res/silentdragon_id.qm</file>
<file alias="silentdragon_nl.qm">res/silentdragon_nl.qm</file>
<file alias="silentdragon_pl.qm">res/silentdragon_pl.qm</file>
<file alias="silentdragon_pt.qm">res/silentdragon_pt.qm</file>
<file alias="silentdragon_ro.qm">res/silentdragon_ro.qm</file>
<file alias="silentdragon_ru.qm">res/silentdragon_ru.qm</file>
<file alias="silentdragon_sr.qm">res/silentdragon_sr.qm</file>
<file alias="silentdragon_tr.qm">res/silentdragon_tr.qm</file>
<file alias="silentdragon_uk.qm">res/silentdragon_uk.qm</file>
<file alias="silentdragon_zh.qm">res/silentdragon_zh.qm</file>
</qresource>
<qresource prefix="/css">
<file alias="blue.css">res/css/blue.css</file>
<file alias="dark.css">res/css/dark.css</file>
<file alias="default.css">res/css/default.css</file>
<file alias="light.css">res/css/light.css</file>
<file alias="midnight.css">res/css/midnight.css</file>
<file alias="dragonx.css">res/css/dragonx.css</file>
</qresource>
<qresource prefix="/images/blue">
<file alias="unchecked.png">res/images/blue/unchecked.png</file>
<file alias="checked.png">res/images/blue/checked.png</file>
<file alias="blue_downArrow.png">res/images/blue/blue_downArrow.png</file>
<file alias="blue_downArrow_small.png">res/images/blue/blue_downArrow_small.png</file>
<file alias="blue_upArrow_small.png">res/images/blue/blue_upArrow_small.png</file>
<file alias="blue_leftArrow_small.png">res/images/blue/blue_leftArrow_small.png</file>
<file alias="blue_rightArrow_small.png">res/images/blue/blue_rightArrow_small.png</file>
<file alias="blue_qtreeview_selected.png">res/images/blue/blue_qtreeview_selected.png</file>
</qresource>
</RCC>

97
application.qrc

@ -1,55 +1,70 @@
<RCC> <RCC>
<qresource prefix="/fonts"> <qresource prefix="/fonts">
<file>res/Ubuntu-R.ttf</file> <file alias="Ubuntu-R.ttf">res/Ubuntu-R.ttf</file>
</qresource> </qresource>
<qresource prefix="/icons"> <qresource prefix="/icons">
<file>res/connected.gif</file> <file alias="connected.gif">res/connected.gif</file>
<file>res/loading.gif</file> <file alias="loading.gif">res/loading.gif</file>
<file>res/paymentreq.gif</file> <file alias="paymentreq.gif">res/paymentreq.gif</file>
<file>res/icon.ico</file> <file alias="icon.ico">res/icon.ico</file>
<file alias="warning.png">res/warning.png</file>
<file alias="verify.png">res/verify.png</file>
<file alias="tx_output.png">res/tx_output.png</file>
<file alias="tx_mined.png">res/tx_mined.png</file>
<file alias="tx_input.png">res/tx_input.png</file>
<file alias="transaction_conflicted.png">res/transaction_conflicted.png</file>
<file alias="transaction_abandoned.png">res/transaction_abandoned.png</file>
<file alias="transaction2.png">res/transaction2.png</file>
<file alias="transaction0.png">res/transaction0.png</file>
<file alias="synced.png">res/synced.png</file>
<file alias="send.png">res/send.png</file>
<file alias="remove.png">res/remove.png</file>
<file alias="lock_open.png">res/lock_open.png</file>
<file alias="tx_inout.png">res/tx_inout.png</file>
<file alias="lock_closed.png">res/lock_closed.png</file>
</qresource> </qresource>
<qresource prefix="/img"> <qresource prefix="/img">
<file>res/zcashdlogo.gif</file> <file alias="hushdlogo.png">res/hushdlogo.png</file>
<file>res/logobig.gif</file> <file alias="logobig.gif">res/logobig.gif</file>
<file>res/silentdragon-animated.gif</file> <file alias="silentdragon-animated-startup-dark.gif">res/silentdragon-animated-startup-dark.gif</file>
<file>res/silentdragon-animated-dark.gif</file>
<file>res/silentdragon-animated-startup.gif</file>
<file>res/silentdragon-animated-startup-dark.gif</file>
</qresource> </qresource>
<qresource prefix="/translations"> <qresource prefix="/translations">
<file>res/silentdragon_bg.qm</file> <file alias="silentdragon_be.qm">res/silentdragon_be.qm</file>
<file>res/silentdragon_de.qm</file> <file alias="silentdragon_bg.qm">res/silentdragon_bg.qm</file>
<file>res/silentdragon_es.qm</file> <file alias="silentdragon_de.qm">res/silentdragon_de.qm</file>
<file>res/silentdragon_fi.qm</file> <file alias="silentdragon_es.qm">res/silentdragon_es.qm</file>
<file>res/silentdragon_fil.qm</file> <file alias="silentdragon_fi.qm">res/silentdragon_fi.qm</file>
<file>res/silentdragon_fr.qm</file> <file alias="silentdragon_fil.qm">res/silentdragon_fil.qm</file>
<file>res/silentdragon_hr.qm</file> <file alias="silentdragon_fr.qm">res/silentdragon_fr.qm</file>
<file>res/silentdragon_it.qm</file> <file alias="silentdragon_hr.qm">res/silentdragon_hr.qm</file>
<file>res/silentdragon_id.qm</file> <file alias="silentdragon_it.qm">res/silentdragon_it.qm</file>
<file>res/silentdragon_nl.qm</file> <file alias="silentdragon_id.qm">res/silentdragon_id.qm</file>
<file>res/silentdragon_pt.qm</file> <file alias="silentdragon_nl.qm">res/silentdragon_nl.qm</file>
<file>res/silentdragon_ro.qm</file> <file alias="silentdragon_pl.qm">res/silentdragon_pl.qm</file>
<file>res/silentdragon_ru.qm</file> <file alias="silentdragon_pt.qm">res/silentdragon_pt.qm</file>
<file>res/silentdragon_sr.qm</file> <file alias="silentdragon_ro.qm">res/silentdragon_ro.qm</file>
<file>res/silentdragon_tr.qm</file> <file alias="silentdragon_ru.qm">res/silentdragon_ru.qm</file>
<file>res/silentdragon_uk.qm</file> <file alias="silentdragon_sr.qm">res/silentdragon_sr.qm</file>
<file>res/silentdragon_zh.qm</file> <file alias="silentdragon_tr.qm">res/silentdragon_tr.qm</file>
<file alias="silentdragon_uk.qm">res/silentdragon_uk.qm</file>
<file alias="silentdragon_zh.qm">res/silentdragon_zh.qm</file>
</qresource> </qresource>
<qresource prefix="/css"> <qresource prefix="/css">
<file>res/css/blue.css</file> <file alias="blue.css">res/css/blue.css</file>
<file>res/css/dark.css</file> <file alias="dark.css">res/css/dark.css</file>
<file>res/css/default.css</file> <file alias="default.css">res/css/default.css</file>
<file>res/css/light.css</file> <file alias="light.css">res/css/light.css</file>
<file>res/css/midnight.css</file> <file alias="midnight.css">res/css/midnight.css</file>
<file alias="dragonx.css">res/css/dragonx.css</file>
</qresource> </qresource>
<qresource prefix="/images/blue"> <qresource prefix="/images/blue">
<file>res/images/blue/unchecked.png</file> <file alias="unchecked.png">res/images/blue/unchecked.png</file>
<file>res/images/blue/checked.png</file> <file alias="checked.png">res/images/blue/checked.png</file>
<file>res/images/blue/blue_downArrow.png</file> <file alias="blue_downArrow.png">res/images/blue/blue_downArrow.png</file>
<file>res/images/blue/blue_downArrow_small.png</file> <file alias="blue_downArrow_small.png">res/images/blue/blue_downArrow_small.png</file>
<file>res/images/blue/blue_upArrow_small.png</file> <file alias="blue_upArrow_small.png">res/images/blue/blue_upArrow_small.png</file>
<file>res/images/blue/blue_leftArrow_small.png</file> <file alias="blue_leftArrow_small.png">res/images/blue/blue_leftArrow_small.png</file>
<file>res/images/blue/blue_rightArrow_small.png</file> <file alias="blue_rightArrow_small.png">res/images/blue/blue_rightArrow_small.png</file>
<file>res/images/blue/blue_qtreeview_selected.png</file> <file alias="blue_qtreeview_selected.png">res/images/blue/blue_qtreeview_selected.png</file>
</qresource> </qresource>
</RCC> </RCC>

BIN
asmap.dat

Binary file not shown.

24
build-sdx.sh

@ -0,0 +1,24 @@
#!/bin/bash
# Copyright 2018-2023 The Hush Developers
# Released under the GPLv3
# This builds a binary called "silentdragonx"
set -e
# TODO: not ideal, hushd.exe should only be looked for on windoze
if [ -e "dragonxd" ]; then
echo "Found dragonxd binary"
elif [ -e "hushd.exe" ]; then
echo "Found hushd.exe binary"
else
echo "dragonxd could not be found!"
echo "Either copy the binary to this dir or make a symlink."
echo "This command will create a symlink to it if this repo is in the same directory as your hush3.git: "
echo "ln -s ../hush3/src/dragonxd"
echo "For windoze you should copy hushd.exe to this directory"
exit 1
fi
# Use a modified QT project file with same build.sh
SDCONF=silentdragonx.pro ./build.sh $@

42
build.sh

@ -1,32 +1,40 @@
#!/bin/bash #!/bin/bash
# Copyright 2019-2020 The Hush Developers # Copyright 2018-2022 The Hush Developers
# Released under the GPLv3 # Released under the GPLv3
set -e set -e
UNAME=$(uname) UNAME=$(uname)
VERSION=$(grep APP_VERSION src/version.h |cut -d\" -f2)
CONF=${SDCONF:-silentdragon.pro}
WALLET="SilentDragon"
if [ "$CONF" == "silentdragonx.pro" ] ; then
WALLET="SilentDragonX"
fi
echo "Compiling $WALLET $VERSION with $JOBS threads..."
if [ "$UNAME" == "Linux" ] ; then if ! command -v qmake &> /dev/null
JOBS=$(nproc) then
elif [ "$UNAME" == "FreeBSD" ] ; then echo "qmake could not be found. Please install QT and try again."
JOBS=$(nproc) exit 1
elif [ "$UNAME" == "Darwin" ] ; then
JOBS=$(sysctl -n hw.ncpu)
else
JOBS=1
fi fi
VERSION=$(cat src/version.h |cut -d\" -f2) qmake --version
echo "Compiling SilentDragon $VERSION with $JOBS threads..."
CONF=silentdragon.pro if ! command -v make &> /dev/null
then
echo "make could not be found. Please install it and try again."
exit 1
fi
make --version
qbuild () { qbuild () {
qmake $CONF -spec linux-clang CONFIG+=debug qmake $CONF -spec linux-clang CONFIG+=debug
make -j$JOBS make -j2 "$@"
} }
qbuild_release () { qbuild_release () {
qmake $CONF -spec linux-clang CONFIG+=release qmake $CONF -spec linux-clang CONFIG+=release
make -j$JOBS make -j2 "$@"
} }
if [ "$1" == "clean" ]; then if [ "$1" == "clean" ]; then
@ -36,9 +44,9 @@ elif [ "$1" == "linguist" ]; then
lrelease $CONF lrelease $CONF
elif [ "$1" == "cleanbuild" ]; then elif [ "$1" == "cleanbuild" ]; then
make clean make clean
qbuild qbuild "$@"
elif [ "$1" == "release" ]; then elif [ "$1" == "release" ]; then
qbuild_release qbuild_release "$@"
else else
qbuild qbuild "$@"
fi fi

64
doc/release-process.md

@ -0,0 +1,64 @@
# SilentDragon Release Process
## High-Level Philosophy
Beware of making high-risk changes too close to a new release, because they will not get as much testing as they should. Don't merge large branches which haven't undergone lots of testing just before a release.
It is best to keep doc/relnotes/README.md up to date as changes and bug fixes are made. It's more work to summarize all changes and bugfixes just before the release.
## Check for changes on master that should be on dev
See https://git.hush.is/hush/hush3/src/branch/master/doc/release-process.md#check-for-changes-on-master-that-should-be-on-dev , there is no sense repeating the exact same thing here.
## Dealing with merge conflicts
SD very often has merge conflicts in generated translation files, because QT embeds line numbers in XML. So even if you don't change translations, but add or remove even a single line from SD source code, it can change the XML. If there are actual changes to translations on both master and dev, you are out of luck and they need to be manually dealt with. But if you want to just use whatever is on master, you can do this:
```
git checkout dev
# this assumes you are using the remote called "origin"
git pull origin dev # make sure it is up to date
git merge --no-ff -X theirs master
```
The last command uses the "theirs" merge strategy option to the "recursive" merge strategy, which is default. See "git help merge" for more details.
If you have a messed up merge or you don't want to deal with conflicts right now, you can do `git merge --abort` to cancel a merge.
## Git Issues
Look for Git issues that should be fixed in the next release: https://git.hush.is/hush/SilentDragon/issues Especially low-risk and simple things and like documentation changes, improvements to error messages. Take note that changing strings in the source code, such as adding a new string or changing an existing one, will affect translations.
## Translations
...
```
# update generated translation data
./build.sh linguist
git commit -am "update translations"
git push
```
## Release process
* Update version in src/version.h
* Sometimes the `dev` branch already has the new version and this is done already
* Verify a full build works correctly: `./build.sh clean; ./build.sh`
* Merge dev branch into master
* Make a new Gitea release from master branch
* There is an option for Gitea to automate making a new Git tag as well
* SD requires a staticly compiled version of QT for release binaries
* If it isn't, the binary will resort to using the system QT which is usually a different version and the binary will not work
* Make linux binaries:
```
# QT_STATIC is a directory with a staticly compiled qt5.x
# HUSH_DIR is a directory containing hushd/hush-cli binaries
# APP_VERSION is the version being released in git tag format (prepended v), such as v1.3.1
QT_STATIC=$HOME/src/qt5 APP_VERSION=vX.Y.Z HUSH_DIR=$HOME/git/hush3 src/scripts/mkrelease.sh
```
* Make linux binary tarball: `./src/scripts/make-binary-tarball.sh`
* Upload to gitea release
* Make debian package with `./src/scripts/make-deb.sh`
* Upload to gitea release

109
doc/relnotes/README.md

@ -0,0 +1,109 @@
# Official SilentDragon Release Notes
SilentDragon release notes were done on Github until 1.0.0
and now are officially part of our Gitea repo at https://git.hush.is/hush/silentdragon
## Downloading Releases
Hush releases are on our own Gitea at <a href="https://git.hush.is/">git.hush.is</a>
and no longer on Github, since they banned Duke Leto and
also because they censor many people around the world and work with
evil organizations.
# SilentDragon 1.4.2 "Waggish Weevil"
```
11 files changed, 35 insertions(+), 32 deletions(-)
```
* Fix a coredump that can happen after importing a private key https://git.hush.is/hush/SilentDragon/issues/155
* Prevent the logging of sensitive data to STDOUT, since it could be redirected to a file or shared in a bug report or screenshot https://git.hush.is/hush/SilentDragon/commit/2754629a95c1efe603b3c3245f90a26b3ed7f177
* Update startup animation graphic https://git.hush.is/hush/SilentDragon/pulls/147
* Allow compiling with a custom number of jobs in build.sh https://git.hush.is/hush/SilentDragon/issues/156
# SilentDragon 1.4.1 "Scintillating Sundew"
```
52 files changed, 7163 insertions(+), 5023 deletions(-)
```
* View details of a transaction #136
* If a tx has no memo, you can simply double click on it to view more details.
* Otherwise, right click and choose View Transaction
* Render more details in View Block #135
* Now all transactions are listed as well as valuePools key
* Greatly improved Private Key Importing
* A custom rescan height or disabling rescanning is now possible
* Invalid privkeys are now filtered out before being sent to the full node
* This prevents confusing popups #142
* Fixed bug where importing multiple taddrs would rescan multiple times
* New Tab "Debug Log" renders content of debug.log
* Allows showing the last X lines of debug.log, defaults to 50 lines
# SilentDragon 1.4.0 "Zany Zooid"
```
95 files changed, 8438 insertions(+), 60854 deletions(-)
```
* Ability to view block info for any height #103
* Support a proxy running on something other than 127.0.0.1 #127
* Bug fix for Windows file path when exporting #128
* Bug fix for `listtransactions` to display more than 10 mining reward txs in Transactions tab #126
* Now compiles on Ubuntu 20.04 thanks to jahway #125
* Translation fixes thanks to onryo #120
* Single set of translations for SD and SDX #122
# SilentDragon 1.3.1 "Omnicompetent Okapi"
```
233 files changed, 77483 insertions(+), 16095 deletions(-)
```
* SD is now able to be a GUI wallet for DragonX, which is called SilentDragonX (SDX).
* This is the very first GUI wallet for a Hush Smart Chain and we believe DragonX users will really enjoy it.
* SDX also includes a Mining tab which allows users to mine via a GUI, no more CLI required to mine!
* The mining tab has been translated into:
* Chinese (ZH)
* German (DE)
* Russian (RU)
* Spanish (ES)
* Ukrainian (UK)
* You now can choose a language translation while the wallet is running in Settings. You no longer need to use the same language as the operating system uses. All currently supported translations are options in a dropdown list.
* New icons for for different kinds of transactions in the Transaction tab
* Previously only port 9050 was supported for proxying via Tor. This would not work with any custom port, or with Tor Browser which uses port 9150. SD now supports a custom proxy port and supports being used with the Tor proxy provided with Tor Browser. This means users can install Tor via a GUI use a Hush GUI wallet with Tor, without ever using the CLI
* SD now gives options to view or copy link to a transaction on a Tor block explorer
* A customized Tor explorer URL can now be set in Settings
* Rescan progress will now be reported in the status bar
* Pairing to the old SilentDragonAndroid (SDA) app has been removed. The new SDA does not need to pair to a desktop wallet.
* Various fixes to support Mac systems with embedded hushd
* Rescan from an arbitrary block height without restarting
* Get a QR code by right-clicking on a zaddr and optionally save to disk
* Make it easier to reply to a memo
* Fix coredump when going to Settings during a rescan
* Ability to manually ban a node, unban a node, or unban all nodes
* More efficiently check for new transactions
* Add HUSH logo to QR codes
* "Report a Bug" menu item now goes to our Telegram Support group
# SilentDragon 1.3.0 "Berserk Bonnacon"
```
60 files changed, 4328 insertions(+), 1568 deletions(-)
```
* :tada: New Polish translation ( @onryo )
* This release of SD is only compatible with hushd 3.9.0 or later, which is a mandatory update
* Older Hush full nodes will not be compatible with the Hush network going forward
* New shinier startup animation by Dan S ( https://twitter.com/Dan\_MGDesign )
* When right-clicking on a zaddr, there are now two new menu options
* Shield all mining funds to this zaddr (z_shieldcoinbase)
* Use this if you are a solo miner who mined full blocks to a taddr
* Only 50 blocks will be shielded at a time. If you have more, run this multiple times.
* Shield all non-mining taddr funds to this zaddr (z_mergetoaddress)
* Use this if you have an old wallet with funds in taddrs
* Only 50 utxos (transactions) will be shielded at a time. If you have more, run this multiple times.
* SD now looks for Hush full node data in `~/.hush/HUSH3` but still supports the legacy location
* The About screen now reports the version of QT5 being used
* In the case of an exception, the default currency will be set to BTC instead of USD
* SD includes its version number in autogenerated HUSH3.conf config files

6
docs/index.html

@ -1,6 +0,0 @@
<html>
<head></head>
<body>
Hello World
</body>
</html>

21
hush-cli

@ -1,21 +0,0 @@
#!/bin/bash
# Copyright (c) 2019 Hush developers
# set working directory to the location of this script
# readlink -f does not always exist
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd $DIR
DIR="$( cd "$( dirname "$( readlink "${BASH_SOURCE[0]}" )" )" && pwd )"
cd $DIR
NAME=HUSH3
CLI=${KOMODOCLI:-./komodo-cli}
if [ -f $CLI ]; then
$CLI -ac_name=$NAME "$@"
else
# We prefix our binary when installed
# system wide on Debain system, to prevent clashes
CLI=hush-komodo-cli
$CLI -ac_name=$NAME "$@"
fi

BIN
images/sd-hushd-tab.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 499 KiB

BIN
images/sd-main-window.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

BIN
images/sd-market-tab.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

BIN
images/sd-peers-tab.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

BIN
images/sd-receive-tab.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 416 KiB

BIN
images/sd-send-tab.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

BIN
images/sd-transactions-tab.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

31
issue_template.md

@ -0,0 +1,31 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
Let us know which version of SilentDragon you have and if you have any non-default settings.
Also let us know if you compiled it yourself, or you are using Debian package or official binaries.
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Desktop (please complete the following information):**
- OS: [e.g. Linux/Windows/Mac]
- OS version
**Additional context**
Add any other context about the problem here.

42
res-drgx/Info.plist

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleExecutable</key>
<string>SilentDragonX</string>
<key>CFBundleGetInfoString</key>
<string>Created by Qt/QMake</string>
<key>CFBundleIconFile</key>
<string>logo.icns</string>
<key>CFBundleIdentifier</key>
<string>com.hush.silentdragonx</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>LSMinimumSystemVersion</key>
<string>10.11</string>
<key>NOTE</key>
<string>This file was generated by Qt/QMake.</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>NSSupportsAutomaticGraphicsSwitching</key>
<true/>
<key>NSRequiresAquaSystemAppearance</key>
<string>YES</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>drgx URI</string>
<key>CFBundleURLSchemes</key>
<array>
<string>drgx</string>
</array>
</dict>
</array>
<key>NSUIElement</key>
<true/>
</dict>
</plist>

BIN
res-drgx/Ubuntu-R.ttf

Binary file not shown.

13
res-drgx/appdmg.json

@ -0,0 +1,13 @@
{
"title": "silentdragon-vRELEASE_VERSION",
"icon": "logo.icns",
"background": "dmgbg.png",
"window" : {
"size" : { "width" : 600, "height" : 100},
"position" : { "x" : 200, "y" : 200}
},
"contents": [
{ "x": 448, "y": 80, "type": "link", "path": "/Applications" },
{ "x": 152, "y": 80, "type": "file", "path": "silentdragon.app" }
]
}

BIN
res-drgx/connected.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

BIN
res-drgx/connectoverinternetcheckbox.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
res-drgx/dmgbg.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
res-drgx/hush-3.6.0.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
res-drgx/hush-dark.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

BIN
res-drgx/hushdlogo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

BIN
res-drgx/icon.ico

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
res-drgx/liblibsodium.a

Binary file not shown.

BIN
res-drgx/libsodium.a

Binary file not shown.

BIN
res-drgx/libsodium.lib

Binary file not shown.

64
res-drgx/libsodium/buildlibsodium.sh

@ -0,0 +1,64 @@
#!/bin/bash
# Copyright (c) 2019-2021 The Hush developers
# Released under the GPLv3
VERSION=1.0.18
LIB="libsodium"
DIR="$LIB-$VERSION"
FILE="$DIR.tar.gz"
URL=https://github.com/MyHush/libsodium/releases/download/${VERSION}/${FILE}
SHA=6f504490b342a4f8a4c4a02fc9b866cbef8622d5df4e5452b46be121e46636c1
# First thing to do is see if libsodium.a exists in the res folder. If it does, then there's nothing to do
if [ -f res/${LIB}.a ]; then
exit 0
fi
echo "Building $LIB"
# Go into the libsodium directory
cd res/$LIB
if [ ! -f $FILE ]; then
curl -LO $URL
fi
echo "$SHA $FILE" | shasum -a 256 --check
# TWO SPACES or sadness sometimes:
# https://unix.stackexchange.com/questions/139891/why-does-verifying-sha256-checksum-with-sha256sum-fail-on-debian-and-work-on-u
echo "$SHA $FILE" | shasum -a 256 --check --status
if [ $? -ne 0 ]; then
FOUNDSHA=$(shasum -a 256 $FILE)
echo "SHA256 mismatch on $FILE!"
echo "$FOUNDSHA did not match $SHA . Aborting..."
exit 1
fi
if [ ! -d $DIR ]; then
tar xf $FILE
fi
# Try to use full core count to build
if [ "$UNAME" == "Linux" ] ; then
JOBS=$(nproc)
elif [ "$UNAME" == "FreeBSD" ] ; then
JOBS=$(nproc)
elif [ "$UNAME" == "Darwin" ] ; then
JOBS=$(sysctl -n hw.ncpu)
else
JOBS=4
fi
# Now build it
cd $DIR
LIBS="" ./configure
make clean
echo "Building $LIB with $JOBS cores..."
if [[ "$OSTYPE" == "darwin"* ]]; then
make CFLAGS="-mmacosx-version-min=10.11" CPPFLAGS="-mmacosx-version-min=10.11" -j$JOBS
else
make -j$JOBS
fi
cd ..
# copy the library to the parents's res/ folder
cp $DIR/src/libsodium/.libs/libsodium.a ../

BIN
res-drgx/libsodiumd.lib

Binary file not shown.

BIN
res-drgx/loading.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

BIN
res-drgx/lock_closed.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

BIN
res-drgx/lock_open.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
res-drgx/logo.icns

Binary file not shown.

BIN
res-drgx/logobig.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

38
res-drgx/mkicns.sh

@ -0,0 +1,38 @@
#!/usr/bin/env bash
###
# Adapted from: https://stackoverflow.com/a/20703594
###
if [ -z "${1+set}" ]; then
echo "Pass path to the inkscape command as first argument"
exit 1
fi
if [ -z "${2+set}" ]; then
echo "Pass svg file as second argument"
exit 1
fi
if [ -z "${3+set}" ]; then
echo "Pass output name (w/o .icns) as third argument"
exit 1
fi
inkscape=$1
svg_file=$2
output_name=$3
set -e
mkdir $output_name.iconset
$inkscape -z -e "$PWD/$output_name.iconset/icon_16x16.png" -w 16 -h 16 -y 0 "$PWD/$svg_file"
$inkscape -z -e "$PWD/$output_name.iconset/icon_16x16@2x.png" -w 32 -h 32 -y 0 "$PWD/$svg_file"
$inkscape -z -e "$PWD/$output_name.iconset/icon_32x32.png" -w 32 -h 32 -y 0 "$PWD/$svg_file"
$inkscape -z -e "$PWD/$output_name.iconset/icon_32x32@2x.png" -w 64 -h 64 -y 0 "$PWD/$svg_file"
$inkscape -z -e "$PWD/$output_name.iconset/icon_128x128.png" -w 128 -h 128 -y 0 "$PWD/$svg_file"
$inkscape -z -e "$PWD/$output_name.iconset/icon_128x128@2x.png" -w 256 -h 256 -y 0 "$PWD/$svg_file"
$inkscape -z -e "$PWD/$output_name.iconset/icon_256x256.png" -w 256 -h 256 -y 0 "$PWD/$svg_file"
$inkscape -z -e "$PWD/$output_name.iconset/icon_256x256@2x.png" -w 512 -h 512 -y 0 "$PWD/$svg_file"
$inkscape -z -e "$PWD/$output_name.iconset/icon_512x512.png" -w 512 -h 512 -y 0 "$PWD/$svg_file"
$inkscape -z -e "$PWD/$output_name.iconset/icon_512x512@2x.png" -w 1024 -h 1024 -y 0 "$PWD/$svg_file"
iconutil -c icns "$output_name.iconset"
rm -R "$output_name.iconset"

BIN
res-drgx/paymentreq.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

712
res-drgx/qt5.natvis

@ -0,0 +1,712 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt VS Tools.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************
-->
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
<Type Name="QPoint">
<AlternativeType Name="QPointF"/>
<DisplayString>{{ x = {xp}, y = {yp} }}</DisplayString>
<Expand>
<Item Name="[x]">xp</Item>
<Item Name="[y]">yp</Item>
</Expand>
</Type>
<Type Name="QRect">
<DisplayString>{{ x = {x1}, y = {y1}, width = {x2 - x1 + 1}, height = {y2 - y1 + 1} }}</DisplayString>
<Expand>
<Item Name="[x]">x1</Item>
<Item Name="[y]">y1</Item>
<Item Name="[width]">x2 - x1 + 1</Item>
<Item Name="[height]">y2 - y1 + 1</Item>
</Expand>
</Type>
<Type Name="QRectF">
<DisplayString>{{ x = {xp}, y = {yp}, width = {w}, height = {h} }}</DisplayString>
<Expand>
<Item Name="[x]">xp</Item>
<Item Name="[y]">yp</Item>
<Item Name="[width]">w</Item>
<Item Name="[height]">h</Item>
</Expand>
</Type>
<Type Name="QSize">
<AlternativeType Name="QSizeF"/>
<DisplayString>{{ width = {wd}, height = {ht} }}</DisplayString>
<Expand>
<Item Name="[width]">wd</Item>
<Item Name="[height]">ht</Item>
</Expand>
</Type>
<Type Name="QLine">
<AlternativeType Name="QLineF"/>
<DisplayString>{{ start point = {pt1}, end point = {pt2} }}</DisplayString>
<Expand>
<Synthetic Name="[start point]">
<DisplayString>{pt1}</DisplayString>
<Expand>
<ExpandedItem>pt1</ExpandedItem>
</Expand>
</Synthetic>
<Synthetic Name="[end point]">
<DisplayString>{pt2}</DisplayString>
<Expand>
<ExpandedItem>pt2</ExpandedItem>
</Expand>
</Synthetic>
</Expand>
</Type>
<Type Name="QPolygon">
<DisplayString>{{ size = {d-&gt;size} }}</DisplayString>
<Expand>
<Item Name="[referenced]">d-&gt;ref.atomic._q_value</Item>
<ArrayItems>
<Size>d-&gt;size</Size>
<ValuePointer>(QPoint*)((reinterpret_cast&lt;char*&gt;(d)) + d-&gt;offset)</ValuePointer>
</ArrayItems>
</Expand>
</Type>
<Type Name="QPolygonF">
<DisplayString>{{ size = {d-&gt;size} }}</DisplayString>
<Expand>
<Item Name="[closed]">
d-&gt;size &gt; 0
&amp;&amp; ((((QPointF*)((reinterpret_cast&lt;char*&gt;(d)) + d-&gt;offset)[0]).xp
== (((QPointF*)((reinterpret_cast&lt;char*&gt;(d)) + d-&gt;offset)[d-&gt;size - 1]).xp)
&amp;&amp; ((((QPointF*)((reinterpret_cast&lt;char*&gt;(d)) + d-&gt;offset)[0]).yp
== (((QPointF*)((reinterpret_cast&lt;char*&gt;(d)) + d-&gt;offset)[d-&gt;size - 1]).yp)
</Item>
<Item Name="[referenced]">d-&gt;ref.atomic._q_value</Item>
<ArrayItems>
<Size>d-&gt;size</Size>
<ValuePointer>(QPointF*)((reinterpret_cast&lt;char*&gt;(d)) + d-&gt;offset)</ValuePointer>
</ArrayItems>
</Expand>
</Type>
<Type Name ="QVector2D">
<DisplayString>{{ x = {xp}, y = {yp} }}</DisplayString>
<Expand>
<Item Name="[x]">xp</Item>
<Item Name="[y]">yp</Item>
</Expand>
</Type>
<Type Name ="QVector3D">
<DisplayString>{{ x = {xp}, y = {yp}, z = {zp} }}</DisplayString>
<Expand>
<Item Name="[x]">xp</Item>
<Item Name="[y]">yp</Item>
<Item Name="[z]">zp</Item>
</Expand>
</Type>
<Type Name ="QVector4D">
<DisplayString>{{ x = {xp}, y = {yp}, z = {zp}, w = {wp} }}</DisplayString>
<Expand>
<Item Name="[x]">xp</Item>
<Item Name="[y]">yp</Item>
<Item Name="[z]">zp</Item>
<Item Name="[w]">wp</Item>
</Expand>
</Type>
<Type Name ="QMatrix">
<DisplayString>
{{ m11 = {_m11}, m12 = {_m12}, m21 = {_m21}, m22 = {_m22}, ... }}
</DisplayString>
<Expand>
<Item Name="[m11]">_m11</Item>
<Item Name="[m12]">_m12</Item>
<Item Name="[m21]">_m21</Item>
<Item Name="[m22]">_m22</Item>
<Item Name="[dx]">_dx</Item>
<Item Name="[dy]">_dy</Item>
</Expand>
</Type>
<Type Name ="QMatrix4x4">
<DisplayString>
{{ m11 = {m[0][0]}, m12 = {m[1][0]}, m13 = {m[2][0]}, m14 = {m[3][0]}, ... }}
</DisplayString>
<Expand>
<Item Name="[m11]">m[0][0]</Item>
<Item Name="[m12]">m[1][0]</Item>
<Item Name="[m13]">m[2][0]</Item>
<Item Name="[m14]">m[3][0]</Item>
<Item Name="[m21]">m[0][1]</Item>
<Item Name="[m22]">m[1][1]</Item>
<Item Name="[m23]">m[2][1]</Item>
<Item Name="[m24]">m[3][1]</Item>
<Item Name="[m31]">m[0][2]</Item>
<Item Name="[m32]">m[1][2]</Item>
<Item Name="[m33]">m[2][2]</Item>
<Item Name="[m34]">m[3][2]</Item>
<Item Name="[m41]">m[0][3]</Item>
<Item Name="[m42]">m[1][3]</Item>
<Item Name="[m43]">m[2][3]</Item>
<Item Name="[m44]">m[3][3]</Item>
</Expand>
</Type>
<Type Name="QSizePolicy">
<DisplayString>
{{ horizontal = {static_cast&lt;Policy&gt;(bits.horPolicy)}, vertical = {static_cast&lt;Policy&gt;(bits.verPolicy)}, type = {ControlType(1 &lt;&lt; bits.ctype)} }}
</DisplayString>
<Expand>
<Synthetic Name="[vertical policy]">
<DisplayString>QSizePolicy::Policy::{static_cast&lt;Policy&gt;(bits.verPolicy)}</DisplayString>
</Synthetic>
<Synthetic Name="[horizontal policy]">
<DisplayString>QSizePolicy::Policy::{static_cast&lt;Policy&gt;(bits.horPolicy)}</DisplayString>
</Synthetic>
<Synthetic Name="[control type]">
<DisplayString>QSizePolicy::ControlType::{ControlType(1 &lt;&lt; bits.ctype)}</DisplayString>
</Synthetic>
<Synthetic Name="[expanding directions]">
<DisplayString
Condition="(static_cast&lt;Policy&gt;(bits.verPolicy) &amp; ExpandFlag)">
Qt::Vertical (2)
</DisplayString>
<DisplayString
Condition="(static_cast&lt;Policy&gt;(bits.horPolicy) &amp; ExpandFlag)">
Qt::Horizontal (1)
</DisplayString>
</Synthetic>
<Item Name="[vertical stretch]">static_cast&lt;int&gt;(bits.verStretch)</Item>
<Item Name="[horizontal stretch]">static_cast&lt;int&gt;(bits.horStretch)</Item>
<Item Name="[has height for width]">bits.hfw == 1</Item>
<Item Name="[has width for height]">bits.wfh == 1</Item>
</Expand>
</Type>
<Type Name="QChar">
<DisplayString>{ucs,c}</DisplayString>
<StringView>ucs,c</StringView>
<Expand>
<Item Name="[latin 1]">ucs > 0xff ? '\0' : char(ucs),c</Item>
<Item Name="[unicode]">ucs,c</Item>
</Expand>
</Type>
<Type Name="QString">
<DisplayString>{((reinterpret_cast&lt;unsigned short*&gt;(d)) + d->offset / 2),sub}</DisplayString>
<StringView>((reinterpret_cast&lt;unsigned short*&gt;(d)) + d->offset / 2),sub</StringView>
<Expand>
<Item Name="[size]">d-&gt;size</Item>
<Item Name="[referenced]">d-&gt;ref.atomic._q_value</Item>
<ArrayItems>
<Size>d-&gt;size</Size>
<ValuePointer>((reinterpret_cast&lt;unsigned short*&gt;(d)) + d->offset / 2),c</ValuePointer>
</ArrayItems>
</Expand>
</Type>
<Type Name="QByteArray">
<DisplayString>{((reinterpret_cast&lt;char*&gt;(d)) + d-&gt;offset),sb}</DisplayString>
<StringView>((reinterpret_cast&lt;char*&gt;(d)) + d-&gt;offset),sb</StringView>
<Expand>
<Item Name="[size]">d-&gt;size</Item>
<Item Name="[referenced]">d-&gt;ref.atomic._q_value</Item>
<ArrayItems>
<Size>d-&gt;size</Size>
<ValuePointer>((reinterpret_cast&lt;char*&gt;(d)) + d-&gt;offset),c</ValuePointer>
</ArrayItems>
</Expand>
</Type>
<Type Name="QBitArray">
<DisplayString>{{ size = {(d.d-&gt;size &lt;&lt; 3) - *((reinterpret_cast&lt;char*&gt;(d.d)) + d.d-&gt;offset)} }}</DisplayString>
<Expand>
<Item Name="[referenced]">d.d-&gt;ref.atomic._q_value</Item>
<IndexListItems>
<Size>(d.d-&gt;size &lt;&lt; 3) - *((reinterpret_cast&lt;char*&gt;(d.d)) + d.d-&gt;offset)</Size>
<ValueNode>
(*(reinterpret_cast&lt;const unsigned char*&gt;((reinterpret_cast&lt;char*&gt;(d.d)) + d.d-&gt;offset) + 1
+ ($i &gt;&gt; 3)) &amp; (1 &lt;&lt; ($i &amp; 7))) != 0
</ValueNode>
</IndexListItems>
</Expand>
</Type>
<Type Name="QVarLengthArray&lt;*&gt;">
<AlternativeType Name="QVarLengthArray&lt;*, int&gt;"/>
<DisplayString>{{ size = {s} }}</DisplayString>
<Expand>
<Item Name="[capacity]">a</Item>
<ArrayItems>
<Size>s</Size>
<ValuePointer>ptr</ValuePointer>
</ArrayItems>
</Expand>
</Type>
<Type Name="QDate">
<DisplayString>{{ julian day = {jd} }}</DisplayString>
<Expand></Expand>
</Type>
<Type Name="QTime">
<DisplayString
Condition="mds == 1">{{ millisecond = {mds} }}</DisplayString>
<DisplayString
Condition="mds != 1">{{ milliseconds = {mds} }}</DisplayString>
<Expand>
<Item Name="[hour]"
Condition="(mds / 3600000) == 1">mds / 3600000, d</Item>
<Item Name="[hours]"
Condition="(mds / 3600000) != 1">mds / 3600000, d</Item>
<Item Name="[minute]"
Condition="((mds % 3600000) / 60000) == 1">(mds % 3600000) / 60000, d</Item>
<Item Name="[minutes]"
Condition="((mds % 3600000) / 60000) != 1">(mds % 3600000) / 60000, d</Item>
<Item Name="[second]"
Condition="((mds / 1000) % 60) == 1">(mds / 1000) % 60, d</Item>
<Item Name="[seconds]"
Condition="((mds / 1000) % 60) != 1">(mds / 1000) % 60, d</Item>
<Item Name="[millisecond]"
Condition="(mds % 1000) == 1">mds % 1000, d</Item>
<Item Name="[milliseconds]"
Condition="(mds % 1000) != 1">mds % 1000, d</Item>
</Expand>
</Type>
<Type Name="QRegularExpression">
<DisplayString>{d.pattern}</DisplayString>
</Type>
<Type Name="QSharedData">
<Expand>
<Item Name="[referenced]">ref._q_value</Item>
</Expand>
</Type>
<Type Name="QSharedPointer&lt;*&gt;">
<DisplayString>strong reference to shared pointer of type {"$T1"}</DisplayString>
<Expand>
<Item Name="[is null]">value == 0</Item>
<Item Name="[weak referenced]">d-&gt;weakref._q_value</Item>
<Item Name="[strong referenced]">d-&gt;strongref._q_value</Item>
</Expand>
</Type>
<Type Name="QSharedDataPointer&lt;*&gt;">
<DisplayString>pointer to implicit shared object of type {"$T1"}</DisplayString>
<Expand>
<ExpandedItem>d</ExpandedItem>
</Expand>
</Type>
<Type Name="QExplicitlySharedDataPointer&lt;*&gt;">
<DisplayString>pointer to explicit shared object of type {"$T1"}</DisplayString>
<Expand>
<ExpandedItem>d</ExpandedItem>
</Expand>
</Type>
<Type Name="QPointer&lt;*&gt;">
<DisplayString>guarded pointer to subclass of QObject of type {"$T1"}</DisplayString>
<Expand>
<Item Name="[is null]">wp.d == 0 || wp.d-&gt;strongref._q_value == 0 || wp.value == 0</Item>
</Expand>
</Type>
<Type Name="QWeakPointer&lt;*&gt;">
<DisplayString>weak reference to shared pointer of type {"$T1"}</DisplayString>
<Expand>
<Item Name="[is null]">d == 0 || d-&gt;strongref._q_value == 0 || value == 0</Item>
<Item Name="[weak referenced]">d-&gt;weakref._q_value</Item>
<Item Name="[strong referenced]">d-&gt;strongref._q_value</Item>
</Expand>
</Type>
<Type Name="QScopedPointer&lt;*&gt;">
<DisplayString>scoped pointer to a dynamically allocated object of type {"$T1"}</DisplayString>
<Expand>
<Item Name="[is null]">!d</Item>
</Expand>
</Type>
<Type Name="QScopedArrayPointer&lt;*&gt;">
<DisplayString>scoped pointer to dynamically allocated array of objects of type {"$T1"}</DisplayString>
<Expand>
<Item Name="[is null]">!d</Item>
</Expand>
</Type>
<Type Name="QPair&lt;*,*&gt;">
<DisplayString>({first}, {second})</DisplayString>
<Expand>
<Item Name="[first]">first</Item>
<Item Name="[second]">second</Item>
</Expand>
</Type>
<Type Name="QVector&lt;*&gt;">
<AlternativeType Name="QStack&lt;*&gt;"></AlternativeType>
<DisplayString>{{ size = {d-&gt;size} }}</DisplayString>
<Expand>
<Item Name="[referenced]">d-&gt;ref.atomic._q_value</Item>
<ArrayItems>
<Size>d-&gt;size</Size>
<ValuePointer>($T1*)((reinterpret_cast&lt;char*&gt;(d)) + d-&gt;offset)</ValuePointer>
</ArrayItems>
</Expand>
</Type>
<Type Name="QList&lt;*&gt;">
<AlternativeType Name="QStringList"></AlternativeType>
<AlternativeType Name="QQueue&lt;*&gt;"></AlternativeType>
<DisplayString>{{ size = {d-&gt;end - d-&gt;begin} }}</DisplayString>
<Expand>
<Item Name="[referenced]">d-&gt;ref.atomic._q_value</Item>
<IndexListItems>
<Size>d-&gt;end - d-&gt;begin</Size>
<ValueNode>*reinterpret_cast&lt;$T1*&gt;((sizeof($T1) &gt; sizeof(void*))
? reinterpret_cast&lt;Node*&gt;(d->array + d->begin + $i)->v
: reinterpret_cast&lt;$T1*&gt;(d->array + d->begin + $i))
</ValueNode>
</IndexListItems>
</Expand>
</Type>
<Type Name="QLinkedList&lt;*&gt;">
<DisplayString>{{ size = {d-&gt;size} }}</DisplayString>
<Expand>
<Item Name="[referenced]">d-&gt;ref.atomic._q_value</Item>
<LinkedListItems>
<Size>d-&gt;size</Size>
<HeadPointer>d-&gt;n</HeadPointer>
<NextPointer>n</NextPointer>
<ValueNode>(*(QLinkedListNode&lt;$T1&gt;*)this).t</ValueNode>
</LinkedListItems>
</Expand>
</Type>
<Type Name="QMapNode&lt;*,*&gt;">
<DisplayString>({key}, {value})</DisplayString>
<Expand>
<Item Name="[key]">key</Item>
<Item Name="[value]">value</Item>
</Expand>
</Type>
<Type Name="QMap&lt;*,*&gt;">
<AlternativeType Name="QMultiMap&lt;*,*&gt;"/>
<DisplayString>{{ size = {d-&gt;size} }}</DisplayString>
<Expand>
<Item Name="[referenced]">d-&gt;ref.atomic._q_value</Item>
<TreeItems>
<Size>d-&gt;size</Size>
<HeadPointer>d-&gt;header.left</HeadPointer>
<LeftPointer>left</LeftPointer>
<RightPointer>right</RightPointer>
<ValueNode>*((QMapNode&lt;$T1,$T2&gt;*)this)</ValueNode>
</TreeItems>
</Expand>
</Type>
<Type Name="QHashNode&lt;*,*&gt;">
<DisplayString Condition="next == 0">(empty)</DisplayString>
<DisplayString Condition="next != 0">({key}, {value})</DisplayString>
<Expand>
<Item Name="[key]" Condition="next != 0">key</Item>
<Item Name="[value]" Condition="next != 0">value</Item>
</Expand>
</Type>
<Type Name="QHash&lt;*,*&gt;">
<AlternativeType Name="QMultiHash&lt;*,*&gt;"/>
<DisplayString>{{ size = {d-&gt;size} }}</DisplayString>
<Expand>
<Item Name="[referenced]">d-&gt;ref.atomic._q_value</Item>
<IndexListItems>
<Size>d-&gt;numBuckets</Size>
<ValueNode>*((QHashNode&lt;$T1,$T2&gt;*)d-&gt;buckets[$i])</ValueNode>
</IndexListItems>
</Expand>
</Type>
<Type Name="QHashNode&lt;*,QHashDummyValue&gt;">
<DisplayString Condition="next == 0">(empty)</DisplayString>
<DisplayString Condition="next != 0">({key})</DisplayString>
<Expand>
<Item Name="[key]" Condition="next != 0">key</Item>
</Expand>
</Type>
<Type Name="QSet&lt;*&gt;">
<DisplayString>{{ size = {q_hash.d-&gt;size} }}</DisplayString>
<Expand>
<ExpandedItem>q_hash</ExpandedItem>
</Expand>
</Type>
<Type Name="QCache&lt;*,*&gt;::Node">
<DisplayString>({*keyPtr}, {*t})</DisplayString>
<Expand>
<Item Name="[key]">*keyPtr</Item>
<Item Name="[value]">*t</Item>
</Expand>
</Type>
<Type Name="QCache&lt;*,*&gt;">
<DisplayString>{{ size = {hash.d-&gt;size} }}</DisplayString>
<Expand>
<Item Name="[max coast]">mx</Item>
<Item Name="[total coast]">total</Item>
<Item Name="[referenced]">hash.d-&gt;ref.atomic._q_value</Item>
<LinkedListItems>
<Size>hash.d-&gt;size</Size>
<HeadPointer>f</HeadPointer>
<NextPointer>n</NextPointer>
<ValueNode>*((Node*)this)</ValueNode>
</LinkedListItems>
</Expand>
</Type>
<Type Name="QVariant">
<!--Region DisplayString QVariant-->
<DisplayString Condition="d.type == QMetaType::UnknownType">Invalid</DisplayString>
<DisplayString Condition="d.type == QMetaType::Bool">{d.data.b}</DisplayString>
<DisplayString Condition="d.type == QMetaType::Int">{d.data.i}</DisplayString>
<DisplayString Condition="d.type == QMetaType::UInt">{d.data.u}</DisplayString>
<DisplayString Condition="d.type == QMetaType::LongLong">{d.data.ll}</DisplayString>
<DisplayString Condition="d.type == QMetaType::ULongLong">{d.data.ull}</DisplayString>
<DisplayString Condition="d.type == QMetaType::Double">{d.data.d}</DisplayString>
<DisplayString Condition="d.type == QMetaType::QChar">{d.data.c}</DisplayString>
<DisplayString Condition="d.type == QMetaType::QVariantMap">
{*((QMap&lt;QString,QVariant&gt;*)(d.is_shared ? d.data.shared-&gt;ptr
: reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))}
</DisplayString>
<DisplayString Condition="d.type == QMetaType::QVariantList">
{*((QList&lt;QVariant&gt;*)(d.is_shared ? d.data.shared-&gt;ptr
: reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))}
</DisplayString>
<DisplayString Condition="d.type == QMetaType::QString">
{*((QString*)(d.is_shared ? d.data.shared-&gt;ptr
: reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))}
</DisplayString>
<DisplayString Condition="d.type == QMetaType::QStringList">
{*((QStringList*)(d.is_shared ? d.data.shared-&gt;ptr
: reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))}
</DisplayString>
<DisplayString Condition="d.type == QMetaType::QByteArray">
{*((QByteArray*)(d.is_shared ? d.data.shared-&gt;ptr
: reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))}
</DisplayString>
<DisplayString Condition="d.type == QMetaType::QBitArray">
{*((QBitArray*)(d.is_shared ? d.data.shared-&gt;ptr
: reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))}
</DisplayString>
<DisplayString Condition="d.type == QMetaType::QDate">
{*((QDate*)(d.is_shared ? d.data.shared-&gt;ptr
: reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))}
</DisplayString>
<DisplayString Condition="d.type == QMetaType::QTime">
{*((QTime*)(d.is_shared ? d.data.shared-&gt;ptr
: reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))}
</DisplayString>
<DisplayString Condition="d.type == QMetaType::QDateTime">DateTime</DisplayString>
<DisplayString Condition="d.type == QMetaType::QUrl">Url</DisplayString>
<DisplayString Condition="d.type == QMetaType::QLocale">Locale</DisplayString>
<DisplayString Condition="d.type == QMetaType::QRect">
{*((QRect*)(d.is_shared ? d.data.shared-&gt;ptr
: reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))}
</DisplayString>
<DisplayString Condition="d.type == QMetaType::QRectF">
{*((QRectF*)(d.is_shared ? d.data.shared-&gt;ptr
: reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))}
</DisplayString>
<DisplayString Condition="d.type == QMetaType::QSize">
{*((QSize*)(d.is_shared ? d.data.shared-&gt;ptr
: reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))}
</DisplayString>
<DisplayString Condition="d.type == QMetaType::QSizeF">
{*((QSizeF*)(d.is_shared ? d.data.shared-&gt;ptr
: reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))}
</DisplayString>
<DisplayString Condition="d.type == QMetaType::QLine">
{*((QLine*)(d.is_shared ? d.data.shared-&gt;ptr
: reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))}
</DisplayString>
<DisplayString Condition="d.type == QMetaType::QLineF">
{*((QLineF*)(d.is_shared ? d.data.shared-&gt;ptr
: reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))}
</DisplayString>
<DisplayString Condition="d.type == QMetaType::QPoint">
{*((QPoint*)(d.is_shared ? d.data.shared-&gt;ptr
: reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))}
</DisplayString>
<DisplayString Condition="d.type == QMetaType::QPointF">
{*((QPointF*)(d.is_shared ? d.data.shared-&gt;ptr
: reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))}
</DisplayString>
<DisplayString Condition="d.type == QMetaType::QRegExp">RegExp</DisplayString>
<DisplayString Condition="d.type == QMetaType::QRegularExpression">RegularExpression</DisplayString>
<DisplayString Condition="d.type == QMetaType::QVariantHash">
{*((QHash&lt;QString,QVariant&gt;*)(d.is_shared ? d.data.shared-&gt;ptr
: reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))}
</DisplayString>
<DisplayString Condition="d.type == QMetaType::QEasingCurve">EasingCurve</DisplayString>
<DisplayString Condition="d.type == QMetaType::QUuid">Uuid</DisplayString>
<DisplayString Condition="d.type == QMetaType::QModelIndex">ModelIndex</DisplayString>
<DisplayString Condition="d.type == QMetaType::LastCoreType">LastCoreType</DisplayString>
<DisplayString Condition="d.type == QMetaType::QFont">Font</DisplayString>
<DisplayString Condition="d.type == QMetaType::QPixmap">Pixmap</DisplayString>
<DisplayString Condition="d.type == QMetaType::QBrush">Brush</DisplayString>
<DisplayString Condition="d.type == QMetaType::QColor">Color</DisplayString>
<DisplayString Condition="d.type == QMetaType::QPalette">Palette</DisplayString>
<DisplayString Condition="d.type == QMetaType::QImage">Image</DisplayString>
<DisplayString Condition="d.type == QMetaType::QPolygon">Polygon</DisplayString>
<DisplayString Condition="d.type == QMetaType::QRegion">Region</DisplayString>
<DisplayString Condition="d.type == QMetaType::QBitmap">Bitmap</DisplayString>
<DisplayString Condition="d.type == QMetaType::QCursor">Cursor</DisplayString>
<DisplayString Condition="d.type == QMetaType::QKeySequence">KeySequence</DisplayString>
<DisplayString Condition="d.type == QMetaType::QPen">Pen</DisplayString>
<DisplayString Condition="d.type == QMetaType::QTextLength">TextLength</DisplayString>
<DisplayString Condition="d.type == QMetaType::QTextFormat">TextFormat</DisplayString>
<DisplayString Condition="d.type == QMetaType::QMatrix">Matrix</DisplayString>
<DisplayString Condition="d.type == QMetaType::QTransform">Transform</DisplayString>
<DisplayString Condition="d.type == QMetaType::QMatrix4x4">Matrix4x4</DisplayString>
<DisplayString Condition="d.type == QMetaType::QVector2D">Vector2D</DisplayString>
<DisplayString Condition="d.type == QMetaType::QVector3D">Vector3D</DisplayString>
<DisplayString Condition="d.type == QMetaType::QVector4D">Vector4D</DisplayString>
<DisplayString Condition="d.type == QMetaType::QQuaternion">Quaternion</DisplayString>
<DisplayString Condition="d.type == QMetaType::QPolygonF">PolygonF</DisplayString>
<DisplayString Condition="d.type == QMetaType::QIcon">Icon</DisplayString>
<DisplayString Condition="d.type == QMetaType::LastGuiType">LastGuiType</DisplayString>
<DisplayString Condition="d.type == QMetaType::QSizePolicy">SizePolicy</DisplayString>
<DisplayString Condition="d.type == QMetaType::User">UserType</DisplayString>
<DisplayString Condition="d.type == 0xffffffff">LastType</DisplayString>
<!--End region DisplayString QVariant-->
<!--Region DisplayView QVariant-->
<StringView Condition="d.type == QMetaType::QChar">d.data.c</StringView>
<StringView Condition="d.type == QMetaType::QString">
*((QString*)(d.is_shared ? d.data.shared-&gt;ptr
: reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))
</StringView>
<StringView Condition="d.type == QMetaType::QByteArray">
*((QByteArray*)(d.is_shared ? d.data.shared-&gt;ptr
: reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))
</StringView>
<!--End region DisplayView QVariant-->
<!--Region Expand QVariant-->
<Expand>
<ExpandedItem Condition="d.type == QMetaType::QVariantMap">
*((QMap&lt;QString,QVariant&gt;*)(d.is_shared ? d.data.shared-&gt;ptr
: reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))
</ExpandedItem>
<ExpandedItem Condition="d.type == QMetaType::QVariantList">
*((QList&lt;QVariant&gt;*)(d.is_shared ? d.data.shared-&gt;ptr
: reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))
</ExpandedItem>
<ExpandedItem Condition="d.type == QMetaType::QString">
*((QString*)(d.is_shared ? d.data.shared-&gt;ptr
: reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))
</ExpandedItem>
<ExpandedItem Condition="d.type == QMetaType::QStringList">
*((QStringList*)(d.is_shared ? d.data.shared-&gt;ptr
: reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))
</ExpandedItem>
<ExpandedItem Condition="d.type == QMetaType::QByteArray">
*((QByteArray*)(d.is_shared ? d.data.shared-&gt;ptr
: reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))
</ExpandedItem>
<ExpandedItem Condition="d.type == QMetaType::QBitArray">
*((QBitArray*)(d.is_shared ? d.data.shared-&gt;ptr
: reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))
</ExpandedItem>
<ExpandedItem Condition="d.type == QMetaType::QDate">
*((QDate*)(d.is_shared ? d.data.shared-&gt;ptr
: reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))
</ExpandedItem>
<ExpandedItem Condition="d.type == QMetaType::QTime">
*((QTime*)(d.is_shared ? d.data.shared-&gt;ptr
: reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))
</ExpandedItem>
<ExpandedItem Condition="d.type == QMetaType::QRect">
*((QRect*)(d.is_shared ? d.data.shared-&gt;ptr
: reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))
</ExpandedItem>
<ExpandedItem Condition="d.type == QMetaType::QRectF">
*((QRectF*)(d.is_shared ? d.data.shared-&gt;ptr
: reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))
</ExpandedItem>
<ExpandedItem Condition="d.type == QMetaType::QSize">
*((QSize*)(d.is_shared ? d.data.shared-&gt;ptr
: reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))
</ExpandedItem>
<ExpandedItem Condition="d.type == QMetaType::QSizeF">
*((QSizeF*)(d.is_shared ? d.data.shared-&gt;ptr
: reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))
</ExpandedItem>
<ExpandedItem Condition="d.type == QMetaType::QLine">
*((QLine*)(d.is_shared ? d.data.shared-&gt;ptr
: reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))
</ExpandedItem>
<ExpandedItem Condition="d.type == QMetaType::QLineF">
*((QLineF*)(d.is_shared ? d.data.shared-&gt;ptr
: reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))
</ExpandedItem>
<ExpandedItem Condition="d.type == QMetaType::QPoint">
*((QPoint*)(d.is_shared ? d.data.shared-&gt;ptr
: reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))
</ExpandedItem>
<ExpandedItem Condition="d.type == QMetaType::QPointF">
*((QPointF*)(d.is_shared ? d.data.shared-&gt;ptr
: reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))
</ExpandedItem>
<ExpandedItem Condition="d.type == QMetaType::QVariantHash">
*((QHash&lt;QString,QVariant&gt;*)(d.is_shared ? d.data.shared-&gt;ptr
: reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))
</ExpandedItem>
</Expand>
<!--End region Expand QVariant-->
</Type>
</AutoVisualizer>

BIN
res-drgx/remove.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

6
res-drgx/resize.sh

@ -0,0 +1,6 @@
#!/bin/bash
for size in 16 32 48 128 256; do
inkscape -z -e $size.png -w $size -h $size logo.svg >/dev/null 2>/dev/null
done
convert 16.png 32.png 48.png 128.png 256.png -colors 256 icon.ico
rm 16.png 32.png 48.png 128.png 256.png

BIN
res-drgx/send.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
res-drgx/silentdragon-animated-dark.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

BIN
res-drgx/silentdragon-animated-loop-dark.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 556 KiB

BIN
res-drgx/silentdragon-animated-loop.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 538 KiB

BIN
res-drgx/silentdragon-animated-startup-dark.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

BIN
res-drgx/silentdragon-animated-startup.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 986 KiB

BIN
res-drgx/silentdragon-animated.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

385
res-drgx/silentdragon.xpm

@ -0,0 +1,385 @@
/* XPM */
static char *c71bf0c12e1a4d3fcb8972d6277bf3abRHr7XrgX2PiRUZpA[] = {
/* columns rows colors chars-per-pixel */
"256 256 123 2 ",
" c black",
". c #1D1E1E",
"X c #101621",
"o c #141A25",
"O c #171D28",
"+ c #181E29",
"@ c #1C222D",
"# c #1F2630",
"$ c #232424",
"% c #202631",
"& c #242A34",
"* c #282E38",
"= c #2C323C",
"- c #30363F",
"; c #313740",
": c #343B44",
"> c #383E47",
", c #393F48",
"< c #3D434C",
"1 c #40464F",
"2 c #464848",
"3 c #414750",
"4 c #454B53",
"5 c #484F57",
"6 c #4B515A",
"7 c #51575F",
"8 c #595B5B",
"9 c #555B63",
"0 c #585E66",
"q c #5C636A",
"w c #61676E",
"e c #62686F",
"r c #656C73",
"t c #686F75",
"y c #697076",
"u c #6E747B",
"i c #717474",
"p c #70767C",
"a c #71787E",
"s c #757B82",
"d c #797F85",
"f c #7A8086",
"g c #7D8489",
"h c #81878D",
"j c #83898F",
"k c #858B91",
"l c #888F94",
"z c #8B9196",
"x c #8E9499",
"c c #90979C",
"v c #92999D",
"b c #969CA1",
"n c #989FA4",
"m c #9BA2A6",
"M c #9EA5A9",
"N c #A1A7AB",
"B c #A3AAAE",
"V c #A6ADB1",
"C c #A8AFB2",
"Z c #ABB2B5",
"A c #AEB5B8",
"S c #B1B6B6",
"D c #B0B7BA",
"F c #B3BABD",
"G c #B6BDC0",
"H c #B8BFC2",
"J c #BCC2C4",
"K c #BFC5C8",
"L c #C1C7CA",
"P c #C4CBCD",
"I c #C7CED0",
"U c #C8CFD1",
"Y c #CCD3D5",
"T c #CFD6D8",
"R c #D0D7D9",
"E c #D4DBDD",
"W c #D7DEE0",
"Q c #D8DFE1",
"! c #D8DFE1",
"~ c #DAE1E2",
"^ c #DBE2E3",
"/ c #DCE3E4",
"( c #DDE4E5",
") c #DEE5E6",
"_ c #DFE5E7",
"` c #DFE6E7",
"' c #DDE4E5",
"] c #E0E7E8",
"[ c #E0E7E8",
"{ c #E1E8E9",
"} c #E2E9EA",
"| c #E3EAEB",
" . c #E4EBEC",
".. c #E5ECED",
"X. c #E6EDEE",
"o. c #E7EEEE",
"O. c #E5ECED",
"+. c #E8EFEF",
"@. c #E8EFEF",
"#. c #E9EFF0",
"$. c #E9EFF0",
"%. c #E9F0F1",
"&. c #EAF1F2",
"*. c #EBF2F3",
"=. c #ECF3F4",
"-. c #EDF4F5",
";. c #EEF5F5",
":. c #EFF6F6",
">. c #EBF2F3",
",. c #F0F7F7",
"<. c #F0F7F7",
"1. c #F1F8F8",
"2. c #F2F9F9",
"3. c #F3FAFA",
"4. c #F3FAFB",
"5. c #F4FBFB",
"6. c #F4FBFC",
"7. c #F5FCFC",
"8. c #F6FDFD",
"9. c #F7FEFE",
"0. c #F4FBFB",
"q. c #F8FFFF",
"w. c #F8FFFF",
/* pixels */
" $ i C E 3.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.2.E Z i $ ",
" 2 J q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.J 2 ",
" . S q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.S . ",
" 2 o.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.@.2 ",
" 8 5.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.5.8 ",
" 2 5.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.5.2 ",
" . o.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.@.. ",
" S q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.S ",
" 2 q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.w.w.w.w.w.w.w.w.q.q.q.q.q.q.2 ",
" J q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.w.w.w.w.w.w.w.w.q.q.q.q.q.q.J ",
"$ w.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.w.w.w.w.w.w.w.w.q.q.q.q.q.q.q.$ ",
"i w.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.w.w.w.w.w.w.w.w.q.q.q.q.q.q.q.i ",
"S q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.<.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.<.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.w.w.w.w.w.w.w.w.w.w.w.w.q.q.q.C ",
"E q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.T q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.R q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.w.w.w.w.w.w.w.w.w.w.w.w.q.q.w.E ",
"1.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.F q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.F q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.3.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.v q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.v q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.s q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.s q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.<.q q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.w 2.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.P y q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.y I q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.v d q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.d v q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.w k q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.k w q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.* l q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.l = q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.[ X v q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.v X { q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.N X v q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.v X B q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.r X m q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.m X t q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.* X N q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.N X * q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.R X X N q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.N X X R q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.z X X Z q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.Z X X z q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.< X X N q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.N X X 4 q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.E X X X N q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.N X X X E q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.g X X X M q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.M X X X h q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.5.& X X X v q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.v X X X * 5.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.N X X X X v q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.v X X X X V 9.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.w.w.w.w.w.w.w.w.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.: X X X X c q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.v X X X X : 9.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.w.w.w.w.w.w.w.w.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.C X X X X X k q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.k X X X X X C q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.w.w.w.w.w.w.w.w.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.<.= X X X X X s q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.s X X X X X = <.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.w.w.w.w.w.w.w.w.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.k X X X X X X t q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.r X X X X X X z 9.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.w.w.w.w.w.w.w.w.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.E o X X X X X X 0 q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.9.q X X X X X X o E q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.w.w.w.w.w.w.w.w.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.8.3 X X X X X X X 5 q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.5 X X X X X X X 4 8.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.w.w.w.w.w.w.w.w.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.! q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.g X X X X X X X X , q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q., X X X X X X X X g q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.w.w.^ w.w.w.w.w.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.v q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.F X X X X X X X X X * q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.9.* X X X X X X X X X D q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.w.w.v w.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.5 5.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.R @ X X X X X X X X X O q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.9.X X X X X X X X X X @ R q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.w.7.5 w.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.4 G q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.[ * X X X X X X X X X X X .q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q. .X X X X X X X X X X X = ] q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.w.F 4 w.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q r q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.&., X X X X X X X X X X X X Y q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.Y X X X X X X X X X X X X > &.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.w.r 0 w.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.p + ;.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.&.3 X X X X X X X X X X X X X D q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.D X X X X X X X X X X X X X 3 &.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.1.+ p q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.z X M q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.8.4 X X X X X X X X X X X X X X b q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.m X X X X X X X X X X X X X X 4 9.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.N o l q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.C X < q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.l X X X X X X X X X X X X X X g q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.g X X X X X X X X X X X X X X l 9.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.1 X N q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.L X X I q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.5 X X X X X X X X X X X X X w q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.9.9.w X X X X X X X X X X X X X 5 9.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.U . X L 9.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.@.X X r q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q./ @ X X X X X X X X X X X X < q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.&.*.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.1 . X X X X X X X X X X X @ _ q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.r X X @.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.& X O @.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.v X X X X X X X X X X X X @ q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.P P q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.@ X X X X X X X X X X X X v q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.@.+ X & q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.5 X . l q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.8.: X X X X X X X X X X X X _ q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.m m q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.[ X X X X X X X X X X X X : 8.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.z X X 5 q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.p X X & 3.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.D X X X X X X X X X X X X H q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.a a q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.H X X X X X X X X X X X X D q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.5.& X X p q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.M X X X m q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.< X X X X X X X X X X X v q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.6 5 q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.v X X X X X X X X X X X < q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.m X X X M q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.Y X X X ; 8.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.C X X X X X X X X X X X p q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.% % q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.p X X X X X X X X X X X C q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.; X X X Y q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.8.+ X X X A q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.5.% X X X X X X X X X X 4 q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q._ X X [ q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.4 X X X X X X X X X X & 2.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.Z X X X + 8.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.4 X X X < 7.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.f X X X X X X X X X X O 5.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.D X X D q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.+ X X X X X X X X X X d q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.8.< X X X 4 q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.d X X X X C 9.9.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.P X X X X X X X X X X X T q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.l X X l q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.T X X X X X X X X X X X I q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.C X X X X d q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.G X X X X ; 8.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.* X X X X X X X X X X m q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.0 X X 0 q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.M X X X X X X X X X X & q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.8.- X X X X F q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.=.o X X X X M q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.w X X X X X X X X X X u 9.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.= X X = q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.p X X X X X X X X X X w q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.N X X X X o =.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.4 X X X X * <.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.v X X X X X X X X X X < q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.&.X X X X #.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.< X X X X X X X X X X v q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.<.* X X X X 4 q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.j X X X X X k 9.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.L X X X X X X X X X X X ;.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.L X X X X L q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.<.o X X X X X X X X X X L q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.k X X X X X j q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.L X X X X X O ^ q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.^ X X X X X X X X X X X G q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.v X X X X v q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.H X X X X X X X X X X X ^ q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.^ o X X X X X P q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.9.% X X X X X q q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.5.X X X X X X X X X X X f q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.r X X X X t q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.g X X X X X X X X X X X 2.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q X X X X X % 8.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.t X X X X X X J q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.X X X X X X X X X X X < q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.< X X X X < q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.3 X X X X X X X X X X X q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.J X X X X X X t q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.D X X X X X X ; <.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.X X X X X X X X X X X X &.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.5.o X X X X o 5.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.*.o X X X X X X X X X X X q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.<.- X X X X X X F q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.2.@ X X X X X X s q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.5.X X X X X X X X X X X X D q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.U X X X X X X Y q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.F X X X X X X X X X X X X 8.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.s X X X X X X @ 2.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.y X X X X X X X P q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q._ X X X X X X X X X X X X s q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.m X X X X X X b q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.s X X X X X X X X X X X X _ q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.P X X X X X X X t q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.K X X X X X X X : <.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.H X X X X X X X X X X X X = q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.t X X X X X X t q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.; X X X X X X X X X X X X H q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.<.: X X X X X X X J q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.9.= X X X X X X X u q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.z X X X X X X X X X X X X X T 9.q.q.q.q.q.q.q.q.q.q.q.q.q.q.> X X X X X X > q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.R X X X X X X X X X X X X X z q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.u X X X X X X X = q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.9.j X X X X X X X X Z q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.6 X X X X X X X X X X X X X l 9.q.q.q.q.q.q.q.q.q.q.q.q.q.;.X X X X X X X X <.q.q.q.q.q.q.q.q.q.q.q.q.q.q.z X X X X X X X X X X X X X 6 q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.Z X X X X X X X X k q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q._ o X X X X X X X # _ 9.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.@.o X X X X X X X X X X X X X < q.q.q.q.q.q.q.q.q.q.q.q.q.q.L X X X X X X X X L q.q.q.q.q.q.q.q.q.q.q.q.q.q.4 X X X X X X X X X X X X X o @.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q._ @ X X X X X X X X [ q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.9.q X X X X X X X X 3 2.9.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.b X X X X X X X X X X X X X X X { q.q.q.q.q.q.q.q.q.q.q.q.q.c X X X X X X X X z q.q.q.q.q.q.q.q.q.q.q.q.q. .o X X X X X X X X X X X X X X v q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.2.3 X X X X X X X X q q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.K X X X X X X X X X r q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.8.- X X X X X X X X X X X X X X X n q.q.q.q.q.q.q.q.q.q.q.q.q.0 X X X X X X X X 0 q.q.q.q.q.q.q.q.q.q.q.q.q.m X X X X X X X X X X X X X X X - 5.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.r X X X X X X X X X K q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.< X X X X X X X X X v q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.M X X X X X X X X X X X X X X X X 4 q.q.q.q.q.q.q.q.q.q.q.q.q.% X X X X X X X X & q.q.q.q.q.q.q.q.q.q.q.q.q.6 X X X X X X X X X X X X X X X X N q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.v X X X X X X X X X < q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.Z X X X X X X X X X o G q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.*.& X X X X X X X X X X X X X X X X X ^ q.q.q.q.q.q.q.q.q.q.q.E X X X X X X X X X X E q.q.q.q.q.q.q.q.q.q.q.[ X X X X X X X X X X X X X X X X X * =.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.G o X X X X X X X X X Z q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.9.- X X X X X X X X X + U q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.u X X X X X X X X X X X X X X X X X X l q.q.q.q.q.q.q.q.q.q.q.B X X X X X X X X X X N q.q.q.q.q.q.q.q.q.q.q.c X X X X X X X X X X X X X X X X X X u q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.U + X X X X X X X X X - 9.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.B X X X X X X X X X X % W q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.;.% X X X X X X X X X X X X X X X X X X > q.q.q.q.q.q.q.q.q.q.q.u X X X X X X X X X X u q.q.q.q.q.q.q.q.q.q.q.1 X X X X X X X X X X X X X X X X X X % =.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.W % X X X X X X X X X X B q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.9.: X X X X X X X X X X = [ q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.J o X X X X X X X X X X X X X X X X X X Y q.q.q.q.q.q.q.q.q.q.; X X X X X X X X X X ; q.q.q.q.q.q.q.q.q.q.E X X X X X X X X X X X X X X X X X X X J q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q._ = X X X X X X X X X X : 9.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.Z X X X X X X X X X X X - [ q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.h X X X X X X X X X X X X X X X X X X s q.q.q.q.q.q.q.q.q./ X X X X X X X X X X X X / q.q.q.q.q.q.q.q.q.f X X X X X X X X X X X X X X X X X X h q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.[ - X X X X X X X X X X X Z q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.4 X X X X X X X X X X X - _ q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.9.4 X X X X X X X X X X X X X X X X X % <.q.q.q.q.q.q.q.q.m X X X X X X X X X X X X m q.q.q.q.q.q.q.q.5.& X X X X X X X X X X X X X X X X X 4 8.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.[ - X X X X X X X X X X X 4 q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.U X X X X X X X X X X X X = E q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q./ + X X X X X X X X X X X X X X X X X N q.q.q.q.q.q.q.6.0 X X . X X X X X X X X X q q.q.q.q.q.q.q.q.Z X X X X X X X X X X X X X X X X X @ / q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.E = X X X X X X X X X X X X U q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.r X X X X X X X X X X X X & U q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.v X X X X X X X X X X X X X X X X X 4 q.q.q.q.q.q.q.6.# X X X X X X X X X X X X % 7.q.q.q.q.q.q.q.6 X X X X X X X X X X X X X X X X X v q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.U % X X X X X X X X X X X X t q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.o.% X X X X X X X X X X X X + F q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.9.> X X X X X X X X X X X X X X X X X T q.q.q.q.q.q.K X X X X X X X X X X X X X X L q.q.q.q.q.q.E X X X X X X X X X X X X X X X X X > 8.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.F + X X X X X X X X X X X X % X.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.N X X X X X X X X X X X X X o z q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.G X X X X X X X X X X X X X X X X X u q.q.q.q.q.q.s X X X X X X X X X X X X X X a q.q.q.q.q.q.f X X X X X X X X X X X X X X X X X G q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.z X X X X X X X X X X X X X X N q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.9.6 X X X X X X X X X X X X X X w =.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.4 X X X X X X X X X X X X X X X X @ o.q.q.q.q.2.% X X X X X X X X X X X X X X & 2.q.q.q.q.;.% . X X X X X X X X X X X X X X X 4 q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.<.w X X X X X X X X X X X X X X 7 q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q._ % X X X X X X X X X X X X X X : Y q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.F X X X X X X X X X X X X X X X X X l q.q.q.q.J X X X X X X X X X X X X X X X X J q.q.q.q.v X X X X X X X X X X X X X X X X X F q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.Y : X X X X X X X X X X X X X X # [ 8.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.C X X X X X X X X X X X X X X X o b q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.9.* X X X X X X X X X X X X X X X X & 2.q.q.9.6.; X X X X X X X X X X X X X X = 8.9.9.9.6.* X X X X X X X X X X X X X X X X = q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.b o X X X X X X X X X X X X X X . B q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.r X X X X X X X X X X X X X X X X 5 ^ q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.g X X X X X X X X X X X X X X X X X M q.q.9.9.m X X X X X X X X X X X X X X n q.9.9.9.C X X X X X X X X X X X X X X X X X f q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q./ 5 X X X X X X X X X X X X X X X X r q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.9.=.: . X X X X X X X X X X X X X X X + c 8.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.R X X X X X X X X X X X X X X X X X > 9.q.q.q.5.= X X X X X X X X X X X X & <.q.q.q.q.3 X X X X X X X X X X X X X X X X X R q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.5.c + X X X X X X X X X X X X X X X X : -.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.9.6.W @ X X X X X X X X X X X X X X X X X > J q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.0 X X X X X X X X X X X X X X X X X A q.q.q.q.b X X X X X X X X X X X X z q.q.q.9.K X X X X X X X X X X X X X X X X X 0 q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.J > X X X X X X X X X X X X X X X X X + W q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.9.q.q.F o X X X X X X X X X X X X X X X X X X 9 T q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.I X X X X X X X X X X X X X X X X X < 9.q.q.q.5.* X X X X X X X X X X & ;.q.q.q.q.5 X X X X X X X X X X X X X X X X X P q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.T 9 X X X X X X X X X X X X X X X X X X o D q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.v X X X X X X X X X X X X X X X X X X X X r R q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.7 X X X X X X X X X X X X X X X X X A q.q.q.q.M X X X X X X X X X X b q.q.q.q.K X X X X X X X X X X X X X X X X X 7 q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.R r X X X X X X X X X X X X X X X X X X X X v q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.s X X X X X X X X X X X X X X X X X X X X X 0 L q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.P X X X X X X X X X X X X X X X X X < 9.9.q.q.5.- X X X X X X X X = 2.9.q.9.9.6 X X X X X X X X X X X X X X X X X P q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.L 0 X X X X X X X X X X X X X X X X X X X X X s q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.w X X X X X X X X X X X X X X X X X X X X . X , n &.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.9 X X X X X X X X X X X X X X X X X A q.q.q.q.V X X X X X X X X M q.q.q.9.K X X X X X X X X X X X X X X X X X 9 q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.&.n , X X X X X X X X X X X X X X X X X X X X X X w q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.5.0 X X X X X X X X X X X X X X X X X X X X X X X O q A <.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.Y X X X X X X X X X X X X X X X X X < 9.q.q.q.9.1 X X X X X X < 9.q.q.q.q.6 X X X X X X X X X X X X X X X X X Y q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.<.A q O X X X X X X X X X X X X X X X X X X X X X X X 0 5.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.5.0 X X X X X X X X X X X X X X X X X X X X X X X X X + 9 b R 9.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q X X X X X X X X X X X X X X X X X B q.q.q.q.L X X X X X X G q.q.q.q.F X X X X X X X X X X X X X X X X X q q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.R b 9 + X X X X X X X X X X X X X X X X X X X X X X X X X 0 5.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.5.w X X X X X X X X X X X X X X X X X X X X X X X X X X X X % q z G ] q.q.q.q.q.q.q.q.! v q.q.q.q.W o X X X X X X X X X X X X X X X X = 2.q.q.q.q.9 X X X X 7 q.q.q.q.9.< . X X X X X X X X X X X X X X X o E q.q.q.q.v ! q.q.q.q.q.q.q.q.[ F z w % X X X X X X X X X X X X X X X X X X X X X X X X X X X X w 5.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.5.u X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X @ > 9 u s k j f @ O [ q.q.q.q.u X X X X X X X X X X X X X X X X X x 9.q.q.q.E o X X X R q.q.q.q.N X X X X X X X X X X X X X X X X X u q.q.q.q._ O @ f k k s u 9 > @ X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X u 7.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.l X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X u q.q.q.q.] + X X X X X X X X X X X X X X X X @ #.q.q.q.q.f X X d q.q.q.q.<.= X X X X X X X X X X X X X X X X O ` q.q.q.q.u X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X z 9.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.A + X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X o ! q.q.q.q.h X X X X X X X X X X X X X X X X X d q.q.q.q.*.& & &.q.q.q.q.z X X X X X X X X X X X X X X X X X g 9.q.q.q.E O X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X + Z q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.Y = X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X r q.q.q.q.=.& X X X X X X X X X X X X X X X X O E q.q.q.q.N N q.q.q.q.{ @ X X X X X X X X X X X X X X X X % =.q.q.q.q.r X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X = Y q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.@.q X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X R q.q.q.q.m X X X X X X X X X X X X X X X X X 7 q.q.q.q.q.q.q.q.q.q.r X X X X X X X X X X X X X X X X X b q.q.q.q.R X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X q #.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.b + X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X 9 q.q.q.q.8.: X X X X X X X X X X X X X X X X X D q.q.q.q.q.q.q.q.P X X X X X X X X X X X X X X X X X ; 6.q.q.q.q.9 X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X O b q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.E 5 X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X J q.q.q.q.F X X X X X X X X X X X X X X X X X = <.q.q.q.q.q.q.q.< X X X X X X X X X X X X X X X X X A 9.q.q.q.J X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X 5 E q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.b @ X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X , 9.q.q.q.q.9 X X X X X X X X X X X X X X X X X j q.q.q.q.q.q.m X X X X X X X X X X X X X X X X X 7 q.q.q.q.9.< X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X @ b q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.] r X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X N q.q.q.q.E o X X X X X X X X X X X X X X X X O E q.q.q.q. .% X X X X X X X X X X X X X X X X o R q.q.q.q.N X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X r _ q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.U 4 X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X * ;.q.q.q.q.g X X X X X X X X X X X X X X X X X 6 9.q.q.q.e X X X X X X X X X X X X X X X X X s q.q.q.q.;.& X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X 4 Y q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.D 3 X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X k 9.q.q.q.=.& X X X X X X X X X X X X X X X X X N q.q.H X X X X X X X X X X X X X X X X X & &.q.q.q.q.l X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X 3 A q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.G 4 X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X + _ q.q.q.q.B X X X X X X X X X X X X X X X X X @ { <.= X X X X X X X X X X X X X X X X X m q.q.q.q._ O X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X 4 H q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.I q O X X X X X X X X X X X X X X X X X X X X X X X X X X X X q q.q.q.q.q.3 X X X X X X X X X X X X X X X X X q f X X X X X X X X X X X X X X X X X < 9.q.q.q.q.q X X X X X X X X X X X X X X X X X X X X X X X X X X . X X w L q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.9.9.{ g # X X X X X X X X X X X X X X X X X X X X X X X X X X X J q.q.q.q.Y o X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X P q.q.q.9.J X X X X X X X X X X X X X X X X X X X X X X X X X X X % g ] 9.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.9.9.-.c # X X X X X X X X X X X X X X X X X X X X X X X X X : 8.q.q.q.q.s X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X p q.q.q.9.6.: X X X X X X X X X X X X X X X X X X X X X X X X X & v <.9.9.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.5.b & X X X X X X X X X X X X X X X X X X X X X X X X z 9.9.9.9.&.* X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X & #.q.q.q.q.c X X X X X X X X X X X X X X X X X X X X X X X X & b 5.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.;.k + X X X X X X X X X X X X X X X X X X X X X . @ } 9.q.9.q.Z X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X N q.q.q.q. .@ X X X X X X X X X X X X X X X X X X X X X X + j ;.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q./ 9 X X X X X X X X X X X X X X X X X X X X X X r q.q.q.q.q.9 X X X X X X X X X X X X X X X X X X X X X X X X X X X X X . 4 q.q.q.q.q.r X X X X X X X X X X X X X X X X X X X X X X 7 / q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.V @ X X X X X X X X X X X X X X X X X X X X X L q.q.q.q.W O X X X X X X X X X X X X X X X X X X X X X X X X X X X X o R q.q.q.q.L X X X X X X X X X X X X X X X X X X X X X % B q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q./ < X X X X X X X X X X X X X X X X X X X X : 2.q.q.q.9.l X X X X X X X X X X X X X X X X X X X X X X X X X X X X h q.q.q.q.2.: X X X X X X X X X X X X X X X X X X X X < / q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.<.9 X X X X X X X X X X X X X X X X X X X X k q.q.q.q.2.< X X X X X X X X X X X X X X X X X X X X X X X X X X : <.q.q.q.q.k X X X X X X X X X X X X X X X X X X X X 9 <.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.9.q X X X X X X X X X X X X X X X X X X X o E q.q.q.q.U o X X X X X X X X X X X X X X X X X X X X X X X X X L q.q.q.q.R o X X X X X X X X X X X X X X X X X X X q 9.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.2.< X X X X X X X X X X X X X X X X X X X 5 q.q.q.q.q.f X X X X X X X X X X X X X X X X X X X X X X X X p q.q.q.q.q.5 X X X X X X X X X X X X X X X X X X X < 5.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.E o X X X X X X X X X X X X X X X X X X X m q.q.q.q.<.; X X X X X X X X X X X X X X X X X X X X X X * *.q.q.q.q.m X X X X X X X X X X X X X X X X X X X o E q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.a X X X X X X X X X X X X X X X X X X X @ { q.q.q.q.L X X X X X X X X X X X X X X X X X X X X X X F q.q.q.q.{ @ X X X X X X X X X X X X X X X X X X X p q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.I X X X X X X X X X X X X X X X X X X X X q q.q.q.q.q.p X X X X X X X X X X X X X X X X X X X X e q.q.q.q.q.q X X X X X X X X X X X X X X X X X X X X P q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.9.8.X X X X X X X X X X X X X X X X X X X X X L q.q.q.q.=.& X X X X X X X X X X X X X X X X X X @ @.q.q.q.q.L X X X X X X X X X X X X X X X X X X X X X 9.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.9.o X X X X X X X X X X X X X X X X X X X 4 2.q.q.q.q.J X X X X X X X X X X X X X X X X X X X X D q.q.q.q.5.4 X X X X X X X X X X X X X X X X X X X o q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.W X X X X X X X X X X X X X X X X X X X & { q.q.q.q.[ & X X X X X X X X X X X X X X X X X X X X @ E q.q.q.q.{ & X X X X X X X X X X X X X X X X X X X ! q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.l X X X X X X X X X X X X X X X X X X o P q.q.q.q.5.4 X X X X X X X X X X X X X X X X X X X X X X > ;.q.q.q.q.P O X X X X X X X X X X X X X X X X X X l q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.@.% X X X X X X X X X X X X X X X X X X m q.q.q.q.q.a X X X X X X X X X X X X X X X X X X X X X X X X e q.q.q.q.q.m X X X X X X X X X X X X X X X X X X % @.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.9.9 X X X X X X X X X X X X X X X X X X u q.q.q.q.q.B X X X X X X X X X X X X X X X X X X X X X X X X X X b q.q.q.q.q.u X X X X X X X X X X X X X X X X X X 9 6.9.9.9.9.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.9.p X X X X X X X X X X X X X X X X X X 4 2.q.q.q.q.Y @ X X X X X X X X X X X X X X X X X X X X X X X X X X o L 9.q.q.q.5.4 X X X X X X X X X X X X X X X X X . a 6.9.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.<.e X X X X X X X X X X X X X X X X X X * { q.q.q.q.o.= X X X X X X X X X X X X X X X X X X X X X X X X X X X X & _ q.q.q.q.{ = X X X X X X X X X X X X X X X X X X r <.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.E < X X X X X X X X X X X X X X X X X X + Y q.q.q.q.5.5 X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X < <.q.q.q.q.T @ X X X X X X X X X X X X X X X X X X < E q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.2.z + X X X X X X X X X X X X X X X X X X X D q.q.q.q.q.u X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X w 9.q.q.q.q.D o X X X X X X X X X X X X X X X X X X O z 2.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.D : X X X X X X X X X X X X X X X X X X X X z q.q.q.q.q.m X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X z q.q.q.q.q.c X X X X X X X X X X X X X X X X X X X X : D q.9.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.G 4 X X X X X X X X X X X X X X X X X X X X X r q.q.q.q.q.L o X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X F q.q.q.q.q.u X X X X X X X X X X X X X X X X X X X X X 4 G 9.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.5.V , X X X X X X X X X X X X X X X X X X X X X . 5 5.q.q.q.q.^ & X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X @ E q.q.q.q.2.5 X X X X X X X X X X X X X X X X X X X X X X < V 2.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q./ g & X X X X X X X X X X X X X X X X X X X X X X X ; } 9.q.q.q.=.: X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X = .q.q.q.q.@.: X X X X X X X X X X X X X X X X X X X X X X X % g / q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.&.N 5 X X X X X X X X X X X X X X X X X X X X X X X X X # W 9.9.q.q.8.6 X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X 4 <.q.q.q.q.^ & X X X X X X X X X X X X X X X X X X X X X X X X X 6 N &.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q._ s , X X X X X X X X X X X X X X X X X X X X X X X X X o L q.9.q.9.q.p X X X X X X X X X X X X X X X X X X X X l l X X X X X X X X X X X X X X X X X X X X w 9.q.q.q.q.P + X X X X X X X X X X X X X X X X X X X X X X X X X < a _ q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.o.B 0 + X X X X X X X X X X X X X X X X X X X X X V q.q.q.q.9.b X X X X X X X X X X X X X X X X X X X X 7 9.6.7 X X X X X X X X X X X X X X X X X X X X k q.q.q.q.q.A X X X X X X X X X X X X X X X X X X X X X O q B .q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.;.B 5 X X X X X X X X X X X X X X X X X X z q.q.q.q.q.F o X X X X X X X X X X X X X X X X X X X & .q.9.} & X X X X X X X X X X X X X X X X X X X X C q.q.q.q.q.v X X X X X X X X X X X X X X X X X X 4 B ;.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.R u o X X X X X X X X X X X X X X u q.q.q.q.9.Y + X X X X X X X X X X X X X X X X X X X o K q.q.q.q.K X X X X X X X X X X X X X X X X X X X X o L q.q.q.q.q.a X X X X X X X X X X X X X X o u R q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q._ u o X X X X X X X X X X X 9 7.q.q.9.9._ & X X X X X X X X X X X X X X X X X X X X k 9.q.q.q.q.q.k X X X X X X X X X X X X X X X X X X X X % E q.q.q.q.9.0 X X X X X X X X X X X O u _ q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q._ w X X X X X X X X X 3 ;.q.q.q.q.&.> X X X X X X X X X X X X X X X X X X X X 6 9.q.q.q.q.q.q.9.9 X X X X X X X X X X X X X X X X X X X X = { q.q.q.q.<.4 X X X X X X X X X q _ q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.L : X X X X X X : o.q.q.q.q.2.6 X X X X X X X X X X X X X X X X X X X X = @.q.q.q.9.q.q.q.q.@.= X X X X X X X X X X X X X X X X X X X X 1 <.q.q.q.q.o.: X X X X X X : L 9.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.<.f X X X X & ! 9.q.q.q.9.r X X X X X X X X X X X X X X X X X X X X o U q.q.q.q.8.8.q.q.q.q.U o X X X X X X X X X X X X X X X X X X X X 9 9.q.q.q.q.^ & X X X X f 2.9.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.9.J & X @ Y q.q.q.q.q.h X X X X X X X X X X X X X X X X X X X X X m q.q.q.q.q.s s q.q.q.q.q.M X X X X X X X X X X X X X X X X X X X X X p 9.q.q.q.q.Y @ X & J q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q._ 4 H q.q.q.q.q.b X X X X X X X X X X X X X X X X X X X X X r q.q.q.q.q.C X X V q.q.q.q.q.t X X X X X X X X X X X X X X X X X X X X X l q.q.q.q.q.J 4 _ q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.Z o X X X X X X X X X X X X X X X X X X X X < 2.q.q.q.q.T + X X O T 9.q.q.q.<.< X X X X X X X X X X X X X X X X X X X X X M q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.9.9.L o X X X X X X X X X X X X X X X X X X X X & / q.q.q.q.&.- X X X X = @.q.q.q.q._ & X X X X X X X X X X X X X X X X X X X X o D q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.T @ X X X X X X X X X X X X X X X X X X X X o L q.q.q.q.9.9 X X X X X X 9 9.9.q.q.q.L O X X X X X X X X X X X X X X X X X X X X + P q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q./ * X X X X X X X X X X X X X X X X X X X X X m q.q.q.q.q.k X X X X X X X X h q.q.q.q.q.m X X X X X X X X X X X X X X X X X X X X X % R q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.o.: X X X X X X X X X X X X X X X X X X X X X u q.q.q.q.q.D X X X X X X X X X X A 9.q.q.q.q.p X X X X X X X X X X X X X X X X X X X X X * ' 9.9.9.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.9.;.3 X X X X X X X X X X X X X X X X X X X X X 5 5.q.q.q.q.R @ X X X X X X X X X X + Y q.q.q.q.5.6 X X X X X X X X X X X X X X X X X X X X X : =.9.9.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.9.9 X X X X X X X X X X X X X X X X X X X X X = o.q.q.q.q.o.= X X X X X X X X X X X X * { q.q.q.q.@.; X X X X X X X X X X X X X X X X X X X X X 4 2.9.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.r X X X X X X X X X X X X X X X X X X X X X @ E q.q.q.q.5.5 X X X X X X X X X X X X X X 4 2.q.q.q.q.E % X X X X X X X X X X X X X X X X X X X X X q 5.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.g X X X X X X X X X X X X X X X X X X X X X o J 9.q.q.q.q.u X X X X X X X X X X X X X X X X r q.q.q.q.q.K o X X X X X X X X X X X X X X X X X X X X . p q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.v X X X X X X X X X X X X X X X X X X X X X X m q.q.q.q.q.v X X X X X X X X X X X X X X X X X X x q.q.q.q.q.N X X X X X X X X X X X X X X X X X X X X X X l q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.C X X X X X X X X X X X X X X X X X X X X X X d q.q.q.q.q.G X X X X X X X X X X X X X X X X X X X X D 9.q.q.q.q.g X X X X X X X X X X X X X X X X X X X X X X n q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.G O X X X X X X X X X X X X X X X X X X X X X 0 8.q.q.q.9.T @ X X X X X X X X X X X X X X X X X X X X @ Y q.q.q.q.9.q X X X X X X X X X X X X X X X X X X X X X X C q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.P + X X X X X X X X X X X X X X X X X X X X X 4 ;.q.q.q.q._ * X X X X X X X X X X X X X X X X X X X X X X * / q.q.q.q.5.5 X X X X X X X X X X X X X X X X X X X X X o J q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.R % X X X X X X X X X X X X X X X X X X X X X : @.q.q.q.q.&.< X X X X X X X X X X X X X X X X X X X X X X X X : =.q.q.q.q.#.> X X X X X X X X X X X X X X X X X X X X X + P q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.^ * X X X X X X X X X X X X X X X X X X X X X * / q.q.q.q.5.7 X X X X X X X X X X X X X X X X X X X X X X X X X X 6 2.q.q.q.q./ * X X X X X X X X X X X X X X X X X X X X X & E q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.9.9.o.; X X X X X X X X X X X X X X X X X X X X X @ Y q.q.q.q.q.t X X X X X X X X X X X X X X X X X X X X X X X X X X X X r q.q.q.q.q.R @ X X X X X X X X X X X X X X X X X X X X X * [ q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.&.< X X X X X X X X X X X X X X X X X X X X X o J q.q.q.q.q.l X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X k q.q.q.q.q.L o X X X X X X X X X X X X X X X X X X X X X : .q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.2.6 X X X X X X X X X X X X X X X X X X X X X X Z q.q.q.q.q.N X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X N q.q.q.q.q.D X X X X X X X X X X X X X X X X X X X X X X 1 =.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.9.0 X X X X X X X X X X X X X X X X X X X X X X m q.q.q.q.q.D X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X o D q.q.q.q.q.N X X X X X X X X X X X X X X X X X X X X X X 6 5.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.9.t X X X X X X X X X X X X X X X X X X X X X X x q.q.q.q.q.K O X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X O J q.q.q.q.q.v X X X X X X X X X X X X X X X X X X X X X X q 9.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.g X X X X X X X X X X X X X X X X X X X X X X g q.q.q.9.9.Y @ X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X @ U q.q.q.q.q.j X X X X X X X X X X X X X X X X X X X X X X u q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.9.9.v X X X X X X X X X X X X X X X X X X X X X X u q.q.q.q.9.W & X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X & E q.q.q.q.q.s X X X X X X X X X X X X X X X X X X X X X X k q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.9.Z X X X X X X X X X X X X X X X X X X X X X X e 5.q.q.q.q.' * . X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X = ] q.q.q.q.q.r X X X X X X X X X X X X X X X X X X X X X X N q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.K X X X X X X X X X X X X X X X X X X X X X X w 9.q.q.q.9.o.; X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X : @.q.q.q.q.5.r X X X X X X X X X X X X X X X X X X X X X o F q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.R % . X X X X X X X X X X X X X X X X X X X X q 8.q.q.q.q.q.c X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X c q.q.q.q.q.8.w X X X X X X X X X X X X X X X X X X X X X @ U q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.{ = X X X X X X X X X X X X X X X X X X X X X 9 5.q.q.q.q.q.q.F X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X F q.q.q.q.q.q.5.q X X X X X X X X X X X X X X X X X X X X X & [ q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.5.4 X X X X X X X X X X X X X X X X X X X X X 9 5.q.q.q.q.q.q.9.^ X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X / q.q.q.q.q.q.q.5.9 X X X X X X X X X X X X X X X X X X X X X 1 <.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.t X X X X X X X X X X X X X X X X X X X X X 9 2.q.q.q.q.q.q.q.q.9.@ X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X + q.q.q.q.q.q.q.q.q.5.0 X X X X X X X X X X X X X X X X X X X X X w q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.M X X X X X X X X X X X X X X X X X X X X X 9 9.q.q.q.q.q.q.q.q.q.q.: X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X : q.q.q.q.q.q.q.q.q.q.2.9 X X X X X X X X X X X X X X X X X X X X X b q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.Y + X X X X X X X X X X X X X X X X X X X X q 2.9.q.q.q.q.q.q.q.q.q.q.6 X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X 6 q.q.q.q.q.q.q.q.q.q.q.8.q . X X X X X X X X X X X X X X X X X X X o U q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.;.- X X X X X X X X X X X X X X X X X X X X w 9.q.q.q.q.q.q.q.q.q.q.q.q.w X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X w q.q.q.q.q.q.q.q.q.q.q.q.5.r X X X X X X X X X X X X X X X X X X X X = #.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.y X X X X X X X X X X X X X X X X X X X X u 7.q.q.q.q.q.q.q.q.q.q.q.q.q.s X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X s q.q.q.q.q.q.q.q.q.q.q.q.q.q.u X X X X X X X X X X X X X X X X X X X X r q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.D X X X X X X X X X X X X X X X X X X X X a 9.q.q.q.q.q.q.q.q.q.q.q.q.q.q.j X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X j q.q.q.q.q.q.q.q.q.q.q.q.q.q.8.s X X X X X X X X X X X X X X X X X X X X A q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.o.% X X X X X X X X X X X X X X X X X X X l q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.k X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X k q.q.q.q.q.q.q.q.q.q.q.q.q.q.9.9.k X X X X X X X X X X X X X X X X X X X % ] q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.r X X X X X X X X X X X X X X X X X X @ C 9.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.l X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X l q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.9.C + X X X X X X X X X X X X X X X X X X q q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.J X X X X X X X X X X X X X X X X X X @ L q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.v X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X v q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.9.9.P @ X X X X X X X X X X X X X X X X X X G q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.2.; X X X X X X X X X X X X X X X X X % Y q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.v X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X v q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.T & X X X X X X X X X X X X X X X X X ; <.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.l X X X X X X X X X X X X X X X X X % T q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.k X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X k q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.R % X X X X X X X X X X X X X X X X X k q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q. .@ X X X X X X X X X X X X X X X X @ R q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.d X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X d q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.T % X X X X X X X X X X X X X X X X + { q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.p X X X X X X X X X X X X X X X X O L q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.p X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X u q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.P + X X X X X X X X X X X X X X X X p q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.E o X X X X X X X X X X X X X X X X Z q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.r X X X X X X X & e 5 X X X X X X X X X X X X X X X X X X X X X X 5 r & X X X X X X X r q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.A X X X X X X X X X X X X X X X X o E q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.e X X X X X X X X X X X X X X X X z q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.H * X X X X X : #.q.q.R 5 X X X X X X X X X X X X X X X X X X 4 R q.q.#.> X X X X X * H q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.z X X X X X X X X X X X X X X X X w q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.! o X X X X X X X X X X X X X X X q q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.#.r X X X X D q.q.q.q.q.p X X X X X X X X X X X X X X X X p 8.q.q.q.q.D X X X X t #.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.r X X X X X X X X X X X X X X X X E q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.u X X X X X X X X X X X X X X X > ;.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.D & X @ 8.q.q.q.q.q.5.4 X X X X X X X X X X X X X X 4 8.q.q.q.q.q.8.+ X & D q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.<.< X X X X X X X X X X X X X X X u q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.{ O X X X X X X X X X X X X X X @ E q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.@.w 5 q.q.q.q.q.q.q.H X X X X X X X X X X X X X X J q.q.q.q.q.q.q.4 e o.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.E @ X X X X X X X X X X X X X X O ] q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.g X X X X X X X X X X X X X X X N q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.E q.q.q.q.q.q.q.<.o X X X X X X X X X X X X o 2.q.q.q.q.q.q.q.E q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.V X X X X X X X X X X X X X X X f q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.9.8.& X X X X X X X X X X X X X X q q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.<.X X X X X X X X X X X X X X 2.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.r X X X X X X X X X X X X X X % 2.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.Z X X X X X X X X X X X X X X * @.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.Z X X X X X X X X X X X X X X Z q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.&.= X X X X X X X X X X X X X X Z q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.6 X X X X X X X X X X X X X X F q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.*.; X X X X X X X X X X X X X X : *.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.J X X X X X X X X X X X X X X 6 q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.^ X X X X X X X X X X X X X X r q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.7 X X X X X X X X X X X X X X X X 9 9.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.9.u X X X X X X X X X X X X X X E q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.l X X X X X X X X X X X X X & o.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.D o X X X X X X X X X X X X X X X A q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.*.& X X X X X X X X X X X X X l q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.> X X X X X X X X X X X X X N q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.n X X X X X X X X X X X X X X b q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.V X X X X X X X X X X X X X > q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.E X X X X X X X X X X X X X 3 9.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.p X X X X X X X X X X X X p q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.9.5 X X X X X X X X X X X X X E q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.z X X X X X X X X X X X X X U 9.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.5.3 X X X X X X X X X X 3 2.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.Y o X X X X X X X X X X X X l q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.< X X X X X X X X X X X X u q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.[ @ X X X X X X X X @ _ q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.s X X X X X X X X X X X X < q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q._ X X X X X X X X X X X X @ @.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.V X X X X X X X X C q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.9.9.&.% X X X X X X X X X X X X / q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.N X X X X X X X X X X X X z q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q X X X X X X q q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.v X X X X X X X X X X X X N q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.w X X X X X X X X X X X * <.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.[ + X X X X + [ q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.2.= X X X X X X X X X X X w q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.& X X X X X X X X X X X m q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.l X X X X l q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.N X X X X X X X X X X X * q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.W X X X X X X X X X X X : 8.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.<.& X X & <.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.9.> X X X X X X X X X X X E q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.N X X X X X X X X X X X C q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.c X X c q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.D X X X X X X X X X X X N q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.p X X X X X X X X X X : 6.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.&.+ + &.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.< X X X X X X X X X X u q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.3 X X X X X X X X X . C 9.9.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.r r q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.A X X X X X X X X X X 1 q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.2.o X X X X X X X X X - 6.9.9.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.D D q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.9.: X X X X X X X X X o 2.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.R X X X X X X X X X X N q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.&.&.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.V X X X X X X X X X X E q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.Z X X X X X X X X X = 5.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.5.- X X X X X X X X X Z q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.k X X X X X X X X X c q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.b X X X X X X X X X h q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.r X X X X X X X X @ *.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.;.% X X X X X X X X r q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.3 X X X X X X X X s q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.g X X X X X X X X 3 q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.% X X X X X X X X ^ q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q._ o X X X X X X X % q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.2.X X X X X X X X q 9.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.w X X X X X X X X 2.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.^ X X X X X X X X K q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.P X X X X X X X X ^ q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.L X X X X X X X > 9.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.> X X X X X X X L q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.A X X X X X X X v q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.b X X X X X X X A q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.M X X X X X X O #.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.=.+ X X X X X X M q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.z X X X X X X r q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.u X X X X X X z q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.g X X X X X X L q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.P X X X X X X h w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.s X X X X X ; q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.: X X X X X s w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.t X X X X X l q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.z X X X X X t w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.r X X X X X _ q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.] X X X X X r w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.0 X X X X 6 q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.7 X X X X 0 q.q.q.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.0 X X X X N q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.B X X X X 0 q.q.q.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.0 X X X o &.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.=.O X X X 0 q.q.q.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.0 X X X q q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.0 X X . 0 q.q.q.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q X X X Z q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.Z X X X 0 w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.r X X + <.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.2.@ X X r w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.r X X q q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q X X r w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.u X X C q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.Z X X p w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.d X o ;.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.;.O X f w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.l X 7 q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.9 X k w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.v X n q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.b X v w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.B X [ q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q._ X B w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.F < q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.< F q.q.q.q.q.q.q.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.",
"2.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.U h q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.h U q.q.q.q.q.q.q.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.2.",
"E q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q._ L q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.L _ q.q.q.q.q.q.q.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.E ",
"Z q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.2.8.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.8.2.q.q.q.q.q.q.q.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.Z ",
"i q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.i ",
"$ q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.$ ",
" J q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.q.q.q.q.q.q.q.q.q.q.q.q.q.q.J ",
" 2 q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.q.q.q.q.q.q.q.q.q.q.q.q.q.q.2 ",
" S q.w.w.w.w.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.q.q.q.q.q.q.q.q.q.q.q.q.q.S ",
" . @.w.w.w.w.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.q.q.q.q.q.q.q.q.q.q.q.q.@.. ",
" 2 7.w.w.w.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.q.q.q.q.q.q.q.q.q.q.q.5.2 ",
" 8 7.w.w.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.q.q.q.q.q.q.q.q.q.q.5.8 ",
" 2 @.w.w.w.w.w.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.q.q.q.q.q.q.q.q.q.@.2 ",
" . S w.w.w.w.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.q.q.q.q.q.q.q.q.S . ",
" 2 J w.w.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.q.q.q.q.J 2 ",
" $ i C E 3.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.3.E Z i $ "
};

1779
res-drgx/silentdragon_template.ts

File diff suppressed because it is too large

BIN
res-drgx/synced.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
res-drgx/transaction0.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

BIN
res-drgx/transaction2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

BIN
res-drgx/transaction_abandoned.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
res-drgx/transaction_conflicted.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

BIN
res-drgx/tx_inout.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
res-drgx/tx_input.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
res-drgx/tx_mined.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
res-drgx/tx_output.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
res-drgx/verify.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
res-drgx/warning.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

0
res/wormholeconnect.png → res-drgx/wormholeconnect.png

Before

Width:  |  Height:  |  Size: 67 KiB

After

Width:  |  Height:  |  Size: 67 KiB

BIN
res-drgx/wxsbanner.bmp

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

BIN
res/zecwallet.xpm → res-drgx/wxsdialog.bmp

Binary file not shown.

Before

Width:  |  Height:  |  Size: 539 KiB

After

Width:  |  Height:  |  Size: 451 KiB

BIN
res-drgx/zcashdlogo.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

2
res/Info.plist

@ -9,7 +9,7 @@
<key>CFBundleIconFile</key> <key>CFBundleIconFile</key>
<string>logo.icns</string> <string>logo.icns</string>
<key>CFBundleIdentifier</key> <key>CFBundleIdentifier</key>
<string>com.myhush.silentdragon</string> <string>com.hush.silentdragon</string>
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>APPL</string> <string>APPL</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>

13
res/SIGNATURES_README

@ -1,13 +0,0 @@
This directory contains the hashes and signatures for SilentDargon
Verify the hashes by running:
sha256sum -c sha256sum-vX.Y.Z.txt
Verify signatures:
1. First, import the public key (Available on GitHub
at https://github.com/ZcashFoundation/zecwallet/blob/master/public_key.asc)
gpg --import public_key.asc
2. Verify signature
gpg --verify <filename.sig> <downloaded-filename-to-verify>

2
res/css/dark.css

@ -1,5 +1,5 @@
QWidget, QMainWindow, QMenuBar, QMenu, QDialog, QTabWidget, QTableView, QTableView::item, QScrollArea, QGroupBox, QPlainTextEdit, QLineEdit, QLabel, MainWindow QWidget, QMainWindow, QMenuBar, QMenu, QDialog, QTabWidget, QTableView, QScrollArea, QGroupBox, QPlainTextEdit, QLineEdit, QLabel, MainWindow
{ {
background-color: #303335; background-color: #303335;
color: #ffffff; color: #ffffff;

114
res/css/dragonx.css

@ -0,0 +1,114 @@
QWidget, QMainWindow, QMenuBar, QMenu, QDialog, QTabWidget, QTableView, QScrollArea, QGroupBox, QPlainTextEdit, QLineEdit, QLabel, MainWindow {
background-color: #232834;
color: #91a4b8;
}
QTabWidget QTabBar::tab {
padding-left:20px;
padding-right:20px;
padding-top:5px;
padding-bottom:5px;
border: 1px solid #343F4B;
background-color:qlineargradient(x1: 0, y1: 0, x2: 0, y2: 0.25, stop: 0 #343F4B, stop: 1 #232834);
}
QTabWidget QTabBar::tab:selected {
min-height: 10px;
background-color:qlineargradient(x1: 0, y1: 0, x2: 0, y2: 0.25, stop: 0 #343F4B, stop: 1 #232834);
color:#91a4b8;
border: 1px ridge #91a4b8;
}
QTabWidget QTabBar::tab:hover {
background-color:qlineargradient(x1: 0, y1: 0, x2: 0, y2: 0.25, stop: 0 #343F4B, stop: 1 #232834);
color:#91a4b8;
border: 1px ridge #91a4b8;
min-height: 20px
}
QHeaderView {
/* Table Header */
background-color:#232834;
}
QHeaderView::section {
/* Table Header Sections */
qproperty-alignment:center;
background-color:qlineargradient(x1: 0, y1: 0, x2: 0, y2: 0.25, stop: 0 #343F4B, stop: 1 #232834);
color:#91a4b8;
min-height:25px;
font-weight:bold;
font-size:11px;
outline:0;
border:1px solid #343F4B;
border-right:1px solid #91a4b8;
border-left:1px solid #91a4b8;
padding-left:5px;
padding-right:5px;
padding-top:2px;
padding-bottom:2px;
}
QHeaderView::section:last {
border-right: 0px solid #d7d7d7;
}
QScrollArea {
background:transparent;
border:0px;
}
QTableView {
/* Table - has to be selected as a class otherwise it throws off QCalendarWidget */
background:#232834;
}
QTableView::item {
/* Table Item */
background-color:#232834;
border:1px solid #91a4b8;
font-size:12px;
}
QTableView::item:selected {
/* Table Item Selected */
background-color:#91a4b8;
color:#232834;
}
QMenuBar {
background-color:qlineargradient(x1: 0, y1: 0, x2: 0, y2: 0.25, stop: 0 #343F4B, stop: 1 #232834);
color: #91a4b8;
}
QMenuBar::item {
background-color:qlineargradient(x1: 0, y1: 0, x2: 0, y2: 0.25, stop: 0 #343F4B, stop: 1 #232834);
color: #91a4b8;
}
QMenuBar::item:selected {
background-color:qlineargradient(x1: 0, y1: 0, x2: 0, y2: 0.25, stop: 0 #343F4B, stop: 1 #232834);
}
QPushButton#startmining {
background-color: #343F4B;
border-color: #91A4B8;
padding: 10px;
}
QPushButton#startmining:hover {
background-color: #232834;
}
QPushButton#startmining:pressed {
background-color: #232834;
}
QPushButton#startmining:disabled {
background-color: #232834;
}
QPushButton#stopmining {
background-color: #343F4B;
border-color: #91A4B8;
padding: 10px;
margin-top: 7px;
}
QPushButton#stopmining:hover {
background-color: #232834;
}
QPushButton#stopmining:pressed {
background-color: #232834;
}
QPushButton#stopmining:disabled {
background-color: #232834;
}
QComboBox#genproclimit{
font-size: 24px;
height: 40px;
}
QMenu::item:selected{
background-color: #343F4B
}

2
res/css/light.css

@ -1,4 +1,4 @@
QWidget, QMainWindow, QMenuBar, QMenu, QDialog, QTabWidget, QTableView, QTableView::item, QScrollArea, QGroupBox, QWidget, QPlainTextEdit, QLineEdit, QLabel, MainWindow QWidget, QMainWindow, QMenuBar, QMenu, QDialog, QTabWidget, QTableView, QScrollArea, QGroupBox, QWidget, QPlainTextEdit, QLineEdit, QLabel, MainWindow
{ {
background-color: #dadada; background-color: #dadada;
color: #000000; color: #000000;

21
res/css/midnight.css

@ -9,7 +9,7 @@ Website: https://www.csharpe.me
License: https://opensource.org/licenses/MIT License: https://opensource.org/licenses/MIT
*/ */
QWidget, QMainWindow, QMenuBar, QMenu, QDialog, QTabWidget, QTableView, QTableView::item, QScrollArea, QGroupBox, QPlainTextEdit, QLineEdit, QLabel, MainWindow QWidget, QMainWindow, QMenuBar, QMenu, QDialog, QTabWidget, QTableView, QScrollArea, QGroupBox, QPlainTextEdit, QLineEdit, QLabel, MainWindow, QPixmap, QHBoxLayout, QVBoxLayout, QGridLayout, QAbstractItemView, QFrame
{ {
background-color: #111; background-color: #111;
color: #fff; color: #fff;
@ -23,6 +23,7 @@ QPushButton:hover {
background: #222; background: #222;
} }
/*
QLineEdit, QRadioButton::indicator::unchecked, QCheckBox::indicator::unchecked { QLineEdit, QRadioButton::indicator::unchecked, QCheckBox::indicator::unchecked {
background: #222; background: #222;
border: 1px solid #333; border: 1px solid #333;
@ -35,19 +36,24 @@ font-size: 12px;
QLineEdit:focus { QLineEdit:focus {
border: 1px solid #9d8400; border: 1px solid #9d8400;
} }*/
/*
QWidget QLabel { QWidget QLabel {
font-size: 11pt; font-size: 11pt;
} }
*/
QWidget QCheckBox { QWidget QCheckBox {
font-weight: bold; font-weight: bold;
} }
QTabWidget QTabBar::tab { QTabWidget QTabBar::tab {
min-height: 15px; /*min-height: 15px;*/
padding: 15px 25px; padding-left:20px;
padding-right:20px;
padding-top:5px;
padding-bottom:5px;
border: 1px ridge #222; border: 1px ridge #222;
left: 1px; /* Fix 1px alignment */ left: 1px; /* Fix 1px alignment */
background-color:qlineargradient(x1: 0, y1: 0, x2: 0, y2: 0.25, stop: 0 #333, stop: 1 #111); background-color:qlineargradient(x1: 0, y1: 0, x2: 0, y2: 0.25, stop: 0 #333, stop: 1 #111);
@ -62,6 +68,7 @@ border-bottom: 0px; /* Overwrites border-bottom */
QTabWidget QTabBar::tab:hover { QTabWidget QTabBar::tab:hover {
background-color:qlineargradient(x1: 0, y1: 0, x2: 0, y2: 0.25, stop: 0 #555, stop: 1 #111); background-color:qlineargradient(x1: 0, y1: 0, x2: 0, y2: 0.25, stop: 0 #555, stop: 1 #111);
min-height: 20px
} }
QHeaderView { /* Table Header */ QHeaderView { /* Table Header */
@ -74,7 +81,7 @@ background-color:qlineargradient(x1: 0, y1: 0, x2: 0, y2: 0.25, stop: 0 #333, st
color:#fff; color:#fff;
min-height:25px; min-height:25px;
font-weight:bold; font-weight:bold;
font-size:12px; font-size:11px;
outline:0; outline:0;
border:1px ridge #222; border:1px ridge #222;
padding: 2px 5px; padding: 2px 5px;
@ -112,8 +119,8 @@ color: #fff;
QMenuBar::item { QMenuBar::item {
background-color:qlineargradient(x1: 0, y1: 0, x2: 0, y2: 0.25, stop: 0 #222, stop: 1 #111); background-color:qlineargradient(x1: 0, y1: 0, x2: 0, y2: 0.25, stop: 0 #222, stop: 1 #111);
color: #fff; color: #fff;
padding: 5px 7px; /*padding: 5px 7px;
margin: 0px; margin: 0px;*/
} }
QMenuBar::item:selected { QMenuBar::item:selected {

BIN
res/hushdlogo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

2
res/libsodium/buildlibsodium.sh

@ -1,5 +1,5 @@
#!/bin/bash #!/bin/bash
# Copyright (c) 2019-2020 The Hush developers # Copyright (c) 2019-2021 The Hush developers
# Released under the GPLv3 # Released under the GPLv3
VERSION=1.0.18 VERSION=1.0.18

BIN
res/lock_closed.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
res/lock_open.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
res/remove.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
res/send.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
res/silentdragon-animated-dark.gif

Binary file not shown.

Before

Width:  |  Height:  |  Size: 406 KiB

BIN
res/silentdragon-animated-startup-dark.gif

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 MiB

After

Width:  |  Height:  |  Size: 888 KiB

BIN
res/silentdragon-animated-startup.gif

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

BIN
res/silentdragon-animated.gif

Binary file not shown.

Before

Width:  |  Height:  |  Size: 406 KiB

811
res/silentdragon.xpm

@ -0,0 +1,811 @@
/* XPM */
static char * silentdragon_xpm[] = {
"256 256 552 2",
" c None",
". c #FDFDFD",
"+ c #FEFEFE",
"@ c #FFFFFF",
"# c #EFEEEF",
"$ c #BABABA",
"% c #EBEAEB",
"& c #C1C0C1",
"* c #C4C2C4",
"= c #EAE9EA",
"- c #949394",
"; c #B8B7B8",
"> c #A0A0A0",
", c #C8C7C8",
"' c #C3C3C3",
") c #6D6C6E",
"! c #EDEDED",
"~ c #DEDEDE",
"{ c #AAA9AA",
"] c #A09EA0",
"^ c #8C8B8C",
"/ c #8A898A",
"( c #656566",
"_ c #E5E5E5",
": c #D6D5D6",
"< c #9C9B9C",
"[ c #878687",
"} c #5F5F60",
"| c #525253",
"1 c #6E6E6F",
"2 c #D2D1D2",
"3 c #919091",
"4 c #A3A1A3",
"5 c #434344",
"6 c #A4A3A4",
"7 c #BCBBBC",
"8 c #3E3E3F",
"9 c #636364",
"0 c #E3E2E3",
"a c #C6C5C6",
"b c #807F80",
"c c #8C8A8C",
"d c #383738",
"e c #929292",
"f c #F0EFF0",
"g c #797879",
"h c #323232",
"i c #616062",
"j c #E9E8E9",
"k c #BEBEBE",
"l c #6F6F6F",
"m c #999899",
"n c #353536",
"o c #4A4A4B",
"p c #E7E6E7",
"q c #464647",
"r c #2E2E2F",
"s c #676667",
"t c #B7B6B7",
"u c #605F60",
"v c #343435",
"w c #ADADAD",
"x c #3A3A3A",
"y c #5D5D5E",
"z c #ABABAC",
"A c #535353",
"B c #848486",
"C c #727273",
"D c #2F2F30",
"E c #5F5E60",
"F c #A2A2A3",
"G c #4C4B4C",
"H c #999999",
"I c #333334",
"J c #2D2D2E",
"K c #444445",
"L c #D5D4D5",
"M c #464646",
"N c #5B5A5C",
"O c #9A9A9A",
"P c #454546",
"Q c #838384",
"R c #ACACAD",
"S c #959595",
"T c #303031",
"U c #989898",
"V c #404040",
"W c #6F6F70",
"X c #5A5A5B",
"Y c #D0D0D0",
"Z c #767676",
"` c #3C3C3D",
" . c #777778",
".. c #484849",
"+. c #CAC9CA",
"@. c #C8C8C8",
"#. c #3B3B3C",
"$. c #565657",
"%. c #6A696A",
"&. c #3A3A3B",
"*. c #CCCBCC",
"=. c #7F7F80",
"-. c #313132",
";. c #303030",
">. c #9B9B9B",
",. c #888788",
"'. c #2E2E2E",
"). c #545455",
"!. c #CCCCCC",
"~. c #DADADA",
"{. c #5E5E5F",
"]. c #363637",
"^. c #737374",
"/. c #323233",
"(. c #575758",
"_. c #585859",
":. c #4C4C4C",
"<. c #CBCBCB",
"[. c #CECECE",
"}. c #505051",
"|. c #B0B0B1",
"1. c #6E6D6E",
"2. c #404041",
"3. c #BFBFBF",
"4. c #B8B8B8",
"5. c #4E4E4F",
"6. c #A6A6A7",
"7. c #757576",
"8. c #7E7E7E",
"9. c #484748",
"0. c #B0B0B0",
"a. c #B9B8B9",
"b. c #383839",
"c. c #9C9C9C",
"d. c #5D5C5E",
"e. c #4F4F50",
"f. c #E8E7E8",
"g. c #DCDBDC",
"h. c #B1B0B1",
"i. c #8D8C8D",
"j. c #6D6C6D",
"k. c #A6A4A6",
"l. c #A6A6A6",
"m. c #383838",
"n. c #A7A7A7",
"o. c #AAAAAA",
"p. c #6E6E6E",
"q. c #585858",
"r. c #6A6A6B",
"s. c #3F3F40",
"t. c #868586",
"u. c #DFDFDF",
"v. c #DDDCDD",
"w. c #D4D3D4",
"x. c #3D3D3E",
"y. c #706F70",
"z. c #4C4C4D",
"A. c #D3D2D3",
"B. c #545454",
"C. c #949494",
"D. c #39393A",
"E. c #CECDCE",
"F. c #BCBCBC",
"G. c #A8A8A9",
"H. c #909090",
"I. c #686768",
"J. c #5B5B5C",
"K. c #3E3E3E",
"L. c #9C9C9D",
"M. c #626162",
"N. c #7E7D7E",
"O. c #B6B5B6",
"P. c #4D4D4E",
"Q. c #A1A1A1",
"R. c #474748",
"S. c #6B6B6C",
"T. c #464546",
"U. c #444444",
"V. c #545354",
"W. c #909091",
"X. c #D6D6D6",
"Y. c #535254",
"Z. c #C1C1C1",
"`. c #363536",
" + c #8D8D8D",
".+ c #C4C4C4",
"++ c #343334",
"@+ c #8C8C8C",
"#+ c #373638",
"$+ c #C2C2C2",
"%+ c #B4B4B4",
"&+ c #626263",
"*+ c #BDBDBD",
"=+ c #B3B3B3",
"-+ c #828182",
";+ c #959596",
">+ c #626262",
",+ c #A4A4A5",
"'+ c #9A999A",
")+ c #C0BFC0",
"!+ c #5C5C5C",
"~+ c #79797A",
"{+ c #B2B0B2",
"]+ c #4A4A4A",
"^+ c #49494A",
"/+ c #858586",
"(+ c #4B4B4C",
"_+ c #343434",
":+ c #B6B6B6",
"<+ c #747475",
"[+ c #585758",
"}+ c #424242",
"|+ c #747474",
"1+ c #A9A7A9",
"2+ c #3B3A3C",
"3+ c #A3A3A3",
"4+ c #787879",
"5+ c #AEADAE",
"6+ c #535354",
"7+ c #6B6A6B",
"8+ c #363636",
"9+ c #575658",
"0+ c #989899",
"a+ c #A4A4A4",
"b+ c #69696A",
"c+ c #EBEBEC",
"d+ c #616162",
"e+ c #656465",
"f+ c #757475",
"g+ c #3E3E40",
"h+ c #979797",
"i+ c #373738",
"j+ c #D2D2D2",
"k+ c #CDCCCD",
"l+ c #5D5C5D",
"m+ c #DEDDDE",
"n+ c #727272",
"o+ c #A8A8A8",
"p+ c #515051",
"q+ c #CFCECF",
"r+ c #8F8F8F",
"s+ c #616061",
"t+ c #C6C6C6",
"u+ c #C7C6C7",
"v+ c #4D4C4D",
"w+ c #757474",
"x+ c #343436",
"y+ c #D9D8D9",
"z+ c #505050",
"A+ c #989698",
"B+ c #DAD9DA",
"C+ c #A9A9A9",
"D+ c #7A797A",
"E+ c #3C3C3C",
"F+ c #C9C8C9",
"G+ c #E1E0E1",
"H+ c #BBBABB",
"I+ c #4F4E50",
"J+ c #ACAAAC",
"K+ c #555556",
"L+ c #606061",
"M+ c #969596",
"N+ c #D4D4D4",
"O+ c #AEAEAF",
"P+ c #D8D7D8",
"Q+ c #696869",
"R+ c #414042",
"S+ c #747374",
"T+ c #818182",
"U+ c #565556",
"V+ c #D7D6D7",
"W+ c #444446",
"X+ c #C0C0C0",
"Y+ c #515151",
"Z+ c #898989",
"`+ c #3A3A3C",
" @ c #5D5D5D",
".@ c #B9B9B9",
"+@ c #414142",
"@@ c #424243",
"#@ c #535253",
"$@ c #484848",
"%@ c #868686",
"&@ c #E8E7E7",
"*@ c #474648",
"=@ c #9E9C9E",
"-@ c #646464",
";@ c #9E9E9E",
">@ c #434244",
",@ c #929192",
"'@ c #3F3E3F",
")@ c #F0EFEF",
"!@ c #525252",
"~@ c #949495",
"{@ c #4B4A4B",
"]@ c #BDBCBD",
"^@ c #646465",
"/@ c #838383",
"(@ c #C2C1C2",
"_@ c #B8B8B9",
":@ c #B2B2B2",
"<@ c #6F6E6F",
"[@ c #515152",
"}@ c #737373",
"|@ c #525152",
"1@ c #EAE9E9",
"2@ c #555455",
"3@ c #838283",
"4@ c #A0A0A1",
"5@ c #4B4A4C",
"6@ c #5E5E5E",
"7@ c #727172",
"8@ c #666667",
"9@ c #E2E1E2",
"0@ c #5A5A5A",
"a@ c #666566",
"b@ c #49484A",
"c@ c #676768",
"d@ c #767677",
"e@ c #A2A1A2",
"f@ c #4F4E4F",
"g@ c #CACACA",
"h@ c #333234",
"i@ c #808080",
"j@ c #5F5F5F",
"k@ c #9C9C9E",
"l@ c #7C7B7C",
"m@ c #D0CFD0",
"n@ c #5C5C5D",
"o@ c #929092",
"p@ c #B8B6B8",
"q@ c #636263",
"r@ c #C3C2C3",
"s@ c #C5C5C5",
"t@ c #555456",
"u@ c #848384",
"v@ c #6D6D6E",
"w@ c #595859",
"x@ c #AFADAF",
"y@ c #676668",
"z@ c #B0AFB0",
"A@ c #6C6C6C",
"B@ c #69686A",
"C@ c #5B5B5B",
"D@ c #B6B6B7",
"E@ c #DBDADB",
"F@ c #838183",
"G@ c #B5B4B5",
"H@ c #D1D0D1",
"I@ c #ABAAAB",
"J@ c #7A7A7A",
"K@ c #757476",
"L@ c #7C7C7C",
"M@ c #989798",
"N@ c #9F9E9F",
"O@ c #DCDCDC",
"P@ c #555555",
"Q@ c #4E4E50",
"R@ c #D8D8D8",
"S@ c #9E9D9E",
"T@ c #7D7D7D",
"U@ c #737274",
"V@ c #A8A7A8",
"W@ c #767576",
"X@ c #565656",
"Y@ c #7B7A7B",
"Z@ c #B2B2B3",
"`@ c #908F90",
" # c #EFEFEF",
".# c #F2F2F2",
"+# c #E1E1E1",
"@# c #BBBBBB",
"## c #3C3C3E",
"$# c #59595A",
"%# c #AEAEAE",
"&# c #EDEDEE",
"*# c #7D7C7D",
"=# c #F6F6F6",
"-# c #FAFAFA",
";# c #848484",
"># c #3B3B3B",
",# c #4E4E4E",
"'# c #C4C3C4",
")# c #424142",
"!# c #818081",
"~# c #E4E3E4",
"{# c #FCFCFC",
"]# c #BEBDBE",
"^# c #E4E4E4",
"/# c #EBEBEB",
"(# c #5B5A5B",
"_# c #A1A0A1",
":# c #ADACAD",
"<# c #F3F3F3",
"[# c #E8E8E8",
"}# c #A7A6A7",
"|# c #AFAEAF",
"1# c #D9D9D9",
"2# c #59585A",
"3# c #6C6C6D",
"4# c #F8F7F8",
"5# c #9F9FA0",
"6# c #828282",
"7# c #979798",
"8# c #ABABAB",
"9# c #787778",
"0# c #848485",
"a# c #3E3D3E",
"b# c #9F9F9F",
"c# c #878788",
"d# c #D1D1D1",
"e# c #8F8E8F",
"f# c #737273",
"g# c #909092",
"h# c #EEEEEE",
"i# c #E5E4E5",
"j# c #B4B3B4",
"k# c #F0F0F0",
"l# c #E0E0E0",
"m# c #9B9A9B",
"n# c #A5A4A5",
"o# c #939293",
"p# c #DFDEDF",
"q# c #868687",
"r# c #E2E2E2",
"s# c #3F3E40",
"t# c #828283",
"u# c #717071",
"v# c #7C7C7D",
"w# c #646364",
"x# c #B9B9BA",
"y# c #515052",
"z# c #A5A5A6",
"A# c #858485",
"B# c #9D9D9D",
"C# c #3D3C3E",
"D# c #CBCACB",
"E# c #BEBCBE",
"F# c #ACACAC",
"G# c #7B7B7B",
"H# c #6F6E70",
"I# c #F4F3F4",
"J# c #7E7E7F",
"K# c #E3E3E3",
"L# c #D7D7D7",
"M# c #ECEBEC",
"N# c #A7A7A8",
"O# c #929293",
"P# c #474747",
"Q# c #5A595A",
"R# c #717172",
"S# c #666666",
"T# c #7B7B7C",
"U# c #8C8C8D",
"V# c #5E5D5E",
"W# c #B2B1B2",
"X# c #F6F5F6",
"Y# c #B4B4B5",
"Z# c #8B8B8C",
"`# c #A09FA0",
" $ c #6C6B6C",
".$ c #BDBDBE",
"+$ c #4F4F4F",
"@$ c #434243",
"#$ c #646264",
"$$ c #6B6A6C",
"%$ c #494849",
"&$ c #ADADAE",
"*$ c #717072",
"=$ c #8F8D8F",
"-$ c #A9A9AA",
";$ c #6A6A6A",
">$ c #EEEDEE",
",$ c #AAAAAB",
"'$ c #F4F4F4",
")$ c #575657",
"!$ c #89898A",
"~$ c #969696",
"{$ c #8A8A8B",
"]$ c #919191",
"^$ c #A3A3A4",
"/$ c #A2A2A2",
"($ c #F1F1F1",
"_$ c #C4C4C5",
":$ c #979697",
"<$ c #4D4C4E",
"[$ c #808081",
"}$ c #9D9D9E",
"|$ c #686869",
"1$ c #BFBEBF",
"2$ c #7A7A7B",
"3$ c #CDCDCD",
"4$ c #E7E7E7",
"5$ c #757575",
"6$ c #EAEAEA",
"7$ c #F8F8F8",
"8$ c #8E8D8E",
"9$ c #8F8F90",
"0$ c #868486",
"a$ c #C9C9C9",
"b$ c #B5B5B5",
"c$ c #C7C7C7",
"d$ c #E5E5E6",
"e$ c #7F7F7F",
"f$ c #A6A5A6",
"g$ c #606060",
"h$ c #4E4D4E",
"i$ c #E6E5E6",
"j$ c #8B8A8B",
"k$ c #B5B3B5",
"l$ c #8E8E8E",
"m$ c #C1C1C2",
"n$ c #444344",
"o$ c #323234",
"p$ c #454445",
"q$ c #707071",
"r$ c #8A8A8A",
"s$ c #9E9E9F",
"t$ c #DDDDDD",
"u$ c #C5C4C5",
"v$ c #4A494A",
"w$ c #363638",
"x$ c #7F7E7F",
"y$ c #ECECEC",
"z$ c #B3B3B4",
"A$ c #919192",
"B$ c #B3B2B3",
"C$ c #E0DFE0",
"D$ c #B7B7B7",
"E$ c #686868",
"F$ c #504F50",
"G$ c #858585",
"H$ c #707070",
"I$ c #EDECED",
"J$ c #777677",
"K$ c #414141",
"L$ c #595959",
"M$ c #AFAFB0",
"N$ c #C9C8C8",
"O$ c #8D8D8E",
"P$ c #E6E6E6",
"Q$ c #5F5E5F",
"R$ c #ACABAC",
"S$ c #BEBEBF",
"T$ c #686668",
"U$ c #C7C6C6",
"V$ c #DBDBDB",
"W$ c #898889",
"X$ c #7B7B7D",
"Y$ c #C3C3C4",
"Z$ c #7E7E80",
"`$ c #D9D9DA",
" . + @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ . ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ # @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ $ % @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ & @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ * @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ = - = @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ; @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ > , @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ ' ) ! @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ~ { @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ] ^ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ / ( _ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ : < @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ [ } @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ! | 1 ! @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ 2 3 @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ 4 5 6 @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ 7 8 9 0 @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ a b @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ c d e @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ f g h i j @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ k l @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ m n o p @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ # q r s j @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ t u @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ m n v w @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ 6 x r y p @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ z A @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ c n r B # @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ! C D r E j @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ F G @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ H I J K L @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ _ M J r N 2 @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ O P @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ # Q n J v R @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ S T J r } p @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ U V # @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ H v J r i # @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ! W r J r X Y @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ Z ` : @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ # .v J J ..+.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @.#.J J r $.0 @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ # %.&.*.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ! =.-.J J ;.>.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ,.r J J '.).!.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ~.{.].k @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ! ^./.J J r (.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ! _.'.J J r :.<.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ [.}.I |.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ j 1.T J J J 2.3.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ 4.#.J J J '.5.[.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ a M ;.6.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ % 7.h J J J ;.b @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ 8.r J J J r 9.0.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ a.b.J c.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ p d.T J J J J e.% @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ f.M J J J J J q g.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ h.r J i.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ _ j.r J J J J v k.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ l.m.J J J J '.5 n.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ o.J J p.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ p q.r J J J J r ^.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ p r.r J J J J J s.3.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ t.J J } @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ u.{.J J J J J J 2.v.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ w.x.J J J J J J s.k.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ # ! @ @ @ @ @ @ @ @ @ @ y.J J z.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ A.B.r J J J J J -.C.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ e T J J J J J J D.] @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ E.F.G.H.I.}.2.} # @ @ @ @ @ @ @ @ @ J.J J K.@ @ @ @ @ @ @ @ @ @ L.M.N.6.O.+.! @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ *.P.J J J J J J r d.# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ j J.J J J J J J J #.Q.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ j < .q.R.&.h r J J J S.@ @ @ @ @ @ @ @ @ @ T.J J h ~ @ @ @ @ @ @ @ @ @ o.J '.-.b.U.V.y.W.X.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ +.Y.r J J J J J J ` $ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ Z.&.J J J J J J J `. +# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ % .+] y.q ++;.D '.J J J J J J '.@+@ @ @ @ @ @ @ @ @ @ #+J J J $+@ @ @ @ @ @ @ @ @ %+].J J J J '.'.;.h 2.&+U *+j @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ =+s.'.J J J J J J D -+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ 1.J J J J J J J J v U # @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ Y ;+>+U.h J J J J J J J J J J J J ;.,+@ @ @ @ @ @ @ @ @ % I J J J '+@ @ @ @ @ @ @ @ @ )+U.J J J J J J J J J J r ` !+~+a # @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ {+]+J J J J J J J J R.p @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ j ^+J J J J J J J J v W ! @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ # @./+(+].;.J J J J J J J J J J J J J J J _+:+@ @ @ @ @ @ @ @ @ @.;.J J J <+@ @ @ @ @ @ @ @ @ A.[+J J J J J J J J J J J J J D I }+|+.+g.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ 1+2+'.J J J J J J J m.3+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ S n J J J J J J J J D 4+p @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ X.5+( &.r J J J J J J J J J J J J J J J J J J &.+.@ @ @ @ @ @ @ @ @ :+;.J J J 6+@ @ @ @ @ @ @ @ @ ! 7+J J J J J J J J J J J J J J J J J 8+9+0+, @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ a+` J J J J J J J J r b+p @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ c+d+'.J J J J J J J J T e+! @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ k f+2.h J J J J J J J J J J J J J J J J J J J J J V ! @ @ @ @ @ @ @ @ @ F r J J J g+@ @ @ @ @ @ @ @ @ @ h+J J J J J J J J J J J J J J J J J J J T D.9 0.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ / i+J J J J J J J J J x j+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ k+D.J J J J J J J J J J l+m+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ % h.9 /.J J J J J J J J J J J J J J J J J J J J J J J J (+@ @ @ @ @ @ @ @ @ @ n+J J J J ].j @ @ @ @ @ @ @ @ @ o+;.J J J J J J J J J J J J J J J J J J J J J r p+U q+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ j r+I J J J J J J J J J T -+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ <+r J J J J J J J J J r [+0 @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ # n.(.].'.J J J J J J J J J J J J J J J J J J r ;.h &.K y g :+@ @ @ @ @ @ @ @ @ g.s+J J J J _+t+@ @ @ @ @ @ @ @ @ u+v+` _+;.r '.J J J J J J J J J J J J J J J J J J I o @+p @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ w+x+J J J J J J J J J '.B.y+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
". @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ Y V.'.J J J J J J J J J r R.@.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ w.m ^+-.'.J J J J J J J J J J J J J J J J J ;.` z+1.A+k B+@ @ @ @ @ @ @ @ @ @ @ @ @ .+o J J J J ;.C+@ @ @ @ @ @ @ @ @ @ @ % .+o.D+[+}+h J J J J J J J J J J J J J J J J J '.D E+-+F+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ G+S.T J J J J J J J J J J i+H+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ . ",
"+ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ Q.h J J J J J J J J J J r I+:+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ # J+K+_+J J J J J J J J J J J J J J J J J r &.L+M+*+N+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ O+D.J J J J '.O @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ P+.+< Q+R+D J J J J J J J J J J J J J J J J J T o m j @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ % e+h J J J J J J J J J J J s+# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ + ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ l+J J J J J J J J J J J '.D.w @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ P+Y./.J J J J J J J J J J J J J J J r b.P.S+:+! @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ F r J J J J J S.# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ !.T+U+8 ;.J J J J J J J J J J J J J J J ;...> % @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ u.6+r J J J J J J J J J J J V V+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ :+` J J J J J J J J J J J J x.>.@ @ @ @ @ @ @ @ @ @ @ @ @ @ X.y T J J J J J J J J J J J J J D W+n+:+_ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ <+J J J J J J 6+E.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ j X+N.Y+/.J J J J J J J J J J J J J J J I N.# @ @ @ @ @ @ @ @ @ @ @ @ @ @ +.K+r J J J J J J J J J J J -.Z+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ N.;.J J J J J J J J J J J J ].t.@ @ @ @ @ @ @ @ @ @ @ @ @ @ % S+h J J J J J J J J J D `+ @< ! @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ 5.J J J J J J ` H+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ f .@b++@-.J J J J J J J J J J J r e.Y @ @ @ @ @ @ @ @ @ @ @ @ @ @ .@@@r J J J J J J J J J J J '.#@X.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ G+$@J J J J J J J J J J J J J -.%@&@@ @ @ @ @ @ @ @ @ @ @ @ @ @ Z+E+J J J J J J D *@%@.+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ n J J J J J J r =@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ j+r+K+h J J J J J J J J T -@G+@ @ @ @ @ @ @ @ @ @ @ @ @ @ ;@>@J J J J J J J J J J J J J n w @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ,@r J J J J J J J J J J J J J I b+% @ @ @ @ @ @ @ @ @ @ @ @ @ # n.'@'.J J h (+[ N+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ X.'.J J J J J J J S+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ j l.q./.'.J J J J /.<+f.@ @ @ @ @ @ @ @ @ @ @ @ @ @ Q.&.J J J J J J J J J J J J J r d+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ )@d.r J J J J J J J J J J J J J r d.*.@ @ @ @ @ @ @ @ @ @ @ @ @ @ u+!@].$.;@! @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ~@J J J J J J J J {@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ]@^@x J J +@U @ @ @ @ @ @ @ @ @ @ @ @ @ @ ! /@i+J J J J J J J J J J J J J J T.(@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ _@x J J J J J J J J J J J J J J r 6+2 @ @ @ @ @ @ @ @ @ @ @ @ @ @ g.:@0 @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ <@J J J J J J J J i+# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ j 4.[@V o.@ @ @ @ @ @ @ @ @ @ @ @ @ @ % 7.v J J J J J J J J J J J J J J D Z+# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ }@D J J J J J J J J J J J J J J r q J+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ j |@J J J J J J J J ;..+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ # @ @ @ @ @ @ @ @ @ @ @ @ @ @ w.} D J J J J J J J J J J J J J J J ..1@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ 0 K.J J J J J J J J J J J J J J J J x.l.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ $ 8 J J J J J J J J D S @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ m+2@r J J J J J J J J J J J J J J J -.>.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ 3@h J J J J J J J J J J J J J J J J ].S @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ 4@;.J J J J J J J J J Q+# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ 0.5@r J J J J J J J J J J J J J J J r 6@% @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ G+q.'.J J J J J J J J J J J J J J J J h 7@_ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ^@J J J J J J J J J J ..$+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ # Q.D.J J J J J J J J J J J J J J J J J i+k @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ n./.J J J J J J J J J J J J J J J J J -.8@9@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ # g+J J J J J J J J J J h 6.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ e D.J J J J J J J J J J J J J J J J J J ( @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ 0@J J J J J J J J J J J J J J J J J J r P.(@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ :+r J J J J J J J J J J J a@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ G+%.h J J J J J J J J J J J J J J J J J J x._ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ 0.D.J J J J J J J J J J J J J J J J J J '.b@o.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ c@J J J J J J J J J J J J K.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ Y L+T J J J J J J J J J J J J J J J J J J -./@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ d@r J J J J J J J J J J J J J J J J J J '.i+[ ! @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ j D.J J J J J J J J J J J J r e@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ :+P r J J J J J J J J J J J J J J J J J J J f@Y @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ g@#.J J J J J J J J J J J J J J J J J J J J h@i@_ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ =+h J J J J J J J J J J J J J j@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ U +@J J J J J J J J J J J J J J J J J J J J ;.k@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ l@r J J J J J J J J J J J J J J J J J J J J ;.6+_ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ 1 J J J J J J J J J J J J J J E+*.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ % D+n J J J J J J J J J J J J J J J J J J J J J v+# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ j P J J J J J J J J J J J J J J J J J J J J J '.$@Q.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ m@K.J J J J J J J J J J J J J J D e @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ !.n@T J J J J J J J J J J J J J J J J J J J J J m.] @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ o@h J J J J J J J J J J J J J J J J J J J J J J ` / # @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ t.r J J J J J J J J J J J J J J J K+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ p@G r J J J J J J J J J J J J J J J J J J J J J '.9 j @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ 0 | '.J J J J J J J J J J J J J J J J J J J J J J h q@E.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ j '@J J J J J J J J J J J J J J J J T =+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ % r+D.'.J J J J J J J J J J J J J J J J J J J J J J n r@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ 4 ;.J J J J J J J J J J J J J J J J J J J J J J J r A s@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ a+D J J J J J J J J J J J J J J J J J t@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ u.^.v J J J J J J J J J J J J J J J J J J J J J J J J 6@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ 6+J J J J J J J J J J J J J J J J J J J J J J J J '.D.u@! @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ !.6+J J J J J J J J J J J J J J J J J J /._@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ p@..r J J J J J J J J J J J J J J J J J J J J J J J J x.@.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ < ].J J J J J J J J J J J J J J J J J J J J J J J J J /.v@v.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ [ -.J J J J J J J J J J J J J J J J J J J u 0 @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ! r+s.J J J J J J J J J J J J J J J J J J J J J J J J J r W # @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ j M.'.J J J J J J J J J J J J J J J J J J J J J J J J J r K w @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ p i+J J J J J J J J J J J J J J J J J J J J -.e @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ A.w@-.J J J J J J J J J J J J J J J J J J J J J J J J J J #.a @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ x@/.J J J J J J J J J J J J J J J J J J J J J J J J J J J n W j+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ j y@J J J J J J J J J J J J J J J J J J J J J J &.u.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ! S V J J J J J J J J J J J J J J J J J J J J J J J J J J J J 1 @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ 6+J J J J J J J J J J J J J J J J J J J J J J J J J J J J r 5.z@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ S ].J J J J J J J J J J J J J J J J J J J J J J r A@p @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ Y B@v J J J J J J J J J J J J J J J J J J J J J J J J J J J J x .+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ o.n J J J J J J J J J J J J J J J J J J J J J J J J J J J J '.n ( +.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ n.i+J J J J J J J J J J J J J J J J J J J J J J J J -.7+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ 0 S E+r J J J J J J J J J J J J J J J J J J J J J J J J J J J J r n+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ j C@'.J J J J J J J J J J J J J J J J J J J J J J J J J J J J J r :.S ! @ @ @ @ @ @ @ @ @ @ @ @ @ @ O.s.J J J J J J J J J J J J J J J J J J J J J J J J J J /.U # @ @ @ @ @ @ @ @ @ @ @ @ @ @ ]@!+I J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J 8 *+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ D@v J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J ;.(+] % @ @ @ @ @ @ @ @ @ @ @ Q.x.J J J J J J J J J J J J J J J J J J J J J J J J J J J J v W E@@ @ @ @ @ @ @ @ @ @ @ :+9 v '.J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J r W @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ j I+J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J -.U+>.L @ @ @ @ @ @ @ ' F@v J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J r ).$ # @ @ @ @ @ @ # G@p.b.J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J n k @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ # ~.H@I@c.^ b J@|+K@L@u@M@a.A.! @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ e r J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J h }+W N@: O@: J+b+#.r J J J J J J J J J J J J -.x.A $.K v '.J J J J J J J J J J J J J J ].P@C.E.O@~.g@N.Q@v r J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J y @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ # R@F.S@/ T@4+U@g T@[ M@V@[.: ~ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ # w.k |.A+W@M.o 2.b.;.r J J J J J J J J J r _+2.X@Y@Z@N+@ @ @ @ @ @ @ @ @ @ @ @ @ % W+J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J D v `+n r J J J J J J J J J J J J J J #.`@*. #.#+#l.p+J J J J J J J J J J J J J J J J '.I &.m.T J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J ].k.@ @ @ @ @ @ @ @ @ @ @ @ @ = @#o@M.K i+;.J J J J J J J J J r T I ##9.$#7@`@%#@#*.&#@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ l.l@).s.v T J J J J J J J J J J J J J J J J J J J r i+G ^.F.@ @ @ @ @ @ @ @ @ @ @ @ *#D J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J ].H =#@ @ @ @ -#[.:.J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J [+P+@ @ @ @ @ @ @ @ @ @ @ j ;#q.` h J J J J J J J J J J J J J J J J J J J r /.>#,#v@'+~.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ y+@#-+6@V T J J J J J J J J J J J J J J J J J J J J I X 4 % @ @ @ @ @ @ @ @ @ '#)#J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J r !#.#@ @ @ @ @ @ @ 5+K.J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J -.;@@ @ @ @ @ @ @ @ @ @ r@b+i+J J J J J J J J J J J J J J J J J J J J r x }.^.h.E.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ~ )+>.C@#.;.J J J J J J J J J J J J J J J J J J '.i+b+' @ @ @ @ @ @ @ @ # ^@'.J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J ].]@@ @ @ @ @ @ @ @ +#9 J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J E+w.@ @ @ @ @ @ @ @ ~#@+@@r J J J J J J J J J J J J J J J J J J D /.f@N.@#N+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ j / X@b.'.J J J J J J J J J J J J J J J J J r ].^.0 @ @ @ @ @ @ @ 0.h J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J 8 m+@ @ @ @ @ @ @ @ {#8.J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J b+@ @ @ @ @ @ @ = Q.@@D J J J J J J J J J J J J J J J J J J h (+Z *.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ j Z@( i+J J J J J J J J J J J J J J J J J J r 5.k.@ @ @ @ @ @ % 2.J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J n ..Q@@@r J J J J J J J J J J J J V _ @ @ @ @ @ @ @ @ @ /@J J J J J J J J J J J J J D @@z.@@h J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J h o.@ @ @ @ @ @ !.9 x+J J J J J J J J J J J J J J J J J J D X@S j+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ j+-@#.r J J J J J J J J J J J J J J J J J ].D+f.@ @ @ @ @ A@J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J n 7@]#^#/#~.N@e.r J J J J J J J J J J V _ @ @ @ @ @ @ @ @ @ /@J J J J J J J J J J J r ).l.~./#~ :+(#-.J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J q w.@ @ @ @ @ _#5 r J J J J J J J J J J J J J J J J J h Y.:#@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ '#&+].J J J J J J J J J J J J J J J J J r e.(@@ @ @ @ ] h J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J 8+,.<#@ @ @ @ {#y+6+r J J J J J J J J J V _ @ @ @ @ @ @ @ @ @ /@J J J J J J J J J J J {.E@@ @ @ @ @ [#Z /.J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J '.%.@ @ @ @ G+y.h J J J J J J J J J J J J J J J J J T z+Q.% @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ! }#$@D J J J J J J J J J J J J J J J J J M ;@@ @ @ )+8 J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J r v@_ @ @ @ @ @ @ @ |#V J J J J J J J J J V _ @ @ @ @ @ @ @ @ @ /@J J J J J J J J J J V [.@ @ @ @ @ @ @ 1#V.J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J ;.F @ @ @ k 2#-.J J J J J J J J J J J J J J J J r b.b _ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ % %@` J J J J J J J J J J J J J J J J J D 3#0 @ w.}.J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J ].O.@ @ @ @ @ @ @ @ ! ^.'.J J J J J J J J V _ @ @ @ @ @ @ @ @ @ /@J J J J J J J J J r b 4#@ @ @ @ @ @ @ @ >.;.J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J _+%+@ % >.m.J J J J J J J J J J J J J J J J J h -@@.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ! 1+}+r J J J J J J J J J J J J J J J J T q@Y P+_.J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J ` : @ @ @ @ @ @ @ @ {#`@D J J J J J J J J V _ @ @ @ @ @ @ @ @ @ /@J J J J J J J J J h 5#@ @ @ @ @ @ @ @ @ t+h J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J b.k ! %@x J J J J J J J J J J J J J J J J '.i+ .p @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ Y 9 -.J J J J J J J J J J J J J J J J r @@6#..J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J 8 ~ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J V _ @ @ @ @ @ @ @ @ @ /@J J J J J J J J J b.8#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J h D+l+D J J J J J J J J J J J J J J J J '.$@z@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ p 1.T J J J J J J J J J J J J J J J J J -.r J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J 8 ~ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J V _ @ @ @ @ @ @ @ @ @ /@J J J J J J J J J b.8#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J '.;.r J J J J J J J J J J J J J J J J r [@a @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ # -+n J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J 8 ~ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J V _ @ @ @ @ @ @ @ @ @ /@J J J J J J J J J b.8#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J r l+w.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ S v J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J 8 ~ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J V _ @ @ @ @ @ @ @ @ @ /@J J J J J J J J J b.8#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J r E p @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ~+I J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J 8 ~ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J V _ @ @ @ @ @ @ @ @ @ /@J J J J J J J J J b.8#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J r (#2 @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ! W@r J J J J J J J J J J J J J J J J J J J J J J J J J J J J J '.;.;.r J J J J J J J J J J J J 8 ~ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J V _ @ @ @ @ @ @ @ @ @ /@J J J J J J J J J b.8#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J J J J J '.;.;.D J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J z.0 @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ~@S = @ @ @ @ @ @ @ @ @ @ @ @ @ p [@r J J J J J J J J J J J J J J J J J J J J J J J J J J r s.9#>.Q.0#z+;.J J J J J J J J J J 8 ~ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J V _ @ @ @ @ @ @ @ @ @ /@J J J J J J J J J b.8#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J J J r a#d@0+b#c#z+D J J J J J J J J J J J J J J J J J J J J J J J J J J J 8 w @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ % T.r ]+.@@ @ @ @ @ @ @ @ @ @ @ @ @ '#9.J J J J J J J J J J J J J J J J J J J J J J J J J T W d#{#@ @ @ % 3@&.J J J J J J J J J 8 ~ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J V _ @ @ @ @ @ @ @ @ @ /@J J J J J J J J J b.8#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J J T 9 Y {#@ @ @ % e#&.J J J J J J J J J J J J J J J J J J J J J J J J J v ;@@ @ @ @ @ @ @ @ @ @ @ @ @ 0 f#E.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ O.v J J @@g#@ @ @ @ @ @ @ @ @ @ @ @ @ >.h J J J J J J J J J J J J J J J J J J J J J J J J K+G+@ @ @ @ @ @ h#-+D J J J J J J J J 8 ~ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J V _ @ i#F.>.>.j#G+@ @ /@J J J J J J J J J b.8#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J J [@V+@ @ @ @ @ @ k#,.D J J J J J J J J J J J J J J J J J J J J J J J J d.% @ @ @ @ @ @ @ @ @ @ @ @ X+5.T o@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ <+'.J J J h 9#% @ @ @ @ @ @ @ @ @ @ @ @ (.J J J J J J J J J J J J J J J J J J J J J J J v { @ @ @ @ @ @ @ @ : 8 J J J J J J J J 8 ~ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J V l#& Y.b.I I ].^+m#<#/@J J J J J J J J J b.8#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J D n#@ @ @ @ @ @ @ @ O@M J J J J J J J J J J J J J J J J J J J J J J J E+N+@ @ @ @ @ @ @ @ @ @ @ @ k.a#J J B.w.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ m@K J J J J J T } j @ @ @ @ @ @ @ @ @ @ @ =+D.J J J J J J J J J J J J J J J J J J J J J J z.V+@ @ @ @ @ @ @ @ 4#9 J J J J J J J J 8 ~ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J x.o#@@J J J J J J -.Q 3#J J J J J J J J J b.8#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J K.p#@ @ @ @ @ @ @ @ 4#7@J J J J J J J J J J J J J J J J J J J J J J -.q#@ @ @ @ @ @ @ @ @ @ @ @ r+m.J J J ].k.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ a+T J J J J J J T 6 @ @ @ @ @ @ @ @ @ @ @ ! ( '.J J J J J J J J J J J J J J J J J J J J J $#r#@ @ @ @ @ @ @ @ @ ~+J J J J J J J J 8 ~ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J -.8 r J J J J J J J x &.J J J J J J J J J b.8#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J 9./#@ @ @ @ @ @ @ @ -#3@J J J J J J J J J J J J J J J J J J J J J J 5 a @ @ @ @ @ @ @ @ @ @ @ a+i+J J J J '.1.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ (.J J J J J J J #.j @ @ @ @ @ @ @ @ @ @ @ @ F.].J J J J J J J J J J J J J J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J 8 ~ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J J J J J J J J J J J J J J J J J J J J J J b.8#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J J J J J J J J J J J J J J D *#@ @ @ @ @ @ @ @ @ @ @ a+x J J J J J J s## @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ j D.J J J J J J J } @ @ @ @ @ @ @ @ @ @ @ @ @ % {@J J J J J J J J J J J J J J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J 8 ~ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J J J J J J J J J J J J J J J J J J J J J J b.8#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J J J J J J J J J J J J J J x+k @ @ @ @ @ @ @ @ @ @ @ S ;.J J J J J J h 4.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ Z@;.J J J J J J v G.@ @ @ @ @ @ @ @ @ @ @ @ @ @ t#J J J J J J J J J J J J J J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J 8 ~ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J J J J J J J J J J J J J J J J J J J J J J b.8#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J J J J J J J J J J J J J J z+@ @ @ @ @ @ @ @ @ @ @ @ (@}+J J J J J J D u#@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ C r J J J J J J M , @ @ @ @ @ @ @ @ @ @ @ @ @ @ $+/.J J J J J J J J J J J J J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J 8 ~ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J J J J J J J J J J J J J J J J J J J J J J b.8#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J J J J J J J J J J J J J '.v#@ @ @ @ @ @ @ @ @ @ @ @ % w#'.J J J J J J e.p @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ Y ,#J J J J J J J a@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ # q J J J J J J J J J J J J J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J 8 ~ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J J J J J J J J J J J J J J J J J J J J J J b.8#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J J J J J J J J J J J J J ].%+@ @ @ @ @ @ @ @ @ @ @ @ @ 0+;.J J J J J J &.x#@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ :+].J J J J J J J n.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ q@J J J J J J J J J J J J J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J 8 ~ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J J J J J J J J J J J J J J J J J J J J J J b.8#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J J J J J J J J J J J J J U.t+@ @ @ @ @ @ @ @ @ @ @ @ @ E.i+J J J J J J r o@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ -+r J J J J J J _+X.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ D+'.J J J J J J J J J J J J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J 8 ~ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J J J J J r -./.;.J J J J J J J J J J J J J b.8#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J J J J J J J J J J J J J ).w.@ @ @ @ @ @ @ @ @ @ @ @ @ @ ..J J J J J J J q@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ 6+J J J J J J J y#@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ z#;.J J J J J J J J J J J J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J 8 ~ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J J J r | A#z@O.B#-@/.J J J J J J J J J J J b.8#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J J J J J J J J J J J J J d+# @ @ @ @ @ @ @ @ @ @ @ @ @ @ D+J J J J J J J E+% @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ # C#J J J J J J J W@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ o+-.J J J J J J J J J J J J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J 8 ~ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J J r $.D#.#@ @ -#m+-+h J J J J J J J J J J b.8#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J J J J J J J J J J J J J r.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ w h J J J J J J r E#@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ D#;.J J J J J J ].%+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ F#_+J J J J J J J J J J J J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J 8 ~ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J J X@X.@ @ @ @ @ @ -#G#T J J J J J J J J J b.8#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J J J J J J J J J J J J J H#@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ 2 }+J J J J J J J =.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ^ ;.J J J J J J q t+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ o+-.J J J J J J J J J J J J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J 8 ~ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J h > -#@ @ @ @ @ @ @ g@5.J J J J J J J J J b.8#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J J J J J J J J J J J J J A@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ # J.J J J J J J J n@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ 8@'.J J J J J J u ! @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ,+;.J J J J J J J J J J J J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J 8 ~ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J ` w.@ @ @ @ @ @ @ @ I#7.J J J J J J J J J b.8#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J J J J J J J J J J J J J i # @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ J#;.J J J J J J )## @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ = }.J J J J J J '.N.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ l@'.J J J J J J J J J J J J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J 8 ~ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J V K#@ @ @ @ @ @ @ @ @ /@J J J J J J J J J b.8#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J J J J J J J J J J J J J ).L#@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ R h J J J J J J &.@.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @.}+J J J J J J ;.|.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ I.J J J J J J J J J J J J J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J 8 ~ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J V _ @ @ @ @ @ @ @ @ @ /@J J J J J J J J J b.8#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J J J J J J J J J J J J J M @.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ (@&.J J J J J J _+%+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ Z@].J J J J J J ;.+.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ # ..J J J J J J J J J J J J J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J 8 ~ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J V _ @ @ @ @ @ @ @ @ @ /@J J J J J J J J J b.8#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J J J J J J J J J J J J J b.:+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ M#$@J J J J J J D e@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ N#h J J J J J J b.g.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ X.n J J J J J J J J J J J J J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J 8 ~ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J V _ @ @ @ @ @ @ @ @ @ /@J J J J J J J J J b.8#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J J J J J J J J J J J J J r O#@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ P@J J J J J J J .@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ N.J J J J J J J P#@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ e#J J J J J J J J J J J J J J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J 8 ~ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J V _ @ @ @ @ @ @ @ @ @ /@J J J J J J J J J _+_#@ @ @ @ @ @ @ @ @ g@I J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J J J J J J J J J J J J J J Q#@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ R#J J J J J J J } # @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ S#J J J J J J J l+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @J J J J J J J J J J J J J J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J 8 ~ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J V _ @ @ @ @ @ @ @ @ @ /@J J J J J J J J J r T#-#@ @ @ @ @ @ @ @ >.;.J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J J J J J J J J J J J J J J &.p @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ,@J J J J J J J z.R@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ y#J J J J J J J T#@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ +.`+J J J J J J J J J J J J J J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J 8 ~ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J V _ @ @ @ @ @ @ @ @ @ /@J J J J J J J J J J }+w.@ @ @ @ @ @ @ 9@$.J J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J J J J J J J J J J J J J J ;.e#@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ g@r J J J J J J x.!.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @@J J J J J J r m @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ U#D J J J J J J J J J J J J J J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J 8 ~ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J V _ @ @ @ @ @ @ @ @ @ /@J J J J J J J J J J J y g.@ @ @ @ @ /#|+-.J J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J J J J J J J J J J J J J J J X@p @ @ @ @ @ @ @ @ @ @ @ @ @ @ R@i+J J J J J J h .+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ m.J J J J J J h $+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ P+v+J J J J J J J J J J J J J J J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J 8 ~ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J V _ @ @ @ @ @ @ @ @ @ /@J J J J J J J J J J J r V#W#/#X#/#(@7+v J J J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J J J J J J J J J J J J J J J b.Y#@ @ @ @ @ @ @ @ @ @ @ @ @ @ # K.J J J J J J r J+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ~.;.J J J J J J D.g@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ !#r J J J J J J J J J J J J J J J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J 8 ~ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J V _ @ @ @ @ @ @ @ @ @ /@J J J J J J J J J J J J J T K...8 /.J J J J J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J J J J J J J J J J J J J J J J 2@# @ @ @ @ @ @ @ @ @ @ @ @ @ @ ..J J J J J J J Z#@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ $+J J J J J J J 8 2 @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ j P J J J J J J J J J J J J J J J J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J 8 ~ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J V _ @ @ @ @ @ @ @ @ @ /@J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J J J J J J J J J J J J J J J J v 0.@ @ @ @ @ @ @ @ @ @ @ @ @ @ K+J J J J J J J *#@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ `#J J J J J J J ..~.@ @ @ @ @ @ @ @ @ @ @ @ @ @ ! 9#D J J J J J J J J J J J J J J J J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J 8 ~ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J V _ @ @ @ @ @ @ @ @ @ /@J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J J J J J J J J J J J J J J J J J R.G+@ @ @ @ @ @ @ @ @ @ @ @ @ I.J J J J J J J $@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ - J J J J J J J |@~ @ @ @ @ @ @ @ @ @ @ @ @ @ @ .$2.J J J J J J J J J J J J J J J J J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J 8 ~ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J V _ @ @ @ @ @ @ @ @ @ /@J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J J J J J J J J J J J J J J J J J T e @ @ @ @ @ @ @ @ @ @ @ @ @ 7@J J J J J J J L+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ %@J J J J J J J n@@ @ @ @ @ @ @ @ @ @ @ @ @ @ # f@J J J J J J J J J J J J J J J J J J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J 8 ~ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J V K#@ @ @ @ @ @ @ @ @ /@J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J J J J J J J J J J J J J J J J J J x a.@ @ @ @ @ @ @ @ @ @ @ @ N.;.J J J J J J (.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ g J J J J J J J 9 @ @ @ @ @ @ @ @ @ @ @ @ @ # N.r J J J J J J J J J J J J J J J J J J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J 8 ~ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J ].%#-#@ @ @ @ @ @ @ @ /@J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J J J J J J J J J J J J J J J J J J J e.p @ @ @ @ @ @ @ @ @ @ @ ,.;.J J J J J J +$@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ U@J J J J J J J b+@ @ @ @ @ @ @ @ @ @ @ @ @ %+@@` @$}.$##$$$$$} (.%$` n h r J J J J J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J 8 ~ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J J 5 ]#@ @ @ @ @ @ @ @ /@J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J J J J J '.;._+&.@$6+} y@$$&$@ @ @ ##&.N.@ @ @ @ @ @ @ @ @ @ @ ,+;.J J J J J J $@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ v@J J J J J J J *$@ @ @ @ @ @ @ @ @ @ @ @ @ B+g.@ @ @ @ @ @ @ @ @ @ @ w.D@=$B.x+J J J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J 8 ~ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J J J R.y+@ @ @ @ @ @ @ /@J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J J J r ..<+z@*.f @ @ @ @ @ @ @ @ @ @ # : # @ @ @ @ @ @ @ @ @ @ o+;.J J J J J J @@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ $J J J J J J J U@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ Y ] ]+D J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J 8 ~ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J J J r S+p#@ @ @ @ @ @ /@J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J r D.b a @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ -$h J J J J J J V @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ;$J J J J J J J U@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ % e ].J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J 8 ~ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J J J J r >+>$@ @ @ @ @ /@J J J J J J J J J J J J J J J ;.r J J J J J J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J r w#u.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ,$_+J J J J J J g+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ %.J J J J J J J U@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ M#w+r J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J 8 ~ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J J J J J -.m#'$@ @ @ @ /@J J J J J J J J J J J J T )$!$~${$9 n J J J J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J (+A.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ,$_+J J J J J J g+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ $J J J J J J J U@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ p+J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J &.D#@ @ @ @ @ @ @ @ 4#c#r J J J J J J J J J J J J J b.]${#@ @ @ /@J J J J J J J J J J J D.Q.f {#@ @ 4#)+R.r J J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J x.7 @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ -$_+J J J J J J g+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ v@J J J J J J J *$@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ >.v J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J h < -#@ @ @ @ @ @ @ B+V#J J J J J J J J J J J J J J J ].^$-#@ -#T@J J J J J J J J J J _+/${#@ @ @ @ @ @ $ 2.J J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J r W # @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ o+;.J J J J J J @@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ n+J J J J J J J r.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @.5 J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J J 5.!.@ @ @ @ @ @ {#!$v J J J J J J J J J J J J J J J J i+c..#a.z.J J J J J J J J J J &+($@ @ @ @ @ @ @ 4#J#;.J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J ;.|.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ,+;.J J J J J J ^+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ g J J J J J J J &+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ! ).J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J J J Y+_$'$@ @ @ ~#:$n J J J J J J J J J J J J J J J J J J T `+/.J J J J J J J J J J h ~@{#@ @ @ @ @ @ @ @ ]#h J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J _+@.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ,.;.J J J J J J 5.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ u@J J J J J J J X @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ $#J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J J J r <$[$%#:+}$|$x J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J _+z#@ @ @ @ @ @ @ @ @ j+_+J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J _+[.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ N.;.J J J J J J (.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ - J J J J J J J | ~ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ # 9+J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J J J J J D ;.;.;.J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J _+N#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J _+g@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ C J J J J J J J L+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ _#J J J J J J J ..~.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ R@z.J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J _+N#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J I k @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ I.J J J J J J J $@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ * J J J J J J J 8 2 @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ 1$8 J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J _+N#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J ;.0+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ (.J J J J J J J 2$@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ~.;.J J J J J J &.g@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ 8#h J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J _+N#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J r W @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ..J J J J J J J @+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ].J J J J J J I $+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ $J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J _+N#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J :.k+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ # g+J J J J J J '.J+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @@J J J J J J r M@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ j K.J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J _+N#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J v =@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ R@m.J J J J J J h .+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ 5.J J J J J J J *#@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ M+r J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J _+N#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J C@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ D#r J J J J J J ` 3$@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ I.J J J J J J J l+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ j I+J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J J J J J J J J J J J J J J J J J J J J J J r o s @@'.J J J J J J J J J J J J J J J J _+N#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J I 3.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ,@J J J J J J J ,#R@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ l@J J J J J J J ^+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ a.v J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J J J J J J J J J J J J J J J J J J J J J J ].%#4$}#%$J J J J J J J J J J J J J J J J _+N#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J 5$@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ W@J J J J J J J d.! @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ 6.-.J J J J J J b.g.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ j w@J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J J J J r x 5.}.R.v J J J J J J J J J J J J R+4$@ {#t+` J J J J J J J J J J J J J J J _+N#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J ` ]@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ (.J J J J J J J 7.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ %+].J J J J J J ;.+.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ] I J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J J J -.v@F#g.9@+.]$..J J J J J J J J J J J @@6$@ @ {#e x J J J J J J J J J J J J J J _+N#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J r |$@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ! $@J J J J J J D ^$@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ a }+J J J J J J ;.:@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ % q J J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J J T q#<#@ @ @ @ {#V+K '.J J J J J J J J J @@6$@ @ @ <#]$T J J J J J J J J J J J J J _+N#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J J /.4.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @.&.J J J J J J I :@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ % }.J J J J J J '.N.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ # Z+D J J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J r <+M#@ @ @ @ @ @ @ :@@@J J J J J J J J J @@6$@ @ @ @ 7$T+;.J J J J J J J J J J J J _+N#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J J J P.0 @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ &$h J J J J J J &.@.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ 9 '.J J J J J J >+! @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ k K.J J J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J ].O.@ @ @ @ @ @ @ @ = y.J J J J J J J J J @@6$@ @ @ @ @ 6$S.r J J J J J J J J J J J _+N#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J J J -.U#@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ +;.J J J J J J )#! @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ 8$;.J J J J J J q t+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ j e.J J J J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J 8 m+@ @ @ @ @ @ @ @ @ 9$D J J J J J J J J @@6$@ @ @ @ @ @ G+6@J J J J J J J J J J J _+N#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J J J J x w @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ # !+J J J J J J J J.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ .@-.J J J J J J b.:+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ S T J J J J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J V ^#@ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J @@6$@ @ @ @ @ @ @ F+s.J J J J J J J J J J _+N#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J J J J J 9+% @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ w.K J J J J J J J l@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ K.J J J J J J '.4+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ 4 &.J J J J J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J V _ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J @@6$@ @ @ @ @ @ @ @ F.:.J J J J J J J J J _+N#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J J J J J D 4+! @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ 0.h J J J J J J r F.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ q.J J J J J J J ,#@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ _ ]+J J J J J J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J V _ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J @@6$@ @ @ @ @ @ @ @ 7$T@J J J J J J J J J _+N#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J J J J J J x ;@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ D+J J J J J J J C#% @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ b '.J J J J J J _+B+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ! C@J J J J J J J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J V _ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J @@6$@ @ @ @ @ @ @ @ @ /@J J J J J J J J J _+N#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J J J J J J J s.j+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ :.J J J J J J J L+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ :+].J J J J J J J 6 @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ # 0$-.J J J J J J J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J V _ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J @@6$@ @ @ @ @ @ @ @ @ /@J J J J J J J J J _+N#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J J J J J J J '.9+m+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ !.i+J J J J J J r `@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ E.:.J J J J J J J $@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ a+m.J J J J J J J J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J V _ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J @@6$@ @ @ @ @ @ @ @ @ /@J J J J J J J J J _+N#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J J J J J J J J T 7+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ < ;.J J J J J J D.:+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ C r J J J J J J q , @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ =+m.J J J J J J J J J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J V _ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J @@6$@ @ @ @ @ @ @ @ @ /@J J J J J J J J J _+N#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J J J J J J J J J r D+# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ % ^@'.J J J J J J e.p @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ Q.;.J J J J J J v o.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ a$,#'.J J J J J J J J J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J V _ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J @@6$@ @ @ @ @ @ @ @ @ /@J J J J J J J J J _+N#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J J J J J J J J J J i+4 @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ .+K J J J J J J r y.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ j D.J J J J J J J L+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ _ z.r J J J J J J J J J J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J V _ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J @@6$@ @ @ @ @ @ @ @ @ /@J J J J J J J J J _+N#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J J J J J J J J J J J &.a+@ @ @ @ @ @ @ @ @ @ @ @ @ @ >.;.J J J J J J ;.b$@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ (.J J J J J J J #.j @ @ @ @ @ @ @ @ @ @ @ @ @ @ G+s+r J J J J J J J J J J J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J V _ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J @@6$@ @ @ @ @ @ @ @ @ /@J J J J J J J J J _+N#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J J J J J J J J J J J J x.c$@ @ @ @ @ @ @ @ @ @ @ @ @ p@,#'.J J J J J x.# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ M+r J J J J J r 8 w.@ @ @ @ @ @ @ @ @ @ @ @ @ ! d+;.J J J J J J J J J J J J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J V _ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J @@6$@ @ @ @ @ @ @ @ @ /@J J J J J J J J J _+N#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J J J J J J J J J J J J '.b@$+@ @ @ @ @ @ @ @ @ @ @ @ @ d$).r J J J J A@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ m@K J J J J J V.(@@ @ @ @ @ @ @ @ @ @ @ @ @ _ %.'.J J J J J J J J J J J J J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J V _ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J R+4$@ @ @ @ @ @ @ @ {#e$J J J J J J J J J _+N#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J J J J J J J J J J J J J J M g@@ @ @ @ @ @ @ @ @ @ @ @ @ _ J@T J J ].Y#@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ W J J J r (._ @ @ @ @ @ @ @ @ @ @ @ @ @ >$}@T J J J J J J J J J J J J J J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J V _ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J 8 g.@ @ @ @ @ @ @ @ ($n+J J J J J J J J J _+N#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J J J J J J J J J J J J J J r B.[.@ @ @ @ @ @ @ @ @ @ @ @ @ % N.I J ,#m@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ _@v J D.U j @ @ @ @ @ @ @ @ @ @ @ @ @ p b+D J J J J J J J J J J J J J J J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J V _ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J I f${#@ @ @ @ @ @ @ u+P.J J J J J J J J J _+N#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J J J J J J J J J J J J J J J r ]+g@@ @ @ @ @ @ @ @ @ @ @ @ @ @ w |@r+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ j K P Q.@ @ @ @ @ @ @ @ @ @ @ @ @ @ p 9#-.J J J J J J J J J J J J J J J J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J V _ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J '.g$~ @ @ @ @ @ @ -#T@T J J J J J J J J J _+N#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J J J J J J J J J J J J J J J J J h$g.@ @ @ @ @ @ @ @ @ @ @ @ @ @ E.G+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @.j @ @ @ @ @ @ @ @ @ @ @ @ @ @ j g$T J J J J J J J J J J J J J J J J J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J V _ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J J r >+E@7$@ @ {#i$j$h J J J J J J J J J J _+N#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J J J J J J J J J J J J J J J J J '.^+k$@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ u.y@D J J J J J J J J J J J J J J J J J J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J V _ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J J J r X@l$:+$ 5#c@T J J J J J J J J J J J _+N#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J J J J J J J J J J J J J J J J J J J P s@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ p B.r J J J J J J J J J J J J J J J J J J J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J V _ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J J J J J D n n -.J J J J J J J J J J J J J _+N#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J J J J J J J J J J J J J J J J J J J '.2.6 @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ m$]+J J J J J J J J J J J J J J J J J J J J J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J V _ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J J J J J J J J J J J J J J J J J J J J J J _+N#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J J J J J J J J J J J J J J J J J J J J J i+m ! @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ n.n$r J J J J J J J J J J J J J J J J J J J J J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J V _ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J J J J J J J J J J J J J J J J J J J J J J _+N#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J J J J J J J J J J J J J J J J J J J J J J i+l@# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ _ r+n J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J._ @ @ @ @ @ @ @ @ @ b J J J J J J J J V _ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J J J J J J J J J J J J J J J J J J J J J J _+N#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J ]+! @ @ @ @ @ @ @ @ -#,.J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J D j@m+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ % b+x+J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J $#9@@ @ @ @ @ @ @ @ @ ~+J J J J J J J J V _ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J J J J J J J J J J J J J J J J J J J J J J _+N#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J q /#@ @ @ @ @ @ @ @ -#t#J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J r B.:+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ J+z.r J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J ..A.@ @ @ @ @ @ @ @ =#J.J J J J J J J J V _ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J J J J J J J J J J J J J J J J J J J J J J _+N#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J &.X.@ @ @ @ @ @ @ @ =#s J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J b.S j @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ p U##.J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J I `#@ @ @ @ @ @ @ @ [.#.J J J J J J J J V _ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J J J J J J J J J J J J J J J J J J J J J J _+N#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J r U @ @ @ @ @ @ @ @ : }+J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J o$q@[.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ k &+p$K q ..z.6+6+6+6+6+z.]+q @@s.#.b.I ;.D J J J J J J J J J J J J J J J J J o : {#@ @ @ @ @ ^#q$D J J J J J J J J V _ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J J J J J J J J J J J J J J J J J J J J J J _+N#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J J q +.{#@ @ @ @ @ j 7.D J J J J J J J J J J J J J J J J r ;.h ].&.s.)#q ..]+!@6+6+6+6+,#(+q P @@| M+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ # g@Y ~.G+@ @ @ @ @ @ @ @ @ @ @ ~ : g@k F#F r$3#).2.h r J J J J J J J J J J J J r J.Z@f {#. =#q+3#v J J J J J J J J J V _ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J I K r J J J J J J J 8 @@'.J J J J J J J J _+N#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J J r 6+0.! {#@ =#q+|+v J J J J J J J J J J J J '.h #.,#a@~+s$G.a.u+A.t$# @ @ @ @ @ @ @ @ @ @ # t$w.g@B+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ! w.u$`@b+K ].;.'.J J J J J J J J r x.9 3@[ S.v$D J J J J J J J J J J V _ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J }+V@P.D J J J J J w$M+2$r J J J J J J J J _+N#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J J J '.` M.x$[ y...T J J J J J J J J J ;._+8 n@Q )+Y g.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ E.o.;$q h J J J J J J J J '.;.;.r J J J J J J J J J J J J V _ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J U.6$L C o ]._+8 ^@%#-#c#r J J J J J J J J _+N#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J J J J J J ;.;.r J J J J J J J J r ` u i.r@% @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ >$@.A+$.I J J J J J J J J J J J J J J J J J J J J J J V _ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J U.! @ y$m@Y#z$(@+#{#@ c#r J J J J J J J J _+N#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J J J J J J J J J J J J J J J r q @+F.j @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ j+D+R.h J J J J J J J J J J J J J J J J J J J V _ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J U.! @ @ @ @ @ @ @ @ @ c#r J J J J J J J J _+N#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J J J J J J J J J J J J r ` I.:@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ *.i.K J J J J J J J J J J J J J J J J J J V _ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J U.! @ @ @ @ @ @ @ @ @ c#r J J J J J J J J _+N#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J J J J J J J J J J J n y.$ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ % 9#s.r J J J J J J J J J J J J J J J V _ @ @ @ @ @ @ @ @ @ 7#;.J J J J J J J J U.! @ @ @ @ @ @ @ @ @ c#r J J J J J J J J _+N#@ @ @ @ @ @ @ @ @ N+_+J J J J J J J J J J J J J J J J J 8+L+3.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @.9 o$J J J J J J J J J J J J J J 8 m+@ @ @ @ @ @ @ @ @ A$;.J J J J J J J J U.! @ @ @ @ @ @ @ @ @ c#r J J J J J J J J _+_#@ @ @ @ @ @ @ @ @ Y _+J J J J J J J J J J J J J J J r G B$# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ! >.V '.J J J J J J J J J J J J b.1$@ @ @ @ @ @ @ @ f .'.J J J J J J J J U.! @ @ @ @ @ @ @ @ @ c#r J J J J J J J J ;.;#{#@ @ @ @ @ @ @ @ o.;.J J J J J J J J J J J J J J /.<+0 @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ # C$G+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ Y E T J J J J J J J J J J J r D+>$@ @ @ @ @ @ @ D$..J J J J J J J J J U.! @ @ @ @ @ @ @ @ @ c#r J J J J J J J J J z.O@@ @ @ @ @ @ @ f.d+'.J J J J J J J J J J J J '.:.Q.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ # C$# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ !.I.L+n@{.q@a@%.7@~+S m+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ G+W ;.J J J J J J J J J J J E+`#-#@ @ @ @ @ i#y r J J J J J J J J J U.! @ @ @ @ @ @ @ @ @ c#r J J J J J J J J J r ~+y$@ @ @ @ @ 4#M+m.J J J J J J J J J J J J r ^+a @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ % 1$%#A+*#C 3#s w#L+u m#@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ E$r J J J J J J '.;.B.0 @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ b &.J J J J J J J J J J J n t.D#4$6$l#%#X r J J J J J J J J J J U.! @ @ @ @ @ @ @ @ @ c#r J J J J J J J J J J T S.k i$/#i$m@J#n J J J J J J J J J J J J T >+i$@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ # $/.;.;.D J J J J '.5.j @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ G+[@J J J J J J J J r L+j @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ! S n J J J J J J J J J J J r 5 i I.(.i+J J J J J J J J J J J J U.! @ @ @ @ @ @ @ @ @ c#r J J J J J J J J J J J J K.d.b+} W+r J J J J J J J J J J J J '.w#G+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ u@-.J J J J J J J J 2.o.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ r@a#J J J J J J J J D ^.% @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ,.n J J J J J J J J J J J J J J J J J J J J J J J J J J J J U.! @ @ @ @ @ @ @ @ @ c#r J J J J J J J J J J J J J J J J J J J J J J J J J J J J J ;.n@! @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ m n J J J J J J J J I ;@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ _#v J J J J J J J J -.<@# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ c I J J J J J J J J J J J J J J J J J J J J J J J J J J J U.! @ @ @ @ @ @ @ @ @ c#r J J J J J J J J J J J J J J J J J J J J J J J J J J J J J d.u.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ >.D.J J J J J J J J r n+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ .h J J J J J J J J h 3@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ % s r J J J J J J J J J J J J J J J J J J J J J J J J J J U.! @ @ @ @ @ @ @ @ @ c#r J J J J J J J J J J J J J J J J J J J J J J J J J J J J 2.0 @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ F##.J J J J J J J J r y p @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ j v@r J J J J J J J J v /@# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ % V.r J J J J J J J J J J J J J J J J J J J J J J J J J U.! @ @ @ @ @ @ @ @ @ c#r J J J J J J J J J J J J J J J J J J J J J J J J J J J n$w @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ =@s.J J J J J J J J J F$u.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ _ }.r J J J J J J J J v u@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ J+s.J J J J J J J J J J J J J J J J J J J J J J J J J U.! @ @ @ @ @ @ @ @ @ c#r J J J J J J J J J J J J J J J J J J J J J J J J J J D `@# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ F#s.J J J J J J J J '.s.:+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ !.V.r J J J J J J J J I ~+% @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ i.D J J J J J J J J J J J J J J J J J J J J J J J J >@/#@ @ @ @ @ @ @ @ @ G$'.J J J J J J J J J J J J J J J J J J J J J J J J J '.K+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ >.#.J J J J J J J J J +@w @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ +.}+J J J J J J J J J I 7@% @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ! 5.J J J J J J J J J J J J J J J J J J J J J J J J x.P+@ @ @ @ @ @ @ @ ! H$J J J J J J J J J J J J J J J J J J J J J J J J J J #.=+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ >.D.J J J J J J J J J n 6 @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ :+5 '.J J J J J J J J -.y@_ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ 4.x J J J J J J J J J J J J J J J J J J J J J J J h H -#@ @ @ @ @ @ @ ]@R.J J J J J J J J J J J J J J J J J J J J J J J J J ;.l@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ # -+n J J J J J J J J J b.U @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ =+@@J J J J J J J J J r ).!.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ! ^.r J J J J J J J J J J J J J J J J J J J J J J J $@H+@ @ @ @ @ @ r#E J J J J J J J J J J J J J J J J J J J J J J J J J J U.u.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ _ $T J J J J J J J J J n >.# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ 0.K.'.J J J J J J J J r ,#{+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ , I J J J J J J J J J J J J J J J J J J J J J J J r o t I$-#-#I#g@a@T J J J J J J J J J J J J J J J J J J J J J J J J J '.b @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ 2 -@-.J J J J J J J J J n -+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ {+%$'.J J J J J J J J '.D.m % @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ s+J J J J J J J J J J J J J J J J J J J J J J J J '.n z+J$2$u D.r J J J J J J J J J J J J J J J J J J J J J J J J J J +@% @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ x@M r J J J J J J J J J &.>.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ =+}+'.J J J J J J J J J ].q#p @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ 0.v J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J D C @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ U +@'.J J J J J J J J J ].U # @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ , B.r J J J J J J J J J D P.F.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ! !+'.J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J 8 k @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ 0 ( h J J J J J J J J J '.+@6 @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ v.!@r J J J J J J J J J '.}+r+# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ S h J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J M.! @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ { 5.r J J J J J J J J J J K$]@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ p 9 h J J J J J J J J J J h -@w.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ E.8 J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J '.M@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ j *#b.J J J J J J J J J J r F$:+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ j 2$v J J J J J J J J J J J x.M+j @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ C@J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J n 1@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ >$_@P.r J J J J J J J J J J T y u.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ o##.'.J J J J J J J J J J v &+k @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ 8$J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J p+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ j C E+J J J J J J J J J J J I W p @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ , 5.r J J J J J J J J J J J v .+.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ X.v J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J D @+@ @ @ @ @ @ @ @ @ @ @ @ @ @ X.o#K.J J J J J J J J J J J r 2._#@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ g@q@/.J J J J J J J J J J J T :.> j @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ..J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J b.5+@ @ @ @ @ @ @ @ @ @ @ @ # .$_.v J J J J J J J J J J J D e.F#@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ,.s.r J J J J J J J J J J '.h ^+l.j @ @ @ @ @ @ @ @ @ @ @ @ @ S.r J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J ,#@.@ @ @ @ @ @ @ @ @ @ ! .+L$n '.J J J J J J J J J J J m.A@% @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ k A r J J J J J J J J J J J J -.[+;@% @ @ @ @ @ @ @ @ @ @ @ o#;.J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J ^@% @ @ @ @ @ @ @ @ @ '#^@m.J J J J J J J J J J J J J @@> % @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ! W@D.'.J J J J J J J J J J J J h z+W.@ @ @ @ @ @ @ @ @ @ |.b.J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J '.b @ @ @ @ @ @ @ @ @ @ B.r J J J J J J J J J J J J ++L+s@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ 3.2@T J J J J J J J J J J J J J ;.0.@ @ @ @ @ @ @ @ @ t+U.J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J ;.M$@ @ @ @ @ @ @ @ @ P+8 J J J J J J J J J J J r ..] ! @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ _ 3@x r J J J J J J J J J J J ;.!#@ @ @ @ @ @ @ @ @ R@F$J J J J J J J i+!+3@y.K h J J J J J J J J J J J J J J J J J J J J J J J J r D.d+=.n+V r J J J J J J ;.(@@ @ @ @ @ @ @ @ @ )+].J J J J J J J J J r I v@Y @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ [.W x J J J J J J J J J J '.>+@ @ @ @ @ @ @ @ @ @ {.J J J J J J n z@<#@ @ r#- v$J J J J J J J J J J J J J J J J J J J J J J ].*#N${#@ @ k+z+'.J J J J J v w.@ @ @ @ @ @ @ @ @ F#h J J J J J J J J I g$0.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ % n.[@/.J J J J J J J J J X@# @ @ @ @ @ @ @ @ @ %.J J J J J J C@=#@ @ @ @ =#7 M r J J J J J J J J J J J J J J J J J J J &.u@M#@ @ @ @ {#7#;.J J J J J b.# @ @ @ @ @ @ @ @ @ e@D J J J J J J ;.M M+_ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ # n.,#v J J J J J J J ]+w.@ @ @ @ @ @ @ @ @ l@J J J J J J O$@ @ @ @ @ @ @ ]#U+'.J J J J J J J J J J J J J J J J J ].> <#@ @ @ @ @ @ A._+J J J J J ##@ @ @ @ @ @ @ @ @ @ Y@J J J J J -.q 3@j @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ G+U (+r J J J J J }+@.@ @ @ @ @ @ @ @ @ !$J J J J J J < @ @ @ @ @ @ @ -#@#i+J J J J J J J J J J J J J J J J r T+=#@ @ @ @ @ @ @ g._+J J J J J K @ @ @ @ @ @ @ @ @ @ E$J J J r K.@+F+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ M#W.:.I '.J J 8 k @ @ @ @ @ @ @ @ @ ~$J J J J J J !$@ @ @ @ @ @ @ @ -#t.r J J J J J J J J J J J J J J J w@P$@ @ @ @ @ @ @ @ E.I J J J J J }.@ @ @ @ @ @ @ @ @ # E J h @@u@p @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
". @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ! W#( i+J #.H+@ @ @ @ @ @ @ @ @ `#J J J J J J Q${#@ @ @ @ @ @ @ @ v.Y.J J J J J J J J J J J J J J v R$@ @ @ @ @ @ @ @ @ `#;.J J J J J n@@ @ @ @ @ @ @ @ @ ~ y 9+>.X.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ . ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ >$=+v@..H+@ @ @ @ @ @ @ @ @ =+J J J J J J x.r#@ @ @ @ @ @ @ @ -#@+D J J J J J J J J J J J J J ]+[#@ @ @ @ @ @ @ @ =#S.r J J J J J a@@ @ @ @ @ @ @ @ @ @ *.g.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ % j @ @ @ @ @ @ @ @ @ '#J J J J J J ;.S@7$@ @ @ @ @ @ @ @ D#].J J J J J J J J J J J J J [ @ @ @ @ @ @ @ @ @ S$V J J J J J J T$@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ '#J J J J J J J J.j+@ @ @ @ @ @ @ @ f ##J J J J J J J J J J J J D k @ @ @ @ @ @ @ @ -#l@;.J J J J J J T$@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ $+J J J J J J J r 7@=#@ @ @ @ @ @ @ {#e.J J J J J J J J J J J J ;.r#@ @ @ @ @ @ @ {#:@++J J J J J J J a@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ `#J J J J J J J J n a+7$@ @ @ @ @ @ {#5.J J J J J J J J J J J J ;.l#@ @ @ @ @ @ {#!.]+J J J J J J J J y @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ U J J J J J J J J J x.e@4#@ @ @ @ @ /###J J J J J J J J J J J J r 4.@ @ @ @ @ {#a 9+r J J J J J J J J !@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ O$J J J J J J J J J J i+c#E@{#@ @ 7$< h J J J J J J J J J J J J J l+P$@ @ @ = F#K J J J J J J J J J J P#@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ v#J J J J J J J J J J J I (#C.U$, ,@n$J J J J J J J J J J J J J J -.S+k g@z@E$K.'.J J J J J J J J J J g+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ 1.J J J J J J J J J J J J J J T T J J J J J J J J J J J J J J J J J J T /.r J J J J J J J J J J J J J `+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ 9 J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J 8+g.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ! t@J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J ;.a$@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ E...J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J ;.:+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ' p+@@` &.].h r J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J '.;._+D.` 2.@@|.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ~ V$: *.*+F#@+d.E+r J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J ].}.9#6.a.t+L ~.t$# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ! @.W$q h '.J J J J J J J J J J J J J J J J J J J J J J J J J J J D x.v@:+R@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ # H+l+/.J J J J J J J J J J J J J J J J J J J J J J J J ;.q >.0 @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ X.@+8 '.J J J J J J J J J J J J J J J J J J J J J /.1 r@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ _ 6+T J J J J J J J J J J J J J J J J J J '.n$m @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ g.X$r J J J J J J J J J J J J J J J J J M Y$@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ 7@T J J J J J J J J J J J J J J r f@% @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ % Z$r J J J J J J J J J J J J J ^+`$@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ p ).'.J J J J J J J J J J J 2+g@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ j F$J J J J J J J J J J 8 a+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ a+E+J J J J J J J J r Z+% @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ -+'.J J J J J J J R.# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ j +@J J J J J J ].U @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ A+I J J J J '.p.! @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ 9@V#J J J J v m$@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ 6 ;.J J J 2@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ f +@J J I Z.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ C J J p+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ k K.r a+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ p L+b.(@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ 4@o @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ a x$@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ [.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ X.2 >$@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
" . + @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ . "};

BIN
res/silentdragon_be.qm

Binary file not shown.

2811
res/silentdragon_be.ts

File diff suppressed because it is too large

1636
res/silentdragon_bg.ts

File diff suppressed because it is too large

BIN
res/silentdragon_de.qm

Binary file not shown.

1852
res/silentdragon_de.ts

File diff suppressed because it is too large

BIN
res/silentdragon_es.qm

Binary file not shown.

1800
res/silentdragon_es.ts

File diff suppressed because it is too large

BIN
res/silentdragon_fi.qm

Binary file not shown.

1779
res/silentdragon_fi.ts

File diff suppressed because it is too large

BIN
res/silentdragon_fil.qm

Binary file not shown.

1700
res/silentdragon_fil.ts

File diff suppressed because it is too large

BIN
res/silentdragon_fr.qm

Binary file not shown.

1789
res/silentdragon_fr.ts

File diff suppressed because it is too large

BIN
res/silentdragon_hr.qm

Binary file not shown.

1720
res/silentdragon_hr.ts

File diff suppressed because it is too large

BIN
res/silentdragon_id.qm

Binary file not shown.

1239
res/silentdragon_id.ts

File diff suppressed because it is too large

BIN
res/silentdragon_it.qm

Binary file not shown.

1764
res/silentdragon_it.ts

File diff suppressed because it is too large

BIN
res/silentdragon_nl.qm

Binary file not shown.

2414
res/silentdragon_nl.ts

File diff suppressed because it is too large

BIN
res/silentdragon_pl.qm

Binary file not shown.

2810
res/silentdragon_pl.ts

File diff suppressed because it is too large

BIN
res/silentdragon_pt.qm

Binary file not shown.

1759
res/silentdragon_pt.ts

File diff suppressed because it is too large

BIN
res/silentdragon_ro.qm

Binary file not shown.

1706
res/silentdragon_ro.ts

File diff suppressed because it is too large

BIN
res/silentdragon_ru.qm

Binary file not shown.

2336
res/silentdragon_ru.ts

File diff suppressed because it is too large

BIN
res/silentdragon_sr.qm

Binary file not shown.

1720
res/silentdragon_sr.ts

File diff suppressed because it is too large

109
res/silentdragon_template.ts

@ -424,7 +424,7 @@
</message> </message>
<message> <message>
<location filename="../src/mainwindow.ui" line="1453"/> <location filename="../src/mainwindow.ui" line="1453"/>
<source>&amp;Hush Discord</source> <source>&amp;Hush Telegram</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
@ -434,7 +434,7 @@
</message> </message>
<message> <message>
<location filename="../src/mainwindow.ui" line="1463"/> <location filename="../src/mainwindow.ui" line="1463"/>
<source>Check github.com for &amp;updates</source> <source>Check git for &amp;updates</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
@ -457,11 +457,6 @@
<source>&amp;Export all private keys</source> <source>&amp;Export all private keys</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<location filename="../src/mainwindow.ui" line="1486"/>
<source>&amp;z-board.net</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<location filename="../src/mainwindow.ui" line="1489"/> <location filename="../src/mainwindow.ui" line="1489"/>
<source>Ctrl+A, Ctrl+Z</source> <source>Ctrl+A, Ctrl+Z</source>
@ -893,60 +888,6 @@ doesn&apos;t look like a z-address</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>
<context>
<name>MobileAppConnector</name>
<message>
<location filename="../src/mobileappconnector.ui" line="14"/>
<source>Connect Mobile App</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mobileappconnector.ui" line="36"/>
<source>Scan this QRCode in SilentDragonAndroid to connect your device</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mobileappconnector.ui" line="43"/>
<source>QR Code</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mobileappconnector.ui" line="49"/>
<source>Connection String</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mobileappconnector.ui" line="84"/>
<source>Allow connections over the internet via SilentDragon wormhole</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mobileappconnector.ui" line="94"/>
<source>SilentDragonAndroid</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mobileappconnector.ui" line="106"/>
<source>Disconnect</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mobileappconnector.ui" line="126"/>
<location filename="../src/mobileappconnector.ui" line="160"/>
<source>TextLabel</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mobileappconnector.ui" line="136"/>
<source>Last seen:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mobileappconnector.ui" line="153"/>
<source>Connection type:</source>
<translation type="unfinished"></translation>
</message>
</context>
<context> <context>
<name>PrivKey</name> <name>PrivKey</name>
<message> <message>
@ -1313,26 +1254,6 @@ Would you like to visit the releases page?</source>
<source>Amount</source> <source>Amount</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<location filename="../src/websockets.cpp" line="370"/>
<source>Connected directly</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/websockets.cpp" line="373"/>
<source>Connected over the internet via SilentDragon wormhole service</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/websockets.cpp" line="667"/>
<source>Node is still syncing.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/websockets.cpp" line="691"/>
<source>No addresses with enough balance to spend! Try sweeping funds into one address</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>RecurringDialog</name> <name>RecurringDialog</name>
@ -1519,7 +1440,7 @@ Would you like to visit the releases page?</source>
</message> </message>
<message> <message>
<location filename="../src/settings.ui" line="230"/> <location filename="../src/settings.ui" line="230"/>
<source>Check github for updates at startup</source> <source>Check git for updates at startup</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
@ -1564,7 +1485,7 @@ Would you like to visit the releases page?</source>
</message> </message>
<message> <message>
<location filename="../src/settings.ui" line="312"/> <location filename="../src/settings.ui" line="312"/>
<source>Connect to github on startup to check for updates</source> <source>Connect to git on startup to check for updates</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
@ -1594,12 +1515,12 @@ Would you like to visit the releases page?</source>
</message> </message>
<message> <message>
<location filename="../src/settings.ui" line="411"/> <location filename="../src/settings.ui" line="411"/>
<source>Testnet Tx Explorer URL</source> <source>Onion Tx Explorer URL</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/settings.ui" line="437"/> <location filename="../src/settings.ui" line="437"/>
<source>Testnet Address Explorer URL</source> <source>Onion Address Explorer URL</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
@ -1760,44 +1681,44 @@ Would you like to visit the releases page?</source>
</message> </message>
</context> </context>
<context> <context>
<name>createZcashConf</name> <name>createHushConf</name>
<message> <message>
<location filename="../src/createzcashconfdialog.ui" line="14"/> <location filename="../src/createhushconfdialog.ui" line="14"/>
<source>Configure HUSH3.conf</source> <source>Configure HUSH3.conf</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/createzcashconfdialog.ui" line="61"/> <location filename="../src/createhushconfdialog.ui" line="61"/>
<source>Show Advanced Configuration</source> <source>Show Advanced Configuration</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/createzcashconfdialog.ui" line="86"/> <location filename="../src/createhushconfdialog.ui" line="86"/>
<source>Your Hush node will be configured for you automatically</source> <source>Your Hush node will be configured for you automatically</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/createzcashconfdialog.ui" line="102"/> <location filename="../src/createhushconfdialog.ui" line="102"/>
<source>Use custom datadir</source> <source>Use custom datadir</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/createzcashconfdialog.ui" line="109"/> <location filename="../src/createhushconfdialog.ui" line="109"/>
<source>Please choose a directory to store your wallet.dat and blockchain</source> <source>Please choose a directory to store your wallet.dat and blockchain</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/createzcashconfdialog.ui" line="118"/> <location filename="../src/createhushconfdialog.ui" line="118"/>
<source>Choose directory</source> <source>Choose directory</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/createzcashconfdialog.ui" line="154"/> <location filename="../src/createhushconfdialog.ui" line="154"/>
<source>Connect over Tor</source> <source>Connect over Tor</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/createzcashconfdialog.ui" line="161"/> <location filename="../src/createhushconfdialog.ui" line="161"/>
<source>Please note that you&apos;ll need to already have a Tor service configured on port 9050</source> <source>Please note that you&apos;ll need to already have a Tor service configured on port 9050</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>

BIN
res/silentdragon_tr.qm

Binary file not shown.

1775
res/silentdragon_tr.ts

File diff suppressed because it is too large

BIN
res/silentdragon_uk.qm

Binary file not shown.

1837
res/silentdragon_uk.ts

File diff suppressed because it is too large

BIN
res/silentdragon_zh.qm

Binary file not shown.

1771
res/silentdragon_zh.ts

File diff suppressed because it is too large

BIN
res/synced.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
res/transaction0.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
res/transaction2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
res/transaction_abandoned.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
res/transaction_conflicted.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
res/tx_inout.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
res/tx_input.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
res/tx_mined.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
res/tx_output.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
res/verify.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

BIN
res/warning.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
res/zcashdlogo.gif

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 74 KiB

4
run-after-build-sdx.sh

@ -0,0 +1,4 @@
#!/usr/bin/env bash
# Copyright 2019-2023 The Hush Developers
./build-sdx.sh && ./silentdragonx

2
run-after-build.sh

@ -1,4 +1,4 @@
#!/bin/bash #!/bin/bash
# Copyright 2019-2020 The Hush Developers # Copyright 2019-2022 The Hush Developers
./build.sh && ./silentdragon ./build.sh && ./silentdragon

BIN
sapling-output.params

Binary file not shown.

BIN
sapling-spend.params

Binary file not shown.

BIN
silentdragon.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

27
silentdragon.pro

@ -1,8 +1,6 @@
#------------------------------------------------- # Copyright 2018-2022 The Hush Developers
# # Released under the GPLv3
# Project created by QtCreator 2018-10-05T09:54:45 # Project created by QtCreator 2018-10-05T09:54:45
#
#-------------------------------------------------
QT += core gui network QT += core gui network
@ -11,7 +9,6 @@ CONFIG += precompile_header
PRECOMPILED_HEADER = src/precompiled.h PRECOMPILED_HEADER = src/precompiled.h
QT += widgets QT += widgets
QT += websockets
TARGET = silentdragon TARGET = silentdragon
@ -51,6 +48,8 @@ SOURCES += \
src/sendtab.cpp \ src/sendtab.cpp \
src/senttxstore.cpp \ src/senttxstore.cpp \
src/txtablemodel.cpp \ src/txtablemodel.cpp \
src/peerstablemodel.cpp \
src/bannedpeerstablemodel.cpp \
src/qrcodelabel.cpp \ src/qrcodelabel.cpp \
src/connection.cpp \ src/connection.cpp \
src/fillediconlabel.cpp \ src/fillediconlabel.cpp \
@ -58,14 +57,13 @@ SOURCES += \
src/logger.cpp \ src/logger.cpp \
src/addresscombo.cpp \ src/addresscombo.cpp \
src/validateaddress.cpp \ src/validateaddress.cpp \
src/websockets.cpp \
src/mobileappconnector.cpp \
src/recurring.cpp \ src/recurring.cpp \
src/requestdialog.cpp \ src/requestdialog.cpp \
src/memoedit.cpp \ src/memoedit.cpp \
src/viewalladdresses.cpp src/viewalladdresses.cpp
HEADERS += \ HEADERS += \
src/guiconstants.h \
src/mainwindow.h \ src/mainwindow.h \
src/precompiled.h \ src/precompiled.h \
src/rpc.h \ src/rpc.h \
@ -75,6 +73,8 @@ HEADERS += \
src/3rdparty/qrcode/QrSegment.hpp \ src/3rdparty/qrcode/QrSegment.hpp \
src/settings.h \ src/settings.h \
src/txtablemodel.h \ src/txtablemodel.h \
src/peerstablemodel.h \
src/bannedpeerstablemodel.h \
src/senttxstore.h \ src/senttxstore.h \
src/qrcodelabel.h \ src/qrcodelabel.h \
src/connection.h \ src/connection.h \
@ -83,15 +83,17 @@ HEADERS += \
src/logger.h \ src/logger.h \
src/addresscombo.h \ src/addresscombo.h \
src/validateaddress.h \ src/validateaddress.h \
src/websockets.h \
src/mobileappconnector.h \
src/recurring.h \ src/recurring.h \
src/requestdialog.h \ src/requestdialog.h \
src/memoedit.h \ src/memoedit.h \
src/viewalladdresses.h src/viewalladdresses.h
FORMS += \ FORMS += \
src/getblock.ui \
src/viewtransaction.ui \
src/mainwindow.ui \ src/mainwindow.ui \
src/qrcode.ui \
src/rescandialog.ui \
src/settings.ui \ src/settings.ui \
src/about.ui \ src/about.ui \
src/confirm.ui \ src/confirm.ui \
@ -104,14 +106,14 @@ FORMS += \
src/connection.ui \ src/connection.ui \
src/addressbook.ui \ src/addressbook.ui \
src/viewalladdresses.ui \ src/viewalladdresses.ui \
src/mobileappconnector.ui \ src/createhushconfdialog.ui \
src/createzcashconfdialog.ui \
src/recurringdialog.ui \ src/recurringdialog.ui \
src/newrecurring.ui \ src/newrecurring.ui \
src/requestdialog.ui src/requestdialog.ui
TRANSLATIONS = res/silentdragon_bg.ts \ TRANSLATIONS = res/silentdragon_be.ts \
res/silentdragon_bg.ts \
res/silentdragon_de.ts \ res/silentdragon_de.ts \
res/silentdragon_es.ts \ res/silentdragon_es.ts \
res/silentdragon_fi.ts \ res/silentdragon_fi.ts \
@ -121,6 +123,7 @@ TRANSLATIONS = res/silentdragon_bg.ts \
res/silentdragon_id.ts \ res/silentdragon_id.ts \
res/silentdragon_it.ts \ res/silentdragon_it.ts \
res/silentdragon_nl.ts \ res/silentdragon_nl.ts \
res/silentdragon_pl.ts \
res/silentdragon_pt.ts \ res/silentdragon_pt.ts \
res/silentdragon_ro.ts \ res/silentdragon_ro.ts \
res/silentdragon_ru.ts \ res/silentdragon_ru.ts \

164
silentdragonx.pro

@ -0,0 +1,164 @@
# Copyright 2018-2023 The Hush Developers
# Released under the GPLv3
QT += core gui network
CONFIG += precompile_header
PRECOMPILED_HEADER = src/precompiled.h
QT += widgets
TARGET = silentdragonx
TEMPLATE = app
# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += \
QT_DEPRECATED_WARNINGS
INCLUDEPATH += src/3rdparty/
INCLUDEPATH += src/
mac: LIBS+= -Wl,-dead_strip
mac: LIBS+= -Wl,-dead_strip_dylibs
mac: LIBS+= -Wl,-bind_at_load
RESOURCES = application-sdx.qrc
MOC_DIR = bin
OBJECTS_DIR = bin
UI_DIR = src
CONFIG += c++14
SOURCES += \
src/main.cpp \
src/mainwindow.cpp \
src/rpc.cpp \
src/balancestablemodel.cpp \
src/3rdparty/qrcode/BitBuffer.cpp \
src/3rdparty/qrcode/QrCode.cpp \
src/3rdparty/qrcode/QrSegment.cpp \
src/settings.cpp \
src/sendtab.cpp \
src/senttxstore.cpp \
src/txtablemodel.cpp \
src/peerstablemodel.cpp \
src/bannedpeerstablemodel.cpp \
src/qrcodelabel.cpp \
src/connection.cpp \
src/fillediconlabel.cpp \
src/addressbook.cpp \
src/logger.cpp \
src/addresscombo.cpp \
src/validateaddress.cpp \
src/recurring.cpp \
src/requestdialog.cpp \
src/memoedit.cpp \
src/viewalladdresses.cpp
HEADERS += \
src/guiconstants.h \
src/mainwindow.h \
src/precompiled.h \
src/rpc.h \
src/balancestablemodel.h \
src/3rdparty/qrcode/BitBuffer.hpp \
src/3rdparty/qrcode/QrCode.hpp \
src/3rdparty/qrcode/QrSegment.hpp \
src/settings.h \
src/txtablemodel.h \
src/peerstablemodel.h \
src/bannedpeerstablemodel.h \
src/senttxstore.h \
src/qrcodelabel.h \
src/connection.h \
src/fillediconlabel.h \
src/addressbook.h \
src/logger.h \
src/addresscombo.h \
src/validateaddress.h \
src/recurring.h \
src/requestdialog.h \
src/memoedit.h \
src/viewalladdresses.h
FORMS += \
src/getblock.ui \
src/viewtransaction.ui \
src/mainwindow.ui \
src/qrcode.ui \
src/rescandialog.ui \
src/settings.ui \
src/about.ui \
src/confirm.ui \
src/privkey.ui \
src/viewkey.ui \
src/memodialog.ui \
src/viewalladdresses.ui \
src/validateaddress.ui \
src/viewalladdresses.ui \
src/connection.ui \
src/addressbook.ui \
src/viewalladdresses.ui \
src/createhushconfdialog.ui \
src/recurringdialog.ui \
src/newrecurring.ui \
src/requestdialog.ui
TRANSLATIONS = res/silentdragon_be.ts \
res/silentdragon_bg.ts \
res/silentdragon_de.ts \
res/silentdragon_es.ts \
res/silentdragon_fi.ts \
res/silentdragon_fil.ts \
res/silentdragon_fr.ts \
res/silentdragon_hr.ts \
res/silentdragon_id.ts \
res/silentdragon_it.ts \
res/silentdragon_nl.ts \
res/silentdragon_pl.ts \
res/silentdragon_pt.ts \
res/silentdragon_ro.ts \
res/silentdragon_ru.ts \
res/silentdragon_sr.ts \
res/silentdragon_tr.ts \
res/silentdragon_uk.ts \
res/silentdragon_zh.ts
include(singleapplication/singleapplication.pri)
DEFINES += QAPPLICATION_CLASS=QApplication _FORTIFY_SOURCE=2
QMAKE_INFO_PLIST = res-drgx/Info.plist
win32: RC_ICONS = res-drgx/icon.ico
ICON = res-drgx/logo.icns
libsodium.target = $$PWD/res/libsodium.a
libsodium.commands = res/libsodium/buildlibsodium.sh
QMAKE_EXTRA_TARGETS += libsodium
QMAKE_CLEAN += res/libsodium.a
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
win32:CONFIG(release, debug|release): LIBS += -L$$PWD/res/ -llibsodium
else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/res/ -llibsodiumd
else:unix: LIBS += -L$$PWD/res/ -lsodium
INCLUDEPATH += $$PWD/res
DEPENDPATH += $$PWD/res
win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$PWD/res/liblibsodium.a
else:win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$PWD/res/liblibsodium.a
else:win32:!win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$PWD/res/libsodium.lib
else:win32:!win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$PWD/res/libsodiumd.lib
else:unix: PRE_TARGETDEPS += $$PWD/res/libsodium.a

3
src/3rdparty/sodium.h

@ -1,9 +1,10 @@
// Copyright (c) 2019-2021 The Hush developers
// Released under the GPLv3
#ifndef sodium_H #ifndef sodium_H
#define sodium_H #define sodium_H
#include "sodium/version.h" #include "sodium/version.h"
#include "sodium/core.h" #include "sodium/core.h"
#include "sodium/crypto_aead_aes256gcm.h" #include "sodium/crypto_aead_aes256gcm.h"
#include "sodium/crypto_aead_chacha20poly1305.h" #include "sodium/crypto_aead_chacha20poly1305.h"

10
src/about.ui

@ -53,13 +53,13 @@
p, li { white-space: pre-wrap; } p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Ubuntu'; font-size:12pt; font-weight:400; font-style:normal;&quot;&gt; &lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Ubuntu'; font-size:12pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8.1pt;&quot;&gt;&lt;br /&gt;&lt;/p&gt; &lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8.1pt;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:11pt;&quot;&gt;Copyright(c) 2019-2020 The Hush developers (GPLv3)&lt;/span&gt;&lt;/p&gt; &lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:11pt;&quot;&gt;Copyright(c) 2019-2022 The Hush developers (GPLv3)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:11pt;&quot;&gt;Copyright (c) 2019 Duke Leto, David Mercer and Aditya Kulkarni. (MIT License)&lt;/span&gt;&lt;/p&gt; &lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:11pt;&quot;&gt;Copyright (c) 2019 Duke Leto, Jane Mercer and Aditya Kulkarni. (MIT License)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;&quot;&gt;&lt;br /&gt;&lt;/p&gt; &lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:11pt;&quot;&gt;Special thanks to:&lt;/span&gt;&lt;/p&gt; &lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:11pt;&quot;&gt;Special thanks to:&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:11pt;&quot;&gt;JSON for Modern C++ : &lt;/span&gt;&lt;a href=&quot;https://nlohmann.github.io/json/&quot;&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2'; font-size:8pt; text-decoration: underline; color:#0000ff;&quot;&gt;https://nlohmann.github.io/json/&lt;/span&gt;&lt;/a&gt;&lt;/p&gt; &lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:11pt;&quot;&gt;JSON for Modern C++ : &lt;/span&gt;&lt;a href=&quot;https://nlohmann.github.io/json/&quot;&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2';text-decoration: underline; color:#0000ff;&quot;&gt;https://nlohmann.github.io/json/&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:11pt;&quot;&gt;QR Code generator library Nayuki : &lt;/span&gt;&lt;a href=&quot;https://www.nayuki.io/page/qr-code-generator-library&quot;&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2'; font-size:8pt; text-decoration: underline; color:#0000ff;&quot;&gt;https://www.nayuki.io/page/qr-code-ge…&lt;/span&gt;&lt;/a&gt;&lt;/p&gt; &lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:11pt;&quot;&gt;QR Code generator library Nayuki : &lt;/span&gt;&lt;a href=&quot;https://www.nayuki.io/page/qr-code-generator-library&quot;&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;&quot;&gt;https://www.nayuki.io/page/qr-code-ge…&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:11pt;&quot;&gt;Made with QT : &lt;/span&gt;&lt;a href=&quot;https://www.qt.io/&quot;&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2'; font-size:8pt; text-decoration: underline; color:#0000ff;&quot;&gt;https://www.qt.io/&lt;/span&gt;&lt;/a&gt;&lt;/p&gt; &lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:11pt;&quot;&gt;Made with QT : &lt;/span&gt;&lt;a href=&quot;https://www.qt.io/&quot;&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;&quot;&gt;https://www.qt.io/&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt; text-decoration: underline; color:#0000ff;&quot;&gt;&lt;br /&gt;&lt;/p&gt; &lt;p style=&quot;-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt; text-decoration: underline; color:#0000ff;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:11pt;&quot;&gt;LICENSE:&lt;/span&gt;&lt;/p&gt; &lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:11pt;&quot;&gt;LICENSE:&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a href=&quot;https://www.gnu.org/licenses/gpl-3.0.en.html &lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a href=&quot;https://www.gnu.org/licenses/gpl-3.0.en.html

13
src/addressbook.cpp

@ -1,3 +1,5 @@
// Copyright 2019-2022 The Hush developers
// Released under the GPLv3
#include "addressbook.h" #include "addressbook.h"
#include "ui_addressbook.h" #include "ui_addressbook.h"
#include "ui_mainwindow.h" #include "ui_mainwindow.h"
@ -5,6 +7,7 @@
#include "mainwindow.h" #include "mainwindow.h"
#include "rpc.h" #include "rpc.h"
extern bool isdragonx;
AddressBookModel::AddressBookModel(QTableView *parent) AddressBookModel::AddressBookModel(QTableView *parent)
: QAbstractTableModel(parent) { : QAbstractTableModel(parent) {
@ -272,13 +275,12 @@ void AddressBook::readFromStorage() {
file.close(); file.close();
} }
// Special. // Add the default donation address if it isn't already present
// Add the default ZecWallet donation address if it isn't already present
// QList<QString> allAddresses; // QList<QString> allAddresses;
// std::transform(allLabels.begin(), allLabels.end(), // std::transform(allLabels.begin(), allLabels.end(),
// std::back_inserter(allAddresses), [=] (auto i) { return i.second; }); // std::back_inserter(allAddresses), [=] (auto i) { return i.second; });
// if (!allAddresses.contains(Settings::getDonationAddr())) { // if (!allAddresses.contains(Settings::getDonationAddr())) {
// allLabels.append(QPair<QString, QString>("ZecWallet donation", Settings::getDonationAddr())); // allLabels.append(QPair<QString, QString>("SilentDragon donation", Settings::getDonationAddr()));
// } // }
} }
@ -292,6 +294,9 @@ void AddressBook::writeToStorage() {
QString AddressBook::writeableFile() { QString AddressBook::writeableFile() {
auto filename = QStringLiteral("addresslabels.dat"); auto filename = QStringLiteral("addresslabels.dat");
if (isdragonx) {
filename = QStringLiteral("addresslabels-drgx.dat");
}
auto dir = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)); auto dir = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation));
if (!dir.exists()) if (!dir.exists())

6
src/addressbook.h

@ -1,3 +1,5 @@
// Copyright 2019-2022 The Hush developers
// Released under the GPLv3
#ifndef ADDRESSBOOK_H #ifndef ADDRESSBOOK_H
#define ADDRESSBOOK_H #define ADDRESSBOOK_H
@ -7,6 +9,8 @@ class MainWindow;
class AddressBookModel : public QAbstractTableModel { class AddressBookModel : public QAbstractTableModel {
Q_OBJECT
public: public:
AddressBookModel(QTableView* parent); AddressBookModel(QTableView* parent);
~AddressBookModel(); ~AddressBookModel();
@ -66,4 +70,4 @@ private:
static AddressBook* instance; static AddressBook* instance;
}; };
#endif // ADDRESSBOOK_H #endif // ADDRESSBOOK_H

4
src/addresscombo.cpp

@ -1,3 +1,5 @@
// Copyright 2019-2022 The Hush developers
// Released under the GPLv3
#include "addresscombo.h" #include "addresscombo.h"
#include "addressbook.h" #include "addressbook.h"
#include "settings.h" #include "settings.h"
@ -36,4 +38,4 @@ void AddressCombo::insertItem(int index, const QString& text, double bal) {
QString txt = AddressBook::addLabelToAddress(text) % QString txt = AddressBook::addLabelToAddress(text) %
"(" % Settings::getDisplayFormat(bal) % ")"; "(" % Settings::getDisplayFormat(bal) % ")";
QComboBox::insertItem(index, txt); QComboBox::insertItem(index, txt);
} }

2
src/addresscombo.h

@ -1,3 +1,5 @@
// Copyright 2019-2022 The Hush developers
// Released under the GPLv3
#ifndef ADDRESSCOMBO_H #ifndef ADDRESSCOMBO_H
#define ADDRESSCOMBO_H #define ADDRESSCOMBO_H

28
src/balancestablemodel.cpp

@ -1,6 +1,9 @@
// Copyright 2019-2022 The Hush developers
// Released under the GPLv3
#include "balancestablemodel.h" #include "balancestablemodel.h"
#include "addressbook.h" #include "addressbook.h"
#include "settings.h" #include "settings.h"
#include "guiconstants.h"
BalancesTableModel::BalancesTableModel(QObject *parent) BalancesTableModel::BalancesTableModel(QObject *parent)
@ -58,6 +61,10 @@ int BalancesTableModel::columnCount(const QModelIndex&) const
QVariant BalancesTableModel::data(const QModelIndex &index, int role) const QVariant BalancesTableModel::data(const QModelIndex &index, int role) const
{ {
// Get current theme name
QString theme_name = Settings::getInstance()->get_theme_name();
QBrush b;
if (loading) { if (loading) {
if (role == Qt::DisplayRole) if (role == Qt::DisplayRole)
return "Loading..."; return "Loading...";
@ -67,21 +74,26 @@ QVariant BalancesTableModel::data(const QModelIndex &index, int role) const
if (role == Qt::TextAlignmentRole && index.column() == 1) return QVariant(Qt::AlignRight | Qt::AlignVCenter); if (role == Qt::TextAlignmentRole && index.column() == 1) return QVariant(Qt::AlignRight | Qt::AlignVCenter);
if (role == Qt::ForegroundRole) { if (role == Qt::ForegroundRole) {
// If any of the UTXOs for this address has zero confirmations, paint it in red // If any of the UTXOs for this address has zero confirmations, paint it in red
const auto& addr = std::get<0>(modeldata->at(index.row())); const auto& addr = std::get<0>(modeldata->at(index.row()));
for (auto utxo : *utxos) { for (auto utxo : *utxos) {
if (utxo.address == addr && utxo.confirmations == 0) { if (utxo.address == addr && utxo.confirmations == 0) {
QBrush b; b.setColor(COLOR_UNCONFIRMED_TX);
b.setColor(Qt::red);
return b; return b;
} }
} }
if (theme_name == "dark" || theme_name == "midnight") {
// Else, just return the default brush b.setColor(COLOR_WHITE);
QBrush b; return b;
b.setColor(Qt::black); }else if (theme_name == "dragonx"){
return b; b.setColor(COLOR_DRAGONX_TEXT);
return b;
}else{
b.setColor(COLOR_BLACK);
return b;
}
return b;
} }
if (role == Qt::DisplayRole) { if (role == Qt::DisplayRole) {

10
src/balancestablemodel.h

@ -1,3 +1,5 @@
// Copyright 2019-2022 The Hush developers
// Released under the GPLv3
#ifndef BALANCESTABLEMODEL_H #ifndef BALANCESTABLEMODEL_H
#define BALANCESTABLEMODEL_H #define BALANCESTABLEMODEL_H
@ -11,8 +13,10 @@ struct UnspentOutput {
bool spendable; bool spendable;
}; };
class BalancesTableModel : public QAbstractTableModel class BalancesTableModel : public QAbstractTableModel {
{
Q_OBJECT
public: public:
BalancesTableModel(QObject* parent); BalancesTableModel(QObject* parent);
~BalancesTableModel(); ~BalancesTableModel();
@ -31,4 +35,4 @@ private:
bool loading = true; bool loading = true;
}; };
#endif // BALANCESTABLEMODEL_H #endif // BALANCESTABLEMODEL_H

135
src/bannedpeerstablemodel.cpp

@ -0,0 +1,135 @@
// Copyright 2019-2022 The Hush developers
// Released under the GPLv3
#include "bannedpeerstablemodel.h"
#include "settings.h"
#include "rpc.h"
BannedPeersTableModel::BannedPeersTableModel(QObject *parent)
: QAbstractTableModel(parent) {
headers << QObject::tr("Address") << QObject::tr("Subnet") << QObject::tr("Banned Until");
}
BannedPeersTableModel::~BannedPeersTableModel() {
delete modeldata;
}
void BannedPeersTableModel::addData(const QList<BannedPeerItem>& data) {
bannedPeers = new QList<BannedPeerItem>();
std::copy(data.begin(), data.end(), std::back_inserter(*bannedPeers));
updateAllData();
}
void BannedPeersTableModel::updateAllData() {
auto newmodeldata = new QList<BannedPeerItem>();
// Copy peer data so GUI can use it
if (bannedPeers != nullptr) std::copy( bannedPeers->begin(), bannedPeers->end(), std::back_inserter(*newmodeldata));
// Sort by banned_until
std::sort(newmodeldata->begin(), newmodeldata->end(), [=] (auto a, auto b) {
return a.banned_until > b.banned_until; // reverse sort
});
// And then swap out the modeldata with the new one.
delete modeldata;
modeldata = newmodeldata;
// do magic
dataChanged(index(0, 0), index(modeldata->size()-1, columnCount(index(0,0))-1));
layoutChanged();
}
int BannedPeersTableModel::rowCount(const QModelIndex&) const
{
if (modeldata == nullptr) return 0;
return modeldata->size();
}
int BannedPeersTableModel::columnCount(const QModelIndex&) const
{
return headers.size();
}
QVariant BannedPeersTableModel::data(const QModelIndex &index, int role) const
{
auto dat = modeldata->at(index.row());
if (role == Qt::DisplayRole) {
switch (index.column()) {
case 0: return dat.address;
case 1: return dat.subnet;
case 2: return QDateTime::fromSecsSinceEpoch(dat.banned_until).toLocalTime().toString();
case 3: return "AS" + QString::number(dat.asn);
}
}
// we show mask because it's possible to ban ranges of addresses
if (role == Qt::ToolTipRole) {
switch (index.column()) {
case 0: return "Network Address";
case 1: return "Subnet Mask";
case 2: return "Banned Until " + QDateTime::fromSecsSinceEpoch(dat.banned_until).toUTC().toString();
case 3: return "Autonomous System Number";
}
}
//TODO: show different icons for IP vs Tor vs other kinds of connections
/*
if (role == Qt::DecorationRole && index.column() == 0) {
if (!dat.memo.isEmpty()) {
// If the memo is a Payment URI, then show a payment request icon
if (dat.memo.startsWith("hush:")) {
QIcon icon(":/icons/paymentreq.gif");
return QVariant(icon.pixmap(16, 16));
} else {
// Return the info pixmap to indicate memo
QIcon icon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxInformation);
return QVariant(icon.pixmap(16, 16));
}
} else {
// Empty pixmap to make it align
QPixmap p(16, 16);
p.fill(Qt::white);
return QVariant(p);
}
}
*/
return QVariant();
}
QVariant BannedPeersTableModel::headerData(int section, Qt::Orientation orientation, int role) const
{
//if (role == Qt::TextAlignmentRole && section == 3) return QVariant(Qt::AlignRight | Qt::AlignVCenter);
if (role == Qt::TextAlignmentRole) return QVariant(Qt::AlignCenter | Qt::AlignVCenter);
if (role == Qt::FontRole) {
QFont f;
f.setBold(true);
return f;
}
if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {
return headers.at(section);
}
return QVariant();
}
QString BannedPeersTableModel::getAddress(int row) const {
return modeldata->at(row).address.trimmed();
}
qint64 BannedPeersTableModel::getASN(int row) const {
return modeldata->at(row).asn;
}
QString BannedPeersTableModel::getSubnet(int row) const {
return modeldata->at(row).subnet;
}
qint64 BannedPeersTableModel::getBannedUntil(int row) const {
return modeldata->at(row).banned_until;
}

37
src/bannedpeerstablemodel.h

@ -0,0 +1,37 @@
// Copyright 2019-2022 The Hush developers
// Released under the GPLv3
#ifndef BANNEDPEERSTABLEMODEL_H
#define BANNEDPEERSTABLEMODEL_H
#include "precompiled.h"
struct BannedPeerItem;
class BannedPeersTableModel: public QAbstractTableModel
{
public:
BannedPeersTableModel(QObject* parent);
~BannedPeersTableModel();
QString getSubnet(int row) const;
QString getAddress(int row) const;
qint64 getASN(int row) const;
qint64 getBannedUntil(int row) const;
int rowCount(const QModelIndex &parent) const;
int columnCount(const QModelIndex &parent) const;
QVariant data(const QModelIndex &index, int role) const;
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
void addData (const QList<BannedPeerItem>& data);
private:
void updateAllData();
QList<BannedPeerItem>* bannedPeers = nullptr;
QList<BannedPeerItem>* modeldata = nullptr;
QList<QString> headers;
};
#endif // BANNEDPEERSTABLEMODEL_H

511
src/connection.cpp

@ -1,16 +1,19 @@
// Copyright 2019-2020 The Hush developers // Copyright 2019-2023 The Hush developers
// GPLv3 // Released under the GPLv3
#include "connection.h" #include "connection.h"
#include "mainwindow.h" #include "mainwindow.h"
#include "settings.h" #include "settings.h"
#include "ui_connection.h" #include "ui_connection.h"
#include "ui_createzcashconfdialog.h" #include "ui_createhushconfdialog.h"
#include "rpc.h" #include "rpc.h"
#include "precompiled.h" #include "precompiled.h"
#include "version.h"
#include "sd.h"
extern bool isdragonx;
ConnectionLoader::ConnectionLoader(MainWindow* main, RPC* rpc) { ConnectionLoader::ConnectionLoader(MainWindow* main, RPC* rpc) {
qDebug() << __func__;
this->main = main; this->main = main;
this->rpc = rpc; this->rpc = rpc;
@ -18,20 +21,17 @@ ConnectionLoader::ConnectionLoader(MainWindow* main, RPC* rpc) {
d->setWindowFlags(d->windowFlags() & ~(Qt::WindowCloseButtonHint | Qt::WindowContextHelpButtonHint)); d->setWindowFlags(d->windowFlags() & ~(Qt::WindowCloseButtonHint | Qt::WindowContextHelpButtonHint));
connD = new Ui_ConnectionDialog(); connD = new Ui_ConnectionDialog();
connD->setupUi(d); connD->setupUi(d);
QMovie *movie1 = new QMovie(":/img/res/silentdragon-animated-startup.gif");; if(isdragonx) {
QMovie *movie2 = new QMovie(":/img/res/silentdragon-animated-startup-dark.gif");; d->setWindowTitle("SilentDragonX");
}
QMovie *movie1 = new QMovie(":/img/silentdragon-animated-startup-dark.gif");;
auto theme = Settings::getInstance()->get_theme_name(); auto theme = Settings::getInstance()->get_theme_name();
auto size = QSize(512,512); auto size = QSize(512,512);
if (theme == "dark" || theme == "midnight") { movie1->setScaledSize(size);
movie2->setScaledSize(size); connD->topIcon->setMovie(movie1);
connD->topIcon->setMovie(movie2); movie1->start();
movie2->start();
} else {
movie1->setScaledSize(size);
connD->topIcon->setMovie(movie1);
movie1->start();
}
main->logger->write("set animation"); main->logger->write("set animation");
qDebug() << "set animation"; qDebug() << "set animation";
} }
@ -44,84 +44,107 @@ ConnectionLoader::~ConnectionLoader() {
} }
void ConnectionLoader::loadConnection() { void ConnectionLoader::loadConnection() {
qDebug() << __func__;
QTimer::singleShot(1, [=]() { this->doAutoConnect(); }); QTimer::singleShot(1, [=]() { this->doAutoConnect(); });
if (!Settings::getInstance()->isHeadless()) if (!Settings::getInstance()->isHeadless())
d->exec(); d->exec();
} }
void ConnectionLoader::doAutoConnect(bool tryEzcashdStart) { void ConnectionLoader::doAutoConnect(bool tryEhushdStart) {
qDebug() << __func__;
// Priority 1: Ensure all params are present. // Priority 1: Ensure all params are present.
if (!verifyParams()) { if (!verifyParams()) {
downloadParams([=]() { this->doAutoConnect(); }); qDebug() << "Cannot find sapling params!";
return; return;
} }
// Priority 2: Try to connect to detect HUSH3.conf and connect to it. // Priority 2: Try to connect to detect HUSH3.conf and connect to it.
auto config = autoDetectZcashConf(); auto config = autoDetectHushConf();
main->logger->write(QObject::tr("Attempting autoconnect")); main->logger->write(QObject::tr("Attempting autoconnect"));
if (config.get() != nullptr) { if (config.get() != nullptr) {
auto connection = makeConnection(config); auto connection = makeConnection(config);
refreshZcashdState(connection, [=] () { refreshHushdState(connection, [=] () {
// Refused connection. So try and start embedded zcashd // Refused connection. So try and start embedded hushd
if (Settings::getInstance()->useEmbedded()) { if (Settings::getInstance()->useEmbedded()) {
if (tryEzcashdStart) { if (tryEhushdStart) {
this->showInformation(QObject::tr("Starting embedded hushd")); if(isdragonx) {
if (this->startEmbeddedZcashd()) { this->showInformation(QObject::tr("Starting embedded dragonxd"));
} else {
this->showInformation(QObject::tr("Starting embedded hushd"));
}
if (this->startEmbeddedHushd()) {
// Embedded hushd started up. Wait a second and then refresh the connection // Embedded hushd started up. Wait a second and then refresh the connection
main->logger->write("Embedded hushd started up, trying autoconnect in 1 sec"); main->logger->write("Embedded hushd started up, trying autoconnect in 1 sec");
QTimer::singleShot(1000, [=]() { doAutoConnect(); } ); QTimer::singleShot(1000, [=]() { doAutoConnect(); } );
} else { } else {
if (config->zcashDaemon) { if (config->hushDaemon) {
// hushd is configured to run as a daemon, so we must wait for a few seconds // hushd is configured to run as a daemon, so we must wait for a few seconds
// to let it start up. // to let it start up.
main->logger->write("hushd is daemon=1. Waiting for it to start up"); main->logger->write("hushd is daemon=1. Waiting for it to start up");
this->showInformation(QObject::tr("hushd is set to run as daemon"), QObject::tr("Waiting for hushd")); this->showInformation(QObject::tr("hushd is set to run as daemon"), QObject::tr("Waiting for hushd"));
QTimer::singleShot(5000, [=]() { doAutoConnect(/* don't attempt to start ehushd */ false); }); QTimer::singleShot(5000, [=]() { doAutoConnect(/* don't attempt to start ehushd */ false); });
} else { } else {
// Something is wrong. // Something is wrong.
// We're going to attempt to connect to the one in the background one last time // We're going to attempt to connect to the one in the background one last time
// and see if that works, else throw an error // and see if that works, else throw an error
main->logger->write("Unknown problem while trying to start hushd!"); main->logger->write("Unknown problem while trying to start hushd!");
QTimer::singleShot(2000, [=]() { doAutoConnect(/* don't attempt to start ezcashd */ false); }); QTimer::singleShot(2000, [=]() { doAutoConnect(/* don't attempt to start ehushd */ false); });
} }
} }
} else { } else {
// We tried to start ezcashd previously, and it didn't work. So, show the error. // We tried to start ehushd previously, and it didn't work. So, show the error.
main->logger->write("Couldn't start embedded hushd for unknown reason"); main->logger->write("Couldn't start embedded hushd for unknown reason");
QString explanation; QString explanation;
if (config->zcashDaemon) { if (config->hushDaemon) {
explanation = QString() % QObject::tr("You have hushd set to start as a daemon, which can cause problems " explanation = QString() % QObject::tr("You have hushd set to start as a daemon, which can cause problems "
"with SilentDragon\n\n." "with SilentDragon\n\n."
"Please remove the following line from your HUSH3.conf and restart SilentDragon\n" "Please remove the following line from your HUSH3.conf and restart SilentDragon\n"
"daemon=1"); "daemon=1");
if (isdragonx) {
explanation = QString() % QObject::tr("You have dragonxd set to start as a daemon, which can cause problems "
"with SilentDragonX\n\n."
"Please remove the following line from your DRAGONX.conf and restart SilentDragonX\n"
"daemon=1");
}
} else { } else {
explanation = QString() % QObject::tr("Couldn't start the embedded hushd.\n\n" explanation = QString() % QObject::tr("Couldn't start the embedded hushd.\n\n"
"Please try restarting.\n\nIf you previously started hushd with custom arguments, you might need to reset HUSH3.conf.\n\n" "Please try restarting.\n\nIf you previously started hushd with custom arguments, you might need to reset HUSH3.conf.\n\n"
"If all else fails, please run hushd manually.") % "If all else fails, please run hushd manually.") %
(ezcashd ? QObject::tr("The process returned") + ":\n\n" % ezcashd->errorString() : QString("")); (ehushd ? QObject::tr("The process returned") + ":\n\n" % ehushd->errorString() : QString(""));
if(isdragonx) {
explanation = QString() % QObject::tr("Couldn't start the embedded dragonxd.\n\n"
"Please try restarting.\n\nIf you previously started hushd with custom arguments, you might need to reset DRAGONX.conf.\n\n"
"If all else fails, please run dragonxd manually.") %
(ehushd ? QObject::tr("The process returned") + ":\n\n" % ehushd->errorString() : QString(""));
}
} }
this->showError(explanation); this->showError(explanation);
} }
} else { } else {
// HUSH3.conf exists, there's no connection, and the user asked us not to start hushd. Error! // HUSH3.conf exists, there's no connection, and the user asked us not to start hushd. Error!
main->logger->write("Not using embedded and couldn't connect to hushd"); main->logger->write("Not using embedded and couldn't connect to hushd");
QString explanation = QString() % QObject::tr("Couldn't connect to hushd configured in HUSH3.conf.\n\n" QString explanation = QString() % QObject::tr("Couldn't connect to hushd configured in HUSH3.conf.\n\n"
"Not starting embedded hushd because --no-embedded was passed"); "Not starting embedded hushd because --no-embedded was passed");
if(isdragonx) {
main->logger->write("Not using embedded and couldn't connect to dragonxd");
QString explanation = QString() % QObject::tr("Couldn't connect to dragonxd configured in DRAGONX.conf.\n\n"
"Not starting embedded dragonxd because --no-embedded was passed");
}
this->showError(explanation); this->showError(explanation);
} }
}); });
} else { } else {
if (Settings::getInstance()->useEmbedded()) { if (Settings::getInstance()->useEmbedded()) {
// HUSH3.conf was not found, so create one // HUSH3.conf was not found, so create one
createZcashConf(); createHushConf();
} else { } else {
// Fall back to manual connect // Fall back to manual connect
doManualConnect(); doManualConnect();
} }
} }
} }
QString randomPassword() { QString randomPassword() {
@ -130,11 +153,17 @@ QString randomPassword() {
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"; "abcdefghijklmnopqrstuvwxyz";
const int passwordLength = 10; // Assume we have low entropy randomness,
// so we generate a longer password than we probably need
const int passwordLength = 32;
char* s = new char[passwordLength + 1]; char* s = new char[passwordLength + 1];
for (int i = 0; i < passwordLength; ++i) { for (int i = 0; i < passwordLength; ++i) {
#ifdef Q_OS_LINUX
s[i] = alphanum[randombytes_uniform(sizeof(alphanum))]; s[i] = alphanum[randombytes_uniform(sizeof(alphanum))];
#else
s[i] = alphanum[rand() % (sizeof(alphanum) - 1)];
#endif
} }
s[passwordLength] = 0; s[passwordLength] = 0;
@ -143,18 +172,18 @@ QString randomPassword() {
/** /**
* This will create a new HUSH3.conf and download params if they cannot be found * This will create a new HUSH3.conf and download params if they cannot be found
*/ */
void ConnectionLoader::createZcashConf() { void ConnectionLoader::createHushConf() {
main->logger->write("createZcashConf"); main->logger->write(__func__);
auto confLocation = zcashConfWritableLocation(); auto confLocation = hushConfWritableLocation();
QFileInfo fi(confLocation); QFileInfo fi(confLocation);
QDialog d(main); QDialog d(main);
Ui_createZcashConf ui; Ui_createHushConf ui;
ui.setupUi(&d); ui.setupUi(&d);
QPixmap logo(":/img/res/zcashdlogo.gif"); QPixmap logo(":/img/hushdlogo.png");
ui.lblTopIcon->setBasePixmap(logo.scaled(512,512, Qt::KeepAspectRatio, Qt::SmoothTransformation)); ui.lblTopIcon->setBasePixmap(logo.scaled(512,512, Qt::KeepAspectRatio, Qt::SmoothTransformation));
ui.btnPickDir->setEnabled(false); ui.btnPickDir->setEnabled(false);
@ -183,9 +212,14 @@ void ConnectionLoader::createZcashConf() {
// Show the dialog // Show the dialog
QString datadir = ""; QString datadir = "";
bool useTor = false; bool useTor = false;
QString torProxy = "127.0.0.1";
QString torPort = "9050";
if (d.exec() == QDialog::Accepted) { if (d.exec() == QDialog::Accepted) {
datadir = ui.lblDirName->text(); datadir = ui.lblDirName->text();
useTor = ui.chkUseTor->isChecked(); useTor = ui.chkUseTor->isChecked();
torProxy = ui.torProxy->text();
torPort = ui.torPort->text();
} }
main->logger->write("Creating file " + confLocation); main->logger->write("Creating file " + confLocation);
@ -193,20 +227,30 @@ void ConnectionLoader::createZcashConf() {
QFile file(confLocation); QFile file(confLocation);
if (!file.open(QIODevice::ReadWrite | QIODevice::Truncate)) { if (!file.open(QIODevice::ReadWrite | QIODevice::Truncate)) {
main->logger->write("Could not create HUSH3.conf, returning"); QString explanation = QString() % (isdragonx ? QObject::tr("Could not create DRAGONX.conf.") : QObject::tr("Could not create HUSH3.conf.") );
main->logger->write(explanation);
QString explanation = QString() % QObject::tr("Could not create HUSH3.conf.");
this->showError(explanation); this->showError(explanation);
return; return;
} }
QTextStream out(&file); QTextStream out(&file);
out << "# Autogenerated by Hush SilentDragon https://myhush.org\n"; if(isdragonx) {
out << "# Autogenerated by Hush SilentDragonX " << APP_VERSION << " https://dragonx.is\n";
} else {
out << "# Autogenerated by Hush SilentDragon " << APP_VERSION << " https://hush.is\n";
}
out << "server=1\n"; out << "server=1\n";
out << "rpcuser=hush\n";
out << "rpcpassword=" % randomPassword() << "\n"; out << "rpcpassword=" % randomPassword() << "\n";
out << "rpcport=18031\n";
if(isdragonx) {
out << "rpcuser=dragonx\n";
out << "rpcport=21769\n";
} else {
out << "rpcuser=hush\n";
out << "rpcport=18031\n";
}
out << "txindex=1\n"; out << "txindex=1\n";
out << "addressindex=1\n"; out << "addressindex=1\n";
out << "spentindex=1\n"; out << "spentindex=1\n";
@ -217,11 +261,15 @@ void ConnectionLoader::createZcashConf() {
// Consolidation is now defaulted to ON for new wallets // Consolidation is now defaulted to ON for new wallets
out << "consolidation=1\n"; out << "consolidation=1\n";
// This is default behavior for hushd 3.6.1 and newer,
// this helps if older hushd's are being used
out << "tls=only\n";
if (!datadir.isEmpty()) { if (!datadir.isEmpty()) {
out << "datadir=" % datadir % "\n"; out << "datadir=" % datadir % "\n";
} }
if (useTor) { if (useTor) {
out << "proxy=127.0.0.1:9050\n"; out << "proxy="<< torProxy << ":" << torPort << "\n";
} }
file.close(); file.close();
@ -231,19 +279,6 @@ void ConnectionLoader::createZcashConf() {
} }
void ConnectionLoader::downloadParams(std::function<void(void)> cb) {
main->logger->write("Adding params to download queue");
// Add all the files to the download queue
downloadQueue = new QQueue<QUrl>();
client = new QNetworkAccessManager(main);
//Currently we fallback to this in rare edgecases, it's not normally executed
downloadQueue->enqueue(QUrl("https://z.cash/downloads/sapling-output.params"));
downloadQueue->enqueue(QUrl("https://z.cash/downloads/sapling-spend.params"));
doNextDownload(cb);
}
void ConnectionLoader::doNextDownload(std::function<void(void)> cb) { void ConnectionLoader::doNextDownload(std::function<void(void)> cb) {
auto fnSaveFileName = [&] (QUrl url) { auto fnSaveFileName = [&] (QUrl url) {
QString path = url.path(); QString path = url.path();
@ -266,7 +301,7 @@ void ConnectionLoader::doNextDownload(std::function<void(void)> cb) {
int filesRemaining = downloadQueue->size(); int filesRemaining = downloadQueue->size();
QString filename = fnSaveFileName(url); QString filename = fnSaveFileName(url);
QString paramsDir = zcashParamsDir(); QString paramsDir = zkParamsDir();
if (QFile(QDir(paramsDir).filePath(filename)).exists()) { if (QFile(QDir(paramsDir).filePath(filename)).exists()) {
main->logger->write(filename + " already exists, skipping"); main->logger->write(filename + " already exists, skipping");
@ -276,7 +311,7 @@ void ConnectionLoader::doNextDownload(std::function<void(void)> cb) {
} }
// The downloaded file is written to a new name, and then renamed when the operation completes. // The downloaded file is written to a new name, and then renamed when the operation completes.
currentOutput = new QFile(QDir(paramsDir).filePath(filename + ".part")); currentOutput = new QFile(QDir(paramsDir).filePath(filename + ".part"));
if (!currentOutput->open(QIODevice::WriteOnly)) { if (!currentOutput->open(QIODevice::WriteOnly)) {
main->logger->write("Couldn't open " + currentOutput->fileName() + " for writing"); main->logger->write("Couldn't open " + currentOutput->fileName() + " for writing");
@ -284,12 +319,12 @@ void ConnectionLoader::doNextDownload(std::function<void(void)> cb) {
} }
main->logger->write("Downloading to " + filename); main->logger->write("Downloading to " + filename);
qDebug() << "Downloading " << url << " to " << filename; qDebug() << "Downloading " << url << " to " << filename;
QNetworkRequest request(url); QNetworkRequest request(url);
request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true); request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
currentDownload = client->get(request); currentDownload = client->get(request);
downloadTime.start(); downloadTime.start();
// Download Progress // Download Progress
QObject::connect(currentDownload, &QNetworkReply::downloadProgress, [=] (auto done, auto total) { QObject::connect(currentDownload, &QNetworkReply::downloadProgress, [=] (auto done, auto total) {
// calculate the download speed // calculate the download speed
@ -309,7 +344,7 @@ void ConnectionLoader::doNextDownload(std::function<void(void)> cb) {
QObject::tr("Downloading ") % filename % (filesRemaining > 1 ? " ( +" % QString::number(filesRemaining) % QObject::tr(" more remaining )") : QString("")), QObject::tr("Downloading ") % filename % (filesRemaining > 1 ? " ( +" % QString::number(filesRemaining) % QObject::tr(" more remaining )") : QString("")),
QString::number(done/1024/1024, 'f', 0) % QObject::tr("MB of ") % QString::number(total/1024/1024, 'f', 0) + QObject::tr("MB at ") % QString::number(speed, 'f', 2) % unit); QString::number(done/1024/1024, 'f', 0) % QObject::tr("MB of ") % QString::number(total/1024/1024, 'f', 0) + QObject::tr("MB at ") % QString::number(speed, 'f', 2) % unit);
}); });
// Download Finished // Download Finished
QObject::connect(currentDownload, &QNetworkReply::finished, [=] () { QObject::connect(currentDownload, &QNetworkReply::finished, [=] () {
// Rename file // Rename file
@ -322,98 +357,119 @@ void ConnectionLoader::doNextDownload(std::function<void(void)> cb) {
if (currentDownload->error()) { if (currentDownload->error()) {
main->logger->write("Downloading " + filename + " failed"); main->logger->write("Downloading " + filename + " failed");
this->showError(QObject::tr("Downloading ") + filename + QObject::tr(" failed. Please check the help site for more info")); this->showError(QObject::tr("Downloading ") + filename + QObject::tr(" failed. Please check the help site for more info"));
} else { } else {
doNextDownload(cb); doNextDownload(cb);
} }
}); });
// Download new data available. // Download new data available.
QObject::connect(currentDownload, &QNetworkReply::readyRead, [=] () { QObject::connect(currentDownload, &QNetworkReply::readyRead, [=] () {
currentOutput->write(currentDownload->readAll()); currentOutput->write(currentDownload->readAll());
}); });
} }
bool ConnectionLoader::startEmbeddedZcashd() { bool ConnectionLoader::startEmbeddedHushd() {
if (!Settings::getInstance()->useEmbedded()) if (!Settings::getInstance()->useEmbedded())
return false; return false;
main->logger->write("Trying to start embedded hushd"); main->logger->write("Trying to start embedded hushd");
// Static because it needs to survive even after this method returns. // Static because it needs to survive even after this method returns.
static QString processStdErrOutput; static QString processStdErrOutput;
if (ezcashd != nullptr) { if (ehushd != nullptr) {
if (ezcashd->state() == QProcess::NotRunning) { if (ehushd->state() == QProcess::NotRunning) {
if (!processStdErrOutput.isEmpty()) { if (!processStdErrOutput.isEmpty()) {
QMessageBox::critical(main, QObject::tr("hushd error"), "hushd said: " + processStdErrOutput, QMessageBox::critical(main, QObject::tr("hushd error"), "hushd said: " + processStdErrOutput,
QMessageBox::Ok); QMessageBox::Ok);
} }
return false; return false;
} else { } else {
return true; return true;
} }
} }
QDir appPath(QCoreApplication::applicationDirPath()); QDir appPath(QCoreApplication::applicationDirPath());
#ifdef Q_OS_WIN64 #ifdef Q_OS_WIN64
auto hushdProgram = appPath.absoluteFilePath("komodod.exe"); auto hushdProgram = appPath.absoluteFilePath("hushd.exe");
// params for DRGX are handled below
#else #else
auto hushdProgram = appPath.absoluteFilePath("komodod"); auto hushdProgram = appPath.absoluteFilePath("hushd");
if (isdragonx) {
hushdProgram = appPath.absoluteFilePath("dragonxd");
}
#endif #endif
//if (!QFile(hushdProgram).exists()) { //if (!QFile(hushdProgram).exists()) {
if (!QFile::exists(hushdProgram)) { if (!QFile::exists(hushdProgram)) {
qDebug() << "Can't find hushd at " << hushdProgram; qDebug() << "Can't find binary at " << hushdProgram;
main->logger->write("Can't find hushd at " + hushdProgram); main->logger->write("Can't find binary at " + hushdProgram);
return false; return false;
} else { } else {
main->logger->write("Found hushd at " + hushdProgram); qDebug() << "Found binary at " << hushdProgram;
main->logger->write("Found binary at " + hushdProgram);
} }
ezcashd = std::shared_ptr<QProcess>(new QProcess(main)); ehushd = std::shared_ptr<QProcess>(new QProcess(main));
QObject::connect(ezcashd.get(), &QProcess::started, [=] () { QObject::connect(ehushd.get(), &QProcess::started, [=] () {
qDebug() << "Embedded hushd started via " << hushdProgram; qDebug() << "Embedded binary started via " << hushdProgram;
}); });
QObject::connect(ezcashd.get(), QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), QObject::connect(ehushd.get(), QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
[=](int exitCode, QProcess::ExitStatus exitStatus) { [=](int exitCode, QProcess::ExitStatus exitStatus) {
qDebug() << "hushd finished with code " << exitCode << "," << exitStatus; qDebug() << "hushd finished with code " << exitCode << "," << exitStatus;
}); });
QObject::connect(ezcashd.get(), &QProcess::errorOccurred, [&] (QProcess::ProcessError error) { QObject::connect(ehushd.get(), &QProcess::errorOccurred, [&] (QProcess::ProcessError error) {
qDebug() << "Couldn't start hushd at " << hushdProgram << ":" << error; qDebug() << "Couldn't start hushd!";
qDebug() << "hushd at " << hushdProgram << ":" << error;
}); });
std::weak_ptr<QProcess> weak_obj(ezcashd); std::weak_ptr<QProcess> weak_obj(ehushd);
auto ptr_main(main); auto ptr_main(main);
QObject::connect(ezcashd.get(), &QProcess::readyReadStandardError, [weak_obj, ptr_main]() { QObject::connect(ehushd.get(), &QProcess::readyReadStandardError, [weak_obj, ptr_main]() {
auto output = weak_obj.lock()->readAllStandardError(); auto output = weak_obj.lock()->readAllStandardError();
ptr_main->logger->write("hushd stderr:" + output); ptr_main->logger->write("hushd stderr:" + output);
processStdErrOutput.append(output); processStdErrOutput.append(output);
}); });
// This string should be the exact arg list seperated by single spaces // This string should be the exact arg list seperated by single spaces
QString params = "-ac_name=HUSH3 -ac_sapling=1 -ac_reward=0,1125000000,562500000 -ac_halving=129,340000,840000 -ac_end=128,340000,5422111 -ac_eras=3 -ac_blocktime=150 -ac_cc=2 -ac_ccenable=228,234,235,236,241 -ac_founders=1 -ac_supply=6178674 -ac_perc=11111111 -clientname=GoldenSandtrout -addnode=188.165.212.101 -addnode=64.120.113.130 -addnode=209.58.144.205 -addnode=94.130.35.94 -ac_cclib=hush3 -ac_script=76a9145eb10cf64f2bab1b457f1f25e658526155928fac88ac"; // Could be modified to start different Hush Smart Chains
QString params = "-tls=only -clientname=GoldenSandtrout"; // "-ac_name=TUSH";
/* This is now enabled by default in hushd
// Binaries come with this file
if(QFile( QDir(".").filePath("asmap.dat") ).exists()) {
auto asmap = appPath.absoluteFilePath("asmap.dat");
params += " -asmap=" + asmap;
} else {
qDebug() << "No ASN map file found";
}
*/
if(isdragonx) {
// dragonxd bash script cannot be used on windows, so specify exact chain params
params += " -ac_name=DRAGONX -ac_algo=randomx -ac_halving=3500000 -ac_reward=300000000 -ac_blocktime=36 -ac_private=1 -addnode=176.126.87.241";
}
QStringList arguments = params.split(" "); QStringList arguments = params.split(" ");
// Finally, actually start the full node
// Finally, actually start the full node
#ifdef Q_OS_LINUX #ifdef Q_OS_LINUX
qDebug() << "Starting on Linux: " + hushdProgram + " " + params; qDebug() << "Starting on Linux: " + hushdProgram + " " + params;
ezcashd->start(hushdProgram, arguments); ehushd->start(hushdProgram, arguments);
#elif defined(Q_OS_DARWIN) #elif defined(Q_OS_DARWIN)
qDebug() << "Starting on Darwin: " + hushdProgram + " " + params; qDebug() << "Starting on Darwin: " + hushdProgram + " " + params;
ezcashd->start(hushdProgram, arguments); ehushd->start(hushdProgram, arguments);
#elif defined(Q_OS_WIN64) #elif defined(Q_OS_WIN64)
qDebug() << "Starting on Win64: " + hushdProgram + " " + params; qDebug() << "Starting on Win64: " + hushdProgram + " " + params;
ezcashd->setWorkingDirectory(appPath.absolutePath()); ehushd->setWorkingDirectory(appPath.absolutePath());
ezcashd->start(hushdProgram, arguments); ehushd->start(hushdProgram, arguments);
#else #else
qDebug() << "Starting on Unknown OS(!): " + hushdProgram + " " + params; qDebug() << "Starting on Unknown OS(!): " + hushdProgram + " " + params;
ezcashd->setWorkingDirectory(appPath.absolutePath()); ehushd->setWorkingDirectory(appPath.absolutePath());
ezcashd->start(hushdProgram, arguments); ehushd->start(hushdProgram, arguments);
#endif // Q_OS_LINUX #endif // Q_OS_LINUX
main->logger->write("Started via " + hushdProgram + " " + params); main->logger->write("Started via " + hushdProgram + " " + params);
@ -436,9 +492,9 @@ void ConnectionLoader::doManualConnect() {
} }
auto connection = makeConnection(config); auto connection = makeConnection(config);
refreshZcashdState(connection, [=] () { refreshHushdState(connection, [=] () {
QString explanation = QString() QString explanation = QString()
% QObject::tr("Could not connect to hushd configured in settings.\n\n" % QObject::tr("Could not connect to hushd configured in settings.\n\n"
"Please set the host/port and user/password in the Edit->Settings menu."); "Please set the host/port and user/password in the Edit->Settings menu.");
showError(explanation); showError(explanation);
@ -449,9 +505,9 @@ void ConnectionLoader::doManualConnect() {
} }
void ConnectionLoader::doRPCSetConnection(Connection* conn) { void ConnectionLoader::doRPCSetConnection(Connection* conn) {
rpc->setEZcashd(ezcashd); rpc->setEHushd(ehushd);
rpc->setConnection(conn); rpc->setConnection(conn);
d->accept(); d->accept();
delete this; delete this;
@ -459,7 +515,7 @@ void ConnectionLoader::doRPCSetConnection(Connection* conn) {
Connection* ConnectionLoader::makeConnection(std::shared_ptr<ConnectionConfig> config) { Connection* ConnectionLoader::makeConnection(std::shared_ptr<ConnectionConfig> config) {
QNetworkAccessManager* client = new QNetworkAccessManager(main); QNetworkAccessManager* client = new QNetworkAccessManager(main);
QUrl myurl; QUrl myurl;
myurl.setScheme("http"); myurl.setScheme("http");
myurl.setHost(config.get()->host); myurl.setHost(config.get()->host);
@ -468,44 +524,50 @@ Connection* ConnectionLoader::makeConnection(std::shared_ptr<ConnectionConfig> c
QNetworkRequest* request = new QNetworkRequest(); QNetworkRequest* request = new QNetworkRequest();
request->setUrl(myurl); request->setUrl(myurl);
request->setHeader(QNetworkRequest::ContentTypeHeader, "text/plain"); request->setHeader(QNetworkRequest::ContentTypeHeader, "text/plain");
QString userpass = config.get()->rpcuser % ":" % config.get()->rpcpassword; QString userpass = config.get()->rpcuser % ":" % config.get()->rpcpassword;
QString headerData = "Basic " + userpass.toLocal8Bit().toBase64(); QString headerData = "Basic " + userpass.toLocal8Bit().toBase64();
request->setRawHeader("Authorization", headerData.toLocal8Bit()); request->setRawHeader("Authorization", headerData.toLocal8Bit());
return new Connection(main, client, request, config); return new Connection(main, client, request, config);
} }
void ConnectionLoader::refreshZcashdState(Connection* connection, std::function<void(void)> refused) { void ConnectionLoader::refreshHushdState(Connection* connection, std::function<void(void)> refused) {
main->logger->write("refreshing state"); qDebug() << __func__ << ": refreshing state";
QJsonObject payload = { QJsonObject payload = {
{"jsonrpc", "1.0"}, {"jsonrpc", "1.0"},
{"id", "someid"}, {"id", "42"},
{"method", "getinfo"} {"method", "getinfo"}
}; };
connection->doRPC(payload, connection->doRPC(payload,
[=] (auto) { [=] (auto) {
// Success // Success
main->logger->write("hushd is online!"); qDebug() << __func__ << ": hushd is online!";
// Delay 1 second to ensure loading (splash) is seen at least 1 second. // Delay 1 second to ensure loading (splash) is seen at least 1 second.
QTimer::singleShot(1000, [=]() { this->doRPCSetConnection(connection); }); QTimer::singleShot(1000, [=]() { this->doRPCSetConnection(connection); });
}, },
[=] (QNetworkReply* reply, const QJsonValue &res) { [=] (QNetworkReply* reply, const QJsonValue &res) {
// Failed, see what it is. qDebug() << __func__ << ": failed to connect to hushd!";
// Failed, see what it is.
auto err = reply->error(); auto err = reply->error();
//qDebug() << err << res; //qDebug() << err << res;
if (err == QNetworkReply::NetworkError::ConnectionRefusedError) { if (err == QNetworkReply::NetworkError::ConnectionRefusedError) {
refused(); refused();
} else if (err == QNetworkReply::NetworkError::AuthenticationRequiredError) { } else if (err == QNetworkReply::NetworkError::AuthenticationRequiredError) {
main->logger->write("Authentication failed"); main->logger->write("Authentication failed");
QString explanation = QString() % QString explanation = QString() %
QObject::tr("Authentication failed. The username / password you specified was " QObject::tr("Authentication failed. The username / password you specified was "
"not accepted by hushd. Try changing it in the Edit->Settings menu"); "not accepted by hushd. Try changing it in the Edit->Settings menu");
if(isdragonx) {
explanation = QString() %
QObject::tr("Authentication failed. The username / password you specified was "
"not accepted by dragonxd. Try changing it in the Edit->Settings menu");
}
this->showError(explanation); this->showError(explanation);
} else if (err == QNetworkReply::NetworkError::InternalServerError && } else if (err == QNetworkReply::NetworkError::InternalServerError &&
!res.isNull()) { !res.isNull()) {
// The server is loading, so just poll until it succeeds // The server is loading, so just poll until it succeeds
QString status = res["error"].toObject()["message"].toString(); QString status = res["error"].toObject()["message"].toString();
@ -516,10 +578,14 @@ void ConnectionLoader::refreshZcashdState(Connection* connection, std::function<
if (dots > 3) if (dots > 3)
dots = 0; dots = 0;
} }
this->showInformation(QObject::tr("Your hushd is starting up. Please wait."), status); if(isdragonx) {
this->showInformation(QObject::tr("Your dragonxd is starting up. Please wait."), status);
} else {
this->showInformation(QObject::tr("Your hushd is starting up. Please wait."), status);
}
main->logger->write("Waiting for hushd to come online."); main->logger->write("Waiting for hushd to come online.");
// Refresh after one second // Refresh after one second
QTimer::singleShot(1000, [=]() { this->refreshZcashdState(connection, refused); }); QTimer::singleShot(1000, [=]() { this->refreshHushdState(connection, refused); });
} }
} }
); );
@ -529,9 +595,10 @@ void ConnectionLoader::refreshZcashdState(Connection* connection, std::function<
void ConnectionLoader::showInformation(QString info, QString detail) { void ConnectionLoader::showInformation(QString info, QString detail) {
static int rescanCount = 0; static int rescanCount = 0;
if (detail.toLower().startsWith("rescan")) { if (detail.toLower().startsWith("rescan")) {
qDebug() << "showInformation detail = " +detail.toLower();
rescanCount++; rescanCount++;
} }
if (rescanCount > 10) { if (rescanCount > 10) {
detail = detail + "\n" + QObject::tr("This may take several hours, grab some popcorn"); detail = detail + "\n" + QObject::tr("This may take several hours, grab some popcorn");
} }
@ -544,43 +611,80 @@ void ConnectionLoader::showInformation(QString info, QString detail) {
} }
/** /**
* Show error will close the loading dialog and show an error. * Show error will close the loading dialog and show an error.
*/ */
void ConnectionLoader::showError(QString explanation) { void ConnectionLoader::showError(QString explanation) {
rpc->setEZcashd(nullptr); rpc->setEHushd(nullptr);
rpc->noConnection(); rpc->noConnection();
QMessageBox::critical(main, QObject::tr("Connection Error"), explanation, QMessageBox::Ok); QMessageBox::critical(main, QObject::tr("Connection Error"), explanation, QMessageBox::Ok);
d->close(); d->close();
} }
QString ConnectionLoader::locateZcashConfFile() { QString ConnectionLoader::locateHushConfFile() {
// HSC's have no legacy locations
if (isdragonx) {
auto acname = "DRAGONX";
#ifdef Q_OS_LINUX
auto confLocation = QStandardPaths::locate(QStandardPaths::HomeLocation, QString(".hush/") + acname + "/" + acname + ".conf");
#elif defined(Q_OS_DARWIN)
auto confLocation = QStandardPaths::locate(QStandardPaths::HomeLocation, QString("Library/Application Support/Hush/") + acname + "/" + acname + ".conf");
#else
auto confLocation = QStandardPaths::locate(QStandardPaths::AppDataLocation, QString("../../Hush/") + acname + "/" + acname + ".conf");
#endif
qDebug() << "found conf at " << confLocation;
return QDir::cleanPath(confLocation);
}
#ifdef Q_OS_LINUX #ifdef Q_OS_LINUX
auto confLocation = QStandardPaths::locate(QStandardPaths::HomeLocation, ".komodo/HUSH3/HUSH3.conf"); auto confLocation = QStandardPaths::locate(QStandardPaths::HomeLocation, ".hush/HUSH3/HUSH3.conf");
if(!QFile(confLocation).exists()) {
// legacy location
confLocation = QStandardPaths::locate(QStandardPaths::HomeLocation, ".komodo/HUSH3/HUSH3.conf");
}
#elif defined(Q_OS_DARWIN) #elif defined(Q_OS_DARWIN)
auto confLocation = QStandardPaths::locate(QStandardPaths::HomeLocation, "Library/Application Support/Komodo/HUSH3/HUSH3.conf"); auto confLocation = QStandardPaths::locate(QStandardPaths::HomeLocation, "Library/Application Support/Hush/HUSH3/HUSH3.conf");
if(!QFile(confLocation).exists()) {
// legacy location
confLocation = QStandardPaths::locate(QStandardPaths::HomeLocation, "Library/Application Support/Komodo/HUSH3/HUSH3.conf");
}
#else #else
auto confLocation = QStandardPaths::locate(QStandardPaths::AppDataLocation, "../../Komodo/HUSH3/HUSH3.conf"); auto confLocation = QStandardPaths::locate(QStandardPaths::AppDataLocation, "../../Hush/HUSH3/HUSH3.conf");
if(!QFile(confLocation).exists()) {
// legacy location
confLocation = QStandardPaths::locate(QStandardPaths::AppDataLocation, "../../Komodo/HUSH3/HUSH3.conf");
}
#endif #endif
main->logger->write("Found HUSH3.conf at " + QDir::cleanPath(confLocation)); main->logger->write("Found HUSH3.conf at " + QDir::cleanPath(confLocation));
return QDir::cleanPath(confLocation); return QDir::cleanPath(confLocation);
} }
QString ConnectionLoader::zcashConfWritableLocation() { // this function is only used for new config files and does not need to know about legacy locations
QString ConnectionLoader::hushConfWritableLocation() {
#ifdef Q_OS_LINUX #ifdef Q_OS_LINUX
auto confLocation = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)).filePath(".komodo/HUSH3/HUSH3.conf"); auto confLocation = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)).filePath(".hush/HUSH3/HUSH3.conf");
if(isdragonx) {
confLocation = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)).filePath(".hush/DRAGONX/DRAGONX.conf");
}
#elif defined(Q_OS_DARWIN) #elif defined(Q_OS_DARWIN)
auto confLocation = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)).filePath("Library/Application Support/Komodo/HUSH3/HUSH3.conf"); auto confLocation = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)).filePath("Library/Application Support/Hush/HUSH3/HUSH3.conf");
if(isdragonx) {
confLocation = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)).filePath("Library/Application Support/Hush/DRAGONX/DRAGONX.conf");
}
#else #else
auto confLocation = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("../../Komodo/HUSH3/HUSH3.conf"); auto confLocation = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("../../Hush/HUSH3/HUSH3.conf");
if(isdragonx) {
confLocation = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("../../Hush/DRAGONX/DRAGONX.conf");
}
#endif #endif
main->logger->write("Found HUSH3.conf at " + QDir::cleanPath(confLocation)); main->logger->write("HUSH3.conf writeable location at " + QDir::cleanPath(confLocation));
return QDir::cleanPath(confLocation); return QDir::cleanPath(confLocation);
} }
QString ConnectionLoader::zcashParamsDir() { QString ConnectionLoader::zkParamsDir() {
#ifdef Q_OS_LINUX #ifdef Q_OS_LINUX
//TODO: If /usr/share/hush exists, use that. It should not be assumed writeable //TODO: If /usr/share/hush exists, use that. It should not be assumed writeable
auto paramsLocation = QDir(QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)).filePath(".zcash-params")); auto paramsLocation = QDir(QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)).filePath(".zcash-params"));
@ -604,7 +708,7 @@ QString ConnectionLoader::zcashParamsDir() {
} }
bool ConnectionLoader::verifyParams() { bool ConnectionLoader::verifyParams() {
QDir paramsDir(zcashParamsDir()); QDir paramsDir(zkParamsDir());
// TODO: better error reporting if only 1 file exists or is missing // TODO: better error reporting if only 1 file exists or is missing
qDebug() << "Verifying sapling param files exist"; qDebug() << "Verifying sapling param files exist";
@ -626,7 +730,7 @@ bool ConnectionLoader::verifyParams() {
return true; return true;
} }
// this is to support SD on mac in /Applications1 // this is to support SD on mac in /Applications
if( QFile( QDir("/Applications").filePath("silentdragon.app/Contents/MacOS/sapling-output.params") ).exists() && QFile( QDir("/Applications").filePath("./silentdragon.app/Contents/MacOS/sapling-spend.params") ).exists() ) { if( QFile( QDir("/Applications").filePath("silentdragon.app/Contents/MacOS/sapling-output.params") ).exists() && QFile( QDir("/Applications").filePath("./silentdragon.app/Contents/MacOS/sapling-spend.params") ).exists() ) {
qDebug() << "Found params in /Applications/silentdragon.app/Contents/MacOS"; qDebug() << "Found params in /Applications/silentdragon.app/Contents/MacOS";
return true; return true;
@ -638,6 +742,18 @@ bool ConnectionLoader::verifyParams() {
return true; return true;
} }
// this is to support SDX on mac in /Applications
if( QFile( QDir("/Applications").filePath("silentdragonx.app/Contents/MacOS/sapling-output.params") ).exists() && QFile( QDir("/Applications").filePath("./silentdragonx.app/Contents/MacOS/sapling-spend.params") ).exists() ) {
qDebug() << "Found params in /Applications/silentdragonx.app/Contents/MacOS";
return true;
}
// this is to support SDX on mac inside a DMG
if( QFile( QDir("./").filePath("silentdragonx.app/Contents/MacOS/sapling-output.params") ).exists() && QFile( QDir("./").filePath("./silentdragonx.app/Contents/MacOS/sapling-spend.params") ).exists() ) {
qDebug() << "Found params in ./silentdragonx.app/Contents/MacOS";
return true;
}
if (QFile(paramsDir.filePath("sapling-output.params")).exists() && QFile(paramsDir.filePath("sapling-spend.params")).exists()) { if (QFile(paramsDir.filePath("sapling-output.params")).exists() && QFile(paramsDir.filePath("sapling-spend.params")).exists()) {
qDebug() << "Found params in " << paramsDir; qDebug() << "Found params in " << paramsDir;
return true; return true;
@ -648,13 +764,14 @@ bool ConnectionLoader::verifyParams() {
} }
/** /**
* Try to automatically detect a HUSH3/HUSH3.conf file in the correct location and load parameters * Try to automatically detect a HUSH3/HUSH3.conf file
*/ or DRAGONX/DRAGONX.conf in the correct location and load parameters
std::shared_ptr<ConnectionConfig> ConnectionLoader::autoDetectZcashConf() { */
auto confLocation = locateZcashConfFile(); std::shared_ptr<ConnectionConfig> ConnectionLoader::autoDetectHushConf() {
auto confLocation = locateHushConfFile();
if (confLocation.isNull()) { if (confLocation.isNull()) {
// No Zcash file, just return with nothing // No file, just return with nothing
return nullptr; return nullptr;
} }
@ -666,14 +783,14 @@ std::shared_ptr<ConnectionConfig> ConnectionLoader::autoDetectZcashConf() {
QTextStream in(&file); QTextStream in(&file);
auto zcashconf = new ConnectionConfig(); auto hushconf = new ConnectionConfig();
zcashconf->host = "127.0.0.1"; hushconf->host = "127.0.0.1";
zcashconf->connType = ConnectionType::DetectedConfExternalZcashD; hushconf->connType = ConnectionType::DetectedConfExternalHushD;
zcashconf->usingZcashConf = true; hushconf->usingHushConf = true;
zcashconf->zcashDir = QFileInfo(confLocation).absoluteDir().absolutePath(); hushconf->hushDir = QFileInfo(confLocation).absoluteDir().absolutePath();
zcashconf->zcashDaemon = false; hushconf->hushDaemon = false;
Settings::getInstance()->setUsingZcashConf(confLocation); Settings::getInstance()->setUsingHushConf(confLocation);
while (!in.atEnd()) { while (!in.atEnd()) {
QString line = in.readLine(); QString line = in.readLine();
@ -682,73 +799,82 @@ std::shared_ptr<ConnectionConfig> ConnectionLoader::autoDetectZcashConf() {
QString value = line.right(line.length() - s - 1).trimmed(); QString value = line.right(line.length() - s - 1).trimmed();
if (name == "rpcuser") { if (name == "rpcuser") {
zcashconf->rpcuser = value; hushconf->rpcuser = value;
} }
if (name == "rpcpassword") { if (name == "rpcpassword") {
zcashconf->rpcpassword = value; hushconf->rpcpassword = value;
} }
if (name == "rpcport") { if (name == "rpcport") {
zcashconf->port = value; hushconf->port = value;
} }
if (name == "daemon" && value == "1") { if (name == "daemon" && value == "1") {
zcashconf->zcashDaemon = true; hushconf->hushDaemon = true;
} }
if (name == "proxy") { if (name == "proxy") {
zcashconf->proxy = value; hushconf->proxy = value;
} }
if (name == "consolidation") { if (name == "consolidation") {
zcashconf->consolidation = value; hushconf->consolidation = value;
} }
if (name == "deletetx") { if (name == "deletetx") {
zcashconf->deletetx = value; hushconf->deletetx = value;
} }
if (name == "zindex") { if (name == "zindex") {
zcashconf->zindex = value; hushconf->zindex = value;
} }
if (name == "testnet" && if (name == "testnet" &&
value == "1" && value == "1" &&
zcashconf->port.isEmpty()) { hushconf->port.isEmpty()) {
zcashconf->port = "18232"; hushconf->port = "18232";
} }
} }
// If rpcport is not in the file, and it was not set by the testnet=1 flag, then go to default // If rpcport is not in the file, and it was not set by the testnet=1 flag, then go to default
if (zcashconf->port.isEmpty()) zcashconf->port = "18031"; if (hushconf->port.isEmpty()) {
if(isdragonx) {
hushconf->port = "21769";
} else {
hushconf->port = "18031";
}
}
file.close(); file.close();
// In addition to the HUSH3/HUSH3.conf file, also double check the params. // Save to Qsettings
Settings::getInstance()->saveSettings(
hushconf->host,
hushconf->port,
hushconf->rpcuser,
hushconf->rpcpassword);
// In addition to the HUSH3/HUSH3.conf file, also double check the params.
return std::shared_ptr<ConnectionConfig>(zcashconf); return std::shared_ptr<ConnectionConfig>(hushconf);
} }
/** // Load connection settings from the UI, which indicates an unknown, external hushd
* Load connection settings from the UI, which indicates an unknown, external zcashd
*/
std::shared_ptr<ConnectionConfig> ConnectionLoader::loadFromSettings() { std::shared_ptr<ConnectionConfig> ConnectionLoader::loadFromSettings() {
// Load from the QT Settings. qDebug() << __func__ <<": Load data from the QT Settings";
QSettings s; QSettings s;
auto host = s.value("connection/host").toString(); auto host = s.value("connection/host").toString();
auto port = s.value("connection/port").toString(); auto port = s.value("connection/port").toString();
auto username = s.value("connection/rpcuser").toString(); auto username = s.value("connection/rpcuser").toString();
auto password = s.value("connection/rpcpassword").toString(); auto password = s.value("connection/rpcpassword").toString();
if (username.isEmpty() || password.isEmpty()) if (username.isEmpty() || password.isEmpty()) {
qDebug() << __func__ <<": username or password empty, returning null!";
return nullptr; return nullptr;
}
auto uiConfig = new ConnectionConfig{ host, port, username, password, false, false,"","", "", "","", ConnectionType::UISettingsZCashD}; auto uiConfig = new ConnectionConfig{ host, port, username, password, false, false,"","", "", "","", ConnectionType::UISettingsZCashD};
return std::shared_ptr<ConnectionConfig>(uiConfig); return std::shared_ptr<ConnectionConfig>(uiConfig);
} }
/*********************************************************************************** /***********************************************************************************
* Connection Class * Connection Class
************************************************************************************/ ************************************************************************************/
Connection::Connection(MainWindow* m, QNetworkAccessManager* c, QNetworkRequest* r, Connection::Connection(MainWindow* m, QNetworkAccessManager* c, QNetworkRequest* r,
std::shared_ptr<ConnectionConfig> conf) { std::shared_ptr<ConnectionConfig> conf) {
this->restclient = c; this->restclient = c;
this->request = r; this->request = r;
@ -764,11 +890,26 @@ Connection::~Connection() {
void Connection::doRPC(const QJsonValue& payload, const std::function<void(QJsonValue)>& cb, void Connection::doRPC(const QJsonValue& payload, const std::function<void(QJsonValue)>& cb,
const std::function<void(QNetworkReply*, const QJsonValue&)>& ne) { const std::function<void(QNetworkReply*, const QJsonValue&)>& ne) {
if (shutdownInProgress) { if (shutdownInProgress) {
// Ignoring RPC because shutdown in progress DEBUG("Ignoring RPC because shutdown in progress");
return; return;
} }
qDebug() << "RPC:" << payload["method"].toString() << payload; if(payload.isNull() || payload.isUndefined()) {
DEBUG("no payload! ignoring");
return;
} else {
// this will match importprivkey z_importkey z_importviewingkey importwallet z_importwallet
// and some other RPCs that have no GUI
// So this code ends up redacting payloads which contain private keys and filenames which contain private keys
QRegExp re("import");
//DEBUG("payload.toString==" << payload["method"].toString());
//DEBUG("payload.toString.indexIn==" << re.indexIn(payload["method"].toString()) );
if( re.indexIn(payload["method"].toString()) == -1 ) {
DEBUG( payload["method"].toString() << payload );
} else {
DEBUG( payload["method"].toString() << " PAYLOAD REDACTED " );
}
}
QJsonDocument jd_rpc_call(payload.toObject()); QJsonDocument jd_rpc_call(payload.toObject());
QByteArray ba_rpc_call = jd_rpc_call.toJson(); QByteArray ba_rpc_call = jd_rpc_call.toJson();
@ -778,10 +919,10 @@ void Connection::doRPC(const QJsonValue& payload, const std::function<void(QJson
QObject::connect(reply, &QNetworkReply::finished, [=] { QObject::connect(reply, &QNetworkReply::finished, [=] {
reply->deleteLater(); reply->deleteLater();
if (shutdownInProgress) { if (shutdownInProgress) {
// Ignoring callback because shutdown in progress DEBUG("Ignoring callback because shutdown in progress");
return; return;
} }
QJsonDocument jd_reply = QJsonDocument::fromJson(reply->readAll()); QJsonDocument jd_reply = QJsonDocument::fromJson(reply->readAll());
QJsonValue parsed; QJsonValue parsed;
@ -793,21 +934,23 @@ void Connection::doRPC(const QJsonValue& payload, const std::function<void(QJson
if (reply->error() != QNetworkReply::NoError) { if (reply->error() != QNetworkReply::NoError) {
ne(reply, parsed); ne(reply, parsed);
return; return;
} }
if (parsed.isNull()) { if (parsed.isNull()) {
ne(reply, "Unknown error"); ne(reply, "Unknown error");
} }
cb(parsed["result"]); cb(parsed["result"]);
}); });
} }
void Connection::doRPCWithDefaultErrorHandling(const QJsonValue& payload, const std::function<void(QJsonValue)>& cb) { void Connection::doRPCWithDefaultErrorHandling(const QJsonValue& payload, const std::function<void(QJsonValue)>& cb) {
doRPC(payload, cb, [=] (QNetworkReply* reply, const QJsonValue &parsed) { doRPC(payload, cb, [=] (QNetworkReply* reply, const QJsonValue &parsed) {
if (!parsed.isUndefined() && !parsed["error"].toObject()["message"].isNull()) { if (!parsed.isUndefined() && !parsed["error"].toObject()["message"].isNull()) {
DEBUG("got a parse error");
this->showTxError(parsed["error"].toObject()["message"].toString()); this->showTxError(parsed["error"].toObject()["message"].toString());
} else { } else {
DEBUG("got a reply error");
this->showTxError(reply->errorString()); this->showTxError(reply->errorString());
} }
}); });
@ -828,14 +971,14 @@ void Connection::showTxError(const QString& error) {
return; return;
shown = true; shown = true;
QMessageBox::critical(main, QObject::tr("Transaction Error"), QObject::tr("There was an error! : ") + "\n\n" QMessageBox::critical(main, QObject::tr("Error"), QObject::tr("There was an error! : ") + "\n\n"
+ error, QMessageBox::StandardButton::Ok); + error, QMessageBox::StandardButton::Ok);
shown = false; shown = false;
} }
/** /**
* Prevent all future calls from going through * Prevent all future calls from going through
*/ */
void Connection::shutdown() { void Connection::shutdown() {
shutdownInProgress = true; shutdownInProgress = true;
} }

32
src/connection.h

@ -1,3 +1,5 @@
// Copyright 2019-2022 The Hush developers
// Released under the GPLv3
#ifndef CONNECTION_H #ifndef CONNECTION_H
#define CONNECTION_H #define CONNECTION_H
@ -8,9 +10,9 @@
class RPC; class RPC;
enum ConnectionType { enum ConnectionType {
DetectedConfExternalZcashD = 1, DetectedConfExternalHushD = 1,
UISettingsZCashD, UISettingsZCashD,
InternalZcashD InternalHushD
}; };
struct ConnectionConfig { struct ConnectionConfig {
@ -18,9 +20,9 @@ struct ConnectionConfig {
QString port; QString port;
QString rpcuser; QString rpcuser;
QString rpcpassword; QString rpcpassword;
bool usingZcashConf; bool usingHushConf;
bool zcashDaemon; bool hushDaemon;
QString zcashDir; QString hushDir;
QString proxy; QString proxy;
QString consolidation; QString consolidation;
QString deletetx; QString deletetx;
@ -40,32 +42,32 @@ public:
void loadConnection(); void loadConnection();
private: private:
std::shared_ptr<ConnectionConfig> autoDetectZcashConf(); std::shared_ptr<ConnectionConfig> autoDetectHushConf();
std::shared_ptr<ConnectionConfig> loadFromSettings(); std::shared_ptr<ConnectionConfig> loadFromSettings();
Connection* makeConnection(std::shared_ptr<ConnectionConfig> config); Connection* makeConnection(std::shared_ptr<ConnectionConfig> config);
void doAutoConnect(bool tryEzcashdStart = true); void doAutoConnect(bool tryEhushdStart = true);
void doManualConnect(); void doManualConnect();
void createZcashConf(); void createHushConf();
QString locateZcashConfFile(); QString locateHushConfFile();
QString zcashConfWritableLocation(); QString hushConfWritableLocation();
QString zcashParamsDir(); QString zkParamsDir();
bool verifyParams(); bool verifyParams();
void downloadParams(std::function<void(void)> cb); void downloadParams(std::function<void(void)> cb);
void doNextDownload(std::function<void(void)> cb); void doNextDownload(std::function<void(void)> cb);
bool startEmbeddedZcashd(); bool startEmbeddedHushd();
void refreshZcashdState(Connection* connection, std::function<void(void)> refused); void refreshHushdState(Connection* connection, std::function<void(void)> refused);
void showError(QString explanation); void showError(QString explanation);
void showInformation(QString info, QString detail = ""); void showInformation(QString info, QString detail = "");
void doRPCSetConnection(Connection* conn); void doRPCSetConnection(Connection* conn);
std::shared_ptr<QProcess> ezcashd; std::shared_ptr<QProcess> ehushd;
QDialog* d; QDialog* d;
Ui_ConnectionDialog* connD; Ui_ConnectionDialog* connD;
@ -82,7 +84,7 @@ private:
}; };
/** /**
* Represents a connection to a zcashd. It may even start a new zcashd if needed. * Represents a connection to a hushd. It may even start a new hushd if needed.
* This is also a UI class, so it may show a dialog waiting for the connection. * This is also a UI class, so it may show a dialog waiting for the connection.
*/ */
class Connection { class Connection {

32
src/connection.ui

@ -9,10 +9,28 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>513</width> <width>512</width>
<height>513</height> <height>512</height>
</rect> </rect>
</property> </property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>512</width>
<height>512</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>512</width>
<height>512</height>
</size>
</property>
<property name="windowTitle"> <property name="windowTitle">
<string>SilentDragon</string> <string>SilentDragon</string>
</property> </property>
@ -20,6 +38,9 @@
<bool>true</bool> <bool>true</bool>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
<property name="sizeConstraint">
<enum>QLayout::SetFixedSize</enum>
</property>
<property name="leftMargin"> <property name="leftMargin">
<number>0</number> <number>0</number>
</property> </property>
@ -84,13 +105,6 @@
</item> </item>
</layout> </layout>
</widget> </widget>
<customwidgets>
<customwidget>
<class>FilledIconLabel</class>
<extends>QLabel</extends>
<header>fillediconlabel.h</header>
</customwidget>
</customwidgets>
<resources/> <resources/>
<connections/> <connections/>
</ui> </ui>

292
src/createhushconfdialog.ui

@ -0,0 +1,292 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>createHushConf</class>
<widget class="QDialog" name="createHushConf">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>508</width>
<height>369</height>
</rect>
</property>
<property name="windowTitle">
<string>Configuration</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="1">
<widget class="FilledIconLabel" name="lblTopIcon">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="styleSheet">
<string notr="true">background: #fff;</string>
</property>
<property name="text">
<string notr="true"/>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Ok</set>
</property>
<property name="centerButtons">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QPushButton" name="btnAdvancedConfig">
<property name="text">
<string>Show Advanced Configuration</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="2" column="1">
<widget class="QLabel" name="label">
<property name="text">
<string>Your Hush node will be configured for you automatically</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QGroupBox" name="grpAdvanced">
<property name="title">
<string/>
</property>
<widget class="QCheckBox" name="chkCustomDatadir">
<property name="geometry">
<rect>
<x>8</x>
<y>8</y>
<width>148</width>
<height>22</height>
</rect>
</property>
<property name="text">
<string>Use custom datadir</string>
</property>
</widget>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>8</x>
<y>36</y>
<width>395</width>
<height>18</height>
</rect>
</property>
<property name="text">
<string>Please choose a directory to store your wallet.dat and blockchain</string>
</property>
</widget>
<widget class="QLabel" name="label_4">
<property name="geometry">
<rect>
<x>8</x>
<y>102</y>
<width>16</width>
<height>18</height>
</rect>
</property>
<property name="text">
<string notr="true"/>
</property>
</widget>
<widget class="QCheckBox" name="chkUseTor">
<property name="geometry">
<rect>
<x>8</x>
<y>126</y>
<width>133</width>
<height>22</height>
</rect>
</property>
<property name="text">
<string>Connect over Tor</string>
</property>
</widget>
<widget class="QLabel" name="label_5">
<property name="geometry">
<rect>
<x>8</x>
<y>154</y>
<width>415</width>
<height>18</height>
</rect>
</property>
<property name="text">
<string>Please note that you'll need to already have a Tor service configured</string>
</property>
</widget>
<widget class="QLabel" name="label_tor_port">
<property name="geometry">
<rect>
<x>178</x>
<y>178</y>
<width>49</width>
<height>18</height>
</rect>
</property>
<property name="text">
<string>Tor Port</string>
</property>
</widget>
<widget class="QLineEdit" name="torPort">
<property name="geometry">
<rect>
<x>230</x>
<y>178</y>
<width>59</width>
<height>32</height>
</rect>
</property>
<property name="text">
<string notr="true">9050</string>
</property>
</widget>
<widget class="QLineEdit" name="torProxy">
<property name="geometry">
<rect>
<x>62</x>
<y>180</y>
<width>111</width>
<height>32</height>
</rect>
</property>
<property name="text">
<string notr="true">127.0.0.1</string>
</property>
</widget>
<widget class="QLabel" name="label_tor_proxy">
<property name="geometry">
<rect>
<x>10</x>
<y>180</y>
<width>49</width>
<height>18</height>
</rect>
</property>
<property name="text">
<string>Proxy IP</string>
</property>
</widget>
<widget class="QWidget" name="">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="btnPickDir">
<property name="text">
<string>Choose directory</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblDirName">
<property name="text">
<string notr="true"/>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>FilledIconLabel</class>
<extends>QLabel</extends>
<header>fillediconlabel.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>createHushConf</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>createHushConf</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

212
src/createzcashconfdialog.ui

@ -1,212 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>createZcashConf</class>
<widget class="QDialog" name="createZcashConf">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>508</width>
<height>352</height>
</rect>
</property>
<property name="windowTitle">
<string>Configure HUSH3.conf</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="1">
<widget class="FilledIconLabel" name="lblTopIcon">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="styleSheet">
<string notr="true">background: #fff;</string>
</property>
<property name="text">
<string notr="true"/>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Ok</set>
</property>
<property name="centerButtons">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QPushButton" name="btnAdvancedConfig">
<property name="text">
<string>Show Advanced Configuration</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="2" column="1">
<widget class="QLabel" name="label">
<property name="text">
<string>Your Hush node will be configured for you automatically</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QGroupBox" name="grpAdvanced">
<property name="title">
<string/>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QCheckBox" name="chkCustomDatadir">
<property name="text">
<string>Use custom datadir</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Please choose a directory to store your wallet.dat and blockchain</string>
</property>
</widget>
</item>
<item row="2" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="btnPickDir">
<property name="text">
<string>Choose directory</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblDirName">
<property name="text">
<string notr="true"/>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string notr="true"/>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QCheckBox" name="chkUseTor">
<property name="text">
<string>Connect over Tor</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Please note that you'll need to already have a Tor service configured on port 9050</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>FilledIconLabel</class>
<extends>QLabel</extends>
<header>fillediconlabel.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>createZcashConf</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>createZcashConf</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

25
src/fillediconlabel.cpp

@ -1,4 +1,8 @@
// Copyright 2019-2022 The Hush developers
// Released under the GPLv3
#include "fillediconlabel.h" #include "fillediconlabel.h"
#include "settings.h"
#include "guiconstants.h"
FilledIconLabel::FilledIconLabel(QWidget* parent) : FilledIconLabel::FilledIconLabel(QWidget* parent) :
QLabel(parent) { QLabel(parent) {
@ -18,10 +22,27 @@ void FilledIconLabel::resizeEvent(QResizeEvent*) {
QPixmap scaled = basePm.scaled(sz, Qt::KeepAspectRatio, Qt::SmoothTransformation); QPixmap scaled = basePm.scaled(sz, Qt::KeepAspectRatio, Qt::SmoothTransformation);
QString theme_name = Settings::getInstance()->get_theme_name();
QColor color;
if (theme_name == "blue"){
color = COLOR_BLUE_BG;
}else if(theme_name == "light"){
color = COLOR_LIGHT_BG;
}else if(theme_name == "dark"){
color = COLOR_DARK_BG;
}else if(theme_name =="midnight"){
color = COLOR_MIDNIGHT_BG;
}else if(theme_name =="dragonx"){
color = COLOR_DRAGONX_BG;
}else{
color = COLOR_DEFAULT_BG;
}
QPixmap p(sz); QPixmap p(sz);
p.fill(Qt::white); p.fill(color);
QPainter painter(&p); QPainter painter(&p);
painter.drawPixmap((sz.width() - scaled.width()) / 2, (sz.height() - scaled.height()) / 2, scaled); painter.drawPixmap((sz.width() - scaled.width()) / 2, (sz.height() - scaled.height()) / 2, scaled);
QLabel::setPixmap(p); QLabel::setPixmap(p);
} }

4
src/fillediconlabel.h

@ -1,3 +1,5 @@
// Copyright 2019-2022 The Hush developers
// Released under the GPLv3
#ifndef FILLEDICONLABEL_H #ifndef FILLEDICONLABEL_H
#define FILLEDICONLABEL_H #define FILLEDICONLABEL_H
@ -18,4 +20,4 @@ private:
}; };
#endif // FILLEDICONLABEL_H #endif // FILLEDICONLABEL_H

85
src/getblock.ui

@ -0,0 +1,85 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>GetBlock</class>
<widget class="QDialog" name="GetBlock">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Get Block Info</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="1">
<widget class="QLabel" name="lblHeight">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Block Height:</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QTableView" name="tblProps">
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Close</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>GetBlock</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>GetBlock</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

20
src/guiconstants.h

@ -0,0 +1,20 @@
// Copyright 2019-2022 The Hush developers
// Released under the GPLv3
#ifndef GUICONSTANTS_H
#define GUICONSTANTS_H
// Generic colors
#define COLOR_BLACK QColor(0, 0, 0)
#define COLOR_WHITE QColor(255, 255, 255)
#define COLOR_UNCONFIRMED_TX QColor(255, 0, 0)
#define COLOR_DRAGONX_TEXT QColor(145, 164, 184)
// Theme background colors
#define COLOR_DEFAULT_BG QColor(229, 229, 229)
#define COLOR_BLUE_BG QColor(229, 229, 229)
#define COLOR_LIGHT_BG QColor(218, 218, 218)
#define COLOR_DARK_BG QColor(48, 51, 53)
#define COLOR_MIDNIGHT_BG QColor(17, 17, 17)
#define COLOR_DRAGONX_BG QColor(35, 40, 52)
#endif // GUICONSTANTS_H

4
src/logger.cpp

@ -1,3 +1,5 @@
// Copyright 2019-2022 The Hush developers
// Released under the GPLv3
#include "logger.h" #include "logger.h"
Logger::Logger(QObject *parent, QString fileName) : QObject(parent) { Logger::Logger(QObject *parent, QString fileName) : QObject(parent) {
@ -28,4 +30,4 @@ void Logger::write(const QString &value) {
Logger::~Logger() { Logger::~Logger() {
if (file != 0) if (file != 0)
file->close(); file->close();
} }

4
src/logger.h

@ -1,3 +1,5 @@
// Copyright 2019-2022 The Hush developers
// Released under the GPLv3
#ifndef LOGGER_H #ifndef LOGGER_H
#define LOGGER_H #define LOGGER_H
@ -20,4 +22,4 @@ public slots:
void write(const QString &value); void write(const QString &value);
}; };
#endif // LOGGER_H #endif // LOGGER_H

41
src/main.cpp

@ -1,13 +1,14 @@
// Copyright 2019-2020 The Hush developers // Copyright 2019-2022 The Hush developers
// GPLv3 // Released under the GPLv3
#include <singleapplication.h> #include <singleapplication.h>
#include "precompiled.h" #include "precompiled.h"
#include "mainwindow.h" #include "mainwindow.h"
#include "rpc.h" #include "rpc.h"
#include "settings.h" #include "settings.h"
#include "version.h" #include "version.h"
#include <QCommandLineParser>
bool isdragonx = 0;
class SignalHandler class SignalHandler
{ {
@ -142,6 +143,16 @@ public:
~Application() {} ~Application() {}
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
fprintf(stderr,"%s: argv0 = %s\n", __func__, argv[0]);
QString binaryName(argv[0]);
binaryName = binaryName.toLower();
QStringList pathParts = binaryName.split(QLatin1Char('/'));
qDebug() << pathParts;
isdragonx = binaryName.endsWith("dragonx") || binaryName.endsWith("dragonx.exe") || binaryName.endsWith("dragonx.app");
qDebug() << "isdragonx=" << isdragonx;
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
@ -175,22 +186,26 @@ public:
} }
QCoreApplication::setOrganizationName("Hush"); QCoreApplication::setOrganizationName("Hush");
QCoreApplication::setApplicationName("SilentDragon"); QCoreApplication::setApplicationName(isdragonx ? "SilentDragonX" : "SilentDragon");
QString locale = QLocale::system().name(); QString locale = QLocale::system().name();
locale.truncate(locale.lastIndexOf('_')); // Get the language code locale.truncate(locale.lastIndexOf('_')); // Get the language code
qDebug() << "Loading locale " << locale; qDebug() << "Loading locale " << locale;
QTranslator translator; QTranslator translator;
translator.load(QString(":/translations/res/silentdragon_") + locale); if(isdragonx) {
translator.load(QString(":/translations/silentdragon_") + locale);
} else {
translator.load(QString(":/translations/silentdragon_") + locale);
}
a.installTranslator(&translator); a.installTranslator(&translator);
QIcon icon(":/icons/res/icon.ico"); QIcon icon(":/icons/icon.ico");
QApplication::setWindowIcon(icon); QApplication::setWindowIcon(icon);
// TODO: update for SD // TODO: update for SD
#ifdef Q_OS_LINUX #ifdef Q_OS_LINUX
QFontDatabase::addApplicationFont(":/fonts/res/Ubuntu-R.ttf"); QFontDatabase::addApplicationFont(":/fonts/Ubuntu-R.ttf");
qApp->setFont(QFont("Ubuntu", 11, QFont::Normal, false)); qApp->setFont(QFont("Ubuntu", 11, QFont::Normal, false));
#endif #endif
@ -220,11 +235,15 @@ public:
} }
w = new MainWindow(); w = new MainWindow();
w->setWindowTitle("SilentDragon v" + QString(APP_VERSION)); if(isdragonx) {
w->setWindowTitle("SilentDragonX v" + QString(APP_VERSION));
} else {
w->setWindowTitle("SilentDragon v" + QString(APP_VERSION));
}
// If there was a payment URI on the command line, pay it // If there was a payment URI on the command line, pay it
if (parser.positionalArguments().length() > 0) { if (parser.positionalArguments().length() > 0) {
w->payZcashURI(parser.positionalArguments()[0]); w->payHushURI(parser.positionalArguments()[0]);
} }
// Listen for any secondary instances telling us about a Hush payment URI // Listen for any secondary instances telling us about a Hush payment URI
@ -232,7 +251,7 @@ public:
QString uri(msg); QString uri(msg);
// We need to execute this async, otherwise the app seems to crash for some reason. // We need to execute this async, otherwise the app seems to crash for some reason.
QTimer::singleShot(1, [=]() { w->payZcashURI(uri); }); QTimer::singleShot(1, [=]() { w->payHushURI(uri); });
}); });
// For MacOS, we have an event filter // For MacOS, we have an event filter

1675
src/mainwindow.cpp

File diff suppressed because it is too large

56
src/mainwindow.h

@ -1,14 +1,16 @@
// Copyright 2019-2022 The Hush developers
// Released under the GPLv3
#ifndef MAINWINDOW_H #ifndef MAINWINDOW_H
#define MAINWINDOW_H #define MAINWINDOW_H
#include "precompiled.h" #include "precompiled.h"
#include "logger.h" #include "logger.h"
#include <memory>
#include "ui_settings.h"
// Forward declare to break circular dependency. // Forward declare to break circular dependency.
class RPC; class RPC;
class Settings; class Settings;
class WSServer;
class WormholeClient;
// Struct used to hold destination info when sending a Tx. // Struct used to hold destination info when sending a Tx.
struct ToFields { struct ToFields {
@ -46,44 +48,58 @@ public:
QString doSendTxValidations(Tx tx); QString doSendTxValidations(Tx tx);
void setDefaultPayFrom(); void setDefaultPayFrom();
void replaceWormholeClient(WormholeClient* newClient);
bool isWebsocketListening();
void createWebsocket(QString wormholecode);
void stopWebsocket();
void balancesReady(); void balancesReady();
void payZcashURI(QString uri = "", QString myAddr = ""); void payHushURI(QString uri = "", QString myAddr = "");
void validateAddress(); void validateAddress();
void getBlock();
void viewTransaction();
void viewTxid(QString txid = "");
void updateLabels(); void updateLabels();
void updateTAddrCombo(bool checked); void updateTAddrCombo(bool checked);
void updateFromCombo(); void updateFromCombo();
Ui::MainWindow* ui; Ui::MainWindow* ui;
Ui_Settings settings;
QLabel* statusLabel; QLabel* statusLabel;
QLabel* statusIcon; QLabel* statusIcon;
QLabel* loadingLabel; QLabel* loadingLabel;
QWidget* zcashdtab;
Logger* logger; Logger* logger;
void doClose(); void doClose();
// loads a language by the given language shortcode (e.g. de, en)
void loadLanguage(QString& rLanguage);
protected:
// this event is called, when a new translator is loaded or the system language is changed
void changeEvent(QEvent* event);
protected slots:
// this slot is called by the language menu actions
void slotLanguageChanged(QString lang);
private: private:
void closeEvent(QCloseEvent* event); void closeEvent(QCloseEvent* event);
QString readDebugLines(uint32_t lines = 50);
void setupSendTab(); void setupSendTab();
void setupPeersTab();
void setupTransactionsTab(); void setupTransactionsTab();
void setupReceiveTab(); void setupReceiveTab();
void setupBalancesTab(); void setupBalancesTab();
void setupHushTab(); void setupHushTab();
void setupChatTab(); void setupChatTab();
void setupMarketTab(); void setupMarketTab();
void setupMiningTab();
void setupDebugLogTab();
void slot_change_theme(const QString& themeName); void slot_change_theme(QString& themeName);
void slot_change_currency(const QString& currencyName); void slot_change_currency(const QString& currencyName);
void setupTurnstileDialog(); void setupTurnstileDialog();
void setupSettingsModal(); void setupSettingsModal();
void setupStatusBar(); void setupStatusBar();
@ -93,9 +109,6 @@ private:
Tx createTxFromSendPage(); Tx createTxFromSendPage();
bool confirmTx(Tx tx); bool confirmTx(Tx tx);
void turnstileDoMigration(QString fromAddr = "");
void turnstileProgress();
void cancelButton(); void cancelButton();
void sendButton(); void sendButton();
void inputComboTextChanged(int index); void inputComboTextChanged(int index);
@ -113,37 +126,44 @@ private:
void memoButtonClicked(int number, bool includeReplyTo = false); void memoButtonClicked(int number, bool includeReplyTo = false);
void fileUploadButtonClicked(int number); void fileUploadButtonClicked(int number);
void setMemoEnabled(int number, bool enabled); void setMemoEnabled(int number, bool enabled);
void rescanButtonClicked(int number);
void donate(); void donate();
void website(); void website();
void discord(); void telegram();
void reportbug(); void reportbug();
void addressBook(); void addressBook();
void postToZBoard();
void importPrivKey(); void importPrivKey();
void exportAllKeys(); void exportAllKeys();
void exportKeys(QString addr = ""); void exportKeys(QString addr = "");
void getViewKey(QString addr = ""); void getViewKey(QString addr = "");
void getQRCode(QString addr = "");
void backupWalletDat(); void backupWalletDat();
void exportTransactions(); void exportTransactions();
void doImport(QList<QString>* keys); void doImport(QList<QString>* keys);
void restoreSavedStates(); void restoreSavedStates();
void retranslateMiningTab();
bool eventFilter(QObject *object, QEvent *event); bool eventFilter(QObject *object, QEvent *event);
bool uiPaymentsReady = false; bool uiPaymentsReady = false;
QString pendingURIPayment; QString pendingURIPayment;
WSServer* wsserver = nullptr;
WormholeClient* wormhole = nullptr;
RPC* rpc = nullptr; RPC* rpc = nullptr;
QCompleter* labelCompleter = nullptr; QCompleter* labelCompleter = nullptr;
QRegExpValidator* amtValidator = nullptr; QRegExpValidator* amtValidator = nullptr;
QRegExpValidator* feesValidator = nullptr; QRegExpValidator* feesValidator = nullptr;
QMovie* loadingMovie; QMovie* loadingMovie;
// creates the language menu dynamically from the content of m_langPath
void createLanguageMenu(void);
QTranslator m_translator; // contains the translations for this application
QTranslator m_translatorQt; // contains the translations for qt
QString m_currLang; // contains the currently loaded language
QString m_langPath; // Path of language files
}; };
#endif // MAINWINDOW_H #endif // MAINWINDOW_H

811
src/mainwindow.ui

File diff suppressed because it is too large

4
src/memoedit.cpp

@ -1,3 +1,5 @@
// Copyright 2019-2022 The Hush developers
// Released under the GPLv3
#include "memoedit.h" #include "memoedit.h"
MemoEdit::MemoEdit(QWidget* parent) : QPlainTextEdit(parent) { MemoEdit::MemoEdit(QWidget* parent) : QPlainTextEdit(parent) {
@ -49,4 +51,4 @@ void MemoEdit::includeReplyTo(QString addr) {
return; return;
this->setPlainText(curText + "\n" + tr("Reply to") + ":\n" + addr); this->setPlainText(curText + "\n" + tr("Reply to") + ":\n" + addr);
} }

10
src/memoedit.h

@ -1,10 +1,14 @@
// Copyright 2019-2022 The Hush developers
// Released under the GPLv3
#ifndef MEMOEDIT_H #ifndef MEMOEDIT_H
#define MEMOEDIT_H #define MEMOEDIT_H
#include "precompiled.h" #include "precompiled.h"
class MemoEdit : public QPlainTextEdit class MemoEdit : public QPlainTextEdit {
{
Q_OBJECT
public: public:
MemoEdit(QWidget* parent); MemoEdit(QWidget* parent);
@ -20,4 +24,4 @@ private:
QPushButton* acceptButton = nullptr; QPushButton* acceptButton = nullptr;
}; };
#endif // MEMOEDIT_H #endif // MEMOEDIT_H

14
src/mobileappconnector.cpp

@ -1,14 +0,0 @@
#include "mobileappconnector.h"
#include "ui_mobileappconnector.h"
MobileAppConnector::MobileAppConnector(QWidget *parent) :
QDialog(parent),
ui(new Ui::MobileAppConnector)
{
ui->setupUi(this);
}
MobileAppConnector::~MobileAppConnector()
{
delete ui;
}

22
src/mobileappconnector.h

@ -1,22 +0,0 @@
#ifndef MOBILEAPPCONNECTOR_H
#define MOBILEAPPCONNECTOR_H
#include <QDialog>
namespace Ui {
class MobileAppConnector;
}
class MobileAppConnector : public QDialog
{
Q_OBJECT
public:
explicit MobileAppConnector(QWidget *parent = nullptr);
~MobileAppConnector();
private:
Ui::MobileAppConnector *ui;
};
#endif // MOBILEAPPCONNECTOR_H

214
src/mobileappconnector.ui

@ -1,214 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MobileAppConnector</class>
<widget class="QDialog" name="MobileAppConnector">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>530</height>
</rect>
</property>
<property name="windowTitle">
<string>Connect Mobile App</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="4" column="1" colspan="2">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Close</set>
</property>
</widget>
</item>
<item row="0" column="0" colspan="3">
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Scan this QRCode in SilentDragonAndroid to connect your device</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>QR Code</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Connection String</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLineEdit" name="txtConnStr">
<property name="font">
<font>
<pointsize>9</pointsize>
</font>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QRCodeLabel" name="qrcode">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="styleSheet">
<string notr="true">background-color: #fff</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="chkInternetConn">
<property name="text">
<string>Allow connections over the internet via SilentDragon wormhole</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="2" rowspan="2">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>SilentDragonAndroid</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="5" column="0">
<widget class="QPushButton" name="btnDisconnect">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Disconnect</string>
</property>
</widget>
</item>
<item row="6" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="0">
<widget class="QLabel" name="lblLastSeen">
<property name="text">
<string>TextLabel</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Last seen:</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="lblRemoteName">
<property name="text">
<string notr="true">TextLabel</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Connection type:</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="lblConnectionType">
<property name="text">
<string>TextLabel</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>QRCodeLabel</class>
<extends>QLabel</extends>
<header>qrcodelabel.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>MobileAppConnector</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>MobileAppConnector</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

185
src/peerstablemodel.cpp

@ -0,0 +1,185 @@
// Copyright 2019-2022 The Hush developers
// Released under the GPLv3
#include "peerstablemodel.h"
#include "settings.h"
#include "rpc.h"
#include "guiconstants.h"
PeersTableModel::PeersTableModel(QObject *parent)
: QAbstractTableModel(parent) {
headers << QObject::tr("PeerID") << QObject::tr("Address") << QObject::tr("ASN") << QObject::tr("TLS Cipher") << QObject::tr("TLS Verfied") << QObject::tr("Version") << QObject::tr("Protocol Version") << QObject::tr("Ping Time") << QObject::tr("Banscore") << QObject::tr("Bytes received") << QObject::tr("Bytes sent");
}
PeersTableModel::~PeersTableModel() {
delete modeldata;
}
void PeersTableModel::addData(const QList<PeerItem>& data) {
peers = new QList<PeerItem>();
std::copy(data.begin(), data.end(), std::back_inserter(*peers));
updateAllData();
}
void PeersTableModel::updateAllData() {
auto newmodeldata = new QList<PeerItem>();
// Copy peer data so GUI can use it
if (peers != nullptr) std::copy( peers->begin(), peers->end(), std::back_inserter(*newmodeldata));
// Sort by connection time
std::sort(newmodeldata->begin(), newmodeldata->end(), [=] (auto a, auto b) {
return a.conntime > b.conntime; // reverse sort
});
// And then swap out the modeldata with the new one.
delete modeldata;
modeldata = newmodeldata;
// do magic
dataChanged(index(0, 0), index(modeldata->size()-1, columnCount(index(0,0))-1));
layoutChanged();
}
int PeersTableModel::rowCount(const QModelIndex&) const
{
if (modeldata == nullptr) return 0;
return modeldata->size();
}
int PeersTableModel::columnCount(const QModelIndex&) const
{
return headers.size();
}
QVariant PeersTableModel::data(const QModelIndex &index, int role) const
{
// Get current theme name
QString theme_name = Settings::getInstance()->get_theme_name();
QBrush b;
if (role == Qt::ForegroundRole) {
// peers with banscore >=50 will likely be banned soon, color them red
if (modeldata->at(index.row()).banscore >= 50) {
b.setColor(COLOR_UNCONFIRMED_TX);
return b;
}
if (theme_name == "dark" || theme_name == "midnight") {
b.setColor(COLOR_WHITE);
return b;
}else if (theme_name == "dragonx"){
b.setColor(COLOR_DRAGONX_TEXT);
return b;
}else{
b.setColor(COLOR_BLACK);
return b;
}
return b;
}
auto dat = modeldata->at(index.row());
if (role == Qt::DisplayRole) {
switch (index.column()) {
case 0: return dat.peerid;
case 1: return dat.address;
case 2: return "AS" + QString::number(dat.asn);
case 3: return dat.tls_cipher;
case 4: return dat.tls_verified;
case 5: return dat.subver;
case 6: return dat.protocolversion;
case 7: return dat.pingtime;
case 8: return dat.banscore;
case 9: return dat.bytes_received;
case 10: return dat.bytes_sent;
}
}
if (role == Qt::ToolTipRole) {
switch (index.column()) {
case 0: return "Unique Peer ID";
case 1: return "Network Address";
case 2: return "Autonomous System Number";
case 3: return "TLS Ciphersuite";
case 4: return "TLS Certificate verified";
case 5: return "Full Node Version";
case 6: return "P2P Protocol Version";
case 7: return "Ping Time (seconds)";
case 8: return "Banscore";
case 9: return "Bytes received";
case 10: return "Bytes sent";
}
}
//TODO: show different icons for IP vs Tor vs other kinds of connections
/*
if (role == Qt::DecorationRole && index.column() == 0) {
if (!dat.memo.isEmpty()) {
// If the memo is a Payment URI, then show a payment request icon
if (dat.memo.startsWith("hush:")) {
QIcon icon(":/icons/paymentreq.gif");
return QVariant(icon.pixmap(16, 16));
} else {
// Return the info pixmap to indicate memo
QIcon icon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxInformation);
return QVariant(icon.pixmap(16, 16));
}
} else {
// Empty pixmap to make it align
QPixmap p(16, 16);
p.fill(Qt::white);
return QVariant(p);
}
}
*/
return QVariant();
}
QVariant PeersTableModel::headerData(int section, Qt::Orientation orientation, int role) const
{
//if (role == Qt::TextAlignmentRole && section == 3) return QVariant(Qt::AlignRight | Qt::AlignVCenter);
if (role == Qt::TextAlignmentRole) return QVariant(Qt::AlignCenter | Qt::AlignVCenter);
if (role == Qt::FontRole) {
QFont f;
f.setBold(true);
return f;
}
if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {
return headers.at(section);
}
return QVariant();
}
QString PeersTableModel::getPeerId(int row) const {
return QString::number(modeldata->at(row).peerid);
}
QString PeersTableModel::getAddress(int row) const {
return modeldata->at(row).address.trimmed();
}
QString PeersTableModel::getTLSCipher(int row) const {
return modeldata->at(row).tls_cipher;
}
qint64 PeersTableModel::getASN(int row) const {
return modeldata->at(row).asn;
}
qint64 PeersTableModel::getConntime(int row) const {
return modeldata->at(row).conntime;
}
QString PeersTableModel::getType(int row) const {
return modeldata->at(row).type;
}
QString PeersTableModel::getPingtime(int row) const {
return Settings::getDecimalString(modeldata->at(row).pingtime);
}

44
src/peerstablemodel.h

@ -0,0 +1,44 @@
// Copyright 2019-2022 The Hush developers
// Released under the GPLv3
#ifndef PEERSTABLEMODEL_H
#define PEERSTABLEMODEL_H
#include "precompiled.h"
struct PeerItem;
class PeersTableModel: public QAbstractTableModel
{
public:
PeersTableModel(QObject* parent);
~PeersTableModel();
QString getPeerId(int row) const;
QString getAddress(int row) const;
QString getType(int row) const;
qint64 getConntime(int row) const;
qint64 getASN(int row) const;
QString getSubver(int row) const;
QString getTLSCipher(int row) const;
bool getTLSVerified(int row) const;
QString getPingtime(int row) const;
unsigned int getBanscore(int row) const;
unsigned int getProtocolVersion(int row) const;
int rowCount(const QModelIndex &parent) const;
int columnCount(const QModelIndex &parent) const;
QVariant data(const QModelIndex &index, int role) const;
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
void addData (const QList<PeerItem>& data);
private:
void updateAllData();
QList<PeerItem>* peers = nullptr;
QList<PeerItem>* modeldata = nullptr;
QList<QString> headers;
};
#endif // PEERSTABLEMODEL_H

3
src/precompiled.h

@ -1,3 +1,5 @@
// Copyright 2019-2022 The Hush developers
// Released under the GPLv3
#if defined __cplusplus #if defined __cplusplus
/* Add C++ includes here */ /* Add C++ includes here */
@ -60,7 +62,6 @@
#include <QtNetwork/QNetworkRequest> #include <QtNetwork/QNetworkRequest>
#include <QtNetwork/QNetworkAccessManager> #include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkReply> #include <QtNetwork/QNetworkReply>
#include <QtWebSockets/QtWebSockets>
#include <QJsonDocument> #include <QJsonDocument>
#include <QJsonArray> #include <QJsonArray>
#include <QJsonObject> #include <QJsonObject>

34
src/privkey.ui

@ -14,7 +14,7 @@
<string>Private Keys</string> <string>Private Keys</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout"> <layout class="QGridLayout" name="gridLayout">
<item row="1" column="0"> <item row="1" column="0" colspan="3">
<widget class="QPlainTextEdit" name="privKeyTxt"> <widget class="QPlainTextEdit" name="privKeyTxt">
<property name="plainText"> <property name="plainText">
<string/> <string/>
@ -22,6 +22,38 @@
</widget> </widget>
</item> </item>
<item row="2" column="0"> <item row="2" column="0">
<widget class="QCheckBox" name="chkrescan">
<property name="text">
<string>Rescan</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="rescanlabel">
<property name="text">
<string>Rescan Height</string>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QLineEdit" name="rescanfrom">
<property name="text">
<string notr="true">1</string>
</property>
<property name="minimumSize">
<size>
<width>50</width>
</size>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QDialogButtonBox" name="buttonBox"> <widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>

90
src/qrcode.ui

@ -0,0 +1,90 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QRCode</class>
<widget class="QDialog" name="QRCode">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>320</width>
<height>344</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>QR Code</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="sizeConstraint">
<enum>QLayout::SetFixedSize</enum>
</property>
<item row="0" column="0" alignment="Qt::AlignTop">
<widget class="QRCodeLabel" name="qrcodeDisplayAddr">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>300</width>
<height>300</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="baseSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignHCenter|Qt::AlignTop</set>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QPushButton" name="saveQRCodeBtn">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Save</string>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>QRCodeLabel</class>
<extends>QLabel</extends>
<header>qrcodelabel.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

12
src/qrcodelabel.cpp

@ -1,3 +1,5 @@
// Copyright 2019-2022 The Hush developers
// Released under the GPLv3
#include "qrcodelabel.h" #include "qrcodelabel.h"
QRCodeLabel::QRCodeLabel(QWidget *parent) : QRCodeLabel::QRCodeLabel(QWidget *parent) :
@ -24,7 +26,7 @@ QPixmap QRCodeLabel::scaledPixmap() const {
pm.fill(Qt::white); pm.fill(Qt::white);
QPainter painter(&pm); QPainter painter(&pm);
qrcodegen::QrCode qr = qrcodegen::QrCode::encodeText(str.toUtf8().constData(), qrcodegen::QrCode::Ecc::LOW); qrcodegen::QrCode qr = qrcodegen::QrCode::encodeText(str.toUtf8().constData(), qrcodegen::QrCode::Ecc::HIGH);
const int s = qr.getSize()>0?qr.getSize():1; const int s = qr.getSize()>0?qr.getSize():1;
const double w = pm.width(); const double w = pm.width();
const double h = pm.height(); const double h = pm.height();
@ -47,11 +49,15 @@ QPixmap QRCodeLabel::scaledPixmap() const {
} }
} }
} }
// TODO: Maybe add logo if it doesn't break QR code - requires setting Ecc to HIGH
painter.drawPixmap((w/2)-50, (h/2)-50, 100, 100, QPixmap(":/img/logobig.gif"));
painter.end();
return pm; return pm;
} }
void QRCodeLabel::setQrcodeString(QString stra) { void QRCodeLabel::setQrcodeString(QString stra) {
str = stra; str = stra;
QLabel::setPixmap(scaledPixmap()); QLabel::setPixmap(scaledPixmap());
} }

2
src/qrcodelabel.h

@ -1,3 +1,5 @@
// Copyright 2019-2022 The Hush developers
// Released under the GPLv3
#ifndef QRCODELABEL_H #ifndef QRCODELABEL_H
#define QRCODELABEL_H #define QRCODELABEL_H

4
src/recurring.cpp

@ -1,3 +1,5 @@
// Copyright 2019-2022 The Hush developers
// Released under the GPLv3
#include "recurring.h" #include "recurring.h"
#include "mainwindow.h" #include "mainwindow.h"
@ -45,4 +47,4 @@ void Recurring::showEditDialog(QWidget* parent, MainWindow* main, Tx tx) {
ui.txtDesc->setFocus(); ui.txtDesc->setFocus();
d.exec(); d.exec();
} }

4
src/recurring.h

@ -1,3 +1,5 @@
// Copyright 2019-2022 The Hush developers
// Released under the GPLv3
#ifndef RECURRING_H #ifndef RECURRING_H
#define RECURRING_H #define RECURRING_H
@ -33,4 +35,4 @@ public:
static void showEditDialog(QWidget* parent, MainWindow* main, Tx tx); static void showEditDialog(QWidget* parent, MainWindow* main, Tx tx);
}; };
#endif // RECURRING_H #endif // RECURRING_H

23
src/requestdialog.cpp

@ -1,3 +1,5 @@
// Copyright 2019-2022 The Hush developers
// Released under the GPLv3
#include "requestdialog.h" #include "requestdialog.h"
#include "ui_requestdialog.h" #include "ui_requestdialog.h"
#include "settings.h" #include "settings.h"
@ -5,8 +7,8 @@
#include "mainwindow.h" #include "mainwindow.h"
#include "rpc.h" #include "rpc.h"
#include "settings.h" #include "settings.h"
#include "precompiled.h" #include "precompiled.h"
extern bool isdragonx;
RequestDialog::RequestDialog(QWidget *parent) : RequestDialog::RequestDialog(QWidget *parent) :
QDialog(parent), QDialog(parent),
@ -39,7 +41,7 @@ void RequestDialog::setupDialog(MainWindow* main, QDialog* d, Ui_RequestDialog*
} }
req->cmbMyAddress->setCurrentText(main->getRPC()->getDefaultSaplingAddress()); req->cmbMyAddress->setCurrentText(main->getRPC()->getDefaultSaplingAddress());
QIcon icon(":/icons/res/paymentreq.gif"); QIcon icon(":/icons/paymentreq.gif");
req->lblPixmap->setPixmap(icon.pixmap(48, 48)); req->lblPixmap->setPixmap(icon.pixmap(48, 48));
} }
@ -47,8 +49,13 @@ void RequestDialog::setupDialog(MainWindow* main, QDialog* d, Ui_RequestDialog*
void RequestDialog::showPaymentConfirmation(MainWindow* main, QString paymentURI) { void RequestDialog::showPaymentConfirmation(MainWindow* main, QString paymentURI) {
PaymentURI payInfo = Settings::parseURI(paymentURI); PaymentURI payInfo = Settings::parseURI(paymentURI);
if (!payInfo.error.isEmpty()) { if (!payInfo.error.isEmpty()) {
QMessageBox::critical(main, tr("Error paying HUSH URI"), if(isdragonx) {
QMessageBox::critical(main, tr("Error paying DRAGONX URI"),
tr("URI should be of the form 'drgx:<addr>?amt=x&memo=y") + "\n" + payInfo.error);
} else {
QMessageBox::critical(main, tr("Error paying HUSH URI"),
tr("URI should be of the form 'hush:<addr>?amt=x&memo=y") + "\n" + payInfo.error); tr("URI should be of the form 'hush:<addr>?amt=x&memo=y") + "\n" + payInfo.error);
}
return; return;
} }
@ -80,7 +87,7 @@ void RequestDialog::showPaymentConfirmation(MainWindow* main, QString paymentURI
req.lblHeader->setText(tr("You are paying a payment request. Your address will not be visible to the person requesting this payment.")); req.lblHeader->setText(tr("You are paying a payment request. Your address will not be visible to the person requesting this payment."));
if (d.exec() == QDialog::Accepted) { if (d.exec() == QDialog::Accepted) {
main->payZcashURI(paymentURI, req.cmbMyAddress->currentText()); main->payHushURI(paymentURI, req.cmbMyAddress->currentText());
} }
} }
@ -123,17 +130,17 @@ void RequestDialog::showRequestZcash(MainWindow* main) {
req.txtFrom->setFocus(); req.txtFrom->setFocus();
if (d.exec() == QDialog::Accepted) { if (d.exec() == QDialog::Accepted) {
// Construct a zcash Payment URI with the data and pay it immediately. // Construct a Hush Payment URI with the data and pay it immediately.
QString memoURI = "hush:" + req.cmbMyAddress->currentText() QString memoURI = (isdragonx ? "drgx:" : "hush:" ) + req.cmbMyAddress->currentText()
+ "?amt=" + Settings::getDecimalString(req.txtAmount->text().toDouble()) + "?amt=" + Settings::getDecimalString(req.txtAmount->text().toDouble())
+ "&memo=" + QUrl::toPercentEncoding(req.txtMemo->toPlainText()); + "&memo=" + QUrl::toPercentEncoding(req.txtMemo->toPlainText());
QString sendURI = "hush:" + AddressBook::addressFromAddressLabel(req.txtFrom->text()) QString sendURI = (isdragonx ? "drgx:" : "hush:" ) + AddressBook::addressFromAddressLabel(req.txtFrom->text())
+ "?amt=0.0001" + "?amt=0.0001"
+ "&memo=" + QUrl::toPercentEncoding(memoURI); + "&memo=" + QUrl::toPercentEncoding(memoURI);
// If the disclosed address in the memo doesn't have a balance, it will automatically fallback to the default // If the disclosed address in the memo doesn't have a balance, it will automatically fallback to the default
// sapling address // sapling address
main->payZcashURI(sendURI, req.cmbMyAddress->currentText()); main->payHushURI(sendURI, req.cmbMyAddress->currentText());
} }
} }

2
src/requestdialog.h

@ -1,3 +1,5 @@
// Copyright 2019-2022 The Hush developers
// Released under the GPLv3
#ifndef REQUESTDIALOG_H #ifndef REQUESTDIALOG_H
#define REQUESTDIALOG_H #define REQUESTDIALOG_H

2
src/requestdialog.ui

@ -216,7 +216,7 @@
<item row="0" column="2" colspan="2"> <item row="0" column="2" colspan="2">
<widget class="QLabel" name="lblHeader"> <widget class="QLabel" name="lblHeader">
<property name="text"> <property name="text">
<string>Request payment from a Sapling address. You'll send a HUSH 0.0001 transaction to the address with a HUSH payment URI. The memo will be included in the transaction when the address pays you.</string> <string>Request payment from a zaddr. You'll send a 0.0001 transaction to the address with a payment URI. The memo will be included in the transaction when the address pays you.</string>
</property> </property>
<property name="wordWrap"> <property name="wordWrap">
<bool>true</bool> <bool>true</bool>

91
src/rescandialog.ui

@ -0,0 +1,91 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>RescanDialog</class>
<widget class="QDialog" name="RescanDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>542</width>
<height>108</height>
</rect>
</property>
<property name="windowTitle">
<string>Rescan</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="3" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="3" column="1" colspan="2">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
<item row="2" column="0" colspan="3">
<widget class="QLineEdit" name="rescanBlockheight"/>
</item>
<item row="0" column="0" colspan="3">
<widget class="QLabel" name="label">
<property name="text">
<string>Enter block height to rescan from:</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>RescanDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>RescanDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

678
src/rpc.cpp

File diff suppressed because it is too large

80
src/rpc.h

@ -1,19 +1,20 @@
// Copyright 2019-2022 The Hush developers
// Released under the GPLv3
#ifndef RPCCLIENT_H #ifndef RPCCLIENT_H
#define RPCCLIENT_H #define RPCCLIENT_H
#include "precompiled.h" #include "precompiled.h"
#include "balancestablemodel.h" #include "balancestablemodel.h"
#include "txtablemodel.h" #include "txtablemodel.h"
#include "peerstablemodel.h"
#include "bannedpeerstablemodel.h"
#include "ui_mainwindow.h" #include "ui_mainwindow.h"
#include "mainwindow.h" #include "mainwindow.h"
#include "connection.h" #include "connection.h"
class Turnstile;
struct TransactionItem { struct TransactionItem {
QString type; QString type;
qint64 datetime; qint64 datetime;
QString address; QString address;
QString txid; QString txid;
double amount; double amount;
@ -22,6 +23,30 @@ struct TransactionItem {
QString memo; QString memo;
}; };
struct BannedPeerItem {
QString address;
QString subnet;
qint64 banned_until;
qint64 asn;
};
struct PeerItem {
qint64 peerid;
QString type;
qint64 conntime;
QString address;
qint64 asn;
QString tls_cipher;
bool tls_verified;
qint64 banscore;
qint64 protocolversion;
QString subver;
qint64 bytes_received;
qint64 bytes_sent;
double pingtime;
};
struct WatchedTx { struct WatchedTx {
QString opid; QString opid;
Tx tx; Tx tx;
@ -36,16 +61,21 @@ public:
~RPC(); ~RPC();
void setConnection(Connection* c); void setConnection(Connection* c);
void setEZcashd(std::shared_ptr<QProcess> p); void setEHushd(std::shared_ptr<QProcess> p);
const QProcess* getEZcashD() { return ezcashd.get(); } const QProcess* getEHushD() { return ehushd.get(); }
void refresh(bool force = false); void refresh(bool force = false);
void pauseTimer();
void restartTimer();
void refreshAddresses(); void refreshAddresses();
void refreshRescan();
void refreshPeers();
void setban(QString ip, QString command, const std::function<void(QJsonValue)>& cb);
void clearBanned(const std::function<void(QJsonValue)>& cb);
void checkForUpdate(bool silent = true); void checkForUpdate(bool silent = true);
void refreshPrice(); void refreshPrice();
void getZboardTopics(std::function<void(QMap<QString, QString>)> cb);
void executeTransaction(Tx tx, void executeTransaction(Tx tx,
const std::function<void(QString opid)> submitted, const std::function<void(QString opid)> submitted,
@ -54,12 +84,15 @@ public:
void fillTxJsonParams(QJsonArray& params, Tx tx); void fillTxJsonParams(QJsonArray& params, Tx tx);
void sendZTransaction(QJsonValue params, const std::function<void(QJsonValue)>& cb, const std::function<void(QString)>& err); void sendZTransaction(QJsonValue params, const std::function<void(QJsonValue)>& cb, const std::function<void(QString)>& err);
void shieldCoinbase(QJsonArray& params, const std::function<void(QJsonValue)>& cb, const std::function<void(QString)>& err);
void mergeToAddress(QJsonArray& params, const std::function<void(QJsonValue)>& cb, const std::function<void(QString)>& err);
void watchTxStatus(); void watchTxStatus();
const QMap<QString, WatchedTx> getWatchingTxns() { return watchingOps; } const QMap<QString, WatchedTx> getWatchingTxns() { return watchingOps; }
void addNewTxToWatch(const QString& newOpid, WatchedTx wtx); void addNewTxToWatch(const QString& newOpid, WatchedTx wtx);
const TxTableModel* getTransactionsModel() { return transactionsTableModel; } const TxTableModel* getTransactionsModel() { return transactionsTableModel; }
const PeersTableModel* getPeersModel() { return peersTableModel; }
const QList<QString>* getAllZAddresses() { return zaddresses; } const QList<QString>* getAllZAddresses() { return zaddresses; }
const QList<QString>* getAllTAddresses() { return taddresses; } const QList<QString>* getAllTAddresses() { return taddresses; }
const QList<UnspentOutput>* getUTXOs() { return utxos; } const QList<UnspentOutput>* getUTXOs() { return utxos; }
@ -68,26 +101,36 @@ public:
void newZaddr(const std::function<void(QJsonValue)>& cb); void newZaddr(const std::function<void(QJsonValue)>& cb);
void newTaddr(const std::function<void(QJsonValue)>& cb); void newTaddr(const std::function<void(QJsonValue)>& cb);
void z_viewtransaction(QString txid, const std::function<void(QJsonValue)>& cb);
void getrawtransaction(QString txid, const std::function<void(QJsonValue)>& cb);
void setGenerate(int proclimit, const std::function<void(QJsonValue)>& cb);
void stopGenerate(int proclimit, const std::function<void(QJsonValue)>& cb);
void getZPrivKey(QString addr, const std::function<void(QJsonValue)>& cb); void getZPrivKey(QString addr, const std::function<void(QJsonValue)>& cb);
void getZViewKey(QString addr, const std::function<void(QJsonValue)>& cb); void getZViewKey(QString addr, const std::function<void(QJsonValue)>& cb);
void getTPrivKey(QString addr, const std::function<void(QJsonValue)>& cb); void getTPrivKey(QString addr, const std::function<void(QJsonValue)>& cb);
void importZPrivKey(QString addr, bool rescan, const std::function<void(QJsonValue)>& cb); void importZPrivKey(QString addr, bool rescan, const std::function<void(QJsonValue)>& cb);
void importTPrivKey(QString addr, bool rescan, const std::function<void(QJsonValue)>& cb); void importTPrivKey(QString addr, bool rescan, const std::function<void(QJsonValue)>& cb);
void validateAddress(QString address, const std::function<void(QJsonValue)>& cb); void validateAddress(QString address, const std::function<void(QJsonValue)>& cb);
void getBlock(QString height, const std::function<void(QJsonValue)>& cb);
void shutdownZcashd(); void shutdownHushd();
void noConnection(); void noConnection();
bool isEmbedded() { return ezcashd != nullptr; } bool isEmbedded() { return ehushd != nullptr; }
QString getDefaultSaplingAddress(); QString getDefaultSaplingAddress();
QString getDefaultTAddress(); QString getDefaultTAddress();
void getAllPrivKeys(const std::function<void(QList<QPair<QString, QString>>)>); void getAllPrivKeys(const std::function<void(QList<QPair<QString, QString>>)>);
Turnstile* getTurnstile() { return turnstile; }
Connection* getConnection() { return conn; } Connection* getConnection() { return conn; }
void rescan(qint64 height, const std::function<void(QJsonValue)>& cb);
void getRescanInfo(const std::function<void(QJsonValue)>& cb);
void help(const std::function<void(QJsonValue)>& cb);
void getnetworksolps(const std::function<void(QJsonValue)>& cb);
void getlocalsolps(const std::function<void(QJsonValue)>& cb);
private: private:
void refreshBalances(); void refreshBalances();
@ -101,18 +144,23 @@ private:
void getInfoThenRefresh(bool force); void getInfoThenRefresh(bool force);
void getBalance(const std::function<void(QJsonValue)>& cb); void getBalance(const std::function<void(QJsonValue)>& cb);
QJsonValue makePayload(QString method, QString params); QJsonValue makePayload(QString method, QString param, QString param2);
QJsonValue makePayload(QString method, QString param);
QJsonValue makePayload(QString method, int param);
QJsonValue makePayload(QString method); QJsonValue makePayload(QString method);
void getTransparentUnspent (const std::function<void(QJsonValue)>& cb); void getTransparentUnspent (const std::function<void(QJsonValue)>& cb);
void getZUnspent (const std::function<void(QJsonValue)>& cb); void getZUnspent (const std::function<void(QJsonValue)>& cb);
void getTransactions (const std::function<void(QJsonValue)>& cb); void getTransactions (const std::function<void(QJsonValue)>& cb);
void listBanned (const std::function<void(QJsonValue)>& cb);
void getPeerInfo (const std::function<void(QJsonValue)>& cb);
void getZAddresses (const std::function<void(QJsonValue)>& cb); void getZAddresses (const std::function<void(QJsonValue)>& cb);
void getTAddresses (const std::function<void(QJsonValue)>& cb); void getTAddresses (const std::function<void(QJsonValue)>& cb);
void z_sweepstatus (const std::function<void(QJsonValue)>& cb);
void z_consolidationstatus (const std::function<void(QJsonValue)>& cb);
Connection* conn = nullptr; Connection* conn = nullptr;
std::shared_ptr<QProcess> ezcashd = nullptr; std::shared_ptr<QProcess> ehushd = nullptr;
QList<UnspentOutput>* utxos = nullptr; QList<UnspentOutput>* utxos = nullptr;
QMap<QString, double>* allBalances = nullptr; QMap<QString, double>* allBalances = nullptr;
QMap<QString, bool>* usedAddresses = nullptr; QMap<QString, bool>* usedAddresses = nullptr;
@ -122,15 +170,17 @@ private:
QMap<QString, WatchedTx> watchingOps; QMap<QString, WatchedTx> watchingOps;
TxTableModel* transactionsTableModel = nullptr; TxTableModel* transactionsTableModel = nullptr;
PeersTableModel* peersTableModel = nullptr;
BannedPeersTableModel* bannedPeersTableModel = nullptr;
BalancesTableModel* balancesTableModel = nullptr; BalancesTableModel* balancesTableModel = nullptr;
QTimer* timer; QTimer* timer;
QTimer* txTimer; QTimer* txTimer;
QTimer* priceTimer; QTimer* priceTimer;
QTimer* rescanTimer;
Ui::MainWindow* ui; Ui::MainWindow* ui;
MainWindow* main; MainWindow* main;
Turnstile* turnstile;
// Current balance in the UI. If this number updates, then refresh the UI // Current balance in the UI. If this number updates, then refresh the UI
QString currentBalance; QString currentBalance;

2
src/scripts/docker/Dockerfile

@ -40,7 +40,7 @@ RUN cd /opt && rm qt-everywhere-src-5.11.2.tar.xz && rm -rf qt-everywhere-src-5.
RUN cd /opt && \ RUN cd /opt && \
git clone https://github.com/mxe/mxe.git && \ git clone https://github.com/mxe/mxe.git && \
cd /opt/mxe && \ cd /opt/mxe && \
make -j$(nproc) MXE_TARGETS=x86_64-w64-mingw32.static qtbase qtwebsockets make -j$(nproc) MXE_TARGETS=x86_64-w64-mingw32.static qtbase
# Add rust # Add rust
RUN apt install -y gcc-aarch64-linux-gnu RUN apt install -y gcc-aarch64-linux-gnu

2
src/scripts/dotranslations.sh

@ -1,5 +1,5 @@
#!/bin/bash #!/bin/bash
# Copyright (c) 2019-2020 The Hush developers # Copyright (c) 2019-2022 The Hush developers
# Released under the GPLv3 # Released under the GPLv3
if [ -z $QT_STATIC ]; then if [ -z $QT_STATIC ]; then

64
src/scripts/dounifiedbuild.ps1

@ -8,11 +8,11 @@ param (
) )
Write-Host "[Initializing]" Write-Host "[Initializing]"
Remove-Item -Force -ErrorAction Ignore ./artifacts/linux-binaries-zecwallet-v$version.tar.gz Remove-Item -Force -ErrorAction Ignore ./artifacts/linux-binaries-silentdragon-v$version.tar.gz
Remove-Item -Force -ErrorAction Ignore ./artifacts/linux-deb-zecwallet-v$version.deb Remove-Item -Force -ErrorAction Ignore ./artifacts/linux-deb-silentdragon-v$version.deb
Remove-Item -Force -ErrorAction Ignore ./artifacts/Windows-binaries-zecwallet-v$version.zip Remove-Item -Force -ErrorAction Ignore ./artifacts/Windows-binaries-silentdragon-v$version.zip
Remove-Item -Force -ErrorAction Ignore ./artifacts/Windows-installer-zecwallet-v$version.msi Remove-Item -Force -ErrorAction Ignore ./artifacts/Windows-installer-silentdragon-v$version.msi
Remove-Item -Force -ErrorAction Ignore ./artifacts/macOS-zecwallet-v$version.dmg Remove-Item -Force -ErrorAction Ignore ./artifacts/macOS-silentdragon-v$version.dmg
Remove-Item -Force -ErrorAction Ignore ./artifacts/signatures-v$version.tar.gz Remove-Item -Force -ErrorAction Ignore ./artifacts/signatures-v$version.tar.gz
@ -28,7 +28,7 @@ Write-Host ""
Write-Host "[Building on Mac]" Write-Host "[Building on Mac]"
bash src/scripts/mkmacdmg.sh --qt_path ~/Qt/5.11.1/clang_64/ --version $version --zcash_path ~/gi/hush3 --certificate "$certificate" bash src/scripts/mkmacdmg.sh --qt_path ~/Qt/5.11.1/clang_64/ --version $version --hush_path ~/gi/hush3 --certificate "$certificate"
if (! $?) { if (! $?) {
Write-Output "[Error]" Write-Output "[Error]"
exit 1; exit 1;
@ -38,26 +38,26 @@ Write-Host ""
Write-Host "[Building Linux + Windows]" Write-Host "[Building Linux + Windows]"
Write-Host -NoNewline "Copying files.........." Write-Host -NoNewline "Copying files.........."
ssh $server "rm -rf /tmp/zqwbuild" ssh $server "rm -rf /tmp/sdbuild"
ssh $server "mkdir /tmp/zqwbuild" ssh $server "mkdir /tmp/sdbuild"
scp -r src/ singleapplication/ res/ ./silentdragon.pro ./application.qrc ./LICENSE ./README.md ${server}:/tmp/zqwbuild/ | Out-Null scp -r src/ singleapplication/ res/ ./silentdragon.pro ./application.qrc ./LICENSE ./README.md ${server}:/tmp/sdbuild/ | Out-Null
ssh $server "dos2unix -q /tmp/zqwbuild/src/scripts/mkrelease.sh" | Out-Null ssh $server "dos2unix -q /tmp/sdbuild/src/scripts/mkrelease.sh" | Out-Null
ssh $server "dos2unix -q /tmp/zqwbuild/src/version.h" ssh $server "dos2unix -q /tmp/sdbuild/src/version.h"
Write-Host "[OK]" Write-Host "[OK]"
ssh $server "cd /tmp/zqwbuild && APP_VERSION=$version PREV_VERSION=$prev bash src/scripts/mkrelease.sh" ssh $server "cd /tmp/sdbuild && APP_VERSION=$version PREV_VERSION=$prev bash src/scripts/mkrelease.sh"
if (!$?) { if (!$?) {
Write-Output "[Error]" Write-Output "[Error]"
exit 1; exit 1;
} }
New-Item artifacts -itemtype directory -Force | Out-Null New-Item artifacts -itemtype directory -Force | Out-Null
scp ${server}:/tmp/zqwbuild/artifacts/* artifacts/ | Out-Null scp ${server}:/tmp/sdbuild/artifacts/* artifacts/ | Out-Null
scp -r ${server}:/tmp/zqwbuild/release . | Out-Null scp -r ${server}:/tmp/sdbuild/release . | Out-Null
Write-Host -NoNewline "Building Installer....." Write-Host -NoNewline "Building Installer....."
ssh $winserver "Remove-Item -Path zqwbuild -Recurse" | Out-Null ssh $winserver "Remove-Item -Path sdbuild -Recurse" | Out-Null
ssh $winserver "New-Item zqwbuild -itemtype directory" | Out-Null ssh $winserver "New-Item sdbuild -itemtype directory" | Out-Null
# Note: For some mysterious reason, we can't seem to do a scp from here to windows machine. # Note: For some mysterious reason, we can't seem to do a scp from here to windows machine.
# So, we'll ssh to windows, and execute an scp command to pull files from here to there. # So, we'll ssh to windows, and execute an scp command to pull files from here to there.
@ -65,33 +65,33 @@ ssh $winserver "New-Item zqwbuild -itemtype directory" | Out-Null
# so we ssh to windows, and then scp push the file to here. # so we ssh to windows, and then scp push the file to here.
$myhostname = (hostname) | Out-String -NoNewline $myhostname = (hostname) | Out-String -NoNewline
# Powershell seems not to be able to remove this directory for some reason! # Powershell seems not to be able to remove this directory for some reason!
# Remove-Item -Path /tmp/zqwbuild -Recurse -ErrorAction Ignore | Out-Null # Remove-Item -Path /tmp/sdbuild -Recurse -ErrorAction Ignore | Out-Null
bash "rm -rf /tmp/zqwbuild" 2>&1 | Out-Null bash "rm -rf /tmp/sdbuild" 2>&1 | Out-Null
New-Item -Path /tmp/zqwbuild -itemtype directory -Force | Out-Null New-Item -Path /tmp/sdbuild -itemtype directory -Force | Out-Null
Copy-Item src /tmp/zqwbuild/ -Recurse -Force Copy-Item src /tmp/sdbuild/ -Recurse -Force
Copy-Item res /tmp/zqwbuild/ -Recurse -Force Copy-Item res /tmp/sdbuild/ -Recurse -Force
Copy-Item release /tmp/zqwbuild/ -Recurse -Force Copy-Item release /tmp/sdbuild/ -Recurse -Force
# Remove some unnecessary stuff from the tmp directory to speed up copying # Remove some unnecessary stuff from the tmp directory to speed up copying
Remove-Item -Recurse -ErrorAction Ignore /tmp/zqwbuild/res/libsodium Remove-Item -Recurse -ErrorAction Ignore /tmp/sdbuild/res/libsodium
ssh $winserver "scp -r ${myhostname}:/tmp/zqwbuild/* zqwbuild/" ssh $winserver "scp -r ${myhostname}:/tmp/sdbuild/* sdbuild/"
ssh $winserver "cd zqwbuild ; src/scripts/mkwininstaller.ps1 -version $version" >/dev/null ssh $winserver "cd sdbuild ; src/scripts/mkwininstaller.ps1 -version $version" >/dev/null
if (!$?) { if (!$?) {
Write-Output "[Error]" Write-Output "[Error]"
exit 1; exit 1;
} }
ssh $winserver "scp zqwbuild/artifacts/* ${myhostname}:/tmp/zqwbuild/" ssh $winserver "scp sdbuild/artifacts/* ${myhostname}:/tmp/sdbuild/"
Copy-Item /tmp/zqwbuild/*.msi artifacts/ Copy-Item /tmp/sdbuild/*.msi artifacts/
Write-Host "[OK]" Write-Host "[OK]"
# Finally, test to make sure all files exist # Finally, test to make sure all files exist
Write-Host -NoNewline "Checking Build........." Write-Host -NoNewline "Checking Build........."
if (! (Test-Path ./artifacts/linux-binaries-zecwallet-v$version.tar.gz) -or if (! (Test-Path ./artifacts/linux-binaries-silentdragon-v$version.tar.gz) -or
! (Test-Path ./artifacts/linux-deb-zecwallet-v$version.deb) -or ! (Test-Path ./artifacts/linux-deb-silentdragon-v$version.deb) -or
! (Test-Path ./artifacts/Windows-binaries-zecwallet-v$version.zip) -or ! (Test-Path ./artifacts/Windows-binaries-silentdragon-v$version.zip) -or
! (Test-Path ./artifacts/macOS-zecwallet-v$version.dmg) -or ! (Test-Path ./artifacts/macOS-silentdragon-v$version.dmg) -or
! (Test-Path ./artifacts/Windows-installer-zecwallet-v$version.msi) ) { ! (Test-Path ./artifacts/Windows-installer-silentdragon-v$version.msi) ) {
Write-Host "[Error]" Write-Host "[Error]"
exit 1; exit 1;
} }

11
src/scripts/make-binary-tarball.sh

@ -1,5 +1,5 @@
#!/bin/bash #!/bin/bash
# Copyright (c) 2020 The Hush developers # Copyright (c) 2019-2022 The Hush developers
# Released under the GPLv3 # Released under the GPLv3
APP_VERSION=$(cat src/version.h | cut -d\" -f2) APP_VERSION=$(cat src/version.h | cut -d\" -f2)
@ -18,14 +18,11 @@ if [ -e $DIR ]; then
fi fi
mkdir -p $DIR mkdir -p $DIR
strip silentdragon strip silentdragon
strip komodod strip hushd
strip komodo-tx strip hush-tx
strip komodo-cli strip hush-cli
cp silentdragon $DIR cp silentdragon $DIR
cp komodod $DIR
cp komodo-cli $DIR
cp komodo-tx $DIR
cp hushd $DIR cp hushd $DIR
cp hush-cli $DIR cp hush-cli $DIR
cp hush-tx $DIR cp hush-tx $DIR

102
src/scripts/make-deb.sh

@ -1,12 +1,12 @@
#!/bin/bash #!/bin/bash
# Copyright (c) 2019-2020 The Hush developers # Copyright (c) 2019-2022 The Hush developers
# Thanks to Zecwallet for the original code # Thanks to Zecwallet for the original code
# Released under the GPLv3 # Released under the GPLv3
DEBLOG=deb.log.$$ DEBLOG=deb.log.$$
if [ -z $QT_STATIC ]; then if [ -z $QT_STATIC ]; then
echo "QT_STATIC is not set. Please set it to the base directory of a statically compiled Qt"; echo "QT_STATIC is not set; to set it use -static for QT configuration. Please set it to the base directory of a statically compiled Qt";
exit 1; exit 1;
fi fi
@ -15,26 +15,31 @@ if [ -z $APP_VERSION ]; then echo "APP_VERSION is not set"; exit 1; fi
#if [ -z $PREV_VERSION ]; then echo "PREV_VERSION is not set"; exit 1; fi #if [ -z $PREV_VERSION ]; then echo "PREV_VERSION is not set"; exit 1; fi
if [ -z $HUSH_DIR ]; then if [ -z $HUSH_DIR ]; then
echo "HUSH_DIR is not set. Please set it to the base directory of hush3.git" echo "HUSH_DIR is not set. Please set it to the src directory of hush3.git"
exit 1; exit 1;
fi fi
if [ ! -f $HUSH_DIR/komodod ]; then if [ ! -f $HUSH_DIR/hushd ]; then
echo "Couldn't find komodod in $HUSH_DIR . Please build komodod." echo "Couldn't find hushd in $HUSH_DIR . Please build hushd."
exit 1; exit 1;
fi fi
if [ ! -f $HUSH_DIR/komodo-cli ]; then if [ ! -f $HUSH_DIR/hush-cli ]; then
echo "Couldn't find komodo-cli in $HUSH_DIR . Please build komodo-cli." echo "Couldn't find hush-cli in $HUSH_DIR . Please build hush-cli."
exit 1; exit 1;
fi fi
if [ ! -f $HUSH_DIR/komodo-tx ]; then if [ ! -f $HUSH_DIR/hush-tx ]; then
echo "Couldn't find komodo-tx in $HUSH_DIR . Please build komodo-tx." echo "Couldn't find hush-tx in $HUSH_DIR . Please build hush-tx."
exit 1; exit 1;
fi fi
echo -n "Cleaning..............." if [ ! -f $HUSH_DIR/hush-smart-chain ]; then
echo "Couldn't find hush-smart-chain in $HUSH_DIR . Please build hush-smart-chain."
exit 1;
fi
echo "Cleaning..............."
rm -rf bin/* rm -rf bin/*
rm -rf artifacts/* rm -rf artifacts/*
make distclean >/dev/null 2>&1 make distclean >/dev/null 2>&1
@ -43,7 +48,7 @@ echo "[OK]"
echo "" echo ""
echo "[Building $APP_VERSION on" `lsb_release -r`" logging to $DEBLOG ]" echo "[Building $APP_VERSION on" `lsb_release -r`" logging to $DEBLOG ]"
echo -n "Translations............" echo "Translations............"
QT_STATIC=$QT_STATIC bash src/scripts/dotranslations.sh >/dev/null QT_STATIC=$QT_STATIC bash src/scripts/dotranslations.sh >/dev/null
echo -n "Configuring............" echo -n "Configuring............"
$QT_STATIC/bin/qmake silentdragon.pro -spec linux-clang CONFIG+=release > /dev/null $QT_STATIC/bin/qmake silentdragon.pro -spec linux-clang CONFIG+=release > /dev/null
@ -58,7 +63,7 @@ echo "[OK]"
# Test for Qt # Test for Qt
echo -n "Static link............" echo "Static link............"
if [[ $(ldd silentdragon | grep -i "Qt") ]]; then if [[ $(ldd silentdragon | grep -i "Qt") ]]; then
echo "FOUND QT; ABORT"; echo "FOUND QT; ABORT";
exit 1 exit 1
@ -66,37 +71,39 @@ fi
echo "[OK]" echo "[OK]"
echo -n "Packaging.............." echo "Packaging.............."
APP=SilentDragon-v$APP_VERSION APP=SilentDragon-v$APP_VERSION
DIR=bin/$APP DIR=bin/$APP
mkdir $DIR > /dev/null mkdir $DIR > /dev/null
strip silentdragon
cp silentdragon $DIR > /dev/null #Organizing all bins & essentials to centralized folder for tar.gz
cp $HUSH_DIR/artifacts/komodod $DIR > /dev/null echo "Organizing binaries & essentials.............."
cp $HUSH_DIR/artifacts/komodo-cli $DIR > /dev/null cp silentdragon $DIR > /dev/null
cp $HUSH_DIR/artifacts/komodo-tx $DIR > /dev/null cp README.md $DIR > /dev/null
cp $HUSH_DIR/artifacts/hushd $DIR > /dev/null cp LICENSE $DIR > /dev/null
cp $HUSH_DIR/artifacts/hush-cli $DIR > /dev/null
cp $HUSH_DIR/artifacts/hush-tx $DIR > /dev/null
cp README.md $DIR > /dev/null
cp LICENSE $DIR > /dev/null
cd bin && tar czf $APP.tar.gz $DIR/ > /dev/null echo "Stripping silentdragon.............."
cd .. cd $DIR
strip silentdragon
cd ../..
mkdir artifacts >/dev/null 2>&1 echo "Compressing files.............."
cp $DIR.tar.gz ./artifacts/$APP-linux.tar.gz cd bin/
echo "[OK]" tar -czf $APP.tar.gz ./$APP > /dev/null
echo "Copy compressed file.............."
mkdir artifacts >/dev/null 2>&1
cp $APP.tar.gz ./artifacts/$APP-linux.tar.gz
echo -n "[OK]"
echo "Verify Compressed File.............."
if [ -f artifacts/$APP-linux.tar.gz ] ; then if [ -f artifacts/$APP-linux.tar.gz ] ; then
echo -n "Package contents......." echo -n "Package contents......."
# Test if the package is built OK # Test if the package is built OK
if tar tf "artifacts/$APP-linux.tar.gz" | wc -l | grep -q "9"; then if tar -tf "artifacts/$APP-linux.tar.gz" | wc -l | grep -q "4"; then
echo "[OK]" echo "[OK]"
else else
echo "[ERROR] Wrong number of files does not match 9" echo "[ERROR] Wrong number of files does not match 11"
exit 1 exit 1
fi fi
else else
@ -104,26 +111,37 @@ else
exit 1 exit 1
fi fi
echo -n "Building deb..........." echo "Building package..........."
debdir=bin/deb/silentdragon-v$APP_VERSION debdir=deb/silentdragon-v$APP_VERSION
mkdir -p $debdir > /dev/null mkdir -p $debdir > /dev/null
mkdir $debdir/DEBIAN mkdir $debdir/DEBIAN
mkdir -p $debdir/usr/local/bin mkdir -p $debdir/usr/local/bin
cat src/scripts/control | sed "s/RELEASE_VERSION/$APP_VERSION/g" > $debdir/DEBIAN/control mkdir -p $debdir/usr/lib
mkdir -p $debdir/usr/share/pixmaps/
cat ../src/scripts/control | sed "s/RELEASE_VERSION/$APP_VERSION/g" > $debdir/DEBIAN/control
cp silentdragon $debdir/usr/local/bin/ echo "Copying silentdragon bin..........."
# TODO: how does this interact with hushd deb ? cp ../silentdragon $debdir/usr/local/bin/
cp $HUSH_DIR/artifacts/komodod $debdir/usr/local/bin/hush-komodod
mkdir -p $debdir/usr/share/pixmaps/ echo "Copying core libraries from silentdragon binary..........."
cp res/silentdragon.xpm $debdir/usr/share/pixmaps/ # copy the required shared libs to the target folder
# create directories if required
for lib in `ldd $debdir/usr/local/bin/silentdragon | cut -d'>' -f2 | awk '{print $1}'` ; do
if [ -f "$lib" ] ; then
cp -v "$lib" $debdir/usr/lib/
fi
done
echo "Copying SilentDragon icon..........."
cp ../res/silentdragon.xpm $debdir/usr/share/pixmaps/
mkdir -p $debdir/usr/share/applications mkdir -p $debdir/usr/share/applications
cp src/scripts/desktopentry $debdir/usr/share/applications/silentdragon.desktop cp ../src/scripts/desktopentry $debdir/usr/share/applications/silentdragon.desktop
dpkg-deb --build $debdir >/dev/null dpkg-deb --build --root-owner-group $debdir >/dev/null
cp $debdir.deb artifacts/$DIR.deb
echo "[OK]" echo "[Success! $APP .deb has been created in $APP/bin/deb]"
exit 0 exit 0

2
src/scripts/make-only-deb.sh

@ -1,5 +1,5 @@
#!/bin/bash #!/bin/bash
# Copyright (c) 2020 The Hush developers # Copyright (c) 2019-2022 The Hush developers
# Released under the GPLv3 # Released under the GPLv3
echo "Let There Be Debian Packages" echo "Let There Be Debian Packages"

4
src/scripts/mkmacdmg.sh

@ -1,4 +1,6 @@
#!/bin/bash #!/bin/bash
# Copyright (c) 2019-2022 The Hush developers
# Released under the GPLv3
# Accept the variables as command line arguments as well # Accept the variables as command line arguments as well
POSITIONAL=() POSITIONAL=()
@ -112,8 +114,6 @@ rm -f artifcats/silentdragon.dmg >/dev/null 2>&1
rm -f artifacts/rw* >/dev/null 2>&1 rm -f artifacts/rw* >/dev/null 2>&1
cp $HUSH_DIR/src/hushd silentdragon.app/Contents/MacOS/ cp $HUSH_DIR/src/hushd silentdragon.app/Contents/MacOS/
cp $HUSH_DIR/src/hush-cli silentdragon.app/Contents/MacOS/ cp $HUSH_DIR/src/hush-cli silentdragon.app/Contents/MacOS/
cp $HUSH_DIR/src/komodod silentdragon.app/Contents/MacOS/
cp $HUSH_DIR/src/komodo-cli silentdragon.app/Contents/MacOS/
cp $HUSH_DIR/sapling-output.params silentdragon.app/Contents/MacOS/ cp $HUSH_DIR/sapling-output.params silentdragon.app/Contents/MacOS/
cp $HUSH_DIR/sapling-spend.params silentdragon.app/Contents/MacOS/ cp $HUSH_DIR/sapling-spend.params silentdragon.app/Contents/MacOS/
$QT_PATH/bin/macdeployqt silentdragon.app $QT_PATH/bin/macdeployqt silentdragon.app

48
src/scripts/mkrelease.sh

@ -1,5 +1,5 @@
#!/bin/bash #!/bin/bash
# Copyright (c) 2019-2020 The Hush developers # Copyright (c) 2019-2022 The Hush developers
# Thanks to Zecwallet for the original code # Thanks to Zecwallet for the original code
# Released under the GPLv3 # Released under the GPLv3
@ -21,18 +21,18 @@ if [ -z $HUSH_DIR ]; then
exit 1; exit 1;
fi fi
if [ ! -f $HUSH_DIR/komodod ]; then if [ ! -f $HUSH_DIR/hushd ]; then
echo "Couldn't find komodod in $HUSH_DIR . Please build komodod." echo "Couldn't find hushd in $HUSH_DIR . Please build hushd."
exit 1; exit 1;
fi fi
if [ ! -f $HUSH_DIR/komodo-cli ]; then if [ ! -f $HUSH_DIR/hush-cli ]; then
echo "Couldn't find komodo-cli in $HUSH_DIR . Please build komodo-cli." echo "Couldn't find hush-cli in $HUSH_DIR . Please build hush-cli."
exit 1; exit 1;
fi fi
if [ ! -f $HUSH_DIR/komodo-tx ]; then if [ ! -f $HUSH_DIR/hush-tx ]; then
echo "Couldn't find komodo-tx in $HUSH_DIR . Please build komodo-tx." echo "Couldn't find hush-tx in $HUSH_DIR . Please build hush-tx."
exit 1; exit 1;
fi fi
@ -80,8 +80,8 @@ RELEASEFILE2=$RELEASEDIR-$OS-$ARCH.tar.gz
# this is equal to the number of files we package plus 1, for the directory # this is equal to the number of files we package plus 1, for the directory
# that is created # that is created
NUM_FILES1=10 NUM_FILES1=6
NUM_FILES2=12 # 2 additional param files NUM_FILES2=8 # 2 additional param files
echo "Packaging.............." echo "Packaging.............."
mkdir bin/$RELEASEDIR mkdir bin/$RELEASEDIR
@ -92,18 +92,18 @@ strip silentdragon
ls -la silentdragon ls -la silentdragon
cp silentdragon bin/$RELEASEDIR > /dev/null cp silentdragon bin/$RELEASEDIR > /dev/null
cp $HUSH_DIR/komodod bin/$RELEASEDIR > /dev/null strip $HUSH_DIR/hushd
cp $HUSH_DIR/komodo-cli bin/$RELEASEDIR > /dev/null
cp $HUSH_DIR/komodo-tx bin/$RELEASEDIR > /dev/null
cp $HUSH_DIR/hushd bin/$RELEASEDIR > /dev/null cp $HUSH_DIR/hushd bin/$RELEASEDIR > /dev/null
strip $HUSH_DIR/hush-cli
cp $HUSH_DIR/hush-cli bin/$RELEASEDIR > /dev/null cp $HUSH_DIR/hush-cli bin/$RELEASEDIR > /dev/null
cp $HUSH_DIR/hush-tx bin/$RELEASEDIR > /dev/null # I have yet to hear of somebody using this binary, it just bloats our archives
#cp $HUSH_DIR/hush-tx bin/$RELEASEDIR > /dev/null
cp README.md bin/$RELEASEDIR > /dev/null cp README.md bin/$RELEASEDIR > /dev/null
cp LICENSE bin/$RELEASEDIR > /dev/null cp LICENSE bin/$RELEASEDIR > /dev/null
cd bin && tar czf $RELEASEFILE1 $RELEASEDIR/ #> /dev/null cd bin && tar czf $RELEASEFILE1 $RELEASEDIR/ #> /dev/null
#ls -la $RELEASEDIR/ ls -la $RELEASEDIR/
echo "Created $RELEASEFILE1 [OK]" echo "Created $RELEASEFILE1 [OK]"
cd .. cd ..
@ -121,7 +121,7 @@ else
fi fi
cd bin && tar czf $RELEASEFILE2 $RELEASEDIR/ cd bin && tar czf $RELEASEFILE2 $RELEASEDIR/
#ls -la $RELEASEDIR/ ls -la $RELEASEDIR/
echo "Created $RELEASEFILE2 [OK]" echo "Created $RELEASEFILE2 [OK]"
cd .. cd ..
@ -157,6 +157,8 @@ else
fi fi
cd bin cd bin
du -sh $RELEASEFILE1
du -sh $RELEASEFILE2
echo "DONE! Checksums:" echo "DONE! Checksums:"
sha256sum $RELEASEFILE1 sha256sum $RELEASEFILE1
sha256sum $RELEASEFILE2 sha256sum $RELEASEFILE2
@ -177,7 +179,7 @@ cat src/scripts/control | sed "s/RELEASE_VERSION/$APP_VERSION/g" > $debdir/DEBIA
cp silentdragon $debdir/usr/local/bin/ cp silentdragon $debdir/usr/local/bin/
# TODO: how does this interact with hushd deb ? # TODO: how does this interact with hushd deb ?
cp $HUSH_DIR/artifacts/komodod $debdir/usr/local/bin/hush-komodod cp $HUSH_DIR/artifacts/hushd $debdir/usr/local/bin/hushd
mkdir -p $debdir/usr/share/pixmaps/ mkdir -p $debdir/usr/share/pixmaps/
cp res/silentdragon.xpm $debdir/usr/share/pixmaps/ cp res/silentdragon.xpm $debdir/usr/share/pixmaps/
@ -202,14 +204,14 @@ if [ -z $MXE_PATH ]; then
exit 0; exit 0;
fi fi
if [ ! -f $HUSH_DIR/artifacts/komodod.exe ]; then if [ ! -f $HUSH_DIR/artifacts/hushd.exe ]; then
echo "Couldn't find komodod.exe in $HUSH_DIR/artifacts/. Please build komodod.exe" echo "Couldn't find hushd.exe in $HUSH_DIR/artifacts/. Please build hushd.exe"
exit 1; exit 1;
fi fi
if [ ! -f $HUSH_DIR/artifacts/komodo-cli.exe ]; then if [ ! -f $HUSH_DIR/artifacts/hush-cli.exe ]; then
echo "Couldn't find komodo-cli.exe in $HUSH_DIR/artifacts/. Please build komodod-cli.exe" echo "Couldn't find hush-cli.exe in $HUSH_DIR/artifacts/. Please build hushd-cli.exe"
exit 1; exit 1;
fi fi
@ -234,10 +236,8 @@ echo "[OK]"
echo -n "Packaging.............." echo -n "Packaging.............."
mkdir release/silentdragon-v$APP_VERSION mkdir release/silentdragon-v$APP_VERSION
cp release/silentdragon.exe release/silentdragon-v$APP_VERSION cp release/silentdragon.exe release/silentdragon-v$APP_VERSION
cp $HUSH_DIR/artifacts/komodod.exe release/silentdragon-v$APP_VERSION > /dev/null cp $HUSH_DIR/artifacts/hushd.exe release/silentdragon-v$APP_VERSION > /dev/null
cp $HUSH_DIR/artifacts/komodo-cli.exe release/silentdragon-v$APP_VERSION > /dev/null cp $HUSH_DIR/artifacts/hush-cli.exe release/silentdragon-v$APP_VERSION > /dev/null
cp $HUSH_DIR/artifacts/hushd.bat release/silentdragon-v$APP_VERSION > /dev/null
cp $HUSH_DIR/artifacts/hush-cli.bat release/silentdragon-v$APP_VERSION > /dev/null
cp README.md release/silentdragon-v$APP_VERSION cp README.md release/silentdragon-v$APP_VERSION
cp LICENSE release/silentdragon-v$APP_VERSION cp LICENSE release/silentdragon-v$APP_VERSION
cd release && zip -r Windows-binaries-silentdragon-v$APP_VERSION.zip silentdragon-v$APP_VERSION/ > /dev/null cd release && zip -r Windows-binaries-silentdragon-v$APP_VERSION.zip silentdragon-v$APP_VERSION/ > /dev/null

16
src/scripts/mkwininstaller.ps1

@ -2,28 +2,28 @@ param (
[Parameter(Mandatory=$true)][string]$version [Parameter(Mandatory=$true)][string]$version
) )
$target="zecwallet-v$version" $target="silentdragon-v$version"
Remove-Item -Path release/wininstaller -Recurse -ErrorAction Ignore | Out-Null Remove-Item -Path release/wininstaller -Recurse -ErrorAction Ignore | Out-Null
New-Item release/wininstaller -itemtype directory | Out-Null New-Item release/wininstaller -itemtype directory | Out-Null
Copy-Item release/$target/zecwallet.exe release/wininstaller/ Copy-Item release/$target/silentdragon.exe release/wininstaller/
Copy-Item release/$target/LICENSE release/wininstaller/ Copy-Item release/$target/LICENSE release/wininstaller/
Copy-Item release/$target/README.md release/wininstaller/ Copy-Item release/$target/README.md release/wininstaller/
Copy-Item release/$target/zcashd.exe release/wininstaller/ Copy-Item release/$target/hushd.exe release/wininstaller/
Copy-Item release/$target/zcash-cli.exe release/wininstaller/ Copy-Item release/$target/hush-cli.exe release/wininstaller/
Get-Content src/scripts/zec-qt-wallet.wxs | ForEach-Object { $_ -replace "RELEASE_VERSION", "$version" } | Out-File -Encoding utf8 release/wininstaller/zec-qt-wallet.wxs Get-Content src/scripts/silentdragon.wxs | ForEach-Object { $_ -replace "RELEASE_VERSION", "$version" } | Out-File -Encoding utf8 release/wininstaller/silentdragon.wxs
candle.exe release/wininstaller/zec-qt-wallet.wxs -o release/wininstaller/zec-qt-wallet.wixobj candle.exe release/wininstaller/silentdragon.wxs -o release/wininstaller/silentdragon.wixobj
if (!$?) { if (!$?) {
exit 1; exit 1;
} }
light.exe -ext WixUIExtension -cultures:en-us release/wininstaller/zec-qt-wallet.wixobj -out release/wininstaller/zecwallet.msi light.exe -ext WixUIExtension -cultures:en-us release/wininstaller/silentdragon.wixobj -out release/wininstaller/silentdragon.msi
if (!$?) { if (!$?) {
exit 1; exit 1;
} }
New-Item artifacts -itemtype directory -Force | Out-Null New-Item artifacts -itemtype directory -Force | Out-Null
Copy-Item release/wininstaller/zecwallet.msi ./artifacts/Windows-installer-$target.msi Copy-Item release/wininstaller/silentdragon.msi ./artifacts/Windows-installer-$target.msi

2
src/scripts/signbinaries.sh

@ -1,4 +1,6 @@
#!/bin/bash #!/bin/bash
# Copyright (c) 2019-2022 The Hush developers
# Released under the GPLv3
# Accept the variables as command line arguments as well # Accept the variables as command line arguments as well
POSITIONAL=() POSITIONAL=()

10
src/scripts/zec-qt-wallet.wxs → src/scripts/silentdragon.wxs

@ -6,8 +6,8 @@
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." /> <MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate EmbedCab="yes"/> <MediaTemplate EmbedCab="yes"/>
<Icon Id="zecqtwalleticon.exe" SourceFile="res/icon.ico"/> <Icon Id="silentdragonicon.exe" SourceFile="res/icon.ico"/>
<Property Id="ARPPRODUCTICON" Value="zecqtwalleticon.exe" /> <Property Id="ARPPRODUCTICON" Value="silentdragonicon.exe" />
<Feature Id="ProductFeature" Title="silent-dragon" Level="1"> <Feature Id="ProductFeature" Title="silent-dragon" Level="1">
<ComponentGroupRef Id="ProductComponents" /> <ComponentGroupRef Id="ProductComponents" />
@ -57,12 +57,12 @@
<Component Id="ProductComponent" Guid="0D210F5A-53E0-4E7E-CAAD-15A26995505E"> <Component Id="ProductComponent" Guid="0D210F5A-53E0-4E7E-CAAD-15A26995505E">
<File Source="silentdragon.exe" KeyPath="yes"> <File Source="silentdragon.exe" KeyPath="yes">
<Shortcut Id="startMenuShotcut" Advertise="yes" Directory="ApplicationProgramsFolder" <Shortcut Id="startMenuShotcut" Advertise="yes" Directory="ApplicationProgramsFolder"
Name="silentdragon" WorkingDirectory="INSTALLFOLDER" Icon="zecqtwalleticon.exe" > Name="silentdragon" WorkingDirectory="INSTALLFOLDER" Icon="silentdragonicon.exe" >
</Shortcut> </Shortcut>
</File> </File>
<File Source="LICENSE" /> <File Source="LICENSE" />
<File Source="komodod.exe" /> <File Source="hushd.exe" />
<File Source="komodo-cli.exe" /> <File Source="hush-cli.exe" />
<File Source="README.md" /> <File Source="README.md" />
<RegistryKey Root="HKCR" Key="hush"> <RegistryKey Root="HKCR" Key="hush">

5
src/sd.h

@ -0,0 +1,5 @@
// Copyright 2019-2023 The Hush Developers
// Released under the GPLv3
#define DEBUG(x) (qDebug() << QString(__func__) << ": " << x)

97
src/sendtab.cpp

@ -1,4 +1,5 @@
// Copyright 2019-2020 Hush developers // Copyright 2019-2022 The Hush developers
// Released under the GPLv3
#include "mainwindow.h" #include "mainwindow.h"
#include "ui_mainwindow.h" #include "ui_mainwindow.h"
#include "addressbook.h" #include "addressbook.h"
@ -13,7 +14,7 @@
void MainWindow::setupSendTab() { void MainWindow::setupSendTab() {
// Create the validator for send to/amount fields // Create the validator for send to/amount fields
amtValidator = new QRegExpValidator(QRegExp("[0-9]{0,8}\\.?[0-9]{0,8}")); amtValidator = new QRegExpValidator(QRegExp("[0-9]{0,9}\\.?[0-9]{0,8}"));
ui->Amount1->setValidator(amtValidator); ui->Amount1->setValidator(amtValidator);
@ -250,51 +251,69 @@ void MainWindow::addAddressSection() {
Amount1->setPlaceholderText(tr("Amount")); Amount1->setPlaceholderText(tr("Amount"));
Amount1->setObjectName(QString("Amount") % QString::number(itemNumber)); Amount1->setObjectName(QString("Amount") % QString::number(itemNumber));
Amount1->setBaseSize(QSize(200, 0)); Amount1->setBaseSize(QSize(200, 0));
Amount1->setAlignment(Qt::AlignRight); Amount1->setMinimumWidth(200);
Amount1->setSizePolicy(QSizePolicy ::Preferred , QSizePolicy ::Preferred );
Amount1->setAlignment(Qt::AlignRight);
// Create the validator for send to/amount fields // Create the validator for send to/amount fields
Amount1->setValidator(amtValidator); Amount1->setValidator(amtValidator);
QObject::connect(Amount1, &QLineEdit::textChanged, [=] (auto text) { QObject::connect(Amount1, &QLineEdit::textChanged, [=] (auto text) {
this->amountChanged(itemNumber, text); this->amountChanged(itemNumber, text);
}); });
horizontalLayout_13->addWidget(Amount1); horizontalLayout_13->addWidget(Amount1);
auto AmtUSD1 = new QLabel(verticalGroupBox); auto AmtUSD1 = new QLabel(verticalGroupBox);
AmtUSD1->setObjectName(QString("AmtUSD") % QString::number(itemNumber)); AmtUSD1->setObjectName(QString("AmtUSD") % QString::number(itemNumber));
horizontalLayout_13->addWidget(AmtUSD1); horizontalLayout_13->addWidget(AmtUSD1);
/* TODO: Fix so it updates amount on correct recipient row...or just remove. Added for UI consistency.
auto Max1 = new QCheckBox(verticalGroupBox);
Max1->setText(tr("Max Available"));
// Connect Max Available checkbox
QObject::connect(Max1, &QCheckBox::stateChanged, [=] () {
this->maxAmountChecked(Max1->checkState());
});
horizontalLayout_13->addWidget(Max1);
*/
auto horizontalSpacer_4 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); auto horizontalSpacer_4 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
horizontalLayout_13->addItem(horizontalSpacer_4); horizontalLayout_13->addItem(horizontalSpacer_4);
auto MemoBtn1 = new QPushButton(verticalGroupBox);
MemoBtn1->setObjectName(QString("MemoBtn") % QString::number(itemNumber));
MemoBtn1->setText(tr("Memo"));
// Connect Memo Clicked button
QObject::connect(MemoBtn1, &QPushButton::clicked, [=] () {
this->memoButtonClicked(itemNumber);
});
horizontalLayout_13->addWidget(MemoBtn1);
setMemoEnabled(itemNumber, false);
auto FileBtn = new QPushButton(verticalGroupBox); auto FileBtn = new QPushButton(verticalGroupBox);
FileBtn->setObjectName(QString("FileBtn") % QString::number(itemNumber)); FileBtn->setObjectName(QString("FileBtn") % QString::number(itemNumber));
FileBtn->setText(tr("File Upload")); FileBtn->setText(tr("Upload File"));
// Connect File Upload button // Connect File Upload button
QObject::connect(FileBtn, &QPushButton::clicked, [=] () { QObject::connect(FileBtn, &QPushButton::clicked, [=] () {
this->fileUploadButtonClicked(itemNumber); this->fileUploadButtonClicked(itemNumber);
}); });
horizontalLayout_13->addWidget(FileBtn); horizontalLayout_13->addWidget(FileBtn);
sendAddressLayout->addLayout(horizontalLayout_13); sendAddressLayout->addLayout(horizontalLayout_13);
auto horizontalLayout_20 = new QHBoxLayout();
horizontalLayout_20->setSpacing(6);
horizontalLayout_20->setAlignment(Qt::AlignTop);
auto MemoTxt1 = new QLabel(verticalGroupBox); auto MemoTxt1 = new QLabel(verticalGroupBox);
MemoTxt1->setObjectName(QString("MemoTxt") % QString::number(itemNumber)); MemoTxt1->setObjectName(QString("MemoTxt") % QString::number(itemNumber));
MemoTxt1->setSizePolicy(QSizePolicy ::MinimumExpanding , QSizePolicy ::MinimumExpanding );
QFont font1 = Address1->font(); QFont font1 = Address1->font();
font1.setPointSize(font1.pointSize()-1); font1.setPointSize(font1.pointSize()-1);
MemoTxt1->setFont(font1); MemoTxt1->setFont(font1);
MemoTxt1->setWordWrap(true); MemoTxt1->setWordWrap(true);
sendAddressLayout->addWidget(MemoTxt1); horizontalLayout_20->addWidget(MemoTxt1, 0, Qt::AlignTop);
auto MemoBtn1 = new QPushButton(verticalGroupBox);
MemoBtn1->setObjectName(QString("MemoBtn") % QString::number(itemNumber));
MemoBtn1->setText(tr("Memo"));
// Connect Memo Clicked button
QObject::connect(MemoBtn1, &QPushButton::clicked, [=] () {
this->memoButtonClicked(itemNumber);
});
horizontalLayout_20->addWidget(MemoBtn1, 0, Qt::AlignTop);
setMemoEnabled(itemNumber, false);
sendAddressLayout->addLayout(horizontalLayout_20);
ui->sendToLayout->insertWidget(itemNumber-1, verticalGroupBox); ui->sendToLayout->insertWidget(itemNumber-1, verticalGroupBox);
@ -505,24 +524,14 @@ Tx MainWindow::createTxFromSendPage() {
if (Settings::getInstance()->getAllowCustomFees()) { if (Settings::getInstance()->getAllowCustomFees()) {
tx.fee = ui->minerFeeAmt->text().toDouble(); tx.fee = ui->minerFeeAmt->text().toDouble();
} } else {
else {
tx.fee = Settings::getMinerFee(); tx.fee = Settings::getMinerFee();
} }
if (Settings::getInstance()->getAutoShield() && sendChangeToSapling) { if (Settings::getInstance()->getAutoShield() && sendChangeToSapling) {
auto saplingAddr = std::find_if(rpc->getAllZAddresses()->begin(), rpc->getAllZAddresses()->end(), [=](auto i) -> bool { auto saplingAddr = std::find_if(rpc->getAllZAddresses()->begin(), rpc->getAllZAddresses()->end(), [=](auto i) -> bool {
// We're finding a sapling address that is not one of the To addresses, because zcash doesn't allow duplicated addresses
// TODO: Should we disable this in Hush? What are the privacy and chain analysis considerations?
bool isSapling = Settings::getInstance()->isSaplingAddress(i); bool isSapling = Settings::getInstance()->isSaplingAddress(i);
if (!isSapling) return false; if (!isSapling) return false;
// Also check all the To addresses
for (auto t : tx.toAddrs) {
if (t.addr == i)
return false;
}
return true; return true;
}); });
@ -672,9 +681,9 @@ bool MainWindow::confirmTx(Tx tx) {
// And FromAddress in the confirm dialog // And FromAddress in the confirm dialog
confirm.sendFrom->setText(fnSplitAddressForWrap(tx.fromAddr)); confirm.sendFrom->setText(fnSplitAddressForWrap(tx.fromAddr));
QString tooltip = tr("Current balance : ") + QString tooltip = tr("Current balance : ") +
Settings::getZECUSDDisplayFormat(rpc->getAllBalances()->value(tx.fromAddr)); Settings::getHUSHUSDDisplayFormat(rpc->getAllBalances()->value(tx.fromAddr));
tooltip += "\n" + tr("Balance after this Tx: ") + tooltip += "\n" + tr("Balance after this Tx: ") +
Settings::getZECUSDDisplayFormat(rpc->getAllBalances()->value(tx.fromAddr) - totalSpending); Settings::getHUSHUSDDisplayFormat(rpc->getAllBalances()->value(tx.fromAddr) - totalSpending);
confirm.sendFrom->setToolTip(tooltip); confirm.sendFrom->setToolTip(tooltip);
// Show the dialog and submit it if the user confirms // Show the dialog and submit it if the user confirms
@ -684,7 +693,7 @@ bool MainWindow::confirmTx(Tx tx) {
return true; return true;
} else { } else {
return false; return false;
} }
} }
// Send button clicked // Send button clicked
@ -711,18 +720,11 @@ void MainWindow::sendButton() {
auto connD = new Ui_ConnectionDialog(); auto connD = new Ui_ConnectionDialog();
connD->setupUi(d); connD->setupUi(d);
QMovie *movie1 = new QMovie(":/img/res/silentdragon-animated.gif");; QMovie *movie1 = new QMovie(":/img/silentdragon-animated-startup-dark.gif");;
QMovie *movie2 = new QMovie(":/img/res/silentdragon-animated-dark.gif");;
auto theme = Settings::getInstance()->get_theme_name(); auto theme = Settings::getInstance()->get_theme_name();
if (theme == "dark" || theme == "midnight") { movie1->setScaledSize(QSize(512,512));
movie2->setScaledSize(QSize(512,512)); connD->topIcon->setMovie(movie1);
connD->topIcon->setMovie(movie2); movie1->start();
movie2->start();
} else {
movie1->setScaledSize(QSize(512,512));
connD->topIcon->setMovie(movie1);
movie1->start();
}
//connD->topIcon->setBasePixmap(logo.scaled(256, 256, Qt::KeepAspectRatio, Qt::SmoothTransformation)); //connD->topIcon->setBasePixmap(logo.scaled(256, 256, Qt::KeepAspectRatio, Qt::SmoothTransformation));
@ -738,7 +740,7 @@ void MainWindow::sendButton() {
qDebug() << "Computing opid: " << opid; qDebug() << "Computing opid: " << opid;
}, },
[=] (QString, QString txid) { [=] (QString, QString txid) {
ui->statusBar->showMessage(Settings::txidStatusMessage + " " + txid); ui->statusBar->showMessage(Settings::txidStatusMessage + " " + txid);
connD->status->setText(tr("Done!")); connD->status->setText(tr("Done!"));
@ -753,7 +755,8 @@ void MainWindow::sendButton() {
// And switch to the balances tab // And switch to the balances tab
ui->tabWidget->setCurrentIndex(0); ui->tabWidget->setCurrentIndex(0);
}); });
// Force a UI update so we get the unconfirmed Tx
// Force a UI update so we get the unconfirmed Tx
rpc->refresh(true); rpc->refresh(true);
}, },
[=] (QString opid, QString errStr) { [=] (QString opid, QString errStr) {
@ -776,9 +779,10 @@ QString MainWindow::doSendTxValidations(Tx tx) {
} }
for (auto toAddr : tx.toAddrs) { for (auto toAddr : tx.toAddrs) {
//TODO: diff errors for completely invalid vs transparent? Educate.
if (!Settings::isValidAddress(toAddr.addr)) { if (!Settings::isValidAddress(toAddr.addr)) {
QString addr = (toAddr.addr.length() > 100 ? toAddr.addr.left(100) + "..." : toAddr.addr); QString addr = (toAddr.addr.length() > 100 ? toAddr.addr.left(100) + "..." : toAddr.addr);
return QString(tr("Recipient Address ")) % addr % tr(" is Invalid"); return QString(tr("Extreme Privacy! ")) % addr % tr(" is transparent. You must send to a zaddr.");
} }
// This technically shouldn't be possible, but issue #62 seems to have discovered a bug // This technically shouldn't be possible, but issue #62 seems to have discovered a bug
@ -788,7 +792,6 @@ QString MainWindow::doSendTxValidations(Tx tx) {
} }
} }
return QString(); return QString();
} }

12
src/senttxstore.cpp

@ -1,9 +1,16 @@
// Copyright 2019-2022 The Hush developers
// Released under the GPLv3
#include "senttxstore.h" #include "senttxstore.h"
#include "settings.h" #include "settings.h"
extern bool isdragonx;
/// Get the location of the app data file to be written. /// Get the location of the app data file to be written.
QString SentTxStore::writeableFile() { QString SentTxStore::writeableFile() {
auto filename = QStringLiteral("senttxstore.dat"); auto filename = QStringLiteral("senttxstore.dat");
if (isdragonx) {
filename = QStringLiteral("senttxstore-drgx.dat");
}
auto dir = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)); auto dir = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation));
if (!dir.exists()) if (!dir.exists())
@ -12,6 +19,7 @@ QString SentTxStore::writeableFile() {
if (Settings::getInstance()->isTestnet()) { if (Settings::getInstance()->isTestnet()) {
return dir.filePath("testnet-" % filename); return dir.filePath("testnet-" % filename);
} else { } else {
qDebug() << "senttxstore file = " + dir.filePath(filename);
return dir.filePath(filename); return dir.filePath(filename);
} }
} }
@ -43,7 +51,7 @@ QList<TransactionItem> SentTxStore::readSentTxFile() {
sentTx["address"].toString(), sentTx["address"].toString(),
sentTx["txid"].toString(), sentTx["txid"].toString(),
sentTx["amount"].toDouble() + sentTx["fee"].toDouble(), sentTx["amount"].toDouble() + sentTx["fee"].toDouble(),
0, sentTx["from"].toString(), ""}; 0, sentTx["from"].toString(), sentTx["memo"].toString()};
items.push_back(t); items.push_back(t);
} }
@ -55,7 +63,7 @@ void SentTxStore::addToSentTx(Tx tx, QString txid) {
if (!Settings::getInstance()->getSaveZtxs()) if (!Settings::getInstance()->getSaveZtxs())
return; return;
// Also, only store outgoing txs where the from address is a z-Addr. Else, regular zcashd // Also, only store outgoing txs where the from address is a z-Addr. Else, regular hushd
// stores it just fine // stores it just fine
if (!tx.fromAddr.startsWith("z")) if (!tx.fromAddr.startsWith("z"))
return; return;

2
src/senttxstore.h

@ -1,3 +1,5 @@
// Copyright 2019-2022 The Hush developers
// Released under the GPLv3
#ifndef SENTTXSTORE_H #ifndef SENTTXSTORE_H
#define SENTTXSTORE_H #define SENTTXSTORE_H

138
src/settings.cpp

@ -1,7 +1,11 @@
// Copyright 2019-2020 Hush developers // Copyright 2019-2022 Hush developers
// Released under the GPLv3 // Released under the GPLv3
#include "mainwindow.h" #include "mainwindow.h"
#include "settings.h" #include "settings.h"
#include "sd.h"
#include <QUrlQuery>
extern bool isdragonx;
Settings* Settings::instance = nullptr; Settings* Settings::instance = nullptr;
@ -25,7 +29,8 @@ void Settings::setCheckForUpdates(bool allow) {
} }
bool Settings::getAllowFetchPrices() { bool Settings::getAllowFetchPrices() {
return QSettings().value("options/allowfetchprices", true).toBool(); // now defaults to OFF, used to be ON
return QSettings().value("options/allowfetchprices", false).toBool();
} }
void Settings::setAllowFetchPrices(bool allow) { void Settings::setAllowFetchPrices(bool allow) {
@ -35,23 +40,42 @@ void Settings::setAllowFetchPrices(bool allow) {
Explorer Settings::getExplorer() { Explorer Settings::getExplorer() {
// Load from the QT Settings. // Load from the QT Settings.
QSettings s; QSettings s;
//TODO: make it easy for people to use other explorers like komodod.com //TODO: make it easy for people to use other explorers
QString explorer = "https://explorer.myhush.org"; QString explorer = "https://explorer.hush.is";
if(isdragonx) {
explorer = "https://explorer.dragonx.is";
}
auto txExplorerUrl = s.value("explorer/txExplorerUrl", explorer + "/tx/").toString(); QString onionExplorer = "http://jlqhwhak65kokg3pdjp3ufy6almf5spnhsfnugtjsc4z7wtapgozxyad.onion";
auto addressExplorerUrl = s.value("explorer/addressExplorerUrl", explorer + "/address/").toString(); auto txExplorerUrl = s.value("explorer/txExplorerUrl", explorer + "/tx/").toString();
auto testnetTxExplorerUrl = s.value("explorer/testnetTxExplorerUrl").toString(); auto addressExplorerUrl = s.value("explorer/addressExplorerUrl", explorer + "/address/").toString();
auto testnetAddressExplorerUrl = s.value("explorer/testnetAddressExplorerUrl").toString(); auto onionTxExplorerUrl = s.value("explorer/onionTxExplorerUrl", onionExplorer + "/tx/").toString();
auto onionAddressExplorerUrl = s.value("explorer/onionAddressExplorerUrl", onionExplorer + "/address/").toString();
return Explorer{txExplorerUrl, addressExplorerUrl, testnetTxExplorerUrl, testnetAddressExplorerUrl}; // Some users have the old malicious explorer URL saved in their config file, help them out
if (txExplorerUrl == "https://explorer.myhush.org/tx/") {
txExplorerUrl = explorer + "/tx/";
saveExplorer(txExplorerUrl, addressExplorerUrl, onionTxExplorerUrl, onionAddressExplorerUrl);
}
if (addressExplorerUrl == "https://explorer.myhush.org/address/") {
addressExplorerUrl = explorer + "/address/";
saveExplorer(txExplorerUrl, addressExplorerUrl, onionTxExplorerUrl, onionAddressExplorerUrl);
}
//DEBUG("explorer values: " << txExplorerUrl << " " << addressExplorerUrl << " " << onionTxExplorerUrl << " " << onionAddressExplorerUrl );
DEBUG("onionTxExplorerUrl=" % onionTxExplorerUrl);
DEBUG("onionAddressExplorerUrl=" % onionAddressExplorerUrl);
return Explorer{txExplorerUrl, addressExplorerUrl, onionTxExplorerUrl, onionAddressExplorerUrl};
} }
void Settings::saveExplorer(const QString& txExplorerUrl, const QString& addressExplorerUrl, const QString& testnetTxExplorerUrl, const QString& testnetAddressExplorerUrl) { void Settings::saveExplorer(const QString& txExplorerUrl, const QString& addressExplorerUrl, const QString& onionTxExplorerUrl, const QString& onionAddressExplorerUrl) {
QSettings s; QSettings s;
s.setValue("explorer/txExplorerUrl", txExplorerUrl); s.setValue("explorer/txExplorerUrl", txExplorerUrl);
s.setValue("explorer/addressExplorerUrl", addressExplorerUrl); s.setValue("explorer/addressExplorerUrl", addressExplorerUrl);
s.setValue("explorer/testnetTxExplorerUrl", testnetTxExplorerUrl); s.setValue("explorer/onionTxExplorerUrl", onionTxExplorerUrl);
s.setValue("explorer/testnetAddressExplorerUrl", testnetAddressExplorerUrl); s.setValue("explorer/onionAddressExplorerUrl", onionAddressExplorerUrl);
//DEBUG("saving explorer values: " << txExplorerUrl << " " << addressExplorerUrl << " " << onionTxExplorerUrl << " " << onionAddressExplorerUrl );
} }
Config Settings::getSettings() { Config Settings::getSettings() {
@ -89,7 +113,7 @@ void Settings::saveRestoreTableHeader(QTableView* table, QDialog* d, QString tab
}); });
} }
void Settings::setUsingZcashConf(QString confLocation) { void Settings::setUsingHushConf(QString confLocation) {
if (!confLocation.isEmpty()) if (!confLocation.isEmpty())
_confLocation = confLocation; _confLocation = confLocation;
} }
@ -110,13 +134,6 @@ bool Settings::isSaplingAddress(QString addr) {
(!isTestnet() && addr.startsWith("zs1")); (!isTestnet() && addr.startsWith("zs1"));
} }
bool Settings::isSproutAddress(QString addr) {
if (!isValidAddress(addr))
return false;
return isZAddress(addr) && !isSaplingAddress(addr);
}
bool Settings::isZAddress(QString addr) { bool Settings::isZAddress(QString addr) {
if (!isValidAddress(addr)) if (!isValidAddress(addr))
return false; return false;
@ -131,12 +148,12 @@ bool Settings::isTAddress(QString addr) {
return addr.startsWith("R"); return addr.startsWith("R");
} }
int Settings::getZcashdVersion() { int Settings::getHushdVersion() {
return _zcashdVersion; return _hushdVersion;
} }
void Settings::setZcashdVersion(int version) { void Settings::setHushdVersion(int version) {
_zcashdVersion = version; _hushdVersion = version;
} }
bool Settings::isSyncing() { bool Settings::isSyncing() {
@ -246,10 +263,13 @@ void Settings::setAllowCustomFees(bool allow) {
QString Settings::get_theme_name() { QString Settings::get_theme_name() {
// Load from the QT Settings. // Load from the QT Settings.
return QSettings().value("options/theme_name", false).toString(); QString theme_name = QSettings().value("options/theme_name", false).toString();
//qDebug() << __func__ << ": theme_name=" << theme_name;
return theme_name;
} }
void Settings::set_theme_name(QString theme_name) { void Settings::set_theme_name(QString theme_name) {
qDebug() << __func__ << ": settings theme_name=" << theme_name;
QSettings().setValue("options/theme_name", theme_name); QSettings().setValue("options/theme_name", theme_name);
} }
@ -302,7 +322,7 @@ QString Settings::getDisplayFormat(double bal) {
return getDecimalString(bal) % " " % Settings::getTokenName(); return getDecimalString(bal) % " " % Settings::getTokenName();
} }
QString Settings::getZECUSDDisplayFormat(double bal) { QString Settings::getHUSHUSDDisplayFormat(double bal) {
auto usdFormat = getUSDFormat(bal); auto usdFormat = getUSDFormat(bal);
if (!usdFormat.isEmpty()) if (!usdFormat.isEmpty())
return getDisplayFormat(bal) % " (" % getUSDFormat(bal) % ")"; return getDisplayFormat(bal) % " (" % getUSDFormat(bal) % ")";
@ -313,6 +333,9 @@ QString Settings::getZECUSDDisplayFormat(double bal) {
const QString Settings::txidStatusMessage = QString(QObject::tr("Transaction submitted (right click to copy) txid:")); const QString Settings::txidStatusMessage = QString(QObject::tr("Transaction submitted (right click to copy) txid:"));
QString Settings::getTokenName() { QString Settings::getTokenName() {
if (isdragonx) {
return "DRGX";
}
if (Settings::getInstance()->isTestnet()) { if (Settings::getInstance()->isTestnet()) {
return "TUSH"; return "TUSH";
} else { } else {
@ -329,7 +352,7 @@ QString Settings::getDonationAddr() {
return "zs1aq4xnrkjlnxx0zesqye7jz3dfrf3rjh7q5z6u8l6mwyqqaam3gx3j2fkqakp33v93yavq46j83q"; return "zs1aq4xnrkjlnxx0zesqye7jz3dfrf3rjh7q5z6u8l6mwyqqaam3gx3j2fkqakp33v93yavq46j83q";
} }
bool Settings::addToZcashConf(QString confLocation, QString line) { bool Settings::addToHushConf(QString confLocation, QString line) {
QFile file(confLocation); QFile file(confLocation);
if (!file.open(QIODevice::ReadWrite | QIODevice::Append)) if (!file.open(QIODevice::ReadWrite | QIODevice::Append))
return false; return false;
@ -351,8 +374,23 @@ void Settings::set_currency_name(QString currency_name) {
QSettings().setValue("options/currency_name", currency_name); QSettings().setValue("options/currency_name", currency_name);
} }
QString Settings::get_language() {
// use the default system language if none is set
QString locale = QLocale::system().name();
// remove country data, i.e. en_US => en
locale.truncate( locale.lastIndexOf("_"));
auto lang = QSettings().value("options/language", locale).toString();
qDebug() << __func__ << ": found lang=" << lang << " in config file";
return lang;
}
void Settings::set_language(QString lang) {
qDebug() << __func__ << ": setting lang=" << lang << " in config file";
QSettings().setValue("options/language", lang);
}
bool Settings::removeFromZcashConf(QString confLocation, QString option) { bool Settings::removeFromHushConf(QString confLocation, QString option) {
if (confLocation.isEmpty()) if (confLocation.isEmpty())
return false; return false;
@ -390,6 +428,30 @@ double Settings::getMinerFee() {
return 0.0001; return 0.0001;
} }
bool Settings::isValidTransparentPrivateKey(QString pk) {
if (pk.length() > 52) {
DEBUG("privkey invalid, too long");
return false;
}
if (pk.length() < 51) {
DEBUG("privkey invalid, too short");
return false;
}
// TODO: can a taddr privkey start with anything else?
if (pk.startsWith("U") || pk.startsWith("5") || pk.startsWith("L") || pk.startsWith("K") || pk.startsWith("7")) {
// verify only contains base58 characters
QRegExp exp("^[U5LK7][123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{51,52}$", Qt::CaseSensitive);
bool valid = exp.exactMatch(pk);
if(!valid) { DEBUG("privkey invalid, not base58"); }
return valid;
} else {
DEBUG("privkey invalid, wrong prefix");
return false;
}
}
bool Settings::isValidSaplingPrivateKey(QString pk) { bool Settings::isValidSaplingPrivateKey(QString pk) {
if (isTestnet()) { if (isTestnet()) {
QRegExp zspkey("^secret-extended-key-test[0-9a-z]{278}$", Qt::CaseInsensitive); QRegExp zspkey("^secret-extended-key-test[0-9a-z]{278}$", Qt::CaseInsensitive);
@ -419,12 +481,26 @@ QString Settings::paymentURIPretty(PaymentURI uri) {
PaymentURI Settings::parseURI(QString uri) { PaymentURI Settings::parseURI(QString uri) {
PaymentURI ans; PaymentURI ans;
if (!uri.startsWith("hush:")) { auto proto="";
ans.error = "Not a HUSH payment URI"; if (isdragonx) {
return ans; proto ="drgx:";
if (!uri.startsWith(proto % QString(":"))) {
ans.error = "Not a DRGX payment URI";
return ans;
}
} else {
proto = "hush:";
if (!uri.startsWith(proto % QString(":"))) {
ans.error = "Not a HUSH payment URI";
return ans;
}
} }
uri = uri.right(uri.length() - QString("hush:").length()); uri = uri.right(uri.length() - QString("hush:").length());
if(isdragonx) {
uri = uri.right(uri.length() - QString("drgx:").length());
}
QRegExp re("([a-zA-Z0-9]+)"); QRegExp re("([a-zA-Z0-9]+)");
int pos; int pos;

40
src/settings.h

@ -1,4 +1,5 @@
// Copyright 2019 The Hush developers // Copyright 2019-2022 The Hush developers
// Released under the GPLv3
#ifndef SETTINGS_H #ifndef SETTINGS_H
#define SETTINGS_H #define SETTINGS_H
@ -14,8 +15,8 @@ struct Config {
struct Explorer { struct Explorer {
QString txExplorerUrl; QString txExplorerUrl;
QString addressExplorerUrl; QString addressExplorerUrl;
QString testnetTxExplorerUrl; QString onionTxExplorerUrl;
QString testnetAddressExplorerUrl; QString onionAddressExplorerUrl;
}; };
struct ToFields; struct ToFields;
@ -37,7 +38,7 @@ public:
static Settings* getInstance(); static Settings* getInstance();
Explorer getExplorer(); Explorer getExplorer();
void saveExplorer(const QString& txExplorerUrl, const QString& addressExplorerUrl, const QString& testnetTxExplorerUrl, const QString& testnetAddressExplorerUrl); void saveExplorer(const QString& txExplorerUrl, const QString& addressExplorerUrl, const QString& onionTxExplorerUrl, const QString& onionAddressExplorerUrl);
Config getSettings(); Config getSettings();
void saveSettings(const QString& host, const QString& port, const QString& username, const QString& password); void saveSettings(const QString& host, const QString& port, const QString& username, const QString& password);
@ -46,15 +47,15 @@ public:
void setTestnet(bool isTestnet); void setTestnet(bool isTestnet);
bool isSaplingAddress(QString addr); bool isSaplingAddress(QString addr);
bool isSproutAddress(QString addr);
bool isValidSaplingPrivateKey(QString pk); bool isValidSaplingPrivateKey(QString pk);
bool isValidTransparentPrivateKey(QString pk);
bool isSyncing(); bool isSyncing();
void setSyncing(bool syncing); void setSyncing(bool syncing);
int getZcashdVersion(); int getHushdVersion();
void setZcashdVersion(int version); void setHushdVersion(int version);
void setUseEmbedded(bool r) { _useEmbedded = r; } void setUseEmbedded(bool r) { _useEmbedded = r; }
bool useEmbedded() { return _useEmbedded; } bool useEmbedded() { return _useEmbedded; }
@ -88,8 +89,11 @@ public:
QString get_currency_name(); QString get_currency_name();
void set_currency_name(QString currency_name); void set_currency_name(QString currency_name);
void setUsingZcashConf(QString confLocation); QString get_language();
const QString& getZcashdConfLocation() { return _confLocation; } void set_language(QString lang);
void setUsingHushConf(QString confLocation);
const QString& getHushdConfLocation() { return _confLocation; }
void setHUSHPrice(double p) { hushPrice = p; } void setHUSHPrice(double p) { hushPrice = p; }
void set_fiat_price(double p) { fiat_price = p; } void set_fiat_price(double p) { fiat_price = p; }
@ -122,21 +126,20 @@ public:
static QString getDecimalString(double amt); static QString getDecimalString(double amt);
static QString getUSDFormat(double bal); static QString getUSDFormat(double bal);
static QString getDisplayFormat(double bal); static QString getDisplayFormat(double bal);
static QString getZECUSDDisplayFormat(double bal); static QString getHUSHUSDDisplayFormat(double bal);
static QString getTokenName(); static QString getTokenName();
static QString getDonationAddr(); static QString getDonationAddr();
static double getMinerFee(); static double getMinerFee();
static double getZboardAmount();
static QString getZboardAddr();
//TODO: this could be an advanced setting too
static int getMaxMobileAppTxns() { return 30; } static int getMaxMobileAppTxns() { return 30; }
static bool isValidAddress(QString addr); static bool isValidAddress(QString addr);
static bool addToZcashConf(QString confLocation, QString line); static bool addToHushConf(QString confLocation, QString line);
static bool removeFromZcashConf(QString confLocation, QString option); static bool removeFromHushConf(QString confLocation, QString option);
static const QString labelRegExp; static const QString labelRegExp;
@ -145,6 +148,10 @@ public:
static const int quickUpdateSpeed = 3 * 1000; // 3 sec static const int quickUpdateSpeed = 3 * 1000; // 3 sec
static const int priceRefreshSpeed = 15 * 60 * 1000; // 15 mins static const int priceRefreshSpeed = 15 * 60 * 1000; // 15 mins
protected:
// this event is called, when a new translator is loaded or the system language is changed
// void changeEvent(QEvent* event);
private: private:
// This class can only be accessed through Settings::getInstance() // This class can only be accessed through Settings::getInstance()
Settings() = default; Settings() = default;
@ -157,12 +164,11 @@ private:
bool _isTestnet = false; bool _isTestnet = false;
bool _isSyncing = false; bool _isSyncing = false;
int _blockNumber = 0; int _blockNumber = 0;
int _zcashdVersion = 0; int _hushdVersion = 0;
bool _useEmbedded = false; bool _useEmbedded = false;
bool _headless = false; bool _headless = false;
int _peerConnections = 0; int _peerConnections = 0;
double hushPrice = 0.0;
double hushPrice = 0.0;
double fiat_price = 0.0; double fiat_price = 0.0;
unsigned int btcPrice = 0; unsigned int btcPrice = 0;
std::map<QString, double> prices; std::map<QString, double> prices;

413
src/settings.ui

@ -7,7 +7,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>623</width> <width>623</width>
<height>653</height> <height>622</height>
</rect> </rect>
</property> </property>
<property name="minimumSize"> <property name="minimumSize">
@ -22,11 +22,11 @@
<property name="modal"> <property name="modal">
<bool>true</bool> <bool>true</bool>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QGridLayout" name="gridLayout_2">
<item> <item row="0" column="0">
<widget class="QTabWidget" name="tabWidget"> <widget class="QTabWidget" name="tabWidget">
<property name="currentIndex"> <property name="currentIndex">
<number>3</number> <number>1</number>
</property> </property>
<widget class="QWidget" name="tab"> <widget class="QWidget" name="tab">
<attribute name="title"> <attribute name="title">
@ -145,24 +145,165 @@
<string>Options</string> <string>Options</string>
</attribute> </attribute>
<layout class="QGridLayout" name="gridLayout"> <layout class="QGridLayout" name="gridLayout">
<item row="15" column="0"> <item row="0" column="0" colspan="3">
<widget class="QLabel" name="label_20"> <widget class="QCheckBox" name="chkSaveTxs">
<property name="text">
<string>Remember shielded transactions</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="5">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Shielded transactions are saved locally and shown in the transactions tab. If you uncheck this, shielded transactions will not appear in the transactions tab.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="5">
<widget class="QPushButton" name="btnClearSaved">
<property name="text">
<string>Clear History</string>
</property>
</widget>
</item>
<item row="2" column="0" colspan="3">
<widget class="QCheckBox" name="chkCustomFees">
<property name="text">
<string>Allow custom fees</string>
</property>
</widget>
</item>
<item row="3" column="0" colspan="6">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Allow overriding the default fees when sending transactions. Enabling this option may compromise your privacy since fees are transparent. </string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="4" column="0" colspan="5">
<widget class="QCheckBox" name="chkAutoShield">
<property name="text">
<string>Shield change from t-Addresses to your sapling address</string>
</property>
</widget>
</item>
<item row="5" column="0" colspan="6">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Normally, change from t-Addresses goes to another t-Address. Checking this option will send the change to your shielded sapling address instead. Check this option to increase your privacy.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="6" column="0" colspan="3">
<widget class="QCheckBox" name="chkTor">
<property name="text">
<string>Connect via Tor</string>
</property>
</widget>
</item>
<item row="7" column="0" colspan="6">
<widget class="QLabel" name="lblTor">
<property name="text">
<string>Connect to the Tor network via SOCKS proxy, which runs on 127.0.0.1:9050 by default or 127.0.0.1:9150 for Tor Browser. Please note that you'll have to install and run the Tor service externally.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QLabel" name="label_tor_proxy">
<property name="text">
<string>Proxy IP</string>
</property>
</widget>
</item>
<item row="8" column="1" colspan="2">
<widget class="QLineEdit" name="torProxy">
<property name="text">
<string notr="true">127.0.0.1</string>
</property>
</widget>
</item>
<item row="8" column="3">
<widget class="QLabel" name="label_tor_port">
<property name="text">
<string>Tor Port</string>
</property>
</widget>
</item>
<item row="8" column="4">
<widget class="QLineEdit" name="torPort">
<property name="text">
<string notr="true">9050</string>
</property>
</widget>
</item>
<item row="9" column="0" colspan="6">
<widget class="QCheckBox" name="chkCheckUpdates">
<property name="text">
<string>Connect to git.hush.is on startup to check for updates</string>
</property>
</widget>
</item>
<item row="10" column="0" colspan="6">
<widget class="QCheckBox" name="chkFetchPrices">
<property name="text">
<string>Connect to the internet to fetch prices</string>
</property>
</widget>
</item>
<item row="11" column="2">
<widget class="QComboBox" name="comboBoxTheme">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred"> <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="text"> <item>
<string>Theme</string> <property name="text">
</property> <string notr="true">default</string>
<property name="alignment"> </property>
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> </item>
</property> <item>
<property name="text">
<string notr="true">blue</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">light</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">dark</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">midnight</string>
</property>
</item>
<item>
<property name="text">
<string>dragonx</string>
</property>
</item>
</widget> </widget>
</item> </item>
<item row="16" column="0"> <item row="12" column="0" colspan="2">
<widget class="QLabel" name="label_20"> <widget class="QLabel" name="label_201">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred"> <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch> <horstretch>0</horstretch>
@ -177,7 +318,7 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="16" column="1"> <item row="12" column="2">
<widget class="QComboBox" name="comboBoxCurrency"> <widget class="QComboBox" name="comboBoxCurrency">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed"> <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
@ -402,174 +543,45 @@
</item> </item>
</widget> </widget>
</item> </item>
<item row="15" column="1"> <item row="13" column="0" colspan="2">
<widget class="QComboBox" name="comboBoxTheme"> <widget class="QLabel" name="langlabel">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed"> <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<item>
<property name="text">
<string>default</string>
</property>
</item>
<item>
<property name="text">
<string>blue</string>
</property>
</item>
<item>
<property name="text">
<string>light</string>
</property>
</item>
<item>
<property name="text">
<string>dark</string>
</property>
</item>
<item>
<property name="text">
<string>midnight</string>
</property>
</item>
</widget>
</item>
<item row="14" column="0" colspan="2">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="0">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="7" column="0">
<widget class="QCheckBox" name="chkTor">
<property name="text">
<string>Connect via Tor</string>
</property>
</widget>
</item>
<item row="9" column="0" colspan="2">
<widget class="QCheckBox" name="chkCheckUpdates">
<property name="text">
<string>Check github for updates at startup</string>
</property>
</widget>
</item>
<item row="13" column="0" colspan="2">
<widget class="Line" name="line_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="0" column="0" colspan="2">
<widget class="QCheckBox" name="chkSaveTxs">
<property name="text">
<string>Remember shielded transactions</string>
</property>
</widget>
</item>
<item row="6" column="0" colspan="2">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Normally, change from t-Addresses goes to another t-Address. Checking this option will send the change to your shielded sapling address instead. Check this option to increase your privacy.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="4" column="0" colspan="2">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Allow overriding the default fees when sending transactions. Enabling this option may compromise your privacy since fees are transparent. </string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QPushButton" name="btnClearSaved">
<property name="text">
<string>Clear History</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QLabel" name="label_5">
<property name="text"> <property name="text">
<string>Shielded transactions are saved locally and shown in the transactions tab. If you uncheck this, shielded transactions will not appear in the transactions tab.</string> <string>Language</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property> </property>
</widget> <property name="alignment">
</item> <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
<item row="3" column="0">
<widget class="QCheckBox" name="chkCustomFees">
<property name="text">
<string>Allow custom fees</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="5" column="0" colspan="2"> <item row="13" column="2">
<widget class="QCheckBox" name="chkAutoShield"> <widget class="QComboBox" name="comboBoxLanguage">
<property name="text"> <property name="sizePolicy">
<string>Shield change from t-Addresses to your sapling address</string> <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property> </property>
</widget> </widget>
</item> </item>
<item row="8" column="0" colspan="2"> <item row="11" column="0" colspan="2">
<widget class="QLabel" name="lblTor"> <widget class="QLabel" name="label_20">
<property name="text"> <property name="sizePolicy">
<string>Connect to the Tor network via SOCKS proxy running on 127.0.0.1:9050. Please note that you'll have to install and run the Tor service externally.</string> <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
</property> <horstretch>0</horstretch>
<property name="wordWrap"> <verstretch>0</verstretch>
<bool>true</bool> </sizepolicy>
</property> </property>
</widget>
</item>
<item row="10" column="0" colspan="2">
<widget class="QLabel" name="label_8">
<property name="text"> <property name="text">
<string>Connect to github on startup to check for updates</string> <string>Theme</string>
</property>
</widget>
</item>
<item row="12" column="0" colspan="2">
<widget class="QLabel" name="label_10">
<property name="text">
<string>Connect to the internet to fetch HUSH prices</string>
</property> </property>
</widget> <property name="alignment">
</item> <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
<item row="11" column="0" colspan="2">
<widget class="QCheckBox" name="chkFetchPrices">
<property name="text">
<string>Fetch HUSH prices</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -615,7 +627,7 @@
</rect> </rect>
</property> </property>
<property name="text"> <property name="text">
<string notr="true">https://explorer.myhush.org/tx/</string> <string notr="true">https://explorer.hush.is/tx/</string>
</property> </property>
</widget> </widget>
<widget class="QLabel" name="label_15"> <widget class="QLabel" name="label_15">
@ -641,7 +653,7 @@
</rect> </rect>
</property> </property>
<property name="text"> <property name="text">
<string notr="true">https://explorer.myhush.org/address/</string> <string notr="true">https://explorer.hush.is/address/</string>
</property> </property>
</widget> </widget>
<widget class="QLabel" name="label_16"> <widget class="QLabel" name="label_16">
@ -654,10 +666,10 @@
</rect> </rect>
</property> </property>
<property name="text"> <property name="text">
<string>Testnet Tx Explorer URL</string> <string>Onion Tx Explorer URL</string>
</property> </property>
</widget> </widget>
<widget class="QLineEdit" name="testnetTxExplorerUrl"> <widget class="QLineEdit" name="onionTxExplorerUrl">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>9</x> <x>9</x>
@ -667,7 +679,7 @@
</rect> </rect>
</property> </property>
<property name="text"> <property name="text">
<string notr="true">https://explorer.testnet.z.cash/tx/</string> <string notr="true">http://jlqhwhak65kokg3pdjp3ufy6almf5spnhsfnugtjsc4z7wtapgozxyad.onion/tx/</string>
</property> </property>
</widget> </widget>
<widget class="QLabel" name="label_17"> <widget class="QLabel" name="label_17">
@ -680,10 +692,10 @@
</rect> </rect>
</property> </property>
<property name="text"> <property name="text">
<string>Testnet Address Explorer URL</string> <string>Onion Address Explorer URL</string>
</property> </property>
</widget> </widget>
<widget class="QLineEdit" name="testnetAddressExplorerUrl"> <widget class="QLineEdit" name="onionAddressExplorerUrl">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>9</x> <x>9</x>
@ -693,11 +705,14 @@
</rect> </rect>
</property> </property>
<property name="text"> <property name="text">
<string notr="true">https://explorer.testnet.myhush.org/address/</string> <string notr="true">http://jlqhwhak65kokg3pdjp3ufy6almf5spnhsfnugtjsc4z7wtapgozxyad.onion/tx/</string>
</property> </property>
</widget> </widget>
</widget> </widget>
<widget class="QWidget" name="tab_3"> <widget class="QWidget" name="tab_3">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<attribute name="title"> <attribute name="title">
<string>Troubleshooting</string> <string>Troubleshooting</string>
</attribute> </attribute>
@ -717,32 +732,19 @@
<widget class="QLabel" name="label_9"> <widget class="QLabel" name="label_9">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>9</x> <x>10</x>
<y>38</y> <y>10</y>
<width>583</width> <width>583</width>
<height>51</height> <height>51</height>
</rect> </rect>
</property> </property>
<property name="text"> <property name="text">
<string>Rescan the blockchain for any missing wallet transactions and to correct your wallet balance. This may take several hours. You need to restart SilentDragon for this to take effect</string> <string>Rescan the blockchain for any missing wallet transactions and to correct your wallet balance. Click rescan to enter block height to rescan from. This may take several hours depending on submitted block height.</string>
</property> </property>
<property name="wordWrap"> <property name="wordWrap">
<bool>true</bool> <bool>true</bool>
</property> </property>
</widget> </widget>
<widget class="QCheckBox" name="chkRescan">
<property name="geometry">
<rect>
<x>9</x>
<y>9</y>
<width>73</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Rescan</string>
</property>
</widget>
<widget class="Line" name="line_3"> <widget class="Line" name="line_3">
<property name="geometry"> <property name="geometry">
<rect> <rect>
@ -963,10 +965,35 @@
<string>MB</string> <string>MB</string>
</property> </property>
</widget> </widget>
<widget class="QPushButton" name="rescanButton">
<property name="geometry">
<rect>
<x>310</x>
<y>60</y>
<width>281</width>
<height>34</height>
</rect>
</property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="text">
<string>Rescan</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
<property name="default">
<bool>true</bool>
</property>
<property name="flat">
<bool>false</bool>
</property>
</widget>
</widget> </widget>
</widget> </widget>
</item> </item>
<item> <item row="1" column="0">
<widget class="QDialogButtonBox" name="buttonBox"> <widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>

127
src/txtablemodel.cpp

@ -1,6 +1,11 @@
// Copyright 2019-2022 The Hush developers
// Released under the GPLv3
#include "txtablemodel.h" #include "txtablemodel.h"
#include "settings.h" #include "settings.h"
#include "rpc.h" #include "rpc.h"
#include "guiconstants.h"
extern bool isdragonx;
TxTableModel::TxTableModel(QObject *parent) TxTableModel::TxTableModel(QObject *parent)
: QAbstractTableModel(parent) { : QAbstractTableModel(parent) {
@ -70,7 +75,7 @@ bool TxTableModel::exportToCsv(QString fileName) const {
return true; return true;
} }
void TxTableModel::updateAllData() { void TxTableModel::updateAllData() {
auto newmodeldata = new QList<TransactionItem>(); auto newmodeldata = new QList<TransactionItem>();
if (tTrans != nullptr) std::copy( tTrans->begin(), tTrans->end(), std::back_inserter(*newmodeldata)); if (tTrans != nullptr) std::copy( tTrans->begin(), tTrans->end(), std::back_inserter(*newmodeldata));
@ -90,33 +95,63 @@ void TxTableModel::updateAllData() {
layoutChanged(); layoutChanged();
} }
int TxTableModel::rowCount(const QModelIndex&) const
{ QImage TxTableModel::colorizeIcon(QIcon icon, QColor color) const{
QImage img(icon.pixmap(16, 16).toImage());
img = img.convertToFormat(QImage::Format_ARGB32);
for (int x = img.width(); x--; )
{
for (int y = img.height(); y--; )
{
const QRgb rgb = img.pixel(x, y);
img.setPixel(x, y, qRgba(color.red(), color.green(), color.blue(), qAlpha(rgb)));
}
}
return img;
}
int TxTableModel::rowCount(const QModelIndex&) const
{
if (modeldata == nullptr) return 0; if (modeldata == nullptr) return 0;
return modeldata->size(); return modeldata->size();
} }
int TxTableModel::columnCount(const QModelIndex&) const int TxTableModel::columnCount(const QModelIndex&) const
{ {
return headers.size(); return headers.size();
} }
QVariant TxTableModel::data(const QModelIndex &index, int role) const QVariant TxTableModel::data(const QModelIndex &index, int role) const
{ {
// Align column 4 (amount) right // Get current theme name
QString theme_name = Settings::getInstance()->get_theme_name();
QBrush b;
QColor color;
if (theme_name == "dark" || theme_name == "midnight") {
color = COLOR_WHITE;
}else if(theme_name == "dragonx"){
color = COLOR_DRAGONX_TEXT;
}else{
color = COLOR_BLACK;
}
// Align column 4 (amount) right
if (role == Qt::TextAlignmentRole && index.column() == 3) return QVariant(Qt::AlignRight | Qt::AlignVCenter); if (role == Qt::TextAlignmentRole && index.column() == 3) return QVariant(Qt::AlignRight | Qt::AlignVCenter);
if (role == Qt::ForegroundRole) { if (role == Qt::ForegroundRole) {
if (modeldata->at(index.row()).confirmations == 0) { if (modeldata->at(index.row()).confirmations == 0) {
QBrush b; b.setColor(COLOR_UNCONFIRMED_TX);
b.setColor(Qt::red); return b;
}
if (theme_name == "dark" || theme_name == "midnight") {
b.setColor(color);
return b;
}else{
b.setColor(color);
return b; return b;
} }
// Else, just return the default brush
QBrush b;
b.setColor(Qt::black);
return b; return b;
} }
@ -159,18 +194,62 @@ void TxTableModel::updateAllData() {
} }
if (role == Qt::DecorationRole && index.column() == 0) { if (role == Qt::DecorationRole && index.column() == 0) {
//qDebug() << "TX Type = " + dat.type;
if (!dat.memo.isEmpty()) { if (!dat.memo.isEmpty()) {
// If the memo is a Payment URI, then show a payment request icon // If the memo is a Payment URI, then show a payment request icon
if (dat.memo.startsWith("hush:")) { if(isdragonx) {
QIcon icon(":/icons/res/paymentreq.gif"); if (dat.memo.startsWith("drgx:")) {
return QVariant(icon.pixmap(16, 16)); QIcon icon(":/icons/paymentreq.gif");
} else { return QVariant(icon.pixmap(16, 16));
// Return the info pixmap to indicate memo
QIcon icon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxInformation);
return QVariant(icon.pixmap(16, 16));
} }
} else if (dat.memo.startsWith("hush:")) {
QIcon icon(":/icons/paymentreq.gif");
return QVariant(icon.pixmap(16, 16));
}
// Return the info pixmap to indicate memo
QIcon icon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxInformation);
return QVariant(icon.pixmap(16, 16));
} else { } else {
// Empty pixmap to make it align // TODO: Add appropriate icons for types of txs instead of empty pixmap
//qDebug() << "Type = " +getType(index.row()) + "Address = " +getAddr(index.row()) + "From Address = " +getFromAddr(index.row());
// Send
if(this->getType(index.row()) == "send"){
QImage image = colorizeIcon(QIcon(":/icons/tx_output.png"), color);
QIcon icon;
icon.addPixmap(QPixmap::fromImage(image));
return QVariant(icon.pixmap(16, 16));
}
// Send T->Z - Untested
if(this->getType(index.row()) == "send" && !this->getFromAddr(index.row()).startsWith("zs1")){
QImage image = colorizeIcon(QIcon(":/icons/lock_closed.png"), color);
QIcon icon;
icon.addPixmap(QPixmap::fromImage(image));
return QVariant(icon.pixmap(16, 16));
}
// Receive
if(this->getType(index.row()) == "receive"){
QImage image = colorizeIcon(QIcon(":/icons/tx_input.png"), color);
QIcon icon;
icon.addPixmap(QPixmap::fromImage(image));
return QVariant(icon.pixmap(16, 16));
}
// Mined
if(this->getType(index.row()) == "generate"){
QImage image = colorizeIcon(QIcon(":/icons/tx_mined.png"), color);
QIcon icon;
icon.addPixmap(QPixmap::fromImage(image));
return QVariant(icon.pixmap(16, 16));
}
// Empty pixmap to make it align (old behavior)
QPixmap p(16, 16); QPixmap p(16, 16);
p.fill(Qt::white); p.fill(Qt::white);
return QVariant(p); return QVariant(p);
@ -214,6 +293,10 @@ QString TxTableModel::getAddr(int row) const {
return modeldata->at(row).address.trimmed(); return modeldata->at(row).address.trimmed();
} }
QString TxTableModel::getFromAddr(int row) const {
return modeldata->at(row).fromAddr.trimmed();
}
qint64 TxTableModel::getDate(int row) const { qint64 TxTableModel::getDate(int row) const {
return modeldata->at(row).datetime; return modeldata->at(row).datetime;
} }

8
src/txtablemodel.h

@ -1,3 +1,5 @@
// Copyright 2019-2022 The Hush developers
// Released under the GPLv3
#ifndef STRINGSTABLEMODEL_H #ifndef STRINGSTABLEMODEL_H
#define STRINGSTABLEMODEL_H #define STRINGSTABLEMODEL_H
@ -8,16 +10,17 @@ struct TransactionItem;
class TxTableModel: public QAbstractTableModel class TxTableModel: public QAbstractTableModel
{ {
public: public:
TxTableModel(QObject* parent); TxTableModel(QObject* parent);
~TxTableModel(); ~TxTableModel();
void addTData (const QList<TransactionItem>& data); void addTData (const QList<TransactionItem>& data);
void addZSentData(const QList<TransactionItem>& data); void addZSentData(const QList<TransactionItem>& data);
void addZRecvData(const QList<TransactionItem>& data); void addZRecvData(const QList<TransactionItem>& data);
QString getTxId(int row) const; QString getTxId(int row) const;
QString getMemo(int row) const; QString getMemo(int row) const;
QString getAddr(int row) const; QString getAddr(int row) const;
QString getFromAddr(int row) const;
qint64 getDate(int row) const; qint64 getDate(int row) const;
QString getType(int row) const; QString getType(int row) const;
qint64 getConfirmations(int row) const; qint64 getConfirmations(int row) const;
@ -29,6 +32,7 @@ public:
int columnCount(const QModelIndex &parent) const; int columnCount(const QModelIndex &parent) const;
QVariant data(const QModelIndex &index, int role) const; QVariant data(const QModelIndex &index, int role) const;
QVariant headerData(int section, Qt::Orientation orientation, int role) const; QVariant headerData(int section, Qt::Orientation orientation, int role) const;
QImage colorizeIcon(const QIcon icon, const QColor color) const;
private: private:
void updateAllData(); void updateAllData();

5
src/validateaddress.cpp

@ -1,3 +1,5 @@
// Copyright 2019-2022 The Hush developers
// Released under the GPLv3
#include "validateaddress.h" #include "validateaddress.h"
@ -27,6 +29,9 @@ QVariant ValidateAddressesModel::data(const QModelIndex &index, int role) const
return QVariant(); return QVariant();
} }
Qt::ItemFlags ValidateAddressesModel::flags(const QModelIndex &index) const {
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}
QVariant ValidateAddressesModel::headerData(int section, Qt::Orientation orientation, int role) const { QVariant ValidateAddressesModel::headerData(int section, Qt::Orientation orientation, int role) const {
if (role == Qt::DisplayRole && orientation == Qt::Horizontal) { if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {

6
src/validateaddress.h

@ -1,3 +1,5 @@
// Copyright 2019-2022 The Hush developers
// Released under the GPLv3
#ifndef VALIDATEADDRESS_H #ifndef VALIDATEADDRESS_H
#define VALIDATEADDRESS_H #define VALIDATEADDRESS_H
@ -5,6 +7,8 @@
class ValidateAddressesModel : public QAbstractTableModel { class ValidateAddressesModel : public QAbstractTableModel {
Q_OBJECT
public: public:
ValidateAddressesModel(QTableView* parent, QList<QPair<QString, QString>> props); ValidateAddressesModel(QTableView* parent, QList<QPair<QString, QString>> props);
~ValidateAddressesModel() = default; ~ValidateAddressesModel() = default;
@ -14,6 +18,8 @@ public:
QVariant data(const QModelIndex &index, int role) const; QVariant data(const QModelIndex &index, int role) const;
QVariant headerData(int section, Qt::Orientation orientation, int role) const; QVariant headerData(int section, Qt::Orientation orientation, int role) const;
Qt::ItemFlags flags(const QModelIndex &index) const;
private: private:
QList<QPair<QString, QString>> props; QList<QPair<QString, QString>> props;
QStringList headers; QStringList headers;

2
src/version.h

@ -1 +1 @@
#define APP_VERSION "1.0.0" #define APP_VERSION "1.4.2"

2
src/viewalladdresses.cpp

@ -1,3 +1,5 @@
// Copyright 2019-2022 The Hush developers
// Released under the GPLv3
#include "viewalladdresses.h" #include "viewalladdresses.h"
#include "settings.h" #include "settings.h"

6
src/viewalladdresses.h

@ -1,3 +1,5 @@
// Copyright 2019-2022 The Hush developers
// Released under the GPLv3
#ifndef VIEWALLADDRESSES_H #ifndef VIEWALLADDRESSES_H
#define VIEWALLADDRESSES_H #define VIEWALLADDRESSES_H
@ -6,6 +8,8 @@
class ViewAllAddressesModel : public QAbstractTableModel { class ViewAllAddressesModel : public QAbstractTableModel {
Q_OBJECT
public: public:
ViewAllAddressesModel(QTableView* parent, QList<QString> taddrs, RPC* rpc); ViewAllAddressesModel(QTableView* parent, QList<QString> taddrs, RPC* rpc);
~ViewAllAddressesModel() = default; ~ViewAllAddressesModel() = default;
@ -21,4 +25,4 @@ private:
RPC* rpc; RPC* rpc;
}; };
#endif #endif

85
src/viewtransaction.ui

@ -0,0 +1,85 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ViewTransaction</class>
<widget class="QDialog" name="ViewTransaction">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>View Transaction</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="1">
<widget class="QLabel" name="lblHeight">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Transaction ID (txid):</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QTableView" name="tblProps">
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Close</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>ViewTransaction</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>ViewTransaction</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

908
src/websockets.cpp

@ -1,908 +0,0 @@
// Copyright 2019-2020 Hush developers
#include "websockets.h"
#include "rpc.h"
#include "settings.h"
#include "ui_mobileappconnector.h"
#include "version.h"
// Wrap the sendTextMessage to check if the connection is valid and that the parent WebServer didn't close this connection
// for some reason.
void ClientWebSocket::sendTextMessage(QString m) {
if (client) {
if (server && !server->isValidConnection(client)) {
return;
}
if (client->isValid())
client->sendTextMessage(m);
}
}
WSServer::WSServer(quint16 port, bool debug, QObject *parent) :
QObject(parent),
m_pWebSocketServer(new QWebSocketServer(QStringLiteral("Direct Connection Server"),
QWebSocketServer::NonSecureMode, this)),
m_debug(debug)
{
m_mainWindow = (MainWindow *) parent;
if (m_pWebSocketServer->listen(QHostAddress::AnyIPv4, port)) {
if (m_debug)
qDebug() << "Echoserver listening on port" << port;
connect(m_pWebSocketServer, &QWebSocketServer::newConnection,
this, &WSServer::onNewConnection);
connect(m_pWebSocketServer, &QWebSocketServer::closed, this, &WSServer::closed);
}
}
WSServer::~WSServer()
{
qDebug() << "Closing websocket server";
m_pWebSocketServer->close();
qDeleteAll(m_clients.begin(), m_clients.end());
qDebug() << "Deleted all websocket clients";
}
void WSServer::onNewConnection()
{
qDebug() << "Websocket server: new connection";
QWebSocket *pSocket = m_pWebSocketServer->nextPendingConnection();
connect(pSocket, &QWebSocket::textMessageReceived, this, &WSServer::processTextMessage);
connect(pSocket, &QWebSocket::binaryMessageReceived, this, &WSServer::processBinaryMessage);
connect(pSocket, &QWebSocket::disconnected, this, &WSServer::socketDisconnected);
m_clients << pSocket;
}
void WSServer::processTextMessage(QString message)
{
QWebSocket *pClient = qobject_cast<QWebSocket *>(sender());
if (m_debug)
qDebug() << "Message received:" << message;
if (pClient) {
std::shared_ptr<ClientWebSocket> client = std::make_shared<ClientWebSocket>(pClient, this);
AppDataServer::getInstance()->processMessage(message, m_mainWindow, client, AppConnectionType::DIRECT);
}
}
void WSServer::processBinaryMessage(QByteArray message)
{
//QWebSocket *pClient = qobject_cast<QWebSocket *>(sender());
if (m_debug)
qDebug() << "Binary Message received:" << message;
}
void WSServer::socketDisconnected()
{
QWebSocket *pClient = qobject_cast<QWebSocket *>(sender());
if (m_debug)
qDebug() << "socketDisconnected:" << pClient;
if (pClient) {
m_clients.removeAll(pClient);
pClient->deleteLater();
}
}
//===============================
// WormholeClient
//===============================
WormholeClient::WormholeClient(MainWindow* p, QString wormholeCode) {
this->parent = p;
this->code = wormholeCode;
connect();
qDebug() << "New wormhole client after connect()";
}
WormholeClient::~WormholeClient() {
qDebug() << "WormholeClient destructor";
shuttingDown = true;
if (m_webSocket && m_webSocket->isValid()) {
qDebug() << "Wormhole closing!";
m_webSocket->close();
}
if (timer) {
qDebug() << "Wormhole timer stopping";
timer->stop();
}
qDebug() << "Wormhole client destroyed";
delete timer;
qDebug() << "Wormhole timer deleted";
}
void ws_error() {
qDebug() << "websocket error!";
}
void WormholeClient::sslerrors(const QList<QSslError> &)
{
qDebug() << "SSL errors occurred!";
//TODO: don't do this in prod
//m_webSocket->ignoreSslErrors();
}
void WormholeClient::connect() {
qDebug() << "Wormhole::connect";
delete m_webSocket;
m_webSocket = new QWebSocket();
QUrl wormhole = QUrl("wss://wormhole.myhush.org:443");
if (m_webSocket) {
QObject::connect(m_webSocket, &QWebSocket::connected, this, &WormholeClient::onConnected);
QObject::connect(m_webSocket, &QWebSocket::disconnected, this, &WormholeClient::closed);
QObject::connect(m_webSocket, QOverload<const QList<QSslError>&>::of(&QWebSocket::sslErrors), this, &WormholeClient::sslerrors);
qDebug() << "Opening connection to the SilentDragonWormhole";
m_webSocket->open(wormhole);
qDebug() << "Opened connection to " << wormhole;
//TODO: use env var to over-ride
//m_webSocket->open(QUrl("ws://127.0.0.1:7070"));
} else {
qDebug() << "Invalid websocket object!";
}
}
void WormholeClient::retryConnect() {
QTimer::singleShot(5 * 1000 * pow(2, retryCount), [=]() {
if (retryCount < 10) {
qDebug() << "Retrying websocket connection, count=" << this->retryCount;
this->retryCount++;
connect();
} else {
qDebug() << "Retry count exceeded, will not attempt retry any more";
}
});
}
/*
void WormholeClient::retryConnect() {
int max_retries = 10;
qDebug() << "Websocket retryConnect, retryCount=" << retryCount;
if (retryCount>=0 && retryCount<=max_retries) {
QTimer::singleShot(5 * 1000 * pow(2, retryCount), [=]() {
if (retryCount < max_retries) {
this->retryCount++;
qDebug() << "Retrying websocket connection, retrycount=" << this->retryCount;
connect();
} else {
qDebug() << "Retry count of " << retryCount << " exceeded, will not attempt retry any more";
}
});
} else {
qDebug() << "Invalid retryCount=" << retryCount << " detected!";
}
}
*/
// Called when the websocket is closed. If this was closed without our explicitly closing it,
// then we need to try and reconnect
void WormholeClient::closed() {
qDebug() << "Closing websocket";
if (!shuttingDown) {
retryConnect();
}
}
void WormholeClient::onConnected()
{
retryCount = 0;
qDebug() << "WebSocket connected, retryCount=" << retryCount;
QObject::connect(m_webSocket, &QWebSocket::textMessageReceived, this, &WormholeClient::onTextMessageReceived);
auto payload = QJsonDocument( QJsonObject { {"register", code} }).toJson();
qDebug() << "Sending register";
if (m_webSocket && m_webSocket->isValid()) {
m_webSocket->sendTextMessage(payload);
qDebug() << "Sent registration message with code=" << code;
// On connected, we'll also create a timer to ping it every 4 minutes, since the websocket
// will timeout after 5 minutes
timer = new QTimer(parent);
qDebug() << "Created QTimer";
QObject::connect(timer, &QTimer::timeout, [=]() {
qDebug() << "Timer timeout!";
try {
if (!shuttingDown && m_webSocket && m_webSocket->isValid()) {
auto payload = QJsonDocument(QJsonObject { {"ping", "ping"} }).toJson();
qint64 bytes = m_webSocket->sendTextMessage(payload);
qDebug() << "Sent ping, " << bytes << " bytes";
}
} catch (...) {
qDebug() << "Websocket is invalid, no ping sent!";
}
});
unsigned int interval = 1*60*1000; // 1 minute
timer->start(interval);
qDebug() << "Started timer with interval=" << interval;
} else {
qDebug() << "Invalid websocket object onConnected!";
}
}
void WormholeClient::onTextMessageReceived(QString message)
{
qDebug() << "Websocket received msg: " << message;
AppDataServer::getInstance()->processMessage(message, parent, std::make_shared<ClientWebSocket>(m_webSocket), AppConnectionType::INTERNET);
}
// ==============================
// AppDataServer
// ==============================
AppDataServer* AppDataServer::instance = nullptr;
QString AppDataServer::getWormholeCode(QString secretHex) {
qDebug() << "AppDataServer::getWormholeCode";
unsigned char* secret = new unsigned char[crypto_secretbox_KEYBYTES];
sodium_hex2bin(secret, crypto_secretbox_KEYBYTES, secretHex.toStdString().c_str(), crypto_secretbox_KEYBYTES*2,
NULL, NULL, NULL);
unsigned char* out1 = new unsigned char[crypto_hash_sha256_BYTES];
crypto_hash_sha256(out1, secret, crypto_secretbox_KEYBYTES);
unsigned char* out2 = new unsigned char[crypto_hash_sha256_BYTES];
crypto_hash_sha256(out2, out1, crypto_hash_sha256_BYTES);
char* wmcode = new char[crypto_hash_sha256_BYTES*2 + 1];
sodium_bin2hex(wmcode, crypto_hash_sha256_BYTES*2 + 1, out2, crypto_hash_sha256_BYTES);
QString wmcodehex(wmcode);
delete[] wmcode;
delete[] out2;
delete[] out1;
delete[] secret;
qDebug() << "Created wormhole secretHex=" << wmcodehex;
return wmcodehex;
}
QString AppDataServer::getSecretHex() {
QSettings s;
return s.value("mobileapp/secret", "").toString();
}
void AppDataServer::saveNewSecret(QString secretHex) {
QSettings().setValue("mobileapp/secret", secretHex);
if (secretHex.isEmpty())
setAllowInternetConnection(false);
}
bool AppDataServer::getAllowInternetConnection() {
return QSettings().value("mobileapp/allowinternet", false).toBool();
}
void AppDataServer::setAllowInternetConnection(bool allow) {
QSettings().setValue("mobileapp/allowinternet", allow);
}
void AppDataServer::saveLastConnectedOver(AppConnectionType type) {
QSettings().setValue("mobileapp/lastconnectedover", type);
}
AppConnectionType AppDataServer::getLastConnectionType() {
return (AppConnectionType) QSettings().value("mobileapp/lastconnectedover", AppConnectionType::DIRECT).toInt();
}
void AppDataServer::saveLastSeenTime() {
QSettings().setValue("mobileapp/lastseentime", QDateTime::currentSecsSinceEpoch());
}
QDateTime AppDataServer::getLastSeenTime() {
return QDateTime::fromSecsSinceEpoch(QSettings().value("mobileapp/lastseentime", 0).toLongLong());
}
void AppDataServer::setConnectedName(QString name) {
QSettings().setValue("mobileapp/connectedname", name);
}
QString AppDataServer::getConnectedName() {
return QSettings().value("mobileapp/connectedname", "").toString();
}
bool AppDataServer::isAppConnected() {
return !getConnectedName().isEmpty() &&
getLastSeenTime().daysTo(QDateTime::currentDateTime()) < 14;
}
void AppDataServer::connectAppDialog(MainWindow* parent) {
QDialog d(parent);
ui = new Ui_MobileAppConnector();
ui->setupUi(&d);
Settings::saveRestore(&d);
qDebug() << "connectAppDialog";
updateUIWithNewQRCode(parent);
updateConnectedUI();
QObject::connect(ui->btnDisconnect, &QPushButton::clicked, [=] () {
qDebug() << "Disconnecting";
QSettings().setValue("mobileapp/connectedname", "");
saveNewSecret("");
updateConnectedUI();
});
QObject::connect(ui->txtConnStr, &QLineEdit::cursorPositionChanged, [=](int, int) {
ui->txtConnStr->selectAll();
});
QObject::connect(ui->chkInternetConn, &QCheckBox::stateChanged, [=] (int state) {
if (state == Qt::Checked) {
}
qDebug() << "Updating QR";
updateUIWithNewQRCode(parent);
});
// If we're not listening for the app, then start the websockets
if (!parent->isWebsocketListening()) {
qDebug() << "websocket not listening";
QString wormholecode = "";
if (getAllowInternetConnection()) {
wormholecode = AppDataServer::getInstance()->getWormholeCode(AppDataServer::getInstance()->getSecretHex());
qDebug() << "Generated wormholecode=" << wormholecode;
}
parent->createWebsocket(wormholecode);
} else {
qDebug() << "no websocket not listening";
}
d.exec();
// If there is nothing connected when the dialog exits, then shutdown the websockets
if (!isAppConnected()) {
qDebug() << "no app connected, stopping websockets";
parent->stopWebsocket();
}
// Cleanup
tempSecret = "";
delete tempWormholeClient;
tempWormholeClient = nullptr;
delete ui;
ui = nullptr;
qDebug() << "Destroyed tempWormholeClient and ui";
}
void AppDataServer::updateUIWithNewQRCode(MainWindow* mainwindow) {
// Get the address of the localhost
auto addrList = QNetworkInterface::allAddresses();
// Find a suitable address
QString ipv4Addr;
for (auto addr : addrList) {
if (addr.isLoopback() || addr.protocol() == QAbstractSocket::IPv6Protocol)
continue;
ipv4Addr = addr.toString();
break;
}
if (ipv4Addr.isEmpty())
return;
QString uri = "ws://" + ipv4Addr + ":8777";
qDebug() << "Websocket URI: " << uri;
// Get a new secret
unsigned char* secretBin = new unsigned char[crypto_secretbox_KEYBYTES];
randombytes_buf(secretBin, crypto_secretbox_KEYBYTES);
char* secretHex = new char[crypto_secretbox_KEYBYTES*2 + 1];
sodium_bin2hex(secretHex, crypto_secretbox_KEYBYTES*2+1, secretBin, crypto_secretbox_KEYBYTES);
QString secretStr(secretHex);
QString codeStr = uri + "," + secretStr;
if (ui->chkInternetConn->isChecked()) {
codeStr = codeStr + ",1";
}
registerNewTempSecret(secretStr, ui->chkInternetConn->isChecked(), mainwindow);
ui->qrcode->setQrcodeString(codeStr);
ui->txtConnStr->setText(codeStr);
qDebug() << "New QR="<<codeStr;
}
void AppDataServer::registerNewTempSecret(QString tmpSecretHex, bool allowInternet, MainWindow* main) {
qDebug() << "Registering new tempSecret, allowInternet=" << allowInternet;
tempSecret = tmpSecretHex;
delete tempWormholeClient;
tempWormholeClient = nullptr;
if (allowInternet) {
tempWormholeClient = new WormholeClient(main, getWormholeCode(tempSecret));
qDebug() << "Created new wormhole client";
}
}
QString AppDataServer::connDesc(AppConnectionType t) {
if (t == AppConnectionType::DIRECT) {
return QObject::tr("Connected directly");
}
else {
return QObject::tr("Connected over the internet via SilentDragon wormhole service");
}
}
void AppDataServer::updateConnectedUI() {
if (ui == nullptr)
return;
auto remoteName = getConnectedName();
ui->lblRemoteName->setText(remoteName.isEmpty() ? "(Not connected to any device)" : remoteName);
ui->lblLastSeen->setText(remoteName.isEmpty() ? "" : getLastSeenTime().toString(Qt::SystemLocaleLongDate));
ui->lblConnectionType->setText(remoteName.isEmpty() ? "" : connDesc(getLastConnectionType()));
ui->btnDisconnect->setEnabled(!remoteName.isEmpty());
}
QString AppDataServer::getNonceHex(NonceType nt) {
QSettings s;
QString hex;
if (nt == NonceType::LOCAL) {
// The default local nonce starts from 1, to always keep it odd
auto defaultLocalNonce = "01" + QString("00").repeated(crypto_secretbox_NONCEBYTES-1);
hex = s.value("mobileapp/localnoncehex", defaultLocalNonce).toString();
}
else {
hex = s.value("mobileapp/remotenoncehex", QString("00").repeated(crypto_secretbox_NONCEBYTES)).toString();
}
return hex;
}
void AppDataServer::saveNonceHex(NonceType nt, QString noncehex) {
QSettings s;
assert(noncehex.length() == crypto_secretbox_NONCEBYTES * 2);
if (nt == NonceType::LOCAL) {
s.setValue("mobileapp/localnoncehex", noncehex);
}
else {
s.setValue("mobileapp/remotenoncehex", noncehex);
}
s.sync();
}
// Encrypt an outgoing message with the stored secret key.
QString AppDataServer::encryptOutgoing(QString msg) {
// This padding size is ~50% larger than current largest
// message size and makes all current message types
// indistinguishable. If some new message type can
// be larger than this, the padding should probably be increased
int padding = 16*1024;
qDebug() << "Encrypt msg(pad="<<padding<<") prepad len=" << msg.length();
if (msg.length() % padding > 0) {
msg = msg + QString(" ").repeated(padding - (msg.length() % padding));
}
qDebug() << "Encrypt msg postpad len=" << msg.length();
QString localNonceHex = getNonceHex(NonceType::LOCAL);
unsigned char* noncebin = new unsigned char[crypto_secretbox_NONCEBYTES];
sodium_hex2bin(noncebin, crypto_secretbox_NONCEBYTES, localNonceHex.toStdString().c_str(), localNonceHex.length(),
NULL, NULL, NULL);
// Increment the nonce +2 and save
sodium_increment(noncebin, crypto_secretbox_NONCEBYTES);
sodium_increment(noncebin, crypto_secretbox_NONCEBYTES);
char* newLocalNonce = new char[crypto_secretbox_NONCEBYTES*2 + 1];
sodium_memzero(newLocalNonce, crypto_secretbox_NONCEBYTES*2 + 1);
sodium_bin2hex(newLocalNonce, crypto_secretbox_NONCEBYTES*2+1, noncebin, crypto_box_NONCEBYTES);
saveNonceHex(NonceType::LOCAL, QString(newLocalNonce));
unsigned char* secret = new unsigned char[crypto_secretbox_KEYBYTES];
sodium_hex2bin(secret, crypto_secretbox_KEYBYTES, getSecretHex().toStdString().c_str(), crypto_secretbox_KEYBYTES*2,
NULL, NULL, NULL);
int msgSize = strlen(msg.toStdString().c_str());
unsigned char* encrpyted = new unsigned char[ msgSize + crypto_secretbox_MACBYTES];
crypto_secretbox_easy(encrpyted, (const unsigned char *)msg.toStdString().c_str(), msgSize, noncebin, secret);
int encryptedHexSize = (msgSize + crypto_secretbox_MACBYTES) * 2 + 1;
char * encryptedHex = new char[encryptedHexSize];
sodium_memzero(encryptedHex, encryptedHexSize);
sodium_bin2hex(encryptedHex, encryptedHexSize, encrpyted, msgSize + crypto_secretbox_MACBYTES);
auto json = QJsonDocument(QJsonObject{
{"nonce", QString(newLocalNonce)},
{"payload", QString(encryptedHex)},
{"to", getWormholeCode(getSecretHex())}
});
delete[] noncebin;
delete[] newLocalNonce;
delete[] secret;
delete[] encrpyted;
delete[] encryptedHex;
return json.toJson();
}
/**
Attempt to decrypt a message. If the decryption fails, it returns the string "error", the decrypted message otherwise.
It will use the given secret to attempt decryption. In addition, it will enforce that the nonce is greater than the last seen nonce,
unless the skipNonceCheck = true, which is used when attempting decrytption with a temp secret key.
*/
QString AppDataServer::decryptMessage(QJsonDocument msg, QString secretHex, QString lastRemoteNonceHex) {
qDebug() << "Decrypting message";
// Decrypt and then process
QString noncehex = msg.object().value("nonce").toString();
QString encryptedhex = msg.object().value("payload").toString();
// Enforce limits on the size of the message
int MAX_LENGTH = 2*50*1024; // 50kb
if (noncehex.length() > ((int)crypto_secretbox_NONCEBYTES * 2) || encryptedhex.length() > MAX_LENGTH) {
qDebug() << "Encrypted hex size of " << encryptedhex.length() << " bytes is too large!";
return "error";
}
// Check to make sure that the nonce is greater than the last known remote nonce
unsigned char* lastRemoteBin = new unsigned char[crypto_secretbox_NONCEBYTES];
sodium_hex2bin(lastRemoteBin, crypto_secretbox_NONCEBYTES, lastRemoteNonceHex.toStdString().c_str(), lastRemoteNonceHex.length(),
NULL, NULL, NULL);
unsigned char* noncebin = new unsigned char[crypto_secretbox_NONCEBYTES];
sodium_hex2bin(noncebin, crypto_secretbox_NONCEBYTES, noncehex.toStdString().c_str(), noncehex.length(),
NULL, NULL, NULL);
assert(crypto_secretbox_KEYBYTES == crypto_hash_sha256_BYTES);
if (sodium_compare(lastRemoteBin, noncebin, crypto_secretbox_NONCEBYTES) != -1) {
// Refuse to accept a lower nonce, return an error
delete[] lastRemoteBin;
delete[] noncebin;
qDebug() << "Repeated nonce detected, potential attack or misconfiguration! Bailing out.";
return "error";
}
unsigned char* secret = new unsigned char[crypto_secretbox_KEYBYTES];
sodium_hex2bin(secret, crypto_secretbox_KEYBYTES, secretHex.toStdString().c_str(), crypto_secretbox_KEYBYTES*2,
NULL, NULL, NULL);
unsigned char* encrypted = new unsigned char[encryptedhex.length() / 2];
sodium_hex2bin(encrypted, encryptedhex.length() / 2, encryptedhex.toStdString().c_str(), encryptedhex.length(),
NULL, NULL, NULL);
int decryptedLen = encryptedhex.length() / 2 - crypto_secretbox_MACBYTES;
unsigned char* decrypted = new unsigned char[decryptedLen];
int result = crypto_secretbox_open_easy(decrypted, encrypted, encryptedhex.length() / 2, noncebin, secret);
QString payload;
if (result == -1) {
payload = "error";
} else {
// Update the last seen remote hex
saveNonceHex(NonceType::REMOTE, noncehex);
saveLastSeenTime();
char* decryptedStr = new char[decryptedLen + 1];
sodium_memzero(decryptedStr, decryptedLen + 1);
memcpy(decryptedStr, decrypted, decryptedLen);
payload = QString(decryptedStr);
delete[] decryptedStr;
}
delete[] secret;
delete[] lastRemoteBin;
delete[] noncebin;
delete[] encrypted;
delete[] decrypted;
qDebug() << "Returning decrypted payload="<<payload;
return payload;
}
// Process an incoming text message. The message has to be encrypted with the secret key (or the temporary secret key)
void AppDataServer::processMessage(QString message, MainWindow* mainWindow, std::shared_ptr<ClientWebSocket> pClient, AppConnectionType connType) {
qDebug() << "processMessage message";
//qDebug() << "processMessage message=" << message; // this can log sensitive info
auto replyWithError = [=]() {
auto r = QJsonDocument(QJsonObject{
{"error", "Encryption error"},
{"to", getWormholeCode(getSecretHex())}
}).toJson();
pClient->sendTextMessage(r);
return;
};
// First, extract the command from the message
auto msg = QJsonDocument::fromJson(message.toUtf8());
// Check if we got an error from the websocket
if (msg.object().contains("error")) {
qDebug() << "Error:" << msg.toJson();
return;
}
// If the message is a ping, just ignore it
if (msg.object().contains("ping")) {
return;
}
// Then, check if the message is encrpted
if (!msg.object().contains("nonce")) {
replyWithError();
return;
}
auto decrypted = decryptMessage(msg, getSecretHex(), getNonceHex(NonceType::REMOTE));
// If the decryption failed, maybe this is a new connection, so see if the dialog is open and a
// temp secret is in place
if (decrypted == "error") {
// If the dialog is open, then there might be a temporary, new secret key. Attempt to decrypt
// with that.
if (!tempSecret.isEmpty()) {
// Since this is a temp secret, the last seen nonce will be "0", so basically we'll accept any nonce
QString zeroNonce = QString("00").repeated(crypto_secretbox_NONCEBYTES);
decrypted = decryptMessage(msg, tempSecret, zeroNonce);
if (decrypted == "error") {
// Oh, well. Just return an error
replyWithError();
return;
}
else {
// This is a new connection. So, update the the secret. Note the last seen remote nonce has already been updated by
// decryptMessage()
saveNewSecret(tempSecret);
setAllowInternetConnection(tempWormholeClient != nullptr);
// Swap out the wormhole connection
mainWindow->replaceWormholeClient(tempWormholeClient);
tempWormholeClient = nullptr;
saveLastConnectedOver(connType);
processDecryptedMessage(decrypted, mainWindow, pClient);
// If the Connection UI is showing, we have to update the UI as well
if (ui != nullptr) {
// Update the connected phone information
updateConnectedUI();
// Update with a new QR Code for safety, so this secret isn't used by anyone else
updateUIWithNewQRCode(mainWindow);
}
return;
}
}
else {
replyWithError();
return;
}
} else {
saveLastConnectedOver(connType);
processDecryptedMessage(decrypted, mainWindow, pClient);
return;
}
}
// Decrypted method will be executed here.
void AppDataServer::processDecryptedMessage(QString message, MainWindow* mainWindow, std::shared_ptr<ClientWebSocket> pClient) {
//qDebug() << "processDecryptedMessage message=" << message;
// First, extract the command from the message
auto msg = QJsonDocument::fromJson(message.toUtf8());
if (!msg.object().contains("command")) {
auto r = QJsonDocument(QJsonObject{
{"errorCode", -1},
{"errorMessage", "Unknown JSON format"}
}).toJson();
pClient->sendTextMessage(encryptOutgoing(r));
return;
}
if (msg.object()["command"] == "getInfo") {
processGetInfo(msg.object(), mainWindow, pClient);
}
else if (msg.object()["command"] == "getTransactions") {
processGetTransactions(mainWindow, pClient);
}
else if (msg.object()["command"] == "sendTx") {
processSendTx(msg.object()["tx"].toObject(), mainWindow, pClient);
}
else {
auto r = QJsonDocument(QJsonObject{
{"errorCode", -1},
{"errorMessage", "Command not found:" + msg.object()["command"].toString()}
}).toJson();
pClient->sendTextMessage(encryptOutgoing(r));
}
}
// "sendTx" command. This method will actually send money, so be careful with everything
void AppDataServer::processSendTx(QJsonObject sendTx, MainWindow* mainwindow, std::shared_ptr<ClientWebSocket> pClient) {
qDebug() << "processSendTx with to=" << sendTx["to"].toString();
auto error = [=](QString reason) {
auto r = QJsonDocument(QJsonObject{
{"errorCode", -1},
{"errorMessage", "Couldn't send Tx:" + reason}
}).toJson();
pClient->sendTextMessage(encryptOutgoing(r));
return;
};
// Refuse to send if the node is still syncing
if (Settings::getInstance()->isSyncing()) {
error(QObject::tr("Node is still syncing."));
return;
}
// Create a Tx Object
Tx tx;
tx.fee = Settings::getMinerFee();
// Find a from address that has at least the sending amout
double amt = sendTx["amount"].toString().toDouble();
auto allBalances = mainwindow->getRPC()->getAllBalances();
QList<QPair<QString, double>> bals;
for (auto i : allBalances->keys()) {
// Filter out balances that don't have the requisite amount
// TODO: should this be amt+tx.fee?
if (allBalances->value(i) < amt)
continue;
bals.append(QPair<QString, double>(i, allBalances->value(i)));
}
if (bals.isEmpty()) {
error(QObject::tr("No addresses with enough balance to spend! Try sweeping funds into one address"));
return;
}
std::sort(bals.begin(), bals.end(), [=](const QPair<QString, double>a, const QPair<QString, double> b) -> bool {
// Sort z addresses first
return a.first > b.first;
});
tx.fromAddr = bals[0].first;
tx.toAddrs = { ToFields{ sendTx["to"].toString(), amt, sendTx["memo"].toString(), sendTx["memo"].toString().toUtf8().toHex()} };
// TODO: Respect the autoshield change setting
QString validation = mainwindow->doSendTxValidations(tx);
if (!validation.isEmpty()) {
error(validation);
return;
}
QJsonArray params;
mainwindow->getRPC()->fillTxJsonParams(params, tx);
//std::cout << std::setw(2) << params << std::endl;
// And send the Tx
mainwindow->getRPC()->executeTransaction(tx,
[=] (QString) {},
// Submitted Tx successfully
[=] (QString, QString txid) {
auto r = QJsonDocument(QJsonObject{
{"version", 1.0},
{"command", "sendTxSubmitted"},
{"txid", txid}
}).toJson();
pClient->sendTextMessage(encryptOutgoing(r));
},
// Errored while submitting Tx
[=] (QString, QString errStr) {
auto r = QJsonDocument(QJsonObject{
{"version", 1.0},
{"command", "sendTxFailed"},
{"err", errStr}
}).toJson();
pClient->sendTextMessage(encryptOutgoing(r));
}
);
auto r = QJsonDocument(QJsonObject{
{"version", 1.0},
{"command", "sendTx"},
{"result", "success"}
}).toJson();
pClient->sendTextMessage(encryptOutgoing(r));
}
// "getInfo" command
void AppDataServer::processGetInfo(QJsonObject jobj, MainWindow* mainWindow, std::shared_ptr<ClientWebSocket> pClient) {
auto connectedName = jobj["name"].toString();
if (mainWindow == nullptr || mainWindow->getRPC() == nullptr ||
mainWindow->getRPC()->getAllBalances() == nullptr) {
pClient->close(QWebSocketProtocol::CloseCodeNormal, "Not yet ready");
return;
}
// Max spendable safely from a z address and from any address
double maxZSpendable = 0;
double maxSpendable = 0;
for (auto a : mainWindow->getRPC()->getAllBalances()->keys()) {
if (Settings::getInstance()->isSaplingAddress(a)) {
if (mainWindow->getRPC()->getAllBalances()->value(a) > maxZSpendable) {
maxZSpendable = mainWindow->getRPC()->getAllBalances()->value(a);
}
}
if (mainWindow->getRPC()->getAllBalances()->value(a) > maxSpendable) {
maxSpendable = mainWindow->getRPC()->getAllBalances()->value(a);
}
}
setConnectedName(connectedName);
auto r = QJsonDocument(QJsonObject{
{"version", 1.0},
{"command", "getInfo"},
{"saplingAddress", mainWindow->getRPC()->getDefaultSaplingAddress()},
{"tAddress", mainWindow->getRPC()->getDefaultTAddress()},
{"balance", AppDataModel::getInstance()->getTotalBalance()},
{"maxspendable", maxSpendable},
{"maxzspendable", maxZSpendable},
{"tokenName", Settings::getTokenName()},
// changing this will break SDA
{"zecprice", Settings::getInstance()->getHUSHPrice()},
{"serverversion", QString(APP_VERSION)}
}).toJson();
pClient->sendTextMessage(encryptOutgoing(r));
}
void AppDataServer::processGetTransactions(MainWindow* mainWindow, std::shared_ptr<ClientWebSocket> pClient) {
QJsonArray txns;
auto model = mainWindow->getRPC()->getTransactionsModel();
qDebug() << "processGetTransactions";
// Manually add pending ops, so that computing transactions will also show up
auto wtxns = mainWindow->getRPC()->getWatchingTxns();
for (auto opid : wtxns.keys()) {
txns.append(QJsonObject{
{"type", "send"},
{"datetime", QDateTime::currentSecsSinceEpoch()},
{"amount", Settings::getDecimalString(wtxns[opid].tx.toAddrs[0].amount)},
{"txid", ""},
{"address", wtxns[opid].tx.toAddrs[0].addr},
{"memo", wtxns[opid].tx.toAddrs[0].txtMemo},
{"confirmations", 0}
});
}
// Add transactions
for (int i = 0; i < model->rowCount(QModelIndex()) && i < Settings::getMaxMobileAppTxns(); i++) {
txns.append(QJsonObject{
{"type", model->getType(i)},
{"datetime", model->getDate(i)},
{"amount", model->getAmt(i)},
{"txid", model->getTxId(i)},
{"address", model->getAddr(i)},
{"memo", model->getMemo(i)},
{"confirmations", model->getConfirmations(i)}
});
}
auto r = QJsonDocument(QJsonObject{
{"version", 1.0},
{"command", "getTransactions"},
{"transactions", txns}
}).toJson();
pClient->sendTextMessage(encryptOutgoing(r));
}
// ==============================
// AppDataModel
// ==============================
AppDataModel* AppDataModel::instance = nullptr;

177
src/websockets.h

@ -1,177 +0,0 @@
#ifndef WEBSOCKETS_H
#define WEBSOCKETS_H
#include "precompiled.h"
#include "mainwindow.h"
#include "ui_mobileappconnector.h"
QT_FORWARD_DECLARE_CLASS(QWebSocketServer)
QT_FORWARD_DECLARE_CLASS(QWebSocket)
class WSServer;
// We're going to wrap the websocket in this class, because the underlying QWebSocket might get closed
// or deleted while a callback is waiting to get the data back. Therefore, we write a custom "sendTextMessage"
// class that checks all this before sending.
class ClientWebSocket {
public:
ClientWebSocket(QWebSocket* c, WSServer* s = nullptr) { client = c; server = s; }
void sendTextMessage(QString m);
void close(QWebSocketProtocol::CloseCode code, const QString& msg) { client->close(code, msg); }
private:
QWebSocket* client;
WSServer* server;
};
class WSServer : public QObject
{
Q_OBJECT
public:
explicit WSServer(quint16 port, bool debug = false, QObject *parent = nullptr);
bool isValidConnection(QWebSocket* c) { return m_clients.contains(c); }
~WSServer();
Q_SIGNALS:
void closed();
private Q_SLOTS:
void onNewConnection();
void processTextMessage(QString message);
void processBinaryMessage(QByteArray message);
void socketDisconnected();
private:
QWebSocketServer *m_pWebSocketServer;
MainWindow *m_mainWindow;
QList<QWebSocket *> m_clients;
bool m_debug;
};
class WormholeClient : public QObject {
Q_OBJECT
private Q_SLOTS:
void onConnected();
void onTextMessageReceived(QString message);
void closed();
public:
WormholeClient(MainWindow* parent, QString wormholeCode);
~WormholeClient();
void connect();
void retryConnect();
void sslerrors(const QList<QSslError> &);
private:
MainWindow* parent = nullptr;
QWebSocket* m_webSocket = nullptr;
QTimer* timer = nullptr;
QString code;
unsigned int retryCount = 0;
bool shuttingDown = false;
};
enum NonceType {
LOCAL = 1,
REMOTE
};
enum AppConnectionType {
DIRECT = 1,
INTERNET
};
class AppDataServer {
public:
static AppDataServer* getInstance() {
if (instance == nullptr) {
instance = new AppDataServer();
}
return instance;
}
void connectAppDialog(MainWindow* parent);
void updateConnectedUI();
void updateUIWithNewQRCode(MainWindow* mainwindow);
void processSendTx(QJsonObject sendTx, MainWindow* mainwindow, std::shared_ptr<ClientWebSocket> pClient);
void processMessage(QString message, MainWindow* mainWindow, std::shared_ptr<ClientWebSocket> pClient, AppConnectionType connType);
void processGetInfo(QJsonObject jobj, MainWindow* mainWindow, std::shared_ptr<ClientWebSocket> pClient);
void processDecryptedMessage(QString message, MainWindow* mainWindow, std::shared_ptr<ClientWebSocket> pClient);
void processGetTransactions(MainWindow* mainWindow, std::shared_ptr<ClientWebSocket> pClient);
QString decryptMessage(QJsonDocument msg, QString secretHex, QString lastRemoteNonceHex);
QString encryptOutgoing(QString msg);
QString getWormholeCode(QString secretHex);
QString getSecretHex();
void saveNewSecret(QString secretHex);
void registerNewTempSecret(QString tmpSecretHex, bool allowInternet, MainWindow* main);
QString getNonceHex(NonceType nt);
void saveNonceHex(NonceType nt, QString noncehex);
bool getAllowInternetConnection();
void setAllowInternetConnection(bool allow);
void saveLastSeenTime();
QDateTime getLastSeenTime();
void setConnectedName(QString name);
QString getConnectedName();
bool isAppConnected();
QString connDesc(AppConnectionType t);
void saveLastConnectedOver(AppConnectionType type);
AppConnectionType getLastConnectionType();
private:
AppDataServer() = default;
static AppDataServer* instance;
Ui_MobileAppConnector* ui;
QString tempSecret;
WormholeClient* tempWormholeClient = nullptr;
};
class AppDataModel {
public:
static AppDataModel* getInstance() {
if (instance == NULL)
instance = new AppDataModel();
return instance;
}
double getTBalance() { return balTransparent; }
double getZBalance() { return balShielded; }
double getTotalBalance() { return balTotal; }
void setBalances(double transparent, double shielded) {
balTransparent = transparent;
balShielded = shielded;
balTotal = balTransparent + balShielded;
}
private:
AppDataModel() = default; // Private, for singleton
double balTransparent;
double balShielded;
double balTotal;
QString saplingAddress;
static AppDataModel* instance;
};
#endif // WEBSOCKETS_H

170
src/zboard.ui

@ -1,170 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>zboard</class>
<widget class="QDialog" name="zboard">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>588</width>
<height>431</height>
</rect>
</property>
<property name="windowTitle">
<string>Post to z-board.net</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="14" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Total Fee</string>
</property>
</widget>
</item>
<item row="14" column="1">
<widget class="QLabel" name="feeAmount">
<property name="text">
<string notr="true">feeamount</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="12" column="1">
<widget class="QLabel" name="memoSize">
<property name="text">
<string notr="true">0 / 512</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="16" column="0" colspan="2">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
<item row="12" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Memo</string>
</property>
</widget>
</item>
<item row="11" column="0" colspan="2">
<widget class="QLineEdit" name="postAs">
<property name="placeholderText">
<string>(optional)</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Send From</string>
</property>
</widget>
</item>
<item row="10" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Post As:</string>
</property>
</widget>
</item>
<item row="0" column="0" colspan="2">
<widget class="QLabel" name="label_2">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;ZBoard: Fully anonymous and untraceable chat messages based on the ZCash blockchain. &lt;a href=&quot;http://www.z-board.net/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;http://www.z-board.net/&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
<item row="13" column="0" colspan="2">
<widget class="QPlainTextEdit" name="memoTxt"/>
</item>
<item row="6" column="0" colspan="2">
<widget class="QComboBox" name="fromAddr"/>
</item>
<item row="15" column="0">
<widget class="QLabel" name="testnetWarning">
<property name="styleSheet">
<string notr="true">color:red;</string>
</property>
<property name="text">
<string>Warning</string>
</property>
</widget>
</item>
<item row="4" column="0" colspan="2">
<widget class="Line" name="line_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="topicsList"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Posting to Board</string>
</property>
</widget>
</item>
</layout>
</widget>
<tabstops>
<tabstop>fromAddr</tabstop>
<tabstop>postAs</tabstop>
<tabstop>memoTxt</tabstop>
</tabstops>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>zboard</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>zboard</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

9
util/silentdragon.desktop

@ -0,0 +1,9 @@
[Desktop Entry]
Version=1.0
Name=Silent Dragon
Comment=Full-node wallet for HUSH cryptocurrency
Exec=/usr/bin/silentdragon
Icon=/opt/silentdragon/silentdragon.png
Terminal=false
Type=Application
Categories=Network;

24
win-build-sdx.sh

@ -0,0 +1,24 @@
#!/bin/bash
# Copyright 2018-2023 The Hush Developers
# Released under the GPLv3
# This builds a binary called "silentdragonx"
set -e
# TODO: not ideal, hushd.exe should only be looked for on windoze
if [ -e "dragonxd" ]; then
echo "Found dragonxd binary"
elif [ -e "hushd.exe" ]; then
echo "Found hushd.exe binary"
else
echo "dragonxd could not be found!"
echo "Either copy the binary to this dir or make a symlink."
echo "This command will create a symlink to it if this repo is in the same directory as your hush3.git: "
echo "ln -s ../hush3/src/dragonxd"
echo "For windoze you should copy hushd.exe to this directory"
exit 1
fi
# Use a modified QT project file with same build.sh
SDCONF=silentdragonx.pro ./win-build.sh $@

38
win-build.sh

@ -1,24 +1,40 @@
#!/bin/bash #!/bin/bash
# Copyright 2019-2020 The Hush Developers # Copyright 2019-2022 The Hush Developers
# Released under the GPLv3 # Released under the GPLv3
# This script will cross-compile windoze binaries, hopefully! # This script will cross-compile windoze binaries, hopefully!
set -e set -e
UNAME=$(uname) UNAME=$(uname)
if [ "$UNAME" == "Linux" ] ; then #if [ "$UNAME" == "Linux" ] ; then
JOBS=$(nproc) # JOBS=$(nproc)
elif [ "$UNAME" == "FreeBSD" ] ; then #elif [ "$UNAME" == "FreeBSD" ] ; then
JOBS=$(nproc) # JOBS=$(nproc)
elif [ "$UNAME" == "Darwin" ] ; then #elif [ "$UNAME" == "Darwin" ] ; then
JOBS=$(sysctl -n hw.ncpu) # JOBS=$(sysctl -n hw.ncpu)
else #else
JOBS=1 JOBS=1
fi #fi
VERSION=$(cat src/version.h |cut -d\" -f2) VERSION=$(cat src/version.h |cut -d\" -f2)
echo "Compiling SilentDragon $VERSION with $JOBS threads..." CONF=${SDCONF:-silentdragon.pro}
CONF=silentdragon.pro WALLET="SilentDragon"
if [ "$CONF" == "silentdragonx.pro" ] ; then
WALLET="SilentDragonX"
fi
echo "Compiling $WALLET $VERSION with $JOBS threads..."
if ! command -v qmake &> /dev/null
then
echo "qmake could not be found. Please install QT and try again."
exit 1
fi
if ! command -v make &> /dev/null
then
echo "make could not be found. Please install it and try again."
exit 1
fi
qbuild () { qbuild () {
x86_64-w64-mingw32.static-qmake-qt5 $CONF CONFIG+=debug x86_64-w64-mingw32.static-qmake-qt5 $CONF CONFIG+=debug

Loading…
Cancel
Save