1
0
mirror of https://github.com/xmrig/xmrig.git synced 2025-12-06 15:42:38 -05:00

Compare commits

...

197 Commits

Author SHA1 Message Date
XMRig
9f778742a6 v6.13.0 2021-07-01 20:03:52 +07:00
XMRig
015f8aeed4 Merge branch 'dev' 2021-07-01 20:02:38 +07:00
xmrig
9e6311a7e0 Update CHANGELOG.md 2021-07-01 13:54:09 +07:00
XMRig
0af9d2e75b v6.13.0-dev 2021-06-28 19:02:48 +07:00
xmrig
6e2a84a46c Merge pull request #2445 from SChernykh/miner_signature
Support for solo mining with miner signatures (Wownero)
2021-06-28 18:11:13 +07:00
SChernykh
6bb8913066 Correct handling of block submit responses for Dero 2021-06-24 18:06:07 +02:00
SChernykh
cf104ebdc5 Update signing algorithm 2021-06-21 23:49:13 +02:00
XMRig
ecba750442 Add token support for online benchmark. 2021-06-20 09:28:39 +07:00
SChernykh
3967badc55 Added profiling 2021-06-19 16:19:16 +02:00
SChernykh
3f3f9b0661 Fixed GCC warnings 2021-06-19 14:54:03 +02:00
SChernykh
e3fc78a66c Fix Wownero hardfork version 2021-06-18 13:52:24 +02:00
SChernykh
e6d833c227 Proxy miner signature support 2021-06-17 22:48:08 +02:00
SChernykh
ebe299902c Proxy miner signature support (WIP) 2021-06-17 16:58:18 +02:00
SChernykh
bc63b63a2a More sanity checks 2021-06-17 13:18:34 +02:00
SChernykh
e739e7d704 More error handling in DaemonClient::parseJob 2021-06-17 10:39:22 +02:00
SChernykh
1bae083587 Fixed CalculateMerkleTreeHash 2021-06-17 10:26:17 +02:00
SChernykh
88959bd703 BlockTemplate: miner tx and root hash updating 2021-06-16 23:44:05 +02:00
SChernykh
93e689d601 Fix buffer size in generateMinerSignature 2021-06-16 18:20:11 +02:00
SChernykh
a136790bee Added support for solo mining with miner signatures (Wownero) 2021-06-16 18:07:36 +02:00
SChernykh
29f2dd4b9e Cleanup 2021-06-16 11:47:17 +02:00
SChernykh
3003c067d3 Fixed random32_unbiased 2021-06-16 00:19:49 +02:00
SChernykh
89bc6418b1 Secret key derivation 2021-06-16 00:10:34 +02:00
SChernykh
8458b4ee39 Added signature functions 2021-06-15 15:51:29 +02:00
SChernykh
7bfb801ce2 Cryptonote tools WIP 2021-06-15 00:28:32 +02:00
xmrig
4567499905 Merge pull request #2433 from candrews/patch-2
Fix shellcheck warnings in randomx_boost.sh
2021-06-09 23:41:58 +07:00
Craig Andrews
9b63955b09 Fix shellcheck warnings in randomx_boost.sh
Checked using www.shellcheck.net

Specific issues addessed:
* https://github.com/koalaman/shellcheck/wiki/SC2002
* Use POSIX instead of bash for wider compatibility
* Fail on error
2021-06-08 21:56:02 -04:00
XMRig
0414511de0 v6.12.3-dev 2021-05-31 13:51:41 +07:00
XMRig
b61dad128c Merge branch 'master' into dev 2021-05-31 13:49:35 +07:00
XMRig
80ae339343 v6.12.2 2021-05-31 12:58:30 +07:00
XMRig
4d87555398 Merge branch 'dev' 2021-05-31 12:57:55 +07:00
xmrig
bef82c5de6 Update CHANGELOG.md 2021-05-30 21:28:28 +07:00
xmrig
b069ad5dd1 Merge pull request #2358 from zzjzxq33/patch-1
Update openssl version to 1.1.1k
2021-05-30 17:53:53 +07:00
xmrig
f6a0646271 Merge pull request #2401 from SChernykh/dev
RandomX: fix broken light mode mining
2021-05-22 18:54:29 +07:00
SChernykh
b5f1a1feae RandomX: fix broken light mode mining
It broke after #2395
2021-05-22 13:49:22 +02:00
XMRig
1ce059da1c Add "argon2/ninja" algorithm alias. 2021-05-22 15:10:50 +07:00
xmrig
2929451ee1 Merge pull request #2398 from SChernykh/dev
RandomX ARMv8: optimized dataset read
2021-05-21 09:58:54 +07:00
SChernykh
94fecb5e92 RandomX ARMv8: optimized dataset read
Break dependency from readReg2 and readReg3. It should run faster on superscalar and out-of-order CPUs i.e. Apple M1.
2021-05-20 21:24:28 +02:00
xmrig
3bfa5ea038 Merge pull request #2395 from SChernykh/dev
RandomX: rewrote dataset read code
2021-05-20 18:58:48 +07:00
SChernykh
ff82ca57f2 RandomX: rewrote dataset read code
Unified code for AMD and Intel
1% faster on Intel
0.15% faster on AMD Ryzen
2021-05-20 12:45:42 +02:00
xmrig
7f7b1fb073 Merge pull request #2393 from SChernykh/dev
RandomX: added BMI2 version for scratchpad prefetch
2021-05-19 22:54:58 +07:00
SChernykh
d443dd86f1 RandomX: added BMI2 version for scratchpad prefetch
Saves 1 instruction and 1 byte in the main loop.
2021-05-19 17:52:16 +02:00
xmrig
3ac8f6b23a Merge pull request #2386 from SChernykh/dev
Enabled IMUL_RCP optimization for light mode mining
2021-05-17 16:36:23 +07:00
SChernykh
9b1f020a8b Enabled IMUL_RCP optimization for light mode mining
Better fix for #2377
2021-05-17 11:26:40 +02:00
XMRig
8bf88a4e74 Merge branch 'Spudz76-dev-fixCLKawPowPlatformHandling' into dev 2021-05-16 10:10:33 +07:00
XMRig
08a2c143f5 Regenerate OpenCL headers. 2021-05-16 10:09:29 +07:00
Tony Butler
4eb9a1aad5 Fix CL code for KawPow where it assumes everything is AMD 2021-05-15 20:34:57 -06:00
xmrig
c8c40586a1 Merge pull request #2378 from SChernykh/dev
Fixed broken light mode mining on x86
2021-05-16 07:03:57 +07:00
SChernykh
29cb416107 Fixed broken light mode mining on x86 2021-05-15 21:41:39 +02:00
xmrig
465169ff12 Merge pull request #2375 from Spudz76/dev-fixMacOSCudaLoader
Fixup MacOS CUDA backend default loader name
2021-05-14 18:48:09 +07:00
Tony Butler
df2bcd8192 Fixup MacOS CUDA backend default loader name 2021-05-14 05:28:31 -06:00
zzjzxq33
d89bb56964 Update openssl version to 1.1.1k 2021-05-09 11:11:46 +08:00
XMRig
87a0864e3b ...and --cpu-affinity. 2021-05-08 04:36:09 +07:00
XMRig
ecf5579f36 #2351 Fixed help output for --cpu-priority option. 2021-05-08 04:34:22 +07:00
xmrig
d5523d819f Merge pull request #2341 from SChernykh/dev
Update sse2neon.h
2021-05-03 23:17:12 +07:00
SChernykh
dbda2e9ccd Update sse2neon.h 2021-05-03 18:08:59 +02:00
xmrig
8babd7bc0a Merge pull request #2340 from SChernykh/dev
Fix AES detection on FreeBSD on ARM
2021-05-03 19:06:49 +07:00
SChernykh
27ced139a6 Fix AES detection on FreeBSD on ARM 2021-05-03 09:57:43 +02:00
xmrig
b46849e813 Merge pull request #2322 from SChernykh/dev
Update randomx_boost.sh
2021-04-28 19:12:37 +07:00
SChernykh
a96a6108ff Update randomx_boost.sh
- Support builtin MSR, see #2283
- Added detection of AMD EPYC CPUs
2021-04-28 14:10:30 +02:00
xmrig
c50c78b700 Merge pull request #2312 from SChernykh/dev
Add  missing allow_writes=on to randomx_boost.sh
2021-04-25 20:46:07 +07:00
SChernykh
cd7ab2c79f Add missing allow_writes=on to randomx_boost.sh 2021-04-25 15:31:30 +02:00
XMRig
695fbc013b #2280 Disable GPU backends in benchmark mode. 2021-04-25 15:28:45 +07:00
XMRig
a403c53543 Merge branch 'jsonboss-patch-1' into dev 2021-04-24 23:22:56 +07:00
XMRig
e26fbc96e9 Removed unnecessary system call. 2021-04-24 23:22:10 +07:00
XMRig
259c165e60 Merge branch 'patch-1' of https://github.com/jsonboss/xmrig into jsonboss-patch-1 2021-04-24 22:14:59 +07:00
XMRig
7897bf02dc v6.12.2-dev 2021-04-24 01:53:07 +07:00
XMRig
05f62c5ccc Merge branch 'master' into dev 2021-04-24 01:52:37 +07:00
XMRig
d82e100e30 v6.12.1 2021-04-23 19:43:12 +07:00
XMRig
5f869a414c Merge branch 'dev' 2021-04-23 19:42:29 +07:00
xmrig
7fd6be7d83 Update CHANGELOG.md 2021-04-23 18:54:42 +07:00
xmrig
ae6c536e98 Merge pull request #2296 from SChernykh/dev
Fixed Zen3 asm for cn/upx2
2021-04-21 19:52:52 +07:00
XMRig
c66c593123 v6.12.1-dev 2021-04-21 19:51:03 +07:00
XMRig
b3788b2ba3 Merge branch 'master' into dev 2021-04-21 19:49:54 +07:00
SChernykh
b7adb34c37 Fixed Zen3 asm for cn/upx2
- Invalid rounding mode was used which caused rejected shares sometimes
- Also optimized CN implode/explode functions a bit.
2021-04-21 13:22:25 +02:00
XMRig
ace8409a56 v6.12.0 2021-04-20 20:55:58 +07:00
XMRig
e2c757d9dd Merge branch 'dev' 2021-04-20 20:55:35 +07:00
xmrig
da35de993f Update CHANGELOG.md 2021-04-19 23:20:10 +07:00
xmrig
854b7618ef Merge pull request #2289 from SChernykh/dev
RandomX: optimized IMUL_RCP instruction
2021-04-19 22:54:02 +07:00
SChernykh
3477f9fbc1 RandomX: optimized IMUL_RCP instruction
+0.4% on AMD Zen2
+0.3% on AMD Zen3
+0.1% on Intel SandyBridge
+0.3% on rx/wow on Intel SandyBridge
2021-04-19 17:43:58 +02:00
xmrig
5799744f2f Update CHANGELOG.md 2021-04-19 20:56:45 +07:00
xmrig
61d165a314 Merge pull request #2287 from SChernykh/dev
Fixed rounding mode after running cn/upx
2021-04-19 18:06:16 +07:00
SChernykh
69186f2470 Optimized cn/upx for Zen3
0.9% faster
2021-04-19 12:29:44 +02:00
SChernykh
730d4a6cee Fix dvision by zero check in percent() 2021-04-19 12:05:07 +02:00
SChernykh
54bc91d5e3 Fixed rounding mode after running cn/upx 2021-04-19 12:02:57 +02:00
jsonboss
2012ffb231 support builtin msr 2021-04-19 10:38:27 +08:00
XMRig
5f9e0ebc6c v6.12.0-dev 2021-04-18 20:12:03 +07:00
xmrig
f314c69a70 Merge pull request #2278 from SChernykh/dev
Optimized cn/upx2
2021-04-17 23:41:26 +07:00
SChernykh
16fe462cad Optimized cn/upx2 for Ryzen CPUs 2021-04-17 18:18:26 +02:00
xmrig
e6e2987ddf Merge pull request #2276 from SChernykh/dev
Added support for Uplexa (cn/upx2 algorithm)
2021-04-17 20:10:54 +07:00
SChernykh
ed456b02cf Update CnHash.cpp 2021-04-17 15:06:31 +02:00
SChernykh
da7f5826cb Added support for Uplexa (cn/upx2 algorithm) 2021-04-17 14:53:42 +02:00
XMRig
6cb398bb42 Merge branch 'dev' of github.com:xmrig/xmrig into dev 2021-04-14 23:44:42 +07:00
XMRig
748be760e8 Added support for --user command line option for the benchmark. 2021-04-14 23:43:31 +07:00
xmrig
4a4118bb8e Merge pull request #2261 from SChernykh/dev
Show total hashrate if compiled without OpenCL
2021-04-13 19:06:42 +07:00
SChernykh
77f1bf0861 Show total hashrate if compiled without OpenCL 2021-04-13 14:02:29 +02:00
XMRig
6bb29b3e7b v6.11.3-dev 2021-04-11 21:13:39 +07:00
XMRig
f720772338 Merge branch 'master' into dev 2021-04-11 21:13:08 +07:00
XMRig
e53e48b88c v6.11.2 2021-04-11 17:24:46 +07:00
XMRig
ecf36ee891 Merge branch 'dev' 2021-04-11 17:24:23 +07:00
xmrig
23ef949dd3 Update CHANGELOG.md 2021-04-11 11:45:07 +07:00
XMRig
92e708c6e7 Update llhttp to v5.1.0 2021-04-10 21:23:32 +07:00
XMRig
30cfcc27db #2207 Fixed regression in HTTP parser. 2021-04-10 21:02:59 +07:00
XMRig
3c6077fb02 v6.11.2-dev 2021-04-08 00:33:01 +07:00
XMRig
63883b4fa7 Merge branch 'master' into dev 2021-04-08 00:32:21 +07:00
XMRig
0f83b5e06c v6.11.1 2021-04-07 10:34:37 +07:00
XMRig
637a333197 Merge branch 'dev' 2021-04-07 10:33:48 +07:00
xmrig
3171b06048 Update CHANGELOG.md 2021-04-07 10:32:17 +07:00
xmrig
2a66a0fa2f Merge pull request #2239 from SChernykh/dev
Fixed broken "coin" setting functionality
2021-04-07 10:30:28 +07:00
SChernykh
c080d5b962 Fixed broken "coin" setting functionality 2021-04-06 23:02:10 +02:00
XMRig
0133107f14 v6.11.0 2021-04-06 21:11:44 +07:00
XMRig
253e349ef9 Merge branch 'dev' 2021-04-06 21:11:13 +07:00
xmrig
5126cc1414 Update CHANGELOG.md 2021-04-06 15:48:18 +07:00
XMRig
ea1245026d #2234 Use const_cast. 2021-04-06 12:07:06 +07:00
xmrig
2158adb711 Merge pull request #2234 from esrrhs/dev
fix build error on gcc 4.8.5
2021-04-06 12:00:36 +07:00
xmrig
8554bb4d9c Merge pull request #2235 from SChernykh/dev
Fixed cn-heavy for GCC-8
2021-04-04 18:09:09 +07:00
SChernykh
1741354498 Fixed cn-heavy for GCC-8 2021-04-04 10:18:27 +02:00
esrrhs
866e97efcf fix build error on gcc 9.3.0
FileLogWriter.h:34:41: error: array used as initializer
2021-04-04 12:42:14 +08:00
xmrig
277352d072 Merge pull request #2233 from SChernykh/dev
Fixed compilation for ARM
2021-04-03 23:03:05 +07:00
SChernykh
8cae605e1f Update randomx.cmake 2021-04-03 17:59:28 +02:00
SChernykh
59c85eaf6a Fixed compilation for ARM 2021-04-03 17:50:52 +02:00
xmrig
864233c110 Merge pull request #2228 from esrrhs/dev
remove useless v4_random_math_init if algo is not cn/r
2021-04-02 15:49:53 +07:00
xmrig
e9b32b3009 Merge pull request #2229 from SChernykh/dev
Don't use RandomX JIT if WITH_ASM=OFF
2021-04-02 15:47:51 +07:00
SChernykh
ec608bbd05 Don't use RandomX JIT if WITH_ASM=OFF
Because RandomX JIT use asm code
2021-04-02 10:05:46 +02:00
esrrhs
ec2793bcc9 remove useless v4_random_math_init if algo is not cn/r 2021-04-02 14:59:09 +08:00
xmrig
eb40f07552 Merge pull request #2225 from gentoo-monero/fix-2224
Add missing include
2021-04-01 17:27:53 +07:00
Matthew Smith
28f268aeba Add missing include
memory header ends up not being included when built without OpenCL
support.

Closes: https://github.com/xmrig/xmrig/issues/2224
2021-04-01 11:01:55 +01:00
XMRig
bad5458d40 Merge branch 'pr2217' into dev 2021-03-29 18:17:33 +07:00
XMRig
b72e21fc3c Merge branch 'master' of https://github.com/esrrhs/xmrig into pr2217 2021-03-29 18:16:45 +07:00
esrrhs
d578a3828f setBlob should run after setAlgorithm 2021-03-29 12:11:03 +08:00
xmrig
6c417eb9af Merge pull request #2216 from SChernykh/dev
Optimize cn-heavy in GCC builds
2021-03-28 21:13:45 +07:00
SChernykh
dc70893e6b Optimize cn-heavy in GCC builds
+0.7% in GCC builds, but GCC is still slower than MSVC on cn-heavy.
2021-03-28 16:12:09 +02:00
xmrig
c5c958743e Merge pull request #2214 from SChernykh/cn-heavy-opt
Optimized cn-heavy
2021-03-28 09:56:22 +07:00
xmrig
89f2fa6818 Merge pull request #2213 from SChernykh/dev
Fixed use-after-free bug when exiting
2021-03-28 09:55:50 +07:00
SChernykh
bcfd9edaa5 Optimized cn-heavy
- Remove unnecessary type conversion when doing `idx0 = d ^ q;`
- Saves 1 CPU cycle in the main loop
- 0.2% speedup on Ryzen 5 5600X, results on other CPUs may vary
2021-03-27 22:21:01 +01:00
SChernykh
e0f774d6dd Fixed use-after-free bug when exiting 2021-03-27 21:53:40 +01:00
XMRig
955cc366d1 v6.11.0-dev 2021-03-20 13:42:46 +07:00
xmrig
bc4f6249be Merge pull request #2196 from xmrig/feature-dns2
Improved DNS subsystem
2021-03-20 12:50:53 +07:00
XMRig
0d45600b0e Added command line options --dns-ipv6 and --dns-ttl. 2021-03-20 11:12:09 +07:00
XMRig
2c8f7f692c Added DNS config. 2021-03-20 00:09:59 +07:00
XMRig
3e41bdc552 New DNS implementation. 2021-03-16 22:24:37 +07:00
XMRig
5b189696d7 Added DnsRecords class. 2021-03-14 09:44:56 +07:00
XMRig
c6bcea3811 Improved DnsRecord class. 2021-03-13 20:30:52 +07:00
xmrig
900dd13c45 Merge pull request #2177 from SChernykh/dev
Fix `vld1q_u8_x4` compilation error with GCC 10.2
2021-03-13 08:30:44 +07:00
SChernykh
2876f17f65 Fix vld1q_u8_x4 compilation error with GCC 10.2 2021-03-12 16:26:02 +01:00
xmrig
b2563ca8a6 Merge pull request #2172 from bisand/patch-1
Added reference to limits.h in AdlLib_linux.cpp
2021-03-11 18:07:23 +07:00
André Biseth
7c0d60ac68 Added reference to limits.h in AdlLib_linux.cpp
Suggested solution to bug https://github.com/xmrig/xmrig/issues/2171
2021-03-11 11:50:05 +01:00
xmrig
813a1885cb Merge pull request #2169 from SChernykh/dev
Fix wrong type in Handle::deleteLater()
2021-03-11 06:26:27 +07:00
SChernykh
54bcf05b1d Fix wrong type in Handle::deleteLater()
Bug found by Address Sanitizer
2021-03-10 14:55:06 +01:00
XMRig
bbea8810a7 v6.10.1-dev 2021-03-08 06:04:59 +07:00
XMRig
b6514957f1 Merge branch 'master' into dev 2021-03-08 06:04:32 +07:00
XMRig
69590f9777 v6.10.0 2021-03-08 04:05:27 +07:00
xmrig
576ff120e5 Merge pull request #2128 from ianmaddox/patch-1
Minor verbiage tweak
2021-03-08 04:02:02 +07:00
xmrig
2d52118c1b Merge pull request #2161 from coolhaircut/patch-1
Added Userspace MSR permissions clarification in CPU.md
2021-03-08 04:01:15 +07:00
xmrig
28ad59d828 Merge pull request #2129 from felixonmars/patch-1
Correct a typo in doc/CPU.md
2021-03-08 04:00:38 +07:00
XMRig
e0c630f34f Merge branch 'dev' 2021-03-08 03:59:09 +07:00
XMRig
b8f9a326aa 6.10.0-dev 2021-03-07 01:44:38 +07:00
Cool Dude (with a cool haircut)
542617b6db Update CPU.md 2021-03-05 22:54:03 +00:00
XMRig
f5db50c9d7 Sync with the proxy. 2021-03-06 05:32:54 +07:00
XMRig
856c8e6bcd Fixed build without TLS support. 2021-03-06 02:07:10 +07:00
XMRig
b3dbf6e23f http-parser replaced to llhttp. 2021-03-06 01:46:49 +07:00
xmrig
a11c57226b Merge pull request #2158 from SChernykh/dev
Fix GCC compilation
2021-03-04 16:48:05 +07:00
SChernykh
94d2cac775 Fix GCC compilation 2021-03-04 10:45:39 +01:00
XMRig
548a7d46e1 Add note about CPU affinity. 2021-03-04 16:19:06 +07:00
xmrig
bebc163e25 Merge pull request #2157 from SChernykh/dev
Fix crash in cn-heavy on Zen3 with manual thread count
2021-03-04 16:03:54 +07:00
SChernykh
70cddc06ba Fix crash in cn-heavy on Zen3 with manual thread count 2021-03-04 10:02:35 +01:00
XMRig
1f9cdc0564 Update hwloc for MSVC. 2021-03-04 03:23:26 +07:00
XMRig
a5a7ee716d Update build scripts. 2021-03-03 19:38:54 +07:00
xmrig
d2f24d94b9 Merge pull request #2150 from TheGreatMcPain/dev
Update sse2neon.h to the latest master. Fixes build on armv7.
2021-03-02 19:41:11 +07:00
TheGreatMcPain
ba3299b61b Update sse2neon.h to the latest master. Fixes build on armv7.
A few days after this header was introduced. Upstream updated it with
armv7 versions of `_mm_aesenc_si128` which allows xmrig to build
on armv7.
2021-03-02 01:33:25 -06:00
xmrig
ca5dfe7c12 Merge pull request #2147 from SChernykh/dev
Fixed many "new job" messages when solo mining
2021-03-01 23:49:03 +07:00
SChernykh
91ad6fcf3d Fixed many "new job" messages when solo mining
Fix for https://github.com/xmrig/xmrig/issues/2127
2021-03-01 17:46:05 +01:00
XMRig
0b7dfaabe0 Code cleanup. 2021-03-01 19:04:03 +07:00
XMRig
6f8ffb7660 Fixed possible out of order write to log file. 2021-03-01 18:54:20 +07:00
XMRig
4a8e7510e1 #2123 Ignore regex exception. 2021-02-27 15:29:14 +07:00
Felix Yan
32876dd01d Correct a typo in doc/CPU.md 2021-02-24 04:36:27 +08:00
Ian Maddox
37df513b32 Minor verbiage tweak
Fixing mixed phrasing in error message
2021-02-23 11:34:10 -08:00
xmrig
31a5d05dc1 Merge pull request #2122 from SChernykh/dev
Fixed pause logic when both pause on battery and user activity are en…
2021-02-21 22:36:32 +07:00
SChernykh
d478d737c4 Fixed pause logic when both pause on battery and user activity are enabled 2021-02-21 16:33:57 +01:00
XMRig
e20daff4eb v6.9.1-dev 2021-02-21 22:28:15 +07:00
XMRig
1ccdcb1645 Merge branch 'master' into dev 2021-02-21 22:27:36 +07:00
XMRig
072881e1a1 v6.9.0 2021-02-21 21:23:48 +07:00
XMRig
0c4a3cfc30 Merge branch 'dev' 2021-02-21 21:23:15 +07:00
xmrig
cffd0f50a4 Update CPU.md 2021-02-21 20:22:06 +07:00
XMRig
4b1857114e v6.9.0-dev 2021-02-20 14:28:20 +07:00
XMRig
b49fb27e84 Added idle time detection for macOS. 2021-02-20 13:18:31 +07:00
XMRig
ee341118ce #2104 Added user configurable idle time. 2021-02-19 23:35:30 +07:00
XMRig
f599807bbb Simplified code, fixed broken pause. 2021-02-19 16:26:31 +07:00
xmrig
a2ad626012 Merge pull request #2117 from SChernykh/dev
Fixed crash when GPU mining cn-heavy on Zen3 system
2021-02-18 21:08:44 +07:00
SChernykh
e8a99809b6 Fixed crash when GPU mining cn-heavy on Zen3 system 2021-02-18 14:49:37 +01:00
XMRig
0fe20fe88c Merge remote-tracking branch 'remotes/origin/pr2112' into dev 2021-02-18 15:35:59 +07:00
XMRig
d1d1517b4f Fixed macOS build. 2021-02-18 15:22:39 +07:00
XMRig
5980675876 Code and copyright cleanup. 2021-02-18 12:56:39 +07:00
Hansie Odendaal
3b87cd97ce Allow result submission to origin daemon with self-select
With `self-select` mode enabled, the `submit-to-origin` config option
will let the `SelfSelectClient` submit the solution to both
the daemon where it got the template from as well as to
the connected pool, for miners that want to do pool minining
with Monero and solo mining with an altcoin (merged mining variant).

Thank you and special credit to @StriderDM (https://github.com/StriderDM)!
2021-02-17 18:05:13 +02:00
xmrig
d2f01cfa86 Merge pull request #2104 from SChernykh/dev
Added `pause-on-active` option
2021-02-15 11:04:14 +07:00
SChernykh
82830e359a Added pause-on-active option
Windows only for now. When set to true, pauses mining when user touches mouse or keyboard.
2021-02-14 15:32:18 +01:00
XMRig
8e3fec5768 v6.8.3 2021-02-12 22:51:26 +07:00
XMRig
4fd23a1bf4 Merge branch 'master' into dev 2021-02-12 22:50:52 +07:00
188 changed files with 35222 additions and 10812 deletions

View File

@@ -1,3 +1,62 @@
# v6.13.0
- [#2445](https://github.com/xmrig/xmrig/pull/2445) Added support for solo mining with miner signatures for the upcoming Wownero fork.
# v6.12.2
- [#2280](https://github.com/xmrig/xmrig/issues/2280) GPU backends are now disabled in benchmark mode.
- [#2322](https://github.com/xmrig/xmrig/pull/2322) Improved MSR compatibility with recent Linux kernels and updated `randomx_boost.sh`.
- [#2340](https://github.com/xmrig/xmrig/pull/2340) Fixed AES detection on FreeBSD on ARM.
- [#2341](https://github.com/xmrig/xmrig/pull/2341) `sse2neon` updated to the latest version.
- [#2351](https://github.com/xmrig/xmrig/issues/2351) Fixed help output for `--cpu-priority` and `--cpu-affinity` option.
- [#2375](https://github.com/xmrig/xmrig/pull/2375) Fixed macOS CUDA backend default loader name.
- [#2378](https://github.com/xmrig/xmrig/pull/2378) Fixed broken light mode mining on x86.
- [#2379](https://github.com/xmrig/xmrig/pull/2379) Fixed CL code for KawPow where it assumes everything is AMD.
- [#2386](https://github.com/xmrig/xmrig/pull/2386) RandomX: enabled `IMUL_RCP` optimization for light mode mining.
- [#2393](https://github.com/xmrig/xmrig/pull/2393) RandomX: added BMI2 version for scratchpad prefetch.
- [#2395](https://github.com/xmrig/xmrig/pull/2395) RandomX: rewrote dataset read code.
- [#2398](https://github.com/xmrig/xmrig/pull/2398) RandomX: optimized ARMv8 dataset read.
- Added `argon2/ninja` alias for `argon2/wrkz` algorithm.
# v6.12.1
- [#2296](https://github.com/xmrig/xmrig/pull/2296) Fixed Zen3 assembly code for `cn/upx2` algorithm.
# v6.12.0
- [#2276](https://github.com/xmrig/xmrig/pull/2276) Added support for Uplexa (`cn/upx2` algorithm).
- [#2261](https://github.com/xmrig/xmrig/pull/2261) Show total hashrate if compiled without OpenCL.
- [#2289](https://github.com/xmrig/xmrig/pull/2289) RandomX: optimized `IMUL_RCP` instruction.
- Added support for `--user` command line option for online benchmark.
# v6.11.2
- [#2207](https://github.com/xmrig/xmrig/issues/2207) Fixed regression in HTTP parser and llhttp updated to v5.1.0.
# v6.11.1
- [#2239](https://github.com/xmrig/xmrig/pull/2239) Fixed broken `coin` setting functionality.
# v6.11.0
- [#2196](https://github.com/xmrig/xmrig/pull/2196) Improved DNS subsystem and added new DNS specific options.
- [#2172](https://github.com/xmrig/xmrig/pull/2172) Fixed build on Alpine 3.13.
- [#2177](https://github.com/xmrig/xmrig/pull/2177) Fixed ARM specific compilation error with GCC 10.2.
- [#2214](https://github.com/xmrig/xmrig/pull/2214) [#2216](https://github.com/xmrig/xmrig/pull/2216) [#2235](https://github.com/xmrig/xmrig/pull/2235) Optimized `cn-heavy` algorithm.
- [#2217](https://github.com/xmrig/xmrig/pull/2217) Fixed mining job creation sequence.
- [#2225](https://github.com/xmrig/xmrig/pull/2225) Fixed build without OpenCL support on some systems.
- [#2229](https://github.com/xmrig/xmrig/pull/2229) Don't use RandomX JIT if `WITH_ASM=OFF`.
- [#2228](https://github.com/xmrig/xmrig/pull/2228) Removed useless code for cryptonight algorithms.
- [#2234](https://github.com/xmrig/xmrig/pull/2234) Fixed build error on gcc 4.8.
# v6.10.0
- [#2122](https://github.com/xmrig/xmrig/pull/2122) Fixed pause logic when both pause on battery and user activity are enabled.
- [#2123](https://github.com/xmrig/xmrig/issues/2123) Fixed compatibility with gcc 4.8.
- [#2147](https://github.com/xmrig/xmrig/pull/2147) Fixed many `new job` messages when solo mining.
- [#2150](https://github.com/xmrig/xmrig/pull/2150) Updated `sse2neon.h` to the latest master, fixes build on ARMv7.
- [#2157](https://github.com/xmrig/xmrig/pull/2157) Fixed crash in `cn-heavy` on Zen3 with manual thread count.
- Fixed possible out of order write to log file.
- [http-parser](https://github.com/nodejs/http-parser) replaced to [llhttp](https://github.com/nodejs/llhttp).
- For official builds: libuv, hwloc and OpenSSL updated to latest versions.
# v6.9.0
- [#2104](https://github.com/xmrig/xmrig/pull/2104) Added [pause-on-active](https://xmrig.com/docs/miner/config/misc#pause-on-active) config option and `--pause-on-active=N` command line option.
- [#2112](https://github.com/xmrig/xmrig/pull/2112) Added support for [Tari merge mining](https://github.com/tari-project/tari/blob/development/README.md#tari-merge-mining).
- [#2117](https://github.com/xmrig/xmrig/pull/2117) Fixed crash when GPU mining `cn-heavy` on Zen3 system.
# v6.8.2
- [#2080](https://github.com/xmrig/xmrig/pull/2080) Fixed compile error in Termux.
- [#2089](https://github.com/xmrig/xmrig/pull/2089) Optimized CryptoNight-Heavy for Zen3, 7-8% speedup.

View File

@@ -5,6 +5,7 @@ option(WITH_HWLOC "Enable hwloc support" ON)
option(WITH_CN_LITE "Enable CryptoNight-Lite algorithms family" ON)
option(WITH_CN_HEAVY "Enable CryptoNight-Heavy algorithms family" ON)
option(WITH_CN_PICO "Enable CryptoNight-Pico algorithm" ON)
option(WITH_CN_FEMTO "Enable CryptoNight-UPX2 algorithm" ON)
option(WITH_RANDOMX "Enable RandomX algorithms family" ON)
option(WITH_ARGON2 "Enable Argon2 algorithms family" ON)
option(WITH_ASTROBWT "Enable AstroBWT algorithms family" ON)
@@ -147,8 +148,10 @@ elseif (XMRIG_OS_APPLE)
src/App_unix.cpp
src/crypto/common/VirtualMemory_unix.cpp
)
find_library(IOKIT_LIBRARY IOKit)
set(EXTRA_LIBS ${IOKIT_LIBRARY})
find_library(CORESERVICES_LIBRARY CoreServices)
set(EXTRA_LIBS ${IOKIT_LIBRARY} ${CORESERVICES_LIBRARY})
else()
list(APPEND SOURCES_OS
src/App_unix.cpp
@@ -194,6 +197,10 @@ if (WITH_CN_PICO)
add_definitions(/DXMRIG_ALGO_CN_PICO)
endif()
if (WITH_CN_FEMTO)
add_definitions(/DXMRIG_ALGO_CN_FEMTO)
endif()
if (WITH_EMBEDDED_CONFIG)
add_definitions(/DXMRIG_FEATURE_EMBEDDED_CONFIG)
endif()

View File

@@ -19,7 +19,7 @@ XMRig is a high performance, open source, cross platform RandomX, KawPow, Crypto
* **[Build from source](https://xmrig.com/docs/miner/build)**
## Usage
The preferred way to configure the miner is the [JSON config file](src/config.json) as it is more flexible and human friendly. The [command line interface](https://xmrig.com/docs/miner/command-line-options) does not cover all features, such as mining profiles for different algorithms. Important options can be changed during runtime without miner restart by editing the config file or executing API calls.
The preferred way to configure the miner is the [JSON config file](https://xmrig.com/docs/miner/config) as it is more flexible and human friendly. The [command line interface](https://xmrig.com/docs/miner/command-line-options) does not cover all features, such as mining profiles for different algorithms. Important options can be changed during runtime without miner restart by editing the config file or executing [API](https://xmrig.com/docs/miner/api) calls.
* **[Wizard](https://xmrig.com/wizard)** helps you create initial configuration for the miner.
* **[Workers](http://workers.xmrig.info)** helps manage your miners via HTTP API.

View File

@@ -1,3 +1,7 @@
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
add_definitions(/DXMRIG_64_BIT)
endif()
if (WIN32)
set(XMRIG_OS_WIN ON)
elseif (APPLE)

View File

@@ -42,13 +42,13 @@ if (WITH_RANDOMX)
src/crypto/rx/RxVm.cpp
)
if (CMAKE_C_COMPILER_ID MATCHES MSVC)
if (WITH_ASM AND CMAKE_C_COMPILER_ID MATCHES MSVC)
enable_language(ASM_MASM)
list(APPEND SOURCES_CRYPTO
src/crypto/randomx/jit_compiler_x86_static.asm
src/crypto/randomx/jit_compiler_x86.cpp
)
elseif (NOT XMRIG_ARM AND CMAKE_SIZEOF_VOID_P EQUAL 8)
elseif (WITH_ASM AND NOT XMRIG_ARM AND CMAKE_SIZEOF_VOID_P EQUAL 8)
list(APPEND SOURCES_CRYPTO
src/crypto/randomx/jit_compiler_x86_static.S
src/crypto/randomx/jit_compiler_x86.cpp

View File

@@ -1,3 +1,5 @@
**:warning: Recent version of this page https://xmrig.com/docs/miner/config/cpu.**
# CPU backend
All CPU related settings contains in one `cpu` object in config file, CPU backend allow specify multiple profiles and allow switch between them without restrictions by pool request or config change. Default auto-configuration create reasonable minimum of profiles which cover all supported algorithms.
@@ -89,12 +91,12 @@ RandomX mining mode: `auto`, `fast` (2 GB memory), `light` (256 MB memory).
#### `1gb-pages`
Use 1GB hugepages for RandomX dataset (Linux only). Enabled (`true`) or disabled (`false`). It gives 1-3% speedup.
#### `wrmsr`
[MSR mod](https://xmrig.com/docs/miner/randomx-optimization-guide/msr). Enabled (`true`) or disabled (`false`). It gives up to 15% speedup depending on your system. _(**Note**: Userspace MSR writes are no longer enabled by default; the flag `msr.allow_writes=on` must be set for Linux Kernels 5.9 and after.)_
#### `rdmsr`
Restore MSR register values to their original values on exit. Used together with `wrmsr`. Enabled (`true`) or disabled (`false`).
#### `wrmsr`
[MSR mod](https://xmrig.com/docs/miner/randomx-optimization-guide/msr). Enabled (`true`) or disabled (`false`). It gives up to 15% speedup depending on your system.
#### `cache_qos`
[Cache QoS](https://xmrig.com/docs/miner/randomx-optimization-guide/qos). Enabled (`true`) or disabled (`false`). It's useful when you can't or don't want to mine on all CPU cores to make mining hashrate more stable.
@@ -122,7 +124,7 @@ Force enable (`true`) or disable (`false`) hardware AES support. Default value `
Mining threads priority, value from `1` (lowest priority) to `5` (highest possible priority). Default value `null` means miner don't change threads priority at all. Setting priority higher than 2 can make your PC unresponsive.
#### `memory-pool` (since v4.3.0)
Use continuous, persistent memory block for mining threads, useful for preserve huge pages allocation while algorithm swithing. Possible values `false` (feature disabled, by default) or `true` or specific count of 2 MB huge pages. It helps to avoid loosing huge pages for scratchpads when RandomX dataset is updated and mining threads restart after a 2-3 days of mining.
Use continuous, persistent memory block for mining threads, useful for preserve huge pages allocation while algorithm switching. Possible values `false` (feature disabled, by default) or `true` or specific count of 2 MB huge pages. It helps to avoid loosing huge pages for scratchpads when RandomX dataset is updated and mining threads restart after a 2-3 days of mining.
#### `yield` (since v5.1.1)
Prefer system better system response/stability `true` (default value) or maximum hashrate `false`.

View File

@@ -1,6 +1,6 @@
#!/bin/bash -e
HWLOC_VERSION="2.4.0"
HWLOC_VERSION="2.4.1"
mkdir -p deps
mkdir -p deps/include

View File

@@ -1,6 +1,6 @@
#!/bin/bash -e
OPENSSL_VERSION="1.1.1i"
OPENSSL_VERSION="1.1.1k"
mkdir -p deps
mkdir -p deps/include
@@ -17,4 +17,4 @@ make -j$(nproc || sysctl -n hw.ncpu || sysctl -n hw.logicalcpu)
cp -fr include ../../deps
cp libcrypto.a ../../deps/lib
cp libssl.a ../../deps/lib
cd ..
cd ..

View File

@@ -1,6 +1,6 @@
#!/bin/bash -e
UV_VERSION="1.40.0"
UV_VERSION="1.41.0"
mkdir -p deps
mkdir -p deps/include

View File

@@ -1,28 +1,34 @@
#!/bin/bash
#!/bin/sh -e
modprobe msr
MSR_FILE=/sys/module/msr/parameters/allow_writes
if cat /proc/cpuinfo | grep "AMD Ryzen" > /dev/null;
if test -e "$MSR_FILE"; then
echo on > $MSR_FILE
else
modprobe msr allow_writes=on
fi
if grep -E 'AMD Ryzen|AMD EPYC' /proc/cpuinfo > /dev/null;
then
if cat /proc/cpuinfo | grep "cpu family[[:space:]]:[[:space:]]25" > /dev/null;
if grep "cpu family[[:space:]]:[[:space:]]25" /proc/cpuinfo > /dev/null;
then
echo "Detected Ryzen (Zen3)"
echo "Detected Zen3 CPU"
wrmsr -a 0xc0011020 0x4480000000000
wrmsr -a 0xc0011021 0x1c000200000040
wrmsr -a 0xc0011022 0xc000000401500000
wrmsr -a 0xc001102b 0x2000cc14
echo "MSR register values for Ryzen (Zen3) applied"
echo "MSR register values for Zen3 applied"
else
echo "Detected Ryzen (Zen1/Zen2)"
echo "Detected Zen1/Zen2 CPU"
wrmsr -a 0xc0011020 0
wrmsr -a 0xc0011021 0x40
wrmsr -a 0xc0011022 0x1510000
wrmsr -a 0xc001102b 0x2000cc16
echo "MSR register values for Ryzen (Zen1/Zen2) applied"
echo "MSR register values for Zen1/Zen2 applied"
fi
elif cat /proc/cpuinfo | grep "Intel" > /dev/null;
elif grep "Intel" /proc/cpuinfo > /dev/null;
then
echo "Detected Intel"
echo "Detected Intel CPU"
wrmsr -a 0x1a4 0xf
echo "MSR register values for Intel applied"
else

View File

@@ -1,68 +0,0 @@
# Authors ordered by first contribution.
Ryan Dahl <ry@tinyclouds.org>
Jeremy Hinegardner <jeremy@hinegardner.org>
Sergey Shepelev <temotor@gmail.com>
Joe Damato <ice799@gmail.com>
tomika <tomika_nospam@freemail.hu>
Phoenix Sol <phoenix@burninglabs.com>
Cliff Frey <cliff@meraki.com>
Ewen Cheslack-Postava <ewencp@cs.stanford.edu>
Santiago Gala <sgala@apache.org>
Tim Becker <tim.becker@syngenio.de>
Jeff Terrace <jterrace@gmail.com>
Ben Noordhuis <info@bnoordhuis.nl>
Nathan Rajlich <nathan@tootallnate.net>
Mark Nottingham <mnot@mnot.net>
Aman Gupta <aman@tmm1.net>
Tim Becker <tim.becker@kuriositaet.de>
Sean Cunningham <sean.cunningham@mandiant.com>
Peter Griess <pg@std.in>
Salman Haq <salman.haq@asti-usa.com>
Cliff Frey <clifffrey@gmail.com>
Jon Kolb <jon@b0g.us>
Fouad Mardini <f.mardini@gmail.com>
Paul Querna <pquerna@apache.org>
Felix Geisendörfer <felix@debuggable.com>
koichik <koichik@improvement.jp>
Andre Caron <andre.l.caron@gmail.com>
Ivo Raisr <ivosh@ivosh.net>
James McLaughlin <jamie@lacewing-project.org>
David Gwynne <loki@animata.net>
Thomas LE ROUX <thomas@november-eleven.fr>
Randy Rizun <rrizun@ortivawireless.com>
Andre Louis Caron <andre.louis.caron@usherbrooke.ca>
Simon Zimmermann <simonz05@gmail.com>
Erik Dubbelboer <erik@dubbelboer.com>
Martell Malone <martellmalone@gmail.com>
Bertrand Paquet <bpaquet@octo.com>
BogDan Vatra <bogdan@kde.org>
Peter Faiman <peter@thepicard.org>
Corey Richardson <corey@octayn.net>
Tóth Tamás <tomika_nospam@freemail.hu>
Cam Swords <cam.swords@gmail.com>
Chris Dickinson <christopher.s.dickinson@gmail.com>
Uli Köhler <ukoehler@btronik.de>
Charlie Somerville <charlie@charliesomerville.com>
Patrik Stutz <patrik.stutz@gmail.com>
Fedor Indutny <fedor.indutny@gmail.com>
runner <runner.mei@gmail.com>
Alexis Campailla <alexis@janeasystems.com>
David Wragg <david@wragg.org>
Vinnie Falco <vinnie.falco@gmail.com>
Alex Butum <alexbutum@linux.com>
Rex Feng <rexfeng@gmail.com>
Alex Kocharin <alex@kocharin.ru>
Mark Koopman <markmontymark@yahoo.com>
Helge Heß <me@helgehess.eu>
Alexis La Goutte <alexis.lagoutte@gmail.com>
George Miroshnykov <george.miroshnykov@gmail.com>
Maciej Małecki <me@mmalecki.com>
Marc O'Morain <github.com@marcomorain.com>
Jeff Pinner <jpinner@twitter.com>
Timothy J Fontaine <tjfontaine@gmail.com>
Akagi201 <akagi201@gmail.com>
Romain Giraud <giraud.romain@gmail.com>
Jay Satiro <raysatiro@yahoo.com>
Arne Steen <Arne.Steen@gmx.de>
Kjell Schubert <kjell.schubert@gmail.com>
Olivier Mengué <dolmen@cpan.org>

View File

@@ -1,19 +0,0 @@
Copyright Joyent, Inc. and other Node contributors.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.

View File

@@ -1,246 +0,0 @@
HTTP Parser
===========
[![Build Status](https://api.travis-ci.org/nodejs/http-parser.svg?branch=master)](https://travis-ci.org/nodejs/http-parser)
This is a parser for HTTP messages written in C. It parses both requests and
responses. The parser is designed to be used in performance HTTP
applications. It does not make any syscalls nor allocations, it does not
buffer data, it can be interrupted at anytime. Depending on your
architecture, it only requires about 40 bytes of data per message
stream (in a web server that is per connection).
Features:
* No dependencies
* Handles persistent streams (keep-alive).
* Decodes chunked encoding.
* Upgrade support
* Defends against buffer overflow attacks.
The parser extracts the following information from HTTP messages:
* Header fields and values
* Content-Length
* Request method
* Response status code
* Transfer-Encoding
* HTTP version
* Request URL
* Message body
Usage
-----
One `http_parser` object is used per TCP connection. Initialize the struct
using `http_parser_init()` and set the callbacks. That might look something
like this for a request parser:
```c
http_parser_settings settings;
settings.on_url = my_url_callback;
settings.on_header_field = my_header_field_callback;
/* ... */
http_parser *parser = malloc(sizeof(http_parser));
http_parser_init(parser, HTTP_REQUEST);
parser->data = my_socket;
```
When data is received on the socket execute the parser and check for errors.
```c
size_t len = 80*1024, nparsed;
char buf[len];
ssize_t recved;
recved = recv(fd, buf, len, 0);
if (recved < 0) {
/* Handle error. */
}
/* Start up / continue the parser.
* Note we pass recved==0 to signal that EOF has been received.
*/
nparsed = http_parser_execute(parser, &settings, buf, recved);
if (parser->upgrade) {
/* handle new protocol */
} else if (nparsed != recved) {
/* Handle error. Usually just close the connection. */
}
```
`http_parser` needs to know where the end of the stream is. For example, sometimes
servers send responses without Content-Length and expect the client to
consume input (for the body) until EOF. To tell `http_parser` about EOF, give
`0` as the fourth parameter to `http_parser_execute()`. Callbacks and errors
can still be encountered during an EOF, so one must still be prepared
to receive them.
Scalar valued message information such as `status_code`, `method`, and the
HTTP version are stored in the parser structure. This data is only
temporally stored in `http_parser` and gets reset on each new message. If
this information is needed later, copy it out of the structure during the
`headers_complete` callback.
The parser decodes the transfer-encoding for both requests and responses
transparently. That is, a chunked encoding is decoded before being sent to
the on_body callback.
The Special Problem of Upgrade
------------------------------
`http_parser` supports upgrading the connection to a different protocol. An
increasingly common example of this is the WebSocket protocol which sends
a request like
GET /demo HTTP/1.1
Upgrade: WebSocket
Connection: Upgrade
Host: example.com
Origin: http://example.com
WebSocket-Protocol: sample
followed by non-HTTP data.
(See [RFC6455](https://tools.ietf.org/html/rfc6455) for more information the
WebSocket protocol.)
To support this, the parser will treat this as a normal HTTP message without a
body, issuing both on_headers_complete and on_message_complete callbacks. However
http_parser_execute() will stop parsing at the end of the headers and return.
The user is expected to check if `parser->upgrade` has been set to 1 after
`http_parser_execute()` returns. Non-HTTP data begins at the buffer supplied
offset by the return value of `http_parser_execute()`.
Callbacks
---------
During the `http_parser_execute()` call, the callbacks set in
`http_parser_settings` will be executed. The parser maintains state and
never looks behind, so buffering the data is not necessary. If you need to
save certain data for later usage, you can do that from the callbacks.
There are two types of callbacks:
* notification `typedef int (*http_cb) (http_parser*);`
Callbacks: on_message_begin, on_headers_complete, on_message_complete.
* data `typedef int (*http_data_cb) (http_parser*, const char *at, size_t length);`
Callbacks: (requests only) on_url,
(common) on_header_field, on_header_value, on_body;
Callbacks must return 0 on success. Returning a non-zero value indicates
error to the parser, making it exit immediately.
For cases where it is necessary to pass local information to/from a callback,
the `http_parser` object's `data` field can be used.
An example of such a case is when using threads to handle a socket connection,
parse a request, and then give a response over that socket. By instantiation
of a thread-local struct containing relevant data (e.g. accepted socket,
allocated memory for callbacks to write into, etc), a parser's callbacks are
able to communicate data between the scope of the thread and the scope of the
callback in a threadsafe manner. This allows `http_parser` to be used in
multi-threaded contexts.
Example:
```c
typedef struct {
socket_t sock;
void* buffer;
int buf_len;
} custom_data_t;
int my_url_callback(http_parser* parser, const char *at, size_t length) {
/* access to thread local custom_data_t struct.
Use this access save parsed data for later use into thread local
buffer, or communicate over socket
*/
parser->data;
...
return 0;
}
...
void http_parser_thread(socket_t sock) {
int nparsed = 0;
/* allocate memory for user data */
custom_data_t *my_data = malloc(sizeof(custom_data_t));
/* some information for use by callbacks.
* achieves thread -> callback information flow */
my_data->sock = sock;
/* instantiate a thread-local parser */
http_parser *parser = malloc(sizeof(http_parser));
http_parser_init(parser, HTTP_REQUEST); /* initialise parser */
/* this custom data reference is accessible through the reference to the
parser supplied to callback functions */
parser->data = my_data;
http_parser_settings settings; /* set up callbacks */
settings.on_url = my_url_callback;
/* execute parser */
nparsed = http_parser_execute(parser, &settings, buf, recved);
...
/* parsed information copied from callback.
can now perform action on data copied into thread-local memory from callbacks.
achieves callback -> thread information flow */
my_data->buffer;
...
}
```
In case you parse HTTP message in chunks (i.e. `read()` request line
from socket, parse, read half headers, parse, etc) your data callbacks
may be called more than once. `http_parser` guarantees that data pointer is only
valid for the lifetime of callback. You can also `read()` into a heap allocated
buffer to avoid copying memory around if this fits your application.
Reading headers may be a tricky task if you read/parse headers partially.
Basically, you need to remember whether last header callback was field or value
and apply the following logic:
(on_header_field and on_header_value shortened to on_h_*)
------------------------ ------------ --------------------------------------------
| State (prev. callback) | Callback | Description/action |
------------------------ ------------ --------------------------------------------
| nothing (first call) | on_h_field | Allocate new buffer and copy callback data |
| | | into it |
------------------------ ------------ --------------------------------------------
| value | on_h_field | New header started. |
| | | Copy current name,value buffers to headers |
| | | list and allocate new buffer for new name |
------------------------ ------------ --------------------------------------------
| field | on_h_field | Previous name continues. Reallocate name |
| | | buffer and append callback data to it |
------------------------ ------------ --------------------------------------------
| field | on_h_value | Value for current header started. Allocate |
| | | new buffer and copy callback data to it |
------------------------ ------------ --------------------------------------------
| value | on_h_value | Value continues. Reallocate value buffer |
| | | and append callback data to it |
------------------------ ------------ --------------------------------------------
Parsing URLs
------------
A simplistic zero-copy URL parser is provided as `http_parser_parse_url()`.
Users of this library may wish to use it to parse URLs constructed from
consecutive `on_url` callbacks.
See examples of reading in headers:
* [partial example](http://gist.github.com/155877) in C
* [from http-parser tests](http://github.com/joyent/http-parser/blob/37a0ff8/test.c#L403) in C
* [from Node library](http://github.com/joyent/node/blob/842eaf4/src/http.js#L284) in Javascript

File diff suppressed because it is too large Load Diff

View File

@@ -1,442 +0,0 @@
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#ifndef http_parser_h
#define http_parser_h
#ifdef __cplusplus
extern "C" {
#endif
/* Also update SONAME in the Makefile whenever you change these. */
#define HTTP_PARSER_VERSION_MAJOR 2
#define HTTP_PARSER_VERSION_MINOR 9
#define HTTP_PARSER_VERSION_PATCH 3
#include <stddef.h>
#if defined(_WIN32) && !defined(__MINGW32__) && \
(!defined(_MSC_VER) || _MSC_VER<1600) && !defined(__WINE__)
#include <BaseTsd.h>
typedef __int8 int8_t;
typedef unsigned __int8 uint8_t;
typedef __int16 int16_t;
typedef unsigned __int16 uint16_t;
typedef __int32 int32_t;
typedef unsigned __int32 uint32_t;
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
#else
#include <stdint.h>
#endif
/* Compile with -DHTTP_PARSER_STRICT=0 to make less checks, but run
* faster
*/
#ifndef HTTP_PARSER_STRICT
# define HTTP_PARSER_STRICT 1
#endif
/* Maximium header size allowed. If the macro is not defined
* before including this header then the default is used. To
* change the maximum header size, define the macro in the build
* environment (e.g. -DHTTP_MAX_HEADER_SIZE=<value>). To remove
* the effective limit on the size of the header, define the macro
* to a very large number (e.g. -DHTTP_MAX_HEADER_SIZE=0x7fffffff)
*/
#ifndef HTTP_MAX_HEADER_SIZE
# define HTTP_MAX_HEADER_SIZE (80*1024)
#endif
typedef struct http_parser http_parser;
typedef struct http_parser_settings http_parser_settings;
/* Callbacks should return non-zero to indicate an error. The parser will
* then halt execution.
*
* The one exception is on_headers_complete. In a HTTP_RESPONSE parser
* returning '1' from on_headers_complete will tell the parser that it
* should not expect a body. This is used when receiving a response to a
* HEAD request which may contain 'Content-Length' or 'Transfer-Encoding:
* chunked' headers that indicate the presence of a body.
*
* Returning `2` from on_headers_complete will tell parser that it should not
* expect neither a body nor any futher responses on this connection. This is
* useful for handling responses to a CONNECT request which may not contain
* `Upgrade` or `Connection: upgrade` headers.
*
* http_data_cb does not return data chunks. It will be called arbitrarily
* many times for each string. E.G. you might get 10 callbacks for "on_url"
* each providing just a few characters more data.
*/
typedef int (*http_data_cb) (http_parser*, const char *at, size_t length);
typedef int (*http_cb) (http_parser*);
/* Status Codes */
#define HTTP_STATUS_MAP(XX) \
XX(100, CONTINUE, Continue) \
XX(101, SWITCHING_PROTOCOLS, Switching Protocols) \
XX(102, PROCESSING, Processing) \
XX(200, OK, OK) \
XX(201, CREATED, Created) \
XX(202, ACCEPTED, Accepted) \
XX(203, NON_AUTHORITATIVE_INFORMATION, Non-Authoritative Information) \
XX(204, NO_CONTENT, No Content) \
XX(205, RESET_CONTENT, Reset Content) \
XX(206, PARTIAL_CONTENT, Partial Content) \
XX(207, MULTI_STATUS, Multi-Status) \
XX(208, ALREADY_REPORTED, Already Reported) \
XX(226, IM_USED, IM Used) \
XX(300, MULTIPLE_CHOICES, Multiple Choices) \
XX(301, MOVED_PERMANENTLY, Moved Permanently) \
XX(302, FOUND, Found) \
XX(303, SEE_OTHER, See Other) \
XX(304, NOT_MODIFIED, Not Modified) \
XX(305, USE_PROXY, Use Proxy) \
XX(307, TEMPORARY_REDIRECT, Temporary Redirect) \
XX(308, PERMANENT_REDIRECT, Permanent Redirect) \
XX(400, BAD_REQUEST, Bad Request) \
XX(401, UNAUTHORIZED, Unauthorized) \
XX(402, PAYMENT_REQUIRED, Payment Required) \
XX(403, FORBIDDEN, Forbidden) \
XX(404, NOT_FOUND, Not Found) \
XX(405, METHOD_NOT_ALLOWED, Method Not Allowed) \
XX(406, NOT_ACCEPTABLE, Not Acceptable) \
XX(407, PROXY_AUTHENTICATION_REQUIRED, Proxy Authentication Required) \
XX(408, REQUEST_TIMEOUT, Request Timeout) \
XX(409, CONFLICT, Conflict) \
XX(410, GONE, Gone) \
XX(411, LENGTH_REQUIRED, Length Required) \
XX(412, PRECONDITION_FAILED, Precondition Failed) \
XX(413, PAYLOAD_TOO_LARGE, Payload Too Large) \
XX(414, URI_TOO_LONG, URI Too Long) \
XX(415, UNSUPPORTED_MEDIA_TYPE, Unsupported Media Type) \
XX(416, RANGE_NOT_SATISFIABLE, Range Not Satisfiable) \
XX(417, EXPECTATION_FAILED, Expectation Failed) \
XX(421, MISDIRECTED_REQUEST, Misdirected Request) \
XX(422, UNPROCESSABLE_ENTITY, Unprocessable Entity) \
XX(423, LOCKED, Locked) \
XX(424, FAILED_DEPENDENCY, Failed Dependency) \
XX(426, UPGRADE_REQUIRED, Upgrade Required) \
XX(428, PRECONDITION_REQUIRED, Precondition Required) \
XX(429, TOO_MANY_REQUESTS, Too Many Requests) \
XX(431, REQUEST_HEADER_FIELDS_TOO_LARGE, Request Header Fields Too Large) \
XX(451, UNAVAILABLE_FOR_LEGAL_REASONS, Unavailable For Legal Reasons) \
XX(500, INTERNAL_SERVER_ERROR, Internal Server Error) \
XX(501, NOT_IMPLEMENTED, Not Implemented) \
XX(502, BAD_GATEWAY, Bad Gateway) \
XX(503, SERVICE_UNAVAILABLE, Service Unavailable) \
XX(504, GATEWAY_TIMEOUT, Gateway Timeout) \
XX(505, HTTP_VERSION_NOT_SUPPORTED, HTTP Version Not Supported) \
XX(506, VARIANT_ALSO_NEGOTIATES, Variant Also Negotiates) \
XX(507, INSUFFICIENT_STORAGE, Insufficient Storage) \
XX(508, LOOP_DETECTED, Loop Detected) \
XX(510, NOT_EXTENDED, Not Extended) \
XX(511, NETWORK_AUTHENTICATION_REQUIRED, Network Authentication Required) \
enum http_status
{
#define XX(num, name, string) HTTP_STATUS_##name = num,
HTTP_STATUS_MAP(XX)
#undef XX
};
/* Request Methods */
#define HTTP_METHOD_MAP(XX) \
XX(0, DELETE, DELETE) \
XX(1, GET, GET) \
XX(2, HEAD, HEAD) \
XX(3, POST, POST) \
XX(4, PUT, PUT) \
/* pathological */ \
XX(5, CONNECT, CONNECT) \
XX(6, OPTIONS, OPTIONS) \
XX(7, TRACE, TRACE) \
/* WebDAV */ \
XX(8, COPY, COPY) \
XX(9, LOCK, LOCK) \
XX(10, MKCOL, MKCOL) \
XX(11, MOVE, MOVE) \
XX(12, PROPFIND, PROPFIND) \
XX(13, PROPPATCH, PROPPATCH) \
XX(14, SEARCH, SEARCH) \
XX(15, UNLOCK, UNLOCK) \
XX(16, BIND, BIND) \
XX(17, REBIND, REBIND) \
XX(18, UNBIND, UNBIND) \
XX(19, ACL, ACL) \
/* subversion */ \
XX(20, REPORT, REPORT) \
XX(21, MKACTIVITY, MKACTIVITY) \
XX(22, CHECKOUT, CHECKOUT) \
XX(23, MERGE, MERGE) \
/* upnp */ \
XX(24, MSEARCH, M-SEARCH) \
XX(25, NOTIFY, NOTIFY) \
XX(26, SUBSCRIBE, SUBSCRIBE) \
XX(27, UNSUBSCRIBE, UNSUBSCRIBE) \
/* RFC-5789 */ \
XX(28, PATCH, PATCH) \
XX(29, PURGE, PURGE) \
/* CalDAV */ \
XX(30, MKCALENDAR, MKCALENDAR) \
/* RFC-2068, section 19.6.1.2 */ \
XX(31, LINK, LINK) \
XX(32, UNLINK, UNLINK) \
/* icecast */ \
XX(33, SOURCE, SOURCE) \
enum http_method
{
#define XX(num, name, string) HTTP_##name = num,
HTTP_METHOD_MAP(XX)
#undef XX
};
enum http_parser_type { HTTP_REQUEST, HTTP_RESPONSE, HTTP_BOTH };
/* Flag values for http_parser.flags field */
enum flags
{ F_CHUNKED = 1 << 0
, F_CONNECTION_KEEP_ALIVE = 1 << 1
, F_CONNECTION_CLOSE = 1 << 2
, F_CONNECTION_UPGRADE = 1 << 3
, F_TRAILING = 1 << 4
, F_UPGRADE = 1 << 5
, F_SKIPBODY = 1 << 6
, F_CONTENTLENGTH = 1 << 7
, F_TRANSFER_ENCODING = 1 << 8
};
/* Map for errno-related constants
*
* The provided argument should be a macro that takes 2 arguments.
*/
#define HTTP_ERRNO_MAP(XX) \
/* No error */ \
XX(OK, "success") \
\
/* Callback-related errors */ \
XX(CB_message_begin, "the on_message_begin callback failed") \
XX(CB_url, "the on_url callback failed") \
XX(CB_header_field, "the on_header_field callback failed") \
XX(CB_header_value, "the on_header_value callback failed") \
XX(CB_headers_complete, "the on_headers_complete callback failed") \
XX(CB_body, "the on_body callback failed") \
XX(CB_message_complete, "the on_message_complete callback failed") \
XX(CB_status, "the on_status callback failed") \
XX(CB_chunk_header, "the on_chunk_header callback failed") \
XX(CB_chunk_complete, "the on_chunk_complete callback failed") \
\
/* Parsing-related errors */ \
XX(INVALID_EOF_STATE, "stream ended at an unexpected time") \
XX(HEADER_OVERFLOW, \
"too many header bytes seen; overflow detected") \
XX(CLOSED_CONNECTION, \
"data received after completed connection: close message") \
XX(INVALID_VERSION, "invalid HTTP version") \
XX(INVALID_STATUS, "invalid HTTP status code") \
XX(INVALID_METHOD, "invalid HTTP method") \
XX(INVALID_URL, "invalid URL") \
XX(INVALID_HOST, "invalid host") \
XX(INVALID_PORT, "invalid port") \
XX(INVALID_PATH, "invalid path") \
XX(INVALID_QUERY_STRING, "invalid query string") \
XX(INVALID_FRAGMENT, "invalid fragment") \
XX(LF_EXPECTED, "LF character expected") \
XX(INVALID_HEADER_TOKEN, "invalid character in header") \
XX(INVALID_CONTENT_LENGTH, \
"invalid character in content-length header") \
XX(UNEXPECTED_CONTENT_LENGTH, \
"unexpected content-length header") \
XX(INVALID_CHUNK_SIZE, \
"invalid character in chunk size header") \
XX(INVALID_TRANSFER_ENCODING, \
"request has invalid transfer-encoding") \
XX(INVALID_CONSTANT, "invalid constant string") \
XX(INVALID_INTERNAL_STATE, "encountered unexpected internal state")\
XX(STRICT, "strict mode assertion failed") \
XX(PAUSED, "parser is paused") \
XX(UNKNOWN, "an unknown error occurred")
/* Define HPE_* values for each errno value above */
#define HTTP_ERRNO_GEN(n, s) HPE_##n,
enum http_errno {
HTTP_ERRNO_MAP(HTTP_ERRNO_GEN)
};
#undef HTTP_ERRNO_GEN
/* Get an http_errno value from an http_parser */
#define HTTP_PARSER_ERRNO(p) ((enum http_errno) (p)->http_errno)
struct http_parser {
/** PRIVATE **/
unsigned int type : 2; /* enum http_parser_type */
unsigned int state : 7; /* enum state from http_parser.c */
unsigned int header_state : 7; /* enum header_state from http_parser.c */
unsigned int index : 7; /* index into current matcher */
unsigned int lenient_http_headers : 1;
unsigned int flags : 16; /* F_* values from 'flags' enum; semi-public */
uint32_t nread; /* # bytes read in various scenarios */
uint64_t content_length; /* # bytes in body (0 if no Content-Length header) */
/** READ-ONLY **/
unsigned short http_major;
unsigned short http_minor;
unsigned int status_code : 16; /* responses only */
unsigned int method : 8; /* requests only */
unsigned int http_errno : 7;
/* 1 = Upgrade header was present and the parser has exited because of that.
* 0 = No upgrade header present.
* Should be checked when http_parser_execute() returns in addition to
* error checking.
*/
unsigned int upgrade : 1;
/** PUBLIC **/
void *data; /* A pointer to get hook to the "connection" or "socket" object */
};
struct http_parser_settings {
http_cb on_message_begin;
http_data_cb on_url;
http_data_cb on_status;
http_data_cb on_header_field;
http_data_cb on_header_value;
http_cb on_headers_complete;
http_data_cb on_body;
http_cb on_message_complete;
/* When on_chunk_header is called, the current chunk length is stored
* in parser->content_length.
*/
http_cb on_chunk_header;
http_cb on_chunk_complete;
};
enum http_parser_url_fields
{ UF_SCHEMA = 0
, UF_HOST = 1
, UF_PORT = 2
, UF_PATH = 3
, UF_QUERY = 4
, UF_FRAGMENT = 5
, UF_USERINFO = 6
, UF_MAX = 7
};
/* Result structure for http_parser_parse_url().
*
* Callers should index into field_data[] with UF_* values iff field_set
* has the relevant (1 << UF_*) bit set. As a courtesy to clients (and
* because we probably have padding left over), we convert any port to
* a uint16_t.
*/
struct http_parser_url {
uint16_t field_set; /* Bitmask of (1 << UF_*) values */
uint16_t port; /* Converted UF_PORT string */
struct {
uint16_t off; /* Offset into buffer in which field starts */
uint16_t len; /* Length of run in buffer */
} field_data[UF_MAX];
};
/* Returns the library version. Bits 16-23 contain the major version number,
* bits 8-15 the minor version number and bits 0-7 the patch level.
* Usage example:
*
* unsigned long version = http_parser_version();
* unsigned major = (version >> 16) & 255;
* unsigned minor = (version >> 8) & 255;
* unsigned patch = version & 255;
* printf("http_parser v%u.%u.%u\n", major, minor, patch);
*/
unsigned long http_parser_version(void);
void http_parser_init(http_parser *parser, enum http_parser_type type);
/* Initialize http_parser_settings members to 0
*/
void http_parser_settings_init(http_parser_settings *settings);
/* Executes the parser. Returns number of parsed bytes. Sets
* `parser->http_errno` on error. */
size_t http_parser_execute(http_parser *parser,
const http_parser_settings *settings,
const char *data,
size_t len);
/* If http_should_keep_alive() in the on_headers_complete or
* on_message_complete callback returns 0, then this should be
* the last message on the connection.
* If you are the server, respond with the "Connection: close" header.
* If you are the client, close the connection.
*/
int http_should_keep_alive(const http_parser *parser);
/* Returns a string version of the HTTP method. */
const char *http_method_str(enum http_method m);
/* Returns a string version of the HTTP status code. */
const char *http_status_str(enum http_status s);
/* Return a string name of the given error */
const char *http_errno_name(enum http_errno err);
/* Return a string description of the given error */
const char *http_errno_description(enum http_errno err);
/* Initialize all http_parser_url members to 0 */
void http_parser_url_init(struct http_parser_url *u);
/* Parse a URL; return nonzero on failure */
int http_parser_parse_url(const char *buf, size_t buflen,
int is_connect,
struct http_parser_url *u);
/* Pause or un-pause the parser; a nonzero value pauses */
void http_parser_pause(http_parser *parser, int paused);
/* Checks if this is the final chunk of the body. */
int http_body_is_final(const http_parser *parser);
/* Change the maximum header size provided at compile time. */
void http_parser_set_max_header_size(uint32_t size);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,6 +1,6 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2020 Inria. All rights reserved.
* Copyright © 2009-2021 Inria. All rights reserved.
* Copyright © 2009-2012 Université Bordeaux
* Copyright © 2009-2020 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
@@ -2362,22 +2362,9 @@ HWLOC_DECLSPEC hwloc_obj_t hwloc_topology_insert_misc_object(hwloc_topology_t to
/** \brief Allocate a Group object to insert later with hwloc_topology_insert_group_object().
*
* This function returns a new Group object.
* The caller should (at least) initialize its sets before inserting the object.
* See hwloc_topology_insert_group_object().
*
* The \p subtype object attribute may be set to display something else
* than "Group" as the type name for this object in lstopo.
* Custom name/value info pairs may be added with hwloc_obj_add_info() after
* insertion.
*
* The \p kind group attribute should be 0. The \p subkind group attribute may
* be set to identify multiple Groups of the same level.
*
* It is recommended not to set any other object attribute before insertion,
* since the Group may get discarded during insertion.
*
* The object will be destroyed if passed to hwloc_topology_insert_group_object()
* without any set defined.
* The caller should (at least) initialize its sets before inserting
* the object in the topology. See hwloc_topology_insert_group_object().
*/
HWLOC_DECLSPEC hwloc_obj_t hwloc_topology_alloc_group_object(hwloc_topology_t topology);
@@ -2388,34 +2375,44 @@ HWLOC_DECLSPEC hwloc_obj_t hwloc_topology_alloc_group_object(hwloc_topology_t to
* the final location of the Group in the topology.
* Then the object can be passed to this function for actual insertion in the topology.
*
* The group \p dont_merge attribute may be set to prevent the core from
* ever merging this object with another object hierarchically-identical.
*
* Either the cpuset or nodeset field (or both, if compatible) must be set
* to a non-empty bitmap. The complete_cpuset or complete_nodeset may be set
* instead if inserting with respect to the complete topology
* (including disallowed, offline or unknown objects).
*
* It grouping several objects, hwloc_obj_add_other_obj_sets() is an easy way
* If grouping several objects, hwloc_obj_add_other_obj_sets() is an easy way
* to build the Group sets iteratively.
*
* These sets cannot be larger than the current topology, or they would get
* restricted silently.
*
* The core will setup the other sets after actual insertion.
*
* The \p subtype object attribute may be defined (to a dynamically
* allocated string) to display something else than "Group" as the
* type name for this object in lstopo.
* Custom name/value info pairs may be added with hwloc_obj_add_info() after
* insertion.
*
* The group \p dont_merge attribute may be set to \c 1 to prevent
* the hwloc core from ever merging this object with another
* hierarchically-identical object.
* This is useful when the Group itself describes an important feature
* that cannot be exposed anywhere else in the hierarchy.
*
* The group \p kind attribute may be set to a high value such
* as \c 0xffffffff to tell hwloc that this new Group should always
* be discarded in favor of any existing Group with the same locality.
*
* \return The inserted object if it was properly inserted.
*
* \return An existing object if the Group was discarded because the topology already
* contained an object at the same location (the Group did not add any locality information).
* Any name/info key pair set before inserting is appended to the existing object.
* \return An existing object if the Group was merged or discarded
* because the topology already contained an object at the same
* location (the Group did not add any hierarchy information).
*
* \return \c NULL if the insertion failed because of conflicting sets in topology tree.
*
* \return \c NULL if Group objects are filtered-out of the topology (::HWLOC_TYPE_FILTER_KEEP_NONE).
*
* \return \c NULL if the object was discarded because no set was initialized in the Group
* before insert, or all of them were empty.
* \return \c NULL if the object was discarded because no set was
* initialized in the Group before insert, or all of them were empty.
*/
HWLOC_DECLSPEC hwloc_obj_t hwloc_topology_insert_group_object(hwloc_topology_t topology, hwloc_obj_t group);

View File

@@ -11,10 +11,10 @@
#ifndef HWLOC_CONFIG_H
#define HWLOC_CONFIG_H
#define HWLOC_VERSION "2.4.0"
#define HWLOC_VERSION "2.4.1"
#define HWLOC_VERSION_MAJOR 2
#define HWLOC_VERSION_MINOR 4
#define HWLOC_VERSION_RELEASE 0
#define HWLOC_VERSION_RELEASE 1
#define HWLOC_VERSION_GREEK ""
#define __hwloc_restrict

View File

@@ -1,5 +1,5 @@
/*
* Copyright © 2012-2020 Inria. All rights reserved.
* Copyright © 2012-2021 Inria. All rights reserved.
* Copyright © 2013, 2018 Université Bordeaux. All right reserved.
* See COPYING in top-level directory.
*/
@@ -82,9 +82,10 @@ hwloc_opencl_get_device_pci_busid(cl_device_id device,
if (CL_SUCCESS == clret
&& HWLOC_CL_DEVICE_TOPOLOGY_TYPE_PCIE_AMD == amdtopo.raw.type) {
*domain = 0; /* can't do anything better */
*bus = (unsigned) amdtopo.pcie.bus;
*dev = (unsigned) amdtopo.pcie.device;
*func = (unsigned) amdtopo.pcie.function;
/* cl_device_topology_amd stores bus ID in cl_char, dont convert those signed char directly to unsigned int */
*bus = (unsigned) (unsigned char) amdtopo.pcie.bus;
*dev = (unsigned) (unsigned char) amdtopo.pcie.device;
*func = (unsigned) (unsigned char) amdtopo.pcie.function;
return 0;
}

201
src/3rdparty/hwloc/include/hwloc/rsmi.h vendored Normal file
View File

@@ -0,0 +1,201 @@
/*
* Copyright © 2012-2020 Inria. All rights reserved.
* Copyright (c) 2020, Advanced Micro Devices, Inc. All rights reserved.
* Written by Advanced Micro Devices,
* See COPYING in top-level directory.
*/
/** \file
* \brief Macros to help interaction between hwloc and the ROCm SMI Management Library.
*
* Applications that use both hwloc and the ROCm SMI Management Library may want to
* include this file so as to get topology information for AMD GPU devices.
*/
#ifndef HWLOC_RSMI_H
#define HWLOC_RSMI_H
#include "hwloc.h"
#include "hwloc/autogen/config.h"
#include "hwloc/helper.h"
#ifdef HWLOC_LINUX_SYS
#include "hwloc/linux.h"
#endif
#include <rocm_smi/rocm_smi.h>
#ifdef __cplusplus
extern "C" {
#endif
/** \defgroup hwlocality_rsmi Interoperability with the ROCm SMI Management Library
*
* This interface offers ways to retrieve topology information about
* devices managed by the ROCm SMI Management Library.
*
* @{
*/
/** \brief Get the CPU set of logical processors that are physically
* close to AMD GPU device whose index is \p dv_ind.
*
* Return the CPU set describing the locality of the AMD GPU device
* whose index is \p dv_ind.
*
* Topology \p topology and device \p dv_ind must match the local machine.
* I/O devices detection and the ROCm SMI component are not needed in the
* topology.
*
* The function only returns the locality of the device.
* If more information about the device is needed, OS objects should
* be used instead, see hwloc_rsmi_get_device_osdev()
* and hwloc_rsmi_get_device_osdev_by_index().
*
* This function is currently only implemented in a meaningful way for
* Linux; other systems will simply get a full cpuset.
*/
static __hwloc_inline int
hwloc_rsmi_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,
uint32_t dv_ind, hwloc_cpuset_t set)
{
#ifdef HWLOC_LINUX_SYS
/* If we're on Linux, use the sysfs mechanism to get the local cpus */
#define HWLOC_RSMI_DEVICE_SYSFS_PATH_MAX 128
char path[HWLOC_RSMI_DEVICE_SYSFS_PATH_MAX];
rsmi_status_t ret;
uint64_t bdfid = 0;
unsigned domain, device, bus;
if (!hwloc_topology_is_thissystem(topology)) {
errno = EINVAL;
return -1;
}
ret = rsmi_dev_pci_id_get(dv_ind, &bdfid);
if (RSMI_STATUS_SUCCESS != ret) {
errno = EINVAL;
return -1;
}
domain = (bdfid>>32) & 0xffffffff;
bus = ((bdfid & 0xffff)>>8) & 0xff;
device = ((bdfid & 0xff)>>3) & 0x1f;
sprintf(path, "/sys/bus/pci/devices/%04x:%02x:%02x.0/local_cpus", domain, bus, device);
if (hwloc_linux_read_path_as_cpumask(path, set) < 0
|| hwloc_bitmap_iszero(set))
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
#else
/* Non-Linux systems simply get a full cpuset */
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
#endif
return 0;
}
/** \brief Get the hwloc OS device object corresponding to the
* AMD GPU device whose index is \p dv_ind.
*
* Return the OS device object describing the AMD GPU device whose
* index is \p dv_ind. Returns NULL if there is none.
*
* The topology \p topology does not necessarily have to match the current
* machine. For instance the topology may be an XML import of a remote host.
* I/O devices detection and the ROCm SMI component must be enabled in the
* topology.
*
* \note The corresponding PCI device object can be obtained by looking
* at the OS device parent object (unless PCI devices are filtered out).
*/
static __hwloc_inline hwloc_obj_t
hwloc_rsmi_get_device_osdev_by_index(hwloc_topology_t topology, uint32_t dv_ind)
{
hwloc_obj_t osdev = NULL;
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
if (HWLOC_OBJ_OSDEV_GPU == osdev->attr->osdev.type
&& osdev->name
&& !strncmp("rsmi", osdev->name, 4)
&& atoi(osdev->name + 4) == (int) dv_ind)
return osdev;
}
return NULL;
}
/** \brief Get the hwloc OS device object corresponding to AMD GPU device,
* whose index is \p dv_ind.
*
* Return the hwloc OS device object that describes the given
* AMD GPU, whose index is \p dv_ind Return NULL if there is none.
*
* Topology \p topology and device \p dv_ind must match the local machine.
* I/O devices detection and the ROCm SMI component must be enabled in the
* topology. If not, the locality of the object may still be found using
* hwloc_rsmi_get_device_cpuset().
*
* \note The corresponding hwloc PCI device may be found by looking
* at the result parent pointer (unless PCI devices are filtered out).
*/
static __hwloc_inline hwloc_obj_t
hwloc_rsmi_get_device_osdev(hwloc_topology_t topology, uint32_t dv_ind)
{
hwloc_obj_t osdev;
rsmi_status_t ret;
uint64_t bdfid = 0;
unsigned domain, device, bus, func;
uint64_t id;
char uuid[64];
if (!hwloc_topology_is_thissystem(topology)) {
errno = EINVAL;
return NULL;
}
ret = rsmi_dev_pci_id_get(dv_ind, &bdfid);
if (RSMI_STATUS_SUCCESS != ret) {
errno = EINVAL;
return NULL;
}
domain = (bdfid>>32) & 0xffffffff;
bus = ((bdfid & 0xffff)>>8) & 0xff;
device = ((bdfid & 0xff)>>3) & 0x1f;
func = bdfid & 0x7;
ret = rsmi_dev_unique_id_get(dv_ind, &id);
if (RSMI_STATUS_SUCCESS != ret)
uuid[0] = '\0';
else
sprintf(uuid, "%lx", id);
osdev = NULL;
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
hwloc_obj_t pcidev = osdev->parent;
const char *info;
if (strncmp(osdev->name, "rsmi", 4))
continue;
if (pcidev
&& pcidev->type == HWLOC_OBJ_PCI_DEVICE
&& pcidev->attr->pcidev.domain == domain
&& pcidev->attr->pcidev.bus == bus
&& pcidev->attr->pcidev.dev == device
&& pcidev->attr->pcidev.func == func)
return osdev;
info = hwloc_obj_get_info_by_name(osdev, "AMDUUID");
if (info && !strcmp(info, uuid))
return osdev;
}
return NULL;
}
/** @} */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* HWLOC_RSMI_H */

View File

@@ -1,5 +1,5 @@
/*
* Copyright © 2020 Inria. All rights reserved.
* Copyright © 2020-2021 Inria. All rights reserved.
* See COPYING in top-level directory.
*/
@@ -270,7 +270,7 @@ hwloc__cpukinds_check_duplicate_rankings(struct hwloc_topology *topology)
unsigned i,j;
for(i=0; i<topology->nr_cpukinds; i++)
for(j=i+1; j<topology->nr_cpukinds; j++)
if (topology->cpukinds[i].forced_efficiency == topology->cpukinds[j].forced_efficiency)
if (topology->cpukinds[i].ranking_value == topology->cpukinds[j].ranking_value)
/* if any duplicate, fail */
return -1;
return 0;

View File

@@ -1,4 +1,9 @@
#include <private/internal-components.h>
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_noos_component;
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_xml_component;
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_synthetic_component;
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_xml_nolibxml_component;
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_windows_component;
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_x86_component;
static const struct hwloc_component * hwloc_static_components[] = {
&hwloc_noos_component,
&hwloc_xml_component,

View File

@@ -1,5 +1,5 @@
/*
* Copyright © 2010-2020 Inria. All rights reserved.
* Copyright © 2010-2021 Inria. All rights reserved.
* Copyright © 2010-2013 Université Bordeaux
* Copyright © 2010-2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
@@ -908,6 +908,16 @@ static void summarize(struct hwloc_backend *backend, struct procinfo *infos, uns
int gotnuma = 0;
int fulldiscovery = (flags & HWLOC_X86_DISC_FLAG_FULL);
#ifdef HWLOC_DEBUG
hwloc_debug("\nSummary of x86 CPUID topology:\n");
for(i=0; i<nbprocs; i++) {
hwloc_debug("PU %u present=%u apicid=%u on PKG %d CORE %d DIE %d NODE %d\n",
i, infos[i].present, infos[i].apicid,
infos[i].ids[PKG], infos[i].ids[CORE], infos[i].ids[DIE], infos[i].ids[NODE]);
}
hwloc_debug("\n");
#endif
for (i = 0; i < nbprocs; i++)
if (infos[i].present) {
hwloc_bitmap_set(complete_cpuset, i);
@@ -1587,7 +1597,8 @@ hwloc_x86_discover(struct hwloc_backend *backend, struct hwloc_disc_status *dsta
}
if (topology->levels[0][0]->cpuset) {
/* somebody else discovered things */
/* somebody else discovered things, reconnect levels so that we can look at them */
hwloc_topology_reconnect(topology, 0);
if (topology->nb_levels == 2 && topology->level_nbobjects[1] == data->nbprocs) {
/* only PUs were discovered, as much as we would, complete the topology with everything else */
alreadypus = 1;
@@ -1595,7 +1606,6 @@ hwloc_x86_discover(struct hwloc_backend *backend, struct hwloc_disc_status *dsta
}
/* several object types were added, we can't easily complete, just do partial discovery */
hwloc_topology_reconnect(topology, 0);
ret = hwloc_look_x86(backend, flags);
if (ret)
hwloc_obj_add_info(topology->levels[0][0], "Backend", "x86");

View File

@@ -1462,6 +1462,9 @@ hwloc__xml_v2import_distances(hwloc_topology_t topology,
unsigned long long u;
if (heterotypes) {
hwloc_obj_type_t t = HWLOC_OBJ_TYPE_NONE;
if (!*tmp)
/* reached the end of this indexes attribute */
break;
if (hwloc_type_sscanf(tmp, &t, NULL, 0) < 0) {
if (hwloc__xml_verbose())
fprintf(stderr, "%s: %s with unrecognized heterogeneous type %s\n",

View File

@@ -1,6 +1,6 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2020 Inria. All rights reserved.
* Copyright © 2009-2021 Inria. All rights reserved.
* Copyright © 2009-2012, 2020 Université Bordeaux
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
@@ -567,8 +567,9 @@ hwloc_free_unlinked_object(hwloc_obj_t obj)
}
/* Replace old with contents of new object, and make new freeable by the caller.
* Only updates next_sibling/first_child pointers,
* so may only be used during early discovery.
* Requires reconnect (for siblings pointers and group depth),
* fixup of sets (only the main cpuset was likely compared before merging),
* and update of total_memory and group depth.
*/
static void
hwloc_replace_linked_object(hwloc_obj_t old, hwloc_obj_t new)
@@ -1348,7 +1349,7 @@ merge_insert_equal(hwloc_obj_t new, hwloc_obj_t old)
/* returns the result of merge, or NULL if not merged */
static __hwloc_inline hwloc_obj_t
hwloc__insert_try_merge_group(hwloc_obj_t old, hwloc_obj_t new)
hwloc__insert_try_merge_group(hwloc_topology_t topology, hwloc_obj_t old, hwloc_obj_t new)
{
if (new->type == HWLOC_OBJ_GROUP && old->type == HWLOC_OBJ_GROUP) {
/* which group do we keep? */
@@ -1359,6 +1360,7 @@ hwloc__insert_try_merge_group(hwloc_obj_t old, hwloc_obj_t new)
/* keep the new one, it doesn't want to be merged */
hwloc_replace_linked_object(old, new);
topology->modified = 1;
return new;
} else {
@@ -1366,9 +1368,12 @@ hwloc__insert_try_merge_group(hwloc_obj_t old, hwloc_obj_t new)
/* keep the old one, it doesn't want to be merged */
return old;
/* compare subkinds to decice who to keep */
if (new->attr->group.kind < old->attr->group.kind)
/* compare subkinds to decide which group to keep */
if (new->attr->group.kind < old->attr->group.kind) {
/* keep smaller kind */
hwloc_replace_linked_object(old, new);
topology->modified = 1;
}
return old;
}
}
@@ -1394,6 +1399,7 @@ hwloc__insert_try_merge_group(hwloc_obj_t old, hwloc_obj_t new)
* and let the caller free the new object
*/
hwloc_replace_linked_object(old, new);
topology->modified = 1;
return old;
} else {
@@ -1435,7 +1441,7 @@ hwloc___insert_object_by_cpuset(struct hwloc_topology *topology, hwloc_obj_t cur
int setres = res;
if (res == HWLOC_OBJ_EQUAL) {
hwloc_obj_t merged = hwloc__insert_try_merge_group(child, obj);
hwloc_obj_t merged = hwloc__insert_try_merge_group(topology, child, obj);
if (merged)
return merged;
/* otherwise compare actual types to decide of the inclusion */
@@ -1931,12 +1937,24 @@ hwloc_topology_insert_group_object(struct hwloc_topology *topology, hwloc_obj_t
if (!res)
return NULL;
if (res != obj)
/* merged */
if (res != obj && res->type != HWLOC_OBJ_GROUP)
/* merged, not into a Group, nothing to update */
return res;
/* res == obj means that the object was inserted.
* We need to reconnect levels, fill all its cpu/node sets,
* compute its total memory, group depth, etc.
*
* res != obj usually means that our new group was merged into an
* existing object, no need to recompute anything.
* However, if merging with an existing group, depending on their kinds,
* the contents of obj may overwrite the contents of the old group.
* This requires reconnecting levels, filling sets, recomputing total memory, etc.
*/
/* properly inserted */
hwloc_obj_add_children_sets(obj);
hwloc_obj_add_children_sets(res);
if (hwloc_topology_reconnect(topology, 0) < 0)
return NULL;
@@ -1948,7 +1966,7 @@ hwloc_topology_insert_group_object(struct hwloc_topology *topology, hwloc_obj_t
#endif
hwloc_topology_check(topology);
return obj;
return res;
}
hwloc_obj_t
@@ -4658,6 +4676,9 @@ hwloc__check_misc_children(hwloc_topology_t topology, hwloc_bitmap_t gp_indexes,
static void
hwloc__check_object(hwloc_topology_t topology, hwloc_bitmap_t gp_indexes, hwloc_obj_t obj)
{
hwloc_uint64_t total_memory;
hwloc_obj_t child;
assert(!hwloc_bitmap_isset(gp_indexes, obj->gp_index));
hwloc_bitmap_set(gp_indexes, obj->gp_index);
@@ -4715,6 +4736,18 @@ hwloc__check_object(hwloc_topology_t topology, hwloc_bitmap_t gp_indexes, hwloc_
assert(hwloc_cache_type_by_depth_type(obj->attr->cache.depth, obj->attr->cache.type) == obj->type);
}
/* check total memory */
total_memory = 0;
if (obj->type == HWLOC_OBJ_NUMANODE)
total_memory += obj->attr->numanode.local_memory;
for_each_child(child, obj) {
total_memory += child->total_memory;
}
for_each_memory_child(child, obj) {
total_memory += child->total_memory;
}
assert(total_memory == obj->total_memory);
/* check children */
hwloc__check_normal_children(topology, gp_indexes, obj);
hwloc__check_memory_children(topology, gp_indexes, obj);

22
src/3rdparty/llhttp/LICENSE-MIT vendored Normal file
View File

@@ -0,0 +1,22 @@
This software is licensed under the MIT License.
Copyright Fedor Indutny, 2018.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to permit
persons to whom the Software is furnished to do so, subject to the
following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.

135
src/3rdparty/llhttp/README.md vendored Normal file
View File

@@ -0,0 +1,135 @@
# llhttp
[![CI](https://github.com/nodejs/llhttp/workflows/CI/badge.svg)](https://github.com/nodejs/llhttp/actions?query=workflow%3ACI)
Port of [http_parser][0] to [llparse][1].
## Why?
Let's face it, [http_parser][0] is practically unmaintainable. Even
introduction of a single new method results in a significant code churn.
This project aims to:
* Make it maintainable
* Verifiable
* Improving benchmarks where possible
More details in [Fedor Indutny's talk at JSConf EU 2019](https://youtu.be/x3k_5Mi66sY)
## How?
Over time, different approaches for improving [http_parser][0]'s code base
were tried. However, all of them failed due to resulting significant performance
degradation.
This project is a port of [http_parser][0] to TypeScript. [llparse][1] is used
to generate the output C source file, which could be compiled and
linked with the embedder's program (like [Node.js][7]).
## Performance
So far llhttp outperforms http_parser:
| | input size | bandwidth | reqs/sec | time |
|:----------------|-----------:|-------------:|-----------:|--------:|
| **llhttp** | 8192.00 mb | 1777.24 mb/s | 3583799.39 req/sec | 4.61 s |
| **http_parser** | 8192.00 mb | 694.66 mb/s | 1406180.33 req/sec | 11.79 s |
llhttp is faster by approximately **156%**.
## Maintenance
llhttp project has about 1400 lines of TypeScript code describing the parser
itself and around 450 lines of C code and headers providing the helper methods.
The whole [http_parser][0] is implemented in approximately 2500 lines of C, and
436 lines of headers.
All optimizations and multi-character matching in llhttp are generated
automatically, and thus doesn't add any extra maintenance cost. On the contrary,
most of http_parser's code is hand-optimized and unrolled. Instead describing
"how" it should parse the HTTP requests/responses, a maintainer should
implement the new features in [http_parser][0] cautiously, considering
possible performance degradation and manually optimizing the new code.
## Verification
The state machine graph is encoded explicitly in llhttp. The [llparse][1]
automatically checks the graph for absence of loops and correct reporting of the
input ranges (spans) like header names and values. In the future, additional
checks could be performed to get even stricter verification of the llhttp.
## Usage
```C
#include "llhttp.h"
llhttp_t parser;
llhttp_settings_t settings;
/* Initialize user callbacks and settings */
llhttp_settings_init(&settings);
/* Set user callback */
settings.on_message_complete = handle_on_message_complete;
/* Initialize the parser in HTTP_BOTH mode, meaning that it will select between
* HTTP_REQUEST and HTTP_RESPONSE parsing automatically while reading the first
* input.
*/
llhttp_init(&parser, HTTP_BOTH, &settings);
/* Parse request! */
const char* request = "GET / HTTP/1.1\r\n\r\n";
int request_len = strlen(request);
enum llhttp_errno err = llhttp_execute(&parser, request, request_len);
if (err == HPE_OK) {
/* Successfully parsed! */
} else {
fprintf(stderr, "Parse error: %s %s\n", llhttp_errno_name(err),
parser.reason);
}
```
---
### Bindings to other languages
* Python: [pallas/pyllhttp][8]
* Ruby: [metabahn/llhttp][9]
#### LICENSE
This software is licensed under the MIT License.
Copyright Fedor Indutny, 2018.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to permit
persons to whom the Software is furnished to do so, subject to the
following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
[0]: https://github.com/nodejs/http-parser
[1]: https://github.com/nodejs/llparse
[2]: https://en.wikipedia.org/wiki/Register_allocation#Spilling
[3]: https://en.wikipedia.org/wiki/Tail_call
[4]: https://llvm.org/docs/LangRef.html
[5]: https://llvm.org/docs/LangRef.html#call-instruction
[6]: https://clang.llvm.org/
[7]: https://github.com/nodejs/node
[8]: https://github.com/pallas/pyllhttp
[9]: https://github.com/metabahn/llhttp

348
src/3rdparty/llhttp/api.c vendored Normal file
View File

@@ -0,0 +1,348 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "llhttp.h"
#define CALLBACK_MAYBE(PARSER, NAME, ...) \
do { \
const llhttp_settings_t* settings; \
settings = (const llhttp_settings_t*) (PARSER)->settings; \
if (settings == NULL || settings->NAME == NULL) { \
err = 0; \
break; \
} \
err = settings->NAME(__VA_ARGS__); \
} while (0)
void llhttp_init(llhttp_t* parser, llhttp_type_t type,
const llhttp_settings_t* settings) {
llhttp__internal_init(parser);
parser->type = type;
parser->settings = (void*) settings;
}
#if defined(__wasm__)
extern int wasm_on_message_begin(llhttp_t * p);
extern int wasm_on_url(llhttp_t* p, const char* at, size_t length);
extern int wasm_on_status(llhttp_t* p, const char* at, size_t length);
extern int wasm_on_header_field(llhttp_t* p, const char* at, size_t length);
extern int wasm_on_header_value(llhttp_t* p, const char* at, size_t length);
extern int wasm_on_headers_complete(llhttp_t * p);
extern int wasm_on_body(llhttp_t* p, const char* at, size_t length);
extern int wasm_on_message_complete(llhttp_t * p);
const llhttp_settings_t wasm_settings = {
wasm_on_message_begin,
wasm_on_url,
wasm_on_status,
wasm_on_header_field,
wasm_on_header_value,
wasm_on_headers_complete,
wasm_on_body,
wasm_on_message_complete,
NULL,
NULL,
};
llhttp_t* llhttp_alloc(llhttp_type_t type) {
llhttp_t* parser = malloc(sizeof(llhttp_t));
llhttp_init(parser, type, &wasm_settings);
return parser;
}
void llhttp_free(llhttp_t* parser) {
free(parser);
}
/* Some getters required to get stuff from the parser */
uint8_t llhttp_get_type(llhttp_t* parser) {
return parser->type;
}
uint8_t llhttp_get_http_major(llhttp_t* parser) {
return parser->http_major;
}
uint8_t llhttp_get_http_minor(llhttp_t* parser) {
return parser->http_minor;
}
uint8_t llhttp_get_method(llhttp_t* parser) {
return parser->method;
}
int llhttp_get_status_code(llhttp_t* parser) {
return parser->status_code;
}
uint8_t llhttp_get_upgrade(llhttp_t* parser) {
return parser->upgrade;
}
#endif // defined(__wasm__)
void llhttp_reset(llhttp_t* parser) {
llhttp_type_t type = parser->type;
const llhttp_settings_t* settings = parser->settings;
void* data = parser->data;
uint8_t lenient_flags = parser->lenient_flags;
llhttp__internal_init(parser);
parser->type = type;
parser->settings = (void*) settings;
parser->data = data;
parser->lenient_flags = lenient_flags;
}
llhttp_errno_t llhttp_execute(llhttp_t* parser, const char* data, size_t len) {
return llhttp__internal_execute(parser, data, data + len);
}
void llhttp_settings_init(llhttp_settings_t* settings) {
memset(settings, 0, sizeof(*settings));
}
llhttp_errno_t llhttp_finish(llhttp_t* parser) {
int err;
/* We're in an error state. Don't bother doing anything. */
if (parser->error != 0) {
return 0;
}
switch (parser->finish) {
case HTTP_FINISH_SAFE_WITH_CB:
CALLBACK_MAYBE(parser, on_message_complete, parser);
if (err != HPE_OK) return err;
/* FALLTHROUGH */
case HTTP_FINISH_SAFE:
return HPE_OK;
case HTTP_FINISH_UNSAFE:
parser->reason = "Invalid EOF state";
return HPE_INVALID_EOF_STATE;
default:
abort();
}
}
void llhttp_pause(llhttp_t* parser) {
if (parser->error != HPE_OK) {
return;
}
parser->error = HPE_PAUSED;
parser->reason = "Paused";
}
void llhttp_resume(llhttp_t* parser) {
if (parser->error != HPE_PAUSED) {
return;
}
parser->error = 0;
}
void llhttp_resume_after_upgrade(llhttp_t* parser) {
if (parser->error != HPE_PAUSED_UPGRADE) {
return;
}
parser->error = 0;
}
llhttp_errno_t llhttp_get_errno(const llhttp_t* parser) {
return parser->error;
}
const char* llhttp_get_error_reason(const llhttp_t* parser) {
return parser->reason;
}
void llhttp_set_error_reason(llhttp_t* parser, const char* reason) {
parser->reason = reason;
}
const char* llhttp_get_error_pos(const llhttp_t* parser) {
return parser->error_pos;
}
const char* llhttp_errno_name(llhttp_errno_t err) {
#define HTTP_ERRNO_GEN(CODE, NAME, _) case HPE_##NAME: return "HPE_" #NAME;
switch (err) {
HTTP_ERRNO_MAP(HTTP_ERRNO_GEN)
default: abort();
}
#undef HTTP_ERRNO_GEN
}
const char* llhttp_method_name(llhttp_method_t method) {
#define HTTP_METHOD_GEN(NUM, NAME, STRING) case HTTP_##NAME: return #STRING;
switch (method) {
HTTP_METHOD_MAP(HTTP_METHOD_GEN)
default: abort();
}
#undef HTTP_METHOD_GEN
}
void llhttp_set_lenient_headers(llhttp_t* parser, int enabled) {
if (enabled) {
parser->lenient_flags |= LENIENT_HEADERS;
} else {
parser->lenient_flags &= ~LENIENT_HEADERS;
}
}
void llhttp_set_lenient_chunked_length(llhttp_t* parser, int enabled) {
if (enabled) {
parser->lenient_flags |= LENIENT_CHUNKED_LENGTH;
} else {
parser->lenient_flags &= ~LENIENT_CHUNKED_LENGTH;
}
}
void llhttp_set_lenient_keep_alive(llhttp_t* parser, int enabled) {
if (enabled) {
parser->lenient_flags |= LENIENT_KEEP_ALIVE;
} else {
parser->lenient_flags &= ~LENIENT_KEEP_ALIVE;
}
}
/* Callbacks */
int llhttp__on_message_begin(llhttp_t* s, const char* p, const char* endp) {
int err;
CALLBACK_MAYBE(s, on_message_begin, s);
return err;
}
int llhttp__on_url(llhttp_t* s, const char* p, const char* endp) {
int err;
CALLBACK_MAYBE(s, on_url, s, p, endp - p);
return err;
}
int llhttp__on_url_complete(llhttp_t* s, const char* p, const char* endp) {
int err;
CALLBACK_MAYBE(s, on_url_complete, s);
return err;
}
int llhttp__on_status(llhttp_t* s, const char* p, const char* endp) {
int err;
CALLBACK_MAYBE(s, on_status, s, p, endp - p);
return err;
}
int llhttp__on_status_complete(llhttp_t* s, const char* p, const char* endp) {
int err;
CALLBACK_MAYBE(s, on_status_complete, s);
return err;
}
int llhttp__on_header_field(llhttp_t* s, const char* p, const char* endp) {
int err;
CALLBACK_MAYBE(s, on_header_field, s, p, endp - p);
return err;
}
int llhttp__on_header_field_complete(llhttp_t* s, const char* p, const char* endp) {
int err;
CALLBACK_MAYBE(s, on_header_field_complete, s);
return err;
}
int llhttp__on_header_value(llhttp_t* s, const char* p, const char* endp) {
int err;
CALLBACK_MAYBE(s, on_header_value, s, p, endp - p);
return err;
}
int llhttp__on_header_value_complete(llhttp_t* s, const char* p, const char* endp) {
int err;
CALLBACK_MAYBE(s, on_header_value_complete, s);
return err;
}
int llhttp__on_headers_complete(llhttp_t* s, const char* p, const char* endp) {
int err;
CALLBACK_MAYBE(s, on_headers_complete, s);
return err;
}
int llhttp__on_message_complete(llhttp_t* s, const char* p, const char* endp) {
int err;
CALLBACK_MAYBE(s, on_message_complete, s);
return err;
}
int llhttp__on_body(llhttp_t* s, const char* p, const char* endp) {
int err;
CALLBACK_MAYBE(s, on_body, s, p, endp - p);
return err;
}
int llhttp__on_chunk_header(llhttp_t* s, const char* p, const char* endp) {
int err;
CALLBACK_MAYBE(s, on_chunk_header, s);
return err;
}
int llhttp__on_chunk_complete(llhttp_t* s, const char* p, const char* endp) {
int err;
CALLBACK_MAYBE(s, on_chunk_complete, s);
return err;
}
/* Private */
void llhttp__debug(llhttp_t* s, const char* p, const char* endp,
const char* msg) {
if (p == endp) {
fprintf(stderr, "p=%p type=%d flags=%02x next=null debug=%s\n", s, s->type,
s->flags, msg);
} else {
fprintf(stderr, "p=%p type=%d flags=%02x next=%02x debug=%s\n", s,
s->type, s->flags, *p, msg);
}
}

253
src/3rdparty/llhttp/api.h vendored Normal file
View File

@@ -0,0 +1,253 @@
#ifndef INCLUDE_LLHTTP_API_H_
#define INCLUDE_LLHTTP_API_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stddef.h>
#if defined(__wasm__)
#define LLHTTP_EXPORT __attribute__((visibility("default")))
#else
#define LLHTTP_EXPORT
#endif
typedef llhttp__internal_t llhttp_t;
typedef struct llhttp_settings_s llhttp_settings_t;
typedef int (*llhttp_data_cb)(llhttp_t*, const char *at, size_t length);
typedef int (*llhttp_cb)(llhttp_t*);
struct llhttp_settings_s {
/* Possible return values 0, -1, `HPE_PAUSED` */
llhttp_cb on_message_begin;
llhttp_data_cb on_url;
llhttp_data_cb on_status;
llhttp_data_cb on_header_field;
llhttp_data_cb on_header_value;
/* Possible return values:
* 0 - Proceed normally
* 1 - Assume that request/response has no body, and proceed to parsing the
* next message
* 2 - Assume absence of body (as above) and make `llhttp_execute()` return
* `HPE_PAUSED_UPGRADE`
* -1 - Error
* `HPE_PAUSED`
*/
llhttp_cb on_headers_complete;
llhttp_data_cb on_body;
/* Possible return values 0, -1, `HPE_PAUSED` */
llhttp_cb on_message_complete;
/* When on_chunk_header is called, the current chunk length is stored
* in parser->content_length.
* Possible return values 0, -1, `HPE_PAUSED`
*/
llhttp_cb on_chunk_header;
llhttp_cb on_chunk_complete;
llhttp_cb on_url_complete;
llhttp_cb on_status_complete;
llhttp_cb on_header_field_complete;
llhttp_cb on_header_value_complete;
};
/* Initialize the parser with specific type and user settings.
*
* NOTE: lifetime of `settings` has to be at least the same as the lifetime of
* the `parser` here. In practice, `settings` has to be either a static
* variable or be allocated with `malloc`, `new`, etc.
*/
LLHTTP_EXPORT
void llhttp_init(llhttp_t* parser, llhttp_type_t type,
const llhttp_settings_t* settings);
#if defined(__wasm__)
LLHTTP_EXPORT
llhttp_t* llhttp_alloc(llhttp_type_t type);
LLHTTP_EXPORT
void llhttp_free(llhttp_t* parser);
LLHTTP_EXPORT
uint8_t llhttp_get_type(llhttp_t* parser);
LLHTTP_EXPORT
uint8_t llhttp_get_http_major(llhttp_t* parser);
LLHTTP_EXPORT
uint8_t llhttp_get_http_minor(llhttp_t* parser);
LLHTTP_EXPORT
uint8_t llhttp_get_method(llhttp_t* parser);
LLHTTP_EXPORT
int llhttp_get_status_code(llhttp_t* parser);
LLHTTP_EXPORT
uint8_t llhttp_get_upgrade(llhttp_t* parser);
#endif // defined(__wasm__)
/* Reset an already initialized parser back to the start state, preserving the
* existing parser type, callback settings, user data, and lenient flags.
*/
LLHTTP_EXPORT
void llhttp_reset(llhttp_t* parser);
/* Initialize the settings object */
LLHTTP_EXPORT
void llhttp_settings_init(llhttp_settings_t* settings);
/* Parse full or partial request/response, invoking user callbacks along the
* way.
*
* If any of `llhttp_data_cb` returns errno not equal to `HPE_OK` - the parsing
* interrupts, and such errno is returned from `llhttp_execute()`. If
* `HPE_PAUSED` was used as a errno, the execution can be resumed with
* `llhttp_resume()` call.
*
* In a special case of CONNECT/Upgrade request/response `HPE_PAUSED_UPGRADE`
* is returned after fully parsing the request/response. If the user wishes to
* continue parsing, they need to invoke `llhttp_resume_after_upgrade()`.
*
* NOTE: if this function ever returns a non-pause type error, it will continue
* to return the same error upon each successive call up until `llhttp_init()`
* is called.
*/
LLHTTP_EXPORT
llhttp_errno_t llhttp_execute(llhttp_t* parser, const char* data, size_t len);
/* This method should be called when the other side has no further bytes to
* send (e.g. shutdown of readable side of the TCP connection.)
*
* Requests without `Content-Length` and other messages might require treating
* all incoming bytes as the part of the body, up to the last byte of the
* connection. This method will invoke `on_message_complete()` callback if the
* request was terminated safely. Otherwise a error code would be returned.
*/
LLHTTP_EXPORT
llhttp_errno_t llhttp_finish(llhttp_t* parser);
/* Returns `1` if the incoming message is parsed until the last byte, and has
* to be completed by calling `llhttp_finish()` on EOF
*/
LLHTTP_EXPORT
int llhttp_message_needs_eof(const llhttp_t* parser);
/* Returns `1` if there might be any other messages following the last that was
* successfully parsed.
*/
LLHTTP_EXPORT
int llhttp_should_keep_alive(const llhttp_t* parser);
/* Make further calls of `llhttp_execute()` return `HPE_PAUSED` and set
* appropriate error reason.
*
* Important: do not call this from user callbacks! User callbacks must return
* `HPE_PAUSED` if pausing is required.
*/
LLHTTP_EXPORT
void llhttp_pause(llhttp_t* parser);
/* Might be called to resume the execution after the pause in user's callback.
* See `llhttp_execute()` above for details.
*
* Call this only if `llhttp_execute()` returns `HPE_PAUSED`.
*/
LLHTTP_EXPORT
void llhttp_resume(llhttp_t* parser);
/* Might be called to resume the execution after the pause in user's callback.
* See `llhttp_execute()` above for details.
*
* Call this only if `llhttp_execute()` returns `HPE_PAUSED_UPGRADE`
*/
LLHTTP_EXPORT
void llhttp_resume_after_upgrade(llhttp_t* parser);
/* Returns the latest return error */
LLHTTP_EXPORT
llhttp_errno_t llhttp_get_errno(const llhttp_t* parser);
/* Returns the verbal explanation of the latest returned error.
*
* Note: User callback should set error reason when returning the error. See
* `llhttp_set_error_reason()` for details.
*/
LLHTTP_EXPORT
const char* llhttp_get_error_reason(const llhttp_t* parser);
/* Assign verbal description to the returned error. Must be called in user
* callbacks right before returning the errno.
*
* Note: `HPE_USER` error code might be useful in user callbacks.
*/
LLHTTP_EXPORT
void llhttp_set_error_reason(llhttp_t* parser, const char* reason);
/* Returns the pointer to the last parsed byte before the returned error. The
* pointer is relative to the `data` argument of `llhttp_execute()`.
*
* Note: this method might be useful for counting the number of parsed bytes.
*/
LLHTTP_EXPORT
const char* llhttp_get_error_pos(const llhttp_t* parser);
/* Returns textual name of error code */
LLHTTP_EXPORT
const char* llhttp_errno_name(llhttp_errno_t err);
/* Returns textual name of HTTP method */
LLHTTP_EXPORT
const char* llhttp_method_name(llhttp_method_t method);
/* Enables/disables lenient header value parsing (disabled by default).
*
* Lenient parsing disables header value token checks, extending llhttp's
* protocol support to highly non-compliant clients/server. No
* `HPE_INVALID_HEADER_TOKEN` will be raised for incorrect header values when
* lenient parsing is "on".
*
* **(USE AT YOUR OWN RISK)**
*/
LLHTTP_EXPORT
void llhttp_set_lenient_headers(llhttp_t* parser, int enabled);
/* Enables/disables lenient handling of conflicting `Transfer-Encoding` and
* `Content-Length` headers (disabled by default).
*
* Normally `llhttp` would error when `Transfer-Encoding` is present in
* conjunction with `Content-Length`. This error is important to prevent HTTP
* request smuggling, but may be less desirable for small number of cases
* involving legacy servers.
*
* **(USE AT YOUR OWN RISK)**
*/
LLHTTP_EXPORT
void llhttp_set_lenient_chunked_length(llhttp_t* parser, int enabled);
/* Enables/disables lenient handling of `Connection: close` and HTTP/1.0
* requests responses.
*
* Normally `llhttp` would error on (in strict mode) or discard (in loose mode)
* the HTTP request/response after the request/response with `Connection: close`
* and `Content-Length`. This is important to prevent cache poisoning attacks,
* but might interact badly with outdated and insecure clients. With this flag
* the extra request/response will be parsed normally.
*
* **(USE AT YOUR OWN RISK)**
*/
void llhttp_set_lenient_keep_alive(llhttp_t* parser, int enabled);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* INCLUDE_LLHTTP_API_H_ */

149
src/3rdparty/llhttp/http.c vendored Normal file
View File

@@ -0,0 +1,149 @@
#include <stdio.h>
#ifndef LLHTTP__TEST
# include "llhttp.h"
#else
# define llhttp_t llparse_t
#endif /* */
int llhttp_message_needs_eof(const llhttp_t* parser);
int llhttp_should_keep_alive(const llhttp_t* parser);
int llhttp__before_headers_complete(llhttp_t* parser, const char* p,
const char* endp) {
/* Set this here so that on_headers_complete() callbacks can see it */
if ((parser->flags & F_UPGRADE) &&
(parser->flags & F_CONNECTION_UPGRADE)) {
/* For responses, "Upgrade: foo" and "Connection: upgrade" are
* mandatory only when it is a 101 Switching Protocols response,
* otherwise it is purely informational, to announce support.
*/
parser->upgrade =
(parser->type == HTTP_REQUEST || parser->status_code == 101);
} else {
parser->upgrade = (parser->method == HTTP_CONNECT);
}
return 0;
}
/* Return values:
* 0 - No body, `restart`, message_complete
* 1 - CONNECT request, `restart`, message_complete, and pause
* 2 - chunk_size_start
* 3 - body_identity
* 4 - body_identity_eof
* 5 - invalid transfer-encoding for request
*/
int llhttp__after_headers_complete(llhttp_t* parser, const char* p,
const char* endp) {
int hasBody;
hasBody = parser->flags & F_CHUNKED || parser->content_length > 0;
if (parser->upgrade && (parser->method == HTTP_CONNECT ||
(parser->flags & F_SKIPBODY) || !hasBody)) {
/* Exit, the rest of the message is in a different protocol. */
return 1;
}
if (parser->flags & F_SKIPBODY) {
return 0;
} else if (parser->flags & F_CHUNKED) {
/* chunked encoding - ignore Content-Length header, prepare for a chunk */
return 2;
} else if (parser->flags & F_TRANSFER_ENCODING) {
if (parser->type == HTTP_REQUEST &&
(parser->lenient_flags & LENIENT_CHUNKED_LENGTH) == 0) {
/* RFC 7230 3.3.3 */
/* If a Transfer-Encoding header field
* is present in a request and the chunked transfer coding is not
* the final encoding, the message body length cannot be determined
* reliably; the server MUST respond with the 400 (Bad Request)
* status code and then close the connection.
*/
return 5;
} else {
/* RFC 7230 3.3.3 */
/* If a Transfer-Encoding header field is present in a response and
* the chunked transfer coding is not the final encoding, the
* message body length is determined by reading the connection until
* it is closed by the server.
*/
return 4;
}
} else {
if (!(parser->flags & F_CONTENT_LENGTH)) {
if (!llhttp_message_needs_eof(parser)) {
/* Assume content-length 0 - read the next */
return 0;
} else {
/* Read body until EOF */
return 4;
}
} else if (parser->content_length == 0) {
/* Content-Length header given but zero: Content-Length: 0\r\n */
return 0;
} else {
/* Content-Length header given and non-zero */
return 3;
}
}
}
int llhttp__after_message_complete(llhttp_t* parser, const char* p,
const char* endp) {
int should_keep_alive;
should_keep_alive = llhttp_should_keep_alive(parser);
parser->finish = HTTP_FINISH_SAFE;
parser->flags = 0;
/* NOTE: this is ignored in loose parsing mode */
return should_keep_alive;
}
int llhttp_message_needs_eof(const llhttp_t* parser) {
if (parser->type == HTTP_REQUEST) {
return 0;
}
/* See RFC 2616 section 4.4 */
if (parser->status_code / 100 == 1 || /* 1xx e.g. Continue */
parser->status_code == 204 || /* No Content */
parser->status_code == 304 || /* Not Modified */
(parser->flags & F_SKIPBODY)) { /* response to a HEAD request */
return 0;
}
/* RFC 7230 3.3.3, see `llhttp__after_headers_complete` */
if ((parser->flags & F_TRANSFER_ENCODING) &&
(parser->flags & F_CHUNKED) == 0) {
return 1;
}
if (parser->flags & (F_CHUNKED | F_CONTENT_LENGTH)) {
return 0;
}
return 1;
}
int llhttp_should_keep_alive(const llhttp_t* parser) {
if (parser->http_major > 0 && parser->http_minor > 0) {
/* HTTP/1.1 */
if (parser->flags & F_CONNECTION_CLOSE) {
return 0;
}
} else {
/* HTTP/1.0 or earlier */
if (!(parser->flags & F_CONNECTION_KEEP_ALIVE)) {
return 0;
}
}
return !llhttp_message_needs_eof(parser);
}

14926
src/3rdparty/llhttp/llhttp.c vendored Normal file

File diff suppressed because it is too large Load Diff

508
src/3rdparty/llhttp/llhttp.h vendored Normal file
View File

@@ -0,0 +1,508 @@
#ifndef INCLUDE_LLHTTP_H_
#define INCLUDE_LLHTTP_H_
#define LLHTTP_VERSION_MAJOR 5
#define LLHTTP_VERSION_MINOR 1
#define LLHTTP_VERSION_PATCH 0
#ifndef LLHTTP_STRICT_MODE
# define LLHTTP_STRICT_MODE 0
#endif
#ifndef INCLUDE_LLHTTP_ITSELF_H_
#define INCLUDE_LLHTTP_ITSELF_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
typedef struct llhttp__internal_s llhttp__internal_t;
struct llhttp__internal_s {
int32_t _index;
void* _span_pos0;
void* _span_cb0;
int32_t error;
const char* reason;
const char* error_pos;
void* data;
void* _current;
uint64_t content_length;
uint8_t type;
uint8_t method;
uint8_t http_major;
uint8_t http_minor;
uint8_t header_state;
uint8_t lenient_flags;
uint8_t upgrade;
uint8_t finish;
uint16_t flags;
uint16_t status_code;
void* settings;
};
int llhttp__internal_init(llhttp__internal_t* s);
int llhttp__internal_execute(llhttp__internal_t* s, const char* p, const char* endp);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* INCLUDE_LLHTTP_ITSELF_H_ */
#ifndef LLLLHTTP_C_HEADERS_
#define LLLLHTTP_C_HEADERS_
#ifdef __cplusplus
extern "C" {
#endif
enum llhttp_errno {
HPE_OK = 0,
HPE_INTERNAL = 1,
HPE_STRICT = 2,
HPE_LF_EXPECTED = 3,
HPE_UNEXPECTED_CONTENT_LENGTH = 4,
HPE_CLOSED_CONNECTION = 5,
HPE_INVALID_METHOD = 6,
HPE_INVALID_URL = 7,
HPE_INVALID_CONSTANT = 8,
HPE_INVALID_VERSION = 9,
HPE_INVALID_HEADER_TOKEN = 10,
HPE_INVALID_CONTENT_LENGTH = 11,
HPE_INVALID_CHUNK_SIZE = 12,
HPE_INVALID_STATUS = 13,
HPE_INVALID_EOF_STATE = 14,
HPE_INVALID_TRANSFER_ENCODING = 15,
HPE_CB_MESSAGE_BEGIN = 16,
HPE_CB_HEADERS_COMPLETE = 17,
HPE_CB_MESSAGE_COMPLETE = 18,
HPE_CB_CHUNK_HEADER = 19,
HPE_CB_CHUNK_COMPLETE = 20,
HPE_PAUSED = 21,
HPE_PAUSED_UPGRADE = 22,
HPE_PAUSED_H2_UPGRADE = 23,
HPE_USER = 24
};
typedef enum llhttp_errno llhttp_errno_t;
enum llhttp_flags {
F_CONNECTION_KEEP_ALIVE = 0x1,
F_CONNECTION_CLOSE = 0x2,
F_CONNECTION_UPGRADE = 0x4,
F_CHUNKED = 0x8,
F_UPGRADE = 0x10,
F_CONTENT_LENGTH = 0x20,
F_SKIPBODY = 0x40,
F_TRAILING = 0x80,
F_TRANSFER_ENCODING = 0x200
};
typedef enum llhttp_flags llhttp_flags_t;
enum llhttp_lenient_flags {
LENIENT_HEADERS = 0x1,
LENIENT_CHUNKED_LENGTH = 0x2,
LENIENT_KEEP_ALIVE = 0x4
};
typedef enum llhttp_lenient_flags llhttp_lenient_flags_t;
enum llhttp_type {
HTTP_BOTH = 0,
HTTP_REQUEST = 1,
HTTP_RESPONSE = 2
};
typedef enum llhttp_type llhttp_type_t;
enum llhttp_finish {
HTTP_FINISH_SAFE = 0,
HTTP_FINISH_SAFE_WITH_CB = 1,
HTTP_FINISH_UNSAFE = 2
};
typedef enum llhttp_finish llhttp_finish_t;
enum llhttp_method {
HTTP_DELETE = 0,
HTTP_GET = 1,
HTTP_HEAD = 2,
HTTP_POST = 3,
HTTP_PUT = 4,
HTTP_CONNECT = 5,
HTTP_OPTIONS = 6,
HTTP_TRACE = 7,
HTTP_COPY = 8,
HTTP_LOCK = 9,
HTTP_MKCOL = 10,
HTTP_MOVE = 11,
HTTP_PROPFIND = 12,
HTTP_PROPPATCH = 13,
HTTP_SEARCH = 14,
HTTP_UNLOCK = 15,
HTTP_BIND = 16,
HTTP_REBIND = 17,
HTTP_UNBIND = 18,
HTTP_ACL = 19,
HTTP_REPORT = 20,
HTTP_MKACTIVITY = 21,
HTTP_CHECKOUT = 22,
HTTP_MERGE = 23,
HTTP_MSEARCH = 24,
HTTP_NOTIFY = 25,
HTTP_SUBSCRIBE = 26,
HTTP_UNSUBSCRIBE = 27,
HTTP_PATCH = 28,
HTTP_PURGE = 29,
HTTP_MKCALENDAR = 30,
HTTP_LINK = 31,
HTTP_UNLINK = 32,
HTTP_SOURCE = 33,
HTTP_PRI = 34,
HTTP_DESCRIBE = 35,
HTTP_ANNOUNCE = 36,
HTTP_SETUP = 37,
HTTP_PLAY = 38,
HTTP_PAUSE = 39,
HTTP_TEARDOWN = 40,
HTTP_GET_PARAMETER = 41,
HTTP_SET_PARAMETER = 42,
HTTP_REDIRECT = 43,
HTTP_RECORD = 44,
HTTP_FLUSH = 45
};
typedef enum llhttp_method llhttp_method_t;
#define HTTP_ERRNO_MAP(XX) \
XX(0, OK, OK) \
XX(1, INTERNAL, INTERNAL) \
XX(2, STRICT, STRICT) \
XX(3, LF_EXPECTED, LF_EXPECTED) \
XX(4, UNEXPECTED_CONTENT_LENGTH, UNEXPECTED_CONTENT_LENGTH) \
XX(5, CLOSED_CONNECTION, CLOSED_CONNECTION) \
XX(6, INVALID_METHOD, INVALID_METHOD) \
XX(7, INVALID_URL, INVALID_URL) \
XX(8, INVALID_CONSTANT, INVALID_CONSTANT) \
XX(9, INVALID_VERSION, INVALID_VERSION) \
XX(10, INVALID_HEADER_TOKEN, INVALID_HEADER_TOKEN) \
XX(11, INVALID_CONTENT_LENGTH, INVALID_CONTENT_LENGTH) \
XX(12, INVALID_CHUNK_SIZE, INVALID_CHUNK_SIZE) \
XX(13, INVALID_STATUS, INVALID_STATUS) \
XX(14, INVALID_EOF_STATE, INVALID_EOF_STATE) \
XX(15, INVALID_TRANSFER_ENCODING, INVALID_TRANSFER_ENCODING) \
XX(16, CB_MESSAGE_BEGIN, CB_MESSAGE_BEGIN) \
XX(17, CB_HEADERS_COMPLETE, CB_HEADERS_COMPLETE) \
XX(18, CB_MESSAGE_COMPLETE, CB_MESSAGE_COMPLETE) \
XX(19, CB_CHUNK_HEADER, CB_CHUNK_HEADER) \
XX(20, CB_CHUNK_COMPLETE, CB_CHUNK_COMPLETE) \
XX(21, PAUSED, PAUSED) \
XX(22, PAUSED_UPGRADE, PAUSED_UPGRADE) \
XX(23, PAUSED_H2_UPGRADE, PAUSED_H2_UPGRADE) \
XX(24, USER, USER) \
#define HTTP_METHOD_MAP(XX) \
XX(0, DELETE, DELETE) \
XX(1, GET, GET) \
XX(2, HEAD, HEAD) \
XX(3, POST, POST) \
XX(4, PUT, PUT) \
XX(5, CONNECT, CONNECT) \
XX(6, OPTIONS, OPTIONS) \
XX(7, TRACE, TRACE) \
XX(8, COPY, COPY) \
XX(9, LOCK, LOCK) \
XX(10, MKCOL, MKCOL) \
XX(11, MOVE, MOVE) \
XX(12, PROPFIND, PROPFIND) \
XX(13, PROPPATCH, PROPPATCH) \
XX(14, SEARCH, SEARCH) \
XX(15, UNLOCK, UNLOCK) \
XX(16, BIND, BIND) \
XX(17, REBIND, REBIND) \
XX(18, UNBIND, UNBIND) \
XX(19, ACL, ACL) \
XX(20, REPORT, REPORT) \
XX(21, MKACTIVITY, MKACTIVITY) \
XX(22, CHECKOUT, CHECKOUT) \
XX(23, MERGE, MERGE) \
XX(24, MSEARCH, M-SEARCH) \
XX(25, NOTIFY, NOTIFY) \
XX(26, SUBSCRIBE, SUBSCRIBE) \
XX(27, UNSUBSCRIBE, UNSUBSCRIBE) \
XX(28, PATCH, PATCH) \
XX(29, PURGE, PURGE) \
XX(30, MKCALENDAR, MKCALENDAR) \
XX(31, LINK, LINK) \
XX(32, UNLINK, UNLINK) \
XX(33, SOURCE, SOURCE) \
XX(34, PRI, PRI) \
XX(35, DESCRIBE, DESCRIBE) \
XX(36, ANNOUNCE, ANNOUNCE) \
XX(37, SETUP, SETUP) \
XX(38, PLAY, PLAY) \
XX(39, PAUSE, PAUSE) \
XX(40, TEARDOWN, TEARDOWN) \
XX(41, GET_PARAMETER, GET_PARAMETER) \
XX(42, SET_PARAMETER, SET_PARAMETER) \
XX(43, REDIRECT, REDIRECT) \
XX(44, RECORD, RECORD) \
XX(45, FLUSH, FLUSH) \
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* LLLLHTTP_C_HEADERS_ */
#ifndef INCLUDE_LLHTTP_API_H_
#define INCLUDE_LLHTTP_API_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stddef.h>
#if defined(__wasm__)
#define LLHTTP_EXPORT __attribute__((visibility("default")))
#else
#define LLHTTP_EXPORT
#endif
typedef llhttp__internal_t llhttp_t;
typedef struct llhttp_settings_s llhttp_settings_t;
typedef int (*llhttp_data_cb)(llhttp_t*, const char *at, size_t length);
typedef int (*llhttp_cb)(llhttp_t*);
struct llhttp_settings_s {
/* Possible return values 0, -1, `HPE_PAUSED` */
llhttp_cb on_message_begin;
llhttp_data_cb on_url;
llhttp_data_cb on_status;
llhttp_data_cb on_header_field;
llhttp_data_cb on_header_value;
/* Possible return values:
* 0 - Proceed normally
* 1 - Assume that request/response has no body, and proceed to parsing the
* next message
* 2 - Assume absence of body (as above) and make `llhttp_execute()` return
* `HPE_PAUSED_UPGRADE`
* -1 - Error
* `HPE_PAUSED`
*/
llhttp_cb on_headers_complete;
llhttp_data_cb on_body;
/* Possible return values 0, -1, `HPE_PAUSED` */
llhttp_cb on_message_complete;
/* When on_chunk_header is called, the current chunk length is stored
* in parser->content_length.
* Possible return values 0, -1, `HPE_PAUSED`
*/
llhttp_cb on_chunk_header;
llhttp_cb on_chunk_complete;
llhttp_cb on_url_complete;
llhttp_cb on_status_complete;
llhttp_cb on_header_field_complete;
llhttp_cb on_header_value_complete;
};
/* Initialize the parser with specific type and user settings.
*
* NOTE: lifetime of `settings` has to be at least the same as the lifetime of
* the `parser` here. In practice, `settings` has to be either a static
* variable or be allocated with `malloc`, `new`, etc.
*/
LLHTTP_EXPORT
void llhttp_init(llhttp_t* parser, llhttp_type_t type,
const llhttp_settings_t* settings);
#if defined(__wasm__)
LLHTTP_EXPORT
llhttp_t* llhttp_alloc(llhttp_type_t type);
LLHTTP_EXPORT
void llhttp_free(llhttp_t* parser);
LLHTTP_EXPORT
uint8_t llhttp_get_type(llhttp_t* parser);
LLHTTP_EXPORT
uint8_t llhttp_get_http_major(llhttp_t* parser);
LLHTTP_EXPORT
uint8_t llhttp_get_http_minor(llhttp_t* parser);
LLHTTP_EXPORT
uint8_t llhttp_get_method(llhttp_t* parser);
LLHTTP_EXPORT
int llhttp_get_status_code(llhttp_t* parser);
LLHTTP_EXPORT
uint8_t llhttp_get_upgrade(llhttp_t* parser);
#endif // defined(__wasm__)
/* Reset an already initialized parser back to the start state, preserving the
* existing parser type, callback settings, user data, and lenient flags.
*/
LLHTTP_EXPORT
void llhttp_reset(llhttp_t* parser);
/* Initialize the settings object */
LLHTTP_EXPORT
void llhttp_settings_init(llhttp_settings_t* settings);
/* Parse full or partial request/response, invoking user callbacks along the
* way.
*
* If any of `llhttp_data_cb` returns errno not equal to `HPE_OK` - the parsing
* interrupts, and such errno is returned from `llhttp_execute()`. If
* `HPE_PAUSED` was used as a errno, the execution can be resumed with
* `llhttp_resume()` call.
*
* In a special case of CONNECT/Upgrade request/response `HPE_PAUSED_UPGRADE`
* is returned after fully parsing the request/response. If the user wishes to
* continue parsing, they need to invoke `llhttp_resume_after_upgrade()`.
*
* NOTE: if this function ever returns a non-pause type error, it will continue
* to return the same error upon each successive call up until `llhttp_init()`
* is called.
*/
LLHTTP_EXPORT
llhttp_errno_t llhttp_execute(llhttp_t* parser, const char* data, size_t len);
/* This method should be called when the other side has no further bytes to
* send (e.g. shutdown of readable side of the TCP connection.)
*
* Requests without `Content-Length` and other messages might require treating
* all incoming bytes as the part of the body, up to the last byte of the
* connection. This method will invoke `on_message_complete()` callback if the
* request was terminated safely. Otherwise a error code would be returned.
*/
LLHTTP_EXPORT
llhttp_errno_t llhttp_finish(llhttp_t* parser);
/* Returns `1` if the incoming message is parsed until the last byte, and has
* to be completed by calling `llhttp_finish()` on EOF
*/
LLHTTP_EXPORT
int llhttp_message_needs_eof(const llhttp_t* parser);
/* Returns `1` if there might be any other messages following the last that was
* successfully parsed.
*/
LLHTTP_EXPORT
int llhttp_should_keep_alive(const llhttp_t* parser);
/* Make further calls of `llhttp_execute()` return `HPE_PAUSED` and set
* appropriate error reason.
*
* Important: do not call this from user callbacks! User callbacks must return
* `HPE_PAUSED` if pausing is required.
*/
LLHTTP_EXPORT
void llhttp_pause(llhttp_t* parser);
/* Might be called to resume the execution after the pause in user's callback.
* See `llhttp_execute()` above for details.
*
* Call this only if `llhttp_execute()` returns `HPE_PAUSED`.
*/
LLHTTP_EXPORT
void llhttp_resume(llhttp_t* parser);
/* Might be called to resume the execution after the pause in user's callback.
* See `llhttp_execute()` above for details.
*
* Call this only if `llhttp_execute()` returns `HPE_PAUSED_UPGRADE`
*/
LLHTTP_EXPORT
void llhttp_resume_after_upgrade(llhttp_t* parser);
/* Returns the latest return error */
LLHTTP_EXPORT
llhttp_errno_t llhttp_get_errno(const llhttp_t* parser);
/* Returns the verbal explanation of the latest returned error.
*
* Note: User callback should set error reason when returning the error. See
* `llhttp_set_error_reason()` for details.
*/
LLHTTP_EXPORT
const char* llhttp_get_error_reason(const llhttp_t* parser);
/* Assign verbal description to the returned error. Must be called in user
* callbacks right before returning the errno.
*
* Note: `HPE_USER` error code might be useful in user callbacks.
*/
LLHTTP_EXPORT
void llhttp_set_error_reason(llhttp_t* parser, const char* reason);
/* Returns the pointer to the last parsed byte before the returned error. The
* pointer is relative to the `data` argument of `llhttp_execute()`.
*
* Note: this method might be useful for counting the number of parsed bytes.
*/
LLHTTP_EXPORT
const char* llhttp_get_error_pos(const llhttp_t* parser);
/* Returns textual name of error code */
LLHTTP_EXPORT
const char* llhttp_errno_name(llhttp_errno_t err);
/* Returns textual name of HTTP method */
LLHTTP_EXPORT
const char* llhttp_method_name(llhttp_method_t method);
/* Enables/disables lenient header value parsing (disabled by default).
*
* Lenient parsing disables header value token checks, extending llhttp's
* protocol support to highly non-compliant clients/server. No
* `HPE_INVALID_HEADER_TOKEN` will be raised for incorrect header values when
* lenient parsing is "on".
*
* **(USE AT YOUR OWN RISK)**
*/
LLHTTP_EXPORT
void llhttp_set_lenient_headers(llhttp_t* parser, int enabled);
/* Enables/disables lenient handling of conflicting `Transfer-Encoding` and
* `Content-Length` headers (disabled by default).
*
* Normally `llhttp` would error when `Transfer-Encoding` is present in
* conjunction with `Content-Length`. This error is important to prevent HTTP
* request smuggling, but may be less desirable for small number of cases
* involving legacy servers.
*
* **(USE AT YOUR OWN RISK)**
*/
LLHTTP_EXPORT
void llhttp_set_lenient_chunked_length(llhttp_t* parser, int enabled);
/* Enables/disables lenient handling of `Connection: close` and HTTP/1.0
* requests responses.
*
* Normally `llhttp` would error on (in strict mode) or discard (in loose mode)
* the HTTP request/response after the request/response with `Connection: close`
* and `Content-Length`. This is important to prevent cache poisoning attacks,
* but might interact badly with outdated and insecure clients. With this flag
* the extra request/response will be parsed normally.
*
* **(USE AT YOUR OWN RISK)**
*/
void llhttp_set_lenient_keep_alive(llhttp_t* parser, int enabled);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* INCLUDE_LLHTTP_API_H_ */
#endif /* INCLUDE_LLHTTP_H_ */

View File

@@ -85,9 +85,10 @@ public:
}
inline int32_t nonceOffset() const { return currentJob().nonceOffset(); }
inline size_t nonceSize() const { return currentJob().nonceSize(); }
private:
inline int32_t nonceOffset() const { return currentJob().nonceOffset(); }
inline size_t nonceSize() const { return currentJob().nonceSize(); }
inline uint64_t nonceMask() const { return m_nonce_mask[index()]; }
inline void save(const Job &job, uint32_t reserveCount, Nonce::Backend backend)

View File

@@ -20,6 +20,9 @@
#define XMRIG_WORKERS_H
#include <memory>
#include "backend/common/Thread.h"
#include "backend/cpu/CpuLaunchData.h"

View File

@@ -334,13 +334,11 @@ void xmrig::CpuBackend::printHashrate(bool details)
i++;
}
# ifdef XMRIG_FEATURE_OPENCL
Log::print(WHITE_BOLD_S "| - | - | %7s | %7s | %7s |",
Hashrate::format(hashrate()->calc(Hashrate::ShortInterval), num, sizeof num / 3),
Hashrate::format(hashrate()->calc(Hashrate::MediumInterval), num + 8, sizeof num / 3),
Hashrate::format(hashrate()->calc(Hashrate::LargeInterval), num + 8 * 2, sizeof num / 3)
);
# endif
}

View File

@@ -197,6 +197,7 @@ void xmrig::CpuConfig::generate()
count += xmrig::generate<Algorithm::CN_LITE>(m_threads, m_limit);
count += xmrig::generate<Algorithm::CN_HEAVY>(m_threads, m_limit);
count += xmrig::generate<Algorithm::CN_PICO>(m_threads, m_limit);
count += xmrig::generate<Algorithm::CN_FEMTO>(m_threads, m_limit);
count += xmrig::generate<Algorithm::RANDOM_X>(m_threads, m_limit);
count += xmrig::generate<Algorithm::ARGON2>(m_threads, m_limit);
count += xmrig::generate<Algorithm::ASTROBWT>(m_threads, m_limit);

View File

@@ -100,6 +100,15 @@ size_t inline generate<Algorithm::CN_PICO>(Threads<CpuThreads> &threads, uint32_
#endif
#ifdef XMRIG_ALGO_CN_FEMTO
template<>
size_t inline generate<Algorithm::CN_FEMTO>(Threads<CpuThreads>& threads, uint32_t limit)
{
return generate("cn/upx2", threads, Algorithm::CN_UPX2, limit);
}
#endif
#ifdef XMRIG_ALGO_RANDOMX
template<>
size_t inline generate<Algorithm::RANDOM_X>(Threads<CpuThreads> &threads, uint32_t limit)

View File

@@ -83,10 +83,12 @@ xmrig::CpuWorker<N>::CpuWorker(size_t id, const CpuLaunchData &data) :
{
# ifdef XMRIG_ALGO_CN_HEAVY
// cn-heavy optimization for Zen3 CPUs
if ((N == 1) && (m_av == CnHash::AV_SINGLE) && (m_algorithm.family() == Algorithm::CN_HEAVY) && (Cpu::info()->arch() == ICpuInfo::ARCH_ZEN3)) {
if ((N == 1) && (m_av == CnHash::AV_SINGLE) && (m_algorithm.family() == Algorithm::CN_HEAVY) && (m_assembly != Assembly::NONE) && (Cpu::info()->arch() == ICpuInfo::ARCH_ZEN3)) {
std::lock_guard<std::mutex> lock(cn_heavyZen3MemoryMutex);
if (!cn_heavyZen3Memory) {
cn_heavyZen3Memory = new VirtualMemory(m_algorithm.l3() * m_threads, data.hugePages, false, false, node());
// Round up number of threads to the multiple of 8
const size_t num_threads = ((m_threads + 7) / 8) * 8;
cn_heavyZen3Memory = new VirtualMemory(m_algorithm.l3() * num_threads, data.hugePages, false, false, node());
}
m_memory = cn_heavyZen3Memory;
}
@@ -191,6 +193,12 @@ bool xmrig::CpuWorker<N>::selfTest()
}
# endif
# ifdef XMRIG_ALGO_CN_FEMTO
if (m_algorithm.family() == Algorithm::CN_FEMTO) {
return verify(Algorithm::CN_UPX2, test_output_femto_upx2);
}
# endif
# ifdef XMRIG_ALGO_ARGON2
if (m_algorithm.family() == Algorithm::ARGON2) {
return verify(Algorithm::AR2_CHUKWA, argon2_chukwa_test_out) &&
@@ -266,10 +274,16 @@ void xmrig::CpuWorker<N>::start()
bool valid = true;
uint8_t miner_signature_saved[64];
uint8_t* miner_signature_ptr = m_job.blob() + m_job.nonceOffset() + m_job.nonceSize();
# ifdef XMRIG_ALGO_RANDOMX
if (job.algorithm().family() == Algorithm::RANDOM_X) {
if (first) {
first = false;
if (job.hasMinerSignature()) {
job.generateMinerSignature(m_job.blob(), job.size(), miner_signature_ptr);
}
randomx_calculate_hash_first(m_vm, tempHash, m_job.blob(), job.size());
}
@@ -277,6 +291,10 @@ void xmrig::CpuWorker<N>::start()
break;
}
if (job.hasMinerSignature()) {
memcpy(miner_signature_saved, miner_signature_ptr, sizeof(miner_signature_saved));
job.generateMinerSignature(m_job.blob(), job.size(), miner_signature_ptr);
}
randomx_calculate_hash_next(m_vm, tempHash, m_job.blob(), job.size(), m_hash);
}
else
@@ -311,7 +329,7 @@ void xmrig::CpuWorker<N>::start()
else
# endif
if (value < job.target()) {
JobResults::submit(job, current_job_nonces[i], m_hash + (i * 32));
JobResults::submit(job, current_job_nonces[i], m_hash + (i * 32), miner_signature_saved);
}
}
m_count += N;

View File

@@ -309,26 +309,34 @@ xmrig::CpuThreads xmrig::BasicCpuInfo::threads(const Algorithm &algorithm, uint3
return 1;
}
Algorithm::Family f = algorithm.family();
# ifdef XMRIG_ALGO_CN_LITE
if (algorithm.family() == Algorithm::CN_LITE) {
if (f == Algorithm::CN_LITE) {
return CpuThreads(count, 1);
}
# endif
# ifdef XMRIG_ALGO_CN_PICO
if (algorithm.family() == Algorithm::CN_PICO) {
if (f == Algorithm::CN_PICO) {
return CpuThreads(count, 2);
}
# endif
# ifdef XMRIG_ALGO_CN_FEMTO
if (f == Algorithm::CN_FEMTO) {
return CpuThreads(count, 2);
}
# endif
# ifdef XMRIG_ALGO_CN_HEAVY
if (algorithm.family() == Algorithm::CN_HEAVY) {
if (f == Algorithm::CN_HEAVY) {
return CpuThreads(std::max<size_t>(count / 4, 1), 1);
}
# endif
# ifdef XMRIG_ALGO_RANDOMX
if (algorithm.family() == Algorithm::RANDOM_X) {
if (f == Algorithm::RANDOM_X) {
if (algorithm == Algorithm::RX_WOW) {
return count;
}
@@ -338,13 +346,13 @@ xmrig::CpuThreads xmrig::BasicCpuInfo::threads(const Algorithm &algorithm, uint3
# endif
# ifdef XMRIG_ALGO_ARGON2
if (algorithm.family() == Algorithm::ARGON2) {
if (f == Algorithm::ARGON2) {
return count;
}
# endif
# ifdef XMRIG_ALGO_ASTROBWT
if (algorithm.family() == Algorithm::ASTROBWT) {
if (f == Algorithm::ASTROBWT) {
CpuThreads threads;
for (size_t i = 0; i < count; ++i) {
threads.add(i, 0);

View File

@@ -28,7 +28,15 @@
#if __ARM_FEATURE_CRYPTO && !defined(__APPLE__)
# include <sys/auxv.h>
# include <asm/hwcap.h>
# ifndef __FreeBSD__
# include <asm/hwcap.h>
# else
# include <stdint.h>
# include <machine/armreg.h>
# ifndef ID_AA64ISAR0_AES_VAL
# define ID_AA64ISAR0_AES_VAL ID_AA64ISAR0_AES
# endif
# endif
#endif
@@ -62,10 +70,13 @@ xmrig::BasicCpuInfo::BasicCpuInfo() :
# endif
# if __ARM_FEATURE_CRYPTO
# if !defined(__APPLE__)
m_flags.set(FLAG_AES, getauxval(AT_HWCAP) & HWCAP_AES);
# else
# if defined(__APPLE__)
m_flags.set(FLAG_AES, true);
# elif defined(__FreeBSD__)
uint64_t isar0 = READ_SPECIALREG(id_aa64isar0_el1);
m_flags.set(FLAG_AES, ID_AA64ISAR0_AES_VAL(isar0) >= ID_AA64ISAR0_AES_BASE);
# else
m_flags.set(FLAG_AES, getauxval(AT_HWCAP) & HWCAP_AES);
# endif
# endif

View File

@@ -336,11 +336,10 @@ void xmrig::HwlocCpuInfo::processTopLevelCache(hwloc_obj_t cache, const Algorith
size_t cacheHashes = ((L3 + extra) + (scratchpad / 2)) / scratchpad;
# ifdef XMRIG_ALGO_CN_PICO
if (intensity && algorithm == Algorithm::CN_PICO_0 && (cacheHashes / PUs) >= 2) {
Algorithm::Family family = algorithm.family();
if (intensity && ((family == Algorithm::CN_PICO) || (family == Algorithm::CN_FEMTO)) && (cacheHashes / PUs) >= 2) {
intensity = 2;
}
# endif
# ifdef XMRIG_ALGO_RANDOMX
if (extra == 0 && algorithm.l2() > 0) {

View File

@@ -179,6 +179,7 @@ void xmrig::CudaConfig::generate()
count += xmrig::generate<Algorithm::CN_LITE>(m_threads, devices);
count += xmrig::generate<Algorithm::CN_HEAVY>(m_threads, devices);
count += xmrig::generate<Algorithm::CN_PICO>(m_threads, devices);
count += xmrig::generate<Algorithm::CN_FEMTO>(m_threads, devices);
count += xmrig::generate<Algorithm::RANDOM_X>(m_threads, devices);
count += xmrig::generate<Algorithm::ASTROBWT>(m_threads, devices);
count += xmrig::generate<Algorithm::KAWPOW>(m_threads, devices);

View File

@@ -102,6 +102,15 @@ size_t inline generate<Algorithm::CN_PICO>(Threads<CudaThreads> &threads, const
#endif
#ifdef XMRIG_ALGO_CN_FEMTO
template<>
size_t inline generate<Algorithm::CN_FEMTO>(Threads<CudaThreads>& threads, const std::vector<CudaDevice>& devices)
{
return generate("cn/upx2", threads, Algorithm::CN_UPX2, devices);
}
#endif
#ifdef XMRIG_ALGO_RANDOMX
template<>
size_t inline generate<Algorithm::RANDOM_X>(Threads<CudaThreads> &threads, const std::vector<CudaDevice> &devices)

View File

@@ -48,7 +48,7 @@ enum Version : uint32_t
static uv_lib_t cudaLib;
#if defined(__APPLE__)
static String defaultLoader = "/System/Library/Frameworks/OpenCL.framework/OpenCL";
static String defaultLoader = "libxmrig-cuda.dylib";
#elif defined(_WIN32)
static String defaultLoader = "xmrig-cuda.dll";
#else

View File

@@ -219,6 +219,7 @@ void xmrig::OclConfig::generate()
count += xmrig::generate<Algorithm::CN_LITE>(m_threads, devices);
count += xmrig::generate<Algorithm::CN_HEAVY>(m_threads, devices);
count += xmrig::generate<Algorithm::CN_PICO>(m_threads, devices);
count += xmrig::generate<Algorithm::CN_FEMTO>(m_threads, devices);
count += xmrig::generate<Algorithm::RANDOM_X>(m_threads, devices);
count += xmrig::generate<Algorithm::ASTROBWT>(m_threads, devices);
count += xmrig::generate<Algorithm::KAWPOW>(m_threads, devices);

View File

@@ -101,6 +101,15 @@ size_t inline generate<Algorithm::CN_PICO>(Threads<OclThreads> &threads, const s
#endif
#ifdef XMRIG_ALGO_CN_FEMTO
template<>
size_t inline generate<Algorithm::CN_FEMTO>(Threads<OclThreads>& threads, const std::vector<OclDevice>& devices)
{
return generate("cn/upx2", threads, Algorithm::CN_UPX2, devices);
}
#endif
#ifdef XMRIG_ALGO_RANDOMX
template<>
size_t inline generate<Algorithm::RANDOM_X>(Threads<OclThreads> &threads, const std::vector<OclDevice> &devices)

View File

@@ -17,16 +17,17 @@
#define ALGO_CN_PICO_0 16
#define ALGO_CN_PICO_TLO 17
#define ALGO_CN_CCX 18
#define ALGO_RX_0 19
#define ALGO_RX_WOW 20
#define ALGO_RX_ARQMA 21
#define ALGO_RX_SFX 22
#define ALGO_RX_KEVA 23
#define ALGO_AR2_CHUKWA 24
#define ALGO_AR2_CHUKWA_V2 25
#define ALGO_AR2_WRKZ 26
#define ALGO_ASTROBWT_DERO 27
#define ALGO_KAWPOW_RVN 28
#define ALGO_CN_UPX2 19
#define ALGO_RX_0 20
#define ALGO_RX_WOW 21
#define ALGO_RX_ARQMA 22
#define ALGO_RX_SFX 23
#define ALGO_RX_KEVA 24
#define ALGO_AR2_CHUKWA 25
#define ALGO_AR2_CHUKWA_V2 26
#define ALGO_AR2_WRKZ 27
#define ALGO_ASTROBWT_DERO 28
#define ALGO_KAWPOW_RVN 29
#define FAMILY_UNKNOWN 0
#define FAMILY_CN 1

View File

@@ -514,7 +514,7 @@ __kernel void cn1(__global ulong *input, __global uint4 *Scratchpad, __global ul
c = AES_Round(AES0, AES1, AES2, AES3, c, ((uint4 *)a)[0]);
{
# if (ALGO == ALGO_CN_RWZ)
# if ((ALGO == ALGO_CN_RWZ) || (ALGO == ALGO_CN_UPX2))
const ulong2 chunk1 = as_ulong2(SCRATCHPAD_CHUNK(3));
const ulong2 chunk2 = as_ulong2(SCRATCHPAD_CHUNK(2));
const ulong2 chunk3 = as_ulong2(SCRATCHPAD_CHUNK(1));
@@ -561,7 +561,7 @@ __kernel void cn1(__global ulong *input, __global uint4 *Scratchpad, __global ul
t ^= chunk2;
const ulong2 chunk3 = as_ulong2(SCRATCHPAD_CHUNK(3));
# if (ALGO == ALGO_CN_RWZ)
# if ((ALGO == ALGO_CN_RWZ) || (ALGO == ALGO_CN_UPX2))
SCRATCHPAD_CHUNK(1) = as_uint4(chunk1 + bx1);
SCRATCHPAD_CHUNK(2) = as_uint4(chunk3 + bx0);
SCRATCHPAD_CHUNK(3) = as_uint4(chunk2 + ((ulong2 *)a)[0]);

File diff suppressed because it is too large Load Diff

View File

@@ -29,7 +29,11 @@ typedef unsigned long uint64_t;
#endif
#ifndef PLATFORM
#ifdef cl_amd_media_ops
#define PLATFORM OPENCL_PLATFORM_AMD
#else
#define PLATFORM OPENCL_PLATFORM_UNKNOWN
#endif
#endif
#define HASHES_PER_GROUP (GROUP_SIZE / PROGPOW_LANES)

View File

@@ -2,7 +2,7 @@
namespace xmrig {
static const char kawpow_cl[5870] = {
static const char kawpow_cl[5948] = {
0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x63,0x6c,0x5f,0x63,0x6c,0x61,0x6e,0x67,0x5f,0x73,0x74,0x6f,0x72,0x61,0x67,0x65,0x5f,0x63,0x6c,0x61,0x73,0x73,0x5f,0x73,0x70,
0x65,0x63,0x69,0x66,0x69,0x65,0x72,0x73,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x20,0x45,0x58,0x54,0x45,0x4e,0x53,0x49,0x4f,
0x4e,0x20,0x63,0x6c,0x5f,0x63,0x6c,0x61,0x6e,0x67,0x5f,0x73,0x74,0x6f,0x72,0x61,0x67,0x65,0x5f,0x63,0x6c,0x61,0x73,0x73,0x5f,0x73,0x70,0x65,0x63,0x69,0x66,0x69,
@@ -25,168 +25,170 @@ static const char kawpow_cl[5870] = {
0x4e,0x43,0x4c,0x5f,0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x5f,0x41,0x4d,0x44,0x20,0x32,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x4f,0x50,0x45,0x4e,0x43,
0x4c,0x5f,0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x5f,0x43,0x4c,0x4f,0x56,0x45,0x52,0x20,0x33,0x0a,0x23,0x69,0x66,0x6e,0x64,0x65,0x66,0x20,0x4d,0x41,0x58,0x5f,
0x4f,0x55,0x54,0x50,0x55,0x54,0x53,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x4d,0x41,0x58,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x53,0x20,0x36,0x33,0x55,0x0a,
0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x23,0x69,0x66,0x6e,0x64,0x65,0x66,0x20,0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,
0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x5f,0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x5f,0x41,0x4d,0x44,0x0a,0x23,0x65,0x6e,
0x64,0x69,0x66,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x48,0x41,0x53,0x48,0x45,0x53,0x5f,0x50,0x45,0x52,0x5f,0x47,0x52,0x4f,0x55,0x50,0x20,0x28,0x47,0x52,
0x4f,0x55,0x50,0x5f,0x53,0x49,0x5a,0x45,0x20,0x2f,0x20,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x4c,0x41,0x4e,0x45,0x53,0x29,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,
0x65,0x20,0x46,0x4e,0x56,0x5f,0x50,0x52,0x49,0x4d,0x45,0x20,0x30,0x78,0x31,0x30,0x30,0x30,0x31,0x39,0x33,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x46,0x4e,
0x56,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x5f,0x42,0x41,0x53,0x49,0x53,0x20,0x30,0x78,0x38,0x31,0x31,0x63,0x39,0x64,0x63,0x35,0x0a,0x74,0x79,0x70,0x65,0x64,0x65,
0x66,0x20,0x73,0x74,0x72,0x75,0x63,0x74,0x20,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x20,0x28,0x28,0x61,0x6c,0x69,0x67,0x6e,0x65,0x64,
0x28,0x31,0x36,0x29,0x29,0x29,0x20,0x7b,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x5b,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x44,0x41,0x47,0x5f,0x4c,
0x4f,0x41,0x44,0x53,0x5d,0x3b,0x7d,0x20,0x64,0x61,0x67,0x5f,0x74,0x3b,0x0a,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,
0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6b,0x65,0x63,0x63,0x61,0x6b,0x66,0x5f,0x72,0x6e,0x64,0x63,0x5b,0x32,0x34,0x5d,0x3d,0x7b,0x30,0x78,0x30,0x30,0x30,
0x30,0x30,0x30,0x30,0x31,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x32,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x61,0x2c,0x30,0x78,0x38,0x30,
0x30,0x30,0x38,0x30,0x30,0x30,0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x62,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x2c,0x30,0x78,
0x38,0x30,0x30,0x30,0x38,0x30,0x38,0x31,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x39,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x61,0x2c,0x30,
0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x38,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x38,0x30,0x30,0x39,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x61,0x2c,
0x0a,0x30,0x78,0x38,0x30,0x30,0x30,0x38,0x30,0x38,0x62,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x62,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x38,0x30,0x38,
0x39,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x33,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x32,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,
0x38,0x30,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x61,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x61,0x2c,0x0a,0x30,0x78,0x38,0x30,0x30,0x30,
0x38,0x30,0x38,0x31,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x30,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x2c,0x30,0x78,0x38,0x30,0x30,
0x30,0x38,0x30,0x30,0x38,0x7d,0x3b,0x0a,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,
0x74,0x20,0x72,0x61,0x76,0x65,0x6e,0x63,0x6f,0x69,0x6e,0x5f,0x72,0x6e,0x64,0x63,0x5b,0x31,0x35,0x5d,0x3d,0x7b,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x37,
0x32,0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x34,0x31,0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x35,0x36,0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,
0x30,0x30,0x30,0x34,0x35,0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x34,0x45,0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x34,0x33,0x2c,0x0a,0x30,
0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x34,0x46,0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x34,0x39,0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x34,
0x45,0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x34,0x42,0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x34,0x31,0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,
0x30,0x30,0x30,0x35,0x37,0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x35,0x30,0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x34,0x46,0x2c,0x0a,0x30,
0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x35,0x37,0x2c,0x0a,0x7d,0x3b,0x0a,0x76,0x6f,0x69,0x64,0x20,0x6b,0x65,0x63,0x63,0x61,0x6b,0x5f,0x66,0x38,0x30,0x30,0x5f,0x72,
0x6f,0x75,0x6e,0x64,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x74,0x5b,0x32,0x35,0x5d,0x2c,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x72,
0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6b,0x65,0x63,0x63,0x61,0x6b,0x66,0x5f,0x72,0x6f,0x74,0x63,0x5b,
0x32,0x34,0x5d,0x3d,0x7b,0x0a,0x31,0x2c,0x33,0x2c,0x36,0x2c,0x31,0x30,0x2c,0x31,0x35,0x2c,0x32,0x31,0x2c,0x32,0x38,0x2c,0x33,0x36,0x2c,0x34,0x35,0x2c,0x35,0x35,
0x2c,0x32,0x2c,0x31,0x34,0x2c,0x32,0x37,0x2c,0x34,0x31,0x2c,0x35,0x36,0x2c,0x38,0x2c,0x32,0x35,0x2c,0x34,0x33,0x2c,0x36,0x32,0x2c,0x31,0x38,0x2c,0x33,0x39,0x2c,
0x36,0x31,0x2c,0x32,0x30,0x2c,0x34,0x34,0x7d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6b,0x65,0x63,0x63,0x61,0x6b,
0x66,0x5f,0x70,0x69,0x6c,0x6e,0x5b,0x32,0x34,0x5d,0x3d,0x7b,0x0a,0x31,0x30,0x2c,0x37,0x2c,0x31,0x31,0x2c,0x31,0x37,0x2c,0x31,0x38,0x2c,0x33,0x2c,0x35,0x2c,0x31,
0x36,0x2c,0x38,0x2c,0x32,0x31,0x2c,0x32,0x34,0x2c,0x34,0x2c,0x31,0x35,0x2c,0x32,0x33,0x2c,0x31,0x39,0x2c,0x31,0x33,0x2c,0x31,0x32,0x2c,0x32,0x2c,0x32,0x30,0x2c,
0x31,0x34,0x2c,0x32,0x32,0x2c,0x39,0x2c,0x36,0x2c,0x31,0x7d,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x74,0x2c,0x62,0x63,0x5b,0x35,0x5d,0x3b,0x0a,
0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x35,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x62,0x63,0x5b,0x69,0x5d,0x3d,0x73,0x74,
0x5b,0x69,0x5d,0x5e,0x73,0x74,0x5b,0x69,0x2b,0x35,0x5d,0x5e,0x73,0x74,0x5b,0x69,0x2b,0x31,0x30,0x5d,0x5e,0x73,0x74,0x5b,0x69,0x2b,0x31,0x35,0x5d,0x5e,0x73,0x74,
0x5b,0x69,0x2b,0x32,0x30,0x5d,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x35,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,
0x7b,0x0a,0x74,0x3d,0x62,0x63,0x5b,0x28,0x69,0x2b,0x34,0x29,0x20,0x25,0x20,0x35,0x5d,0x5e,0x52,0x4f,0x54,0x4c,0x33,0x32,0x28,0x62,0x63,0x5b,0x28,0x69,0x2b,0x31,
0x29,0x20,0x25,0x20,0x35,0x5d,0x2c,0x31,0x75,0x29,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x3d,0x30,0x3b,0x20,0x6a,
0x3c,0x32,0x35,0x3b,0x20,0x6a,0x2b,0x3d,0x35,0x29,0x0a,0x73,0x74,0x5b,0x6a,0x2b,0x69,0x5d,0x20,0x5e,0x3d,0x20,0x74,0x3b,0x0a,0x7d,0x0a,0x74,0x3d,0x73,0x74,0x5b,
0x31,0x5d,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x32,0x34,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x7b,0x0a,0x75,
0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x3d,0x6b,0x65,0x63,0x63,0x61,0x6b,0x66,0x5f,0x70,0x69,0x6c,0x6e,0x5b,0x69,0x5d,0x3b,0x0a,0x62,0x63,0x5b,0x30,0x5d,
0x3d,0x73,0x74,0x5b,0x6a,0x5d,0x3b,0x0a,0x73,0x74,0x5b,0x6a,0x5d,0x3d,0x52,0x4f,0x54,0x4c,0x33,0x32,0x28,0x74,0x2c,0x6b,0x65,0x63,0x63,0x61,0x6b,0x66,0x5f,0x72,
0x6f,0x74,0x63,0x5b,0x69,0x5d,0x29,0x3b,0x0a,0x74,0x3d,0x62,0x63,0x5b,0x30,0x5d,0x3b,0x0a,0x7d,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,
0x74,0x20,0x6a,0x3d,0x30,0x3b,0x20,0x6a,0x3c,0x32,0x35,0x3b,0x20,0x6a,0x2b,0x3d,0x35,0x29,0x0a,0x7b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,
0x30,0x3b,0x20,0x69,0x3c,0x35,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x62,0x63,0x5b,0x69,0x5d,0x3d,0x73,0x74,0x5b,0x6a,0x2b,0x69,0x5d,0x3b,0x0a,0x66,0x6f,0x72,0x20,
0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x35,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x73,0x74,0x5b,0x6a,0x2b,0x69,0x5d,0x20,0x5e,0x3d,0x20,0x28,
0x7e,0x62,0x63,0x5b,0x28,0x69,0x2b,0x31,0x29,0x20,0x25,0x20,0x35,0x5d,0x29,0x26,0x62,0x63,0x5b,0x28,0x69,0x2b,0x32,0x29,0x20,0x25,0x20,0x35,0x5d,0x3b,0x0a,0x7d,
0x0a,0x73,0x74,0x5b,0x30,0x5d,0x20,0x5e,0x3d,0x20,0x6b,0x65,0x63,0x63,0x61,0x6b,0x66,0x5f,0x72,0x6e,0x64,0x63,0x5b,0x72,0x5d,0x3b,0x0a,0x7d,0x0a,0x75,0x69,0x6e,
0x74,0x36,0x34,0x5f,0x74,0x20,0x6b,0x65,0x63,0x63,0x61,0x6b,0x5f,0x66,0x38,0x30,0x30,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x73,0x74,0x29,0x0a,
0x7b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x72,0x3d,0x30,0x3b,0x20,0x72,0x3c,0x32,0x32,0x3b,0x20,0x72,0x2b,0x2b,0x29,0x20,0x7b,0x0a,0x6b,0x65,0x63,
0x63,0x61,0x6b,0x5f,0x66,0x38,0x30,0x30,0x5f,0x72,0x6f,0x75,0x6e,0x64,0x28,0x73,0x74,0x2c,0x72,0x29,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,
0x65,0x20,0x66,0x6e,0x76,0x31,0x61,0x28,0x68,0x2c,0x20,0x64,0x29,0x20,0x28,0x68,0x20,0x3d,0x20,0x28,0x68,0x20,0x5e,0x20,0x64,0x29,0x20,0x2a,0x20,0x46,0x4e,0x56,
0x5f,0x50,0x52,0x49,0x4d,0x45,0x29,0x0a,0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x73,0x74,0x72,0x75,0x63,0x74,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,
0x74,0x20,0x7a,0x2c,0x77,0x2c,0x6a,0x73,0x72,0x2c,0x6a,0x63,0x6f,0x6e,0x67,0x3b,0x0a,0x7d,0x20,0x6b,0x69,0x73,0x73,0x39,0x39,0x5f,0x74,0x3b,0x0a,0x75,0x69,0x6e,
0x74,0x33,0x32,0x5f,0x74,0x20,0x6b,0x69,0x73,0x73,0x39,0x39,0x28,0x6b,0x69,0x73,0x73,0x39,0x39,0x5f,0x74,0x2a,0x20,0x73,0x74,0x29,0x0a,0x7b,0x0a,0x73,0x74,0x2d,
0x3e,0x7a,0x3d,0x33,0x36,0x39,0x36,0x39,0x2a,0x28,0x73,0x74,0x2d,0x3e,0x7a,0x26,0x36,0x35,0x35,0x33,0x35,0x29,0x2b,0x28,0x73,0x74,0x2d,0x3e,0x7a,0x3e,0x3e,0x31,
0x36,0x29,0x3b,0x0a,0x73,0x74,0x2d,0x3e,0x77,0x3d,0x31,0x38,0x30,0x30,0x30,0x2a,0x28,0x73,0x74,0x2d,0x3e,0x77,0x26,0x36,0x35,0x35,0x33,0x35,0x29,0x2b,0x28,0x73,
0x74,0x2d,0x3e,0x77,0x3e,0x3e,0x31,0x36,0x29,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x4d,0x57,0x43,0x3d,0x28,0x28,0x73,0x74,0x2d,0x3e,0x7a,0x3c,
0x3c,0x31,0x36,0x29,0x2b,0x73,0x74,0x2d,0x3e,0x77,0x29,0x3b,0x0a,0x73,0x74,0x2d,0x3e,0x6a,0x73,0x72,0x20,0x5e,0x3d,0x20,0x28,0x73,0x74,0x2d,0x3e,0x6a,0x73,0x72,
0x3c,0x3c,0x31,0x37,0x29,0x3b,0x0a,0x73,0x74,0x2d,0x3e,0x6a,0x73,0x72,0x20,0x5e,0x3d,0x20,0x28,0x73,0x74,0x2d,0x3e,0x6a,0x73,0x72,0x3e,0x3e,0x31,0x33,0x29,0x3b,
0x0a,0x73,0x74,0x2d,0x3e,0x6a,0x73,0x72,0x20,0x5e,0x3d,0x20,0x28,0x73,0x74,0x2d,0x3e,0x6a,0x73,0x72,0x3c,0x3c,0x35,0x29,0x3b,0x0a,0x73,0x74,0x2d,0x3e,0x6a,0x63,
0x6f,0x6e,0x67,0x3d,0x36,0x39,0x30,0x36,0x39,0x2a,0x73,0x74,0x2d,0x3e,0x6a,0x63,0x6f,0x6e,0x67,0x2b,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x3b,0x0a,0x72,0x65,0x74,
0x75,0x72,0x6e,0x20,0x28,0x28,0x4d,0x57,0x43,0x5e,0x73,0x74,0x2d,0x3e,0x6a,0x63,0x6f,0x6e,0x67,0x29,0x2b,0x73,0x74,0x2d,0x3e,0x6a,0x73,0x72,0x29,0x3b,0x0a,0x7d,
0x0a,0x76,0x6f,0x69,0x64,0x20,0x66,0x69,0x6c,0x6c,0x5f,0x6d,0x69,0x78,0x28,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x73,
0x65,0x65,0x64,0x2c,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6c,0x61,0x6e,0x65,0x5f,0x69,0x64,0x2c,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x6d,
0x69,0x78,0x29,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x66,0x6e,0x76,0x5f,0x68,0x61,0x73,0x68,0x3d,0x46,0x4e,0x56,0x5f,0x4f,0x46,0x46,0x53,
0x45,0x54,0x5f,0x42,0x41,0x53,0x49,0x53,0x3b,0x0a,0x6b,0x69,0x73,0x73,0x39,0x39,0x5f,0x74,0x20,0x73,0x74,0x3b,0x0a,0x73,0x74,0x2e,0x7a,0x3d,0x66,0x6e,0x76,0x31,
0x61,0x28,0x66,0x6e,0x76,0x5f,0x68,0x61,0x73,0x68,0x2c,0x73,0x65,0x65,0x64,0x5b,0x30,0x5d,0x29,0x3b,0x0a,0x73,0x74,0x2e,0x77,0x3d,0x66,0x6e,0x76,0x31,0x61,0x28,
0x66,0x6e,0x76,0x5f,0x68,0x61,0x73,0x68,0x2c,0x73,0x65,0x65,0x64,0x5b,0x31,0x5d,0x29,0x3b,0x0a,0x73,0x74,0x2e,0x6a,0x73,0x72,0x3d,0x66,0x6e,0x76,0x31,0x61,0x28,
0x66,0x6e,0x76,0x5f,0x68,0x61,0x73,0x68,0x2c,0x6c,0x61,0x6e,0x65,0x5f,0x69,0x64,0x29,0x3b,0x0a,0x73,0x74,0x2e,0x6a,0x63,0x6f,0x6e,0x67,0x3d,0x66,0x6e,0x76,0x31,
0x61,0x28,0x66,0x6e,0x76,0x5f,0x68,0x61,0x73,0x68,0x2c,0x6c,0x61,0x6e,0x65,0x5f,0x69,0x64,0x29,0x3b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,
0x6f,0x6c,0x6c,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x52,0x45,0x47,0x53,
0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x6d,0x69,0x78,0x5b,0x69,0x5d,0x3d,0x6b,0x69,0x73,0x73,0x39,0x39,0x28,0x26,0x73,0x74,0x29,0x3b,0x0a,0x7d,0x0a,0x74,0x79,0x70,
0x65,0x64,0x65,0x66,0x20,0x73,0x74,0x72,0x75,0x63,0x74,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x50,
0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x4c,0x41,0x4e,0x45,0x53,0x5d,0x3b,0x0a,0x7d,0x20,0x73,0x68,0x75,0x66,0x66,0x6c,0x65,0x5f,0x74,0x3b,0x0a,0x74,0x79,0x70,0x65,
0x64,0x65,0x66,0x20,0x73,0x74,0x72,0x75,0x63,0x74,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x33,0x32,
0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x5d,0x3b,0x0a,0x7d,0x20,0x68,0x61,0x73,0x68,0x33,0x32,0x5f,0x74,0x3b,0x0a,
0x23,0x69,0x66,0x20,0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x20,0x21,0x3d,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x5f,0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x5f,
0x4e,0x56,0x49,0x44,0x49,0x41,0x20,0x0a,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x72,0x65,0x71,0x64,0x5f,0x77,0x6f,0x72,0x6b,
0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x69,0x7a,0x65,0x28,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x49,0x5a,0x45,0x2c,0x31,0x2c,0x31,0x29,0x29,0x29,0x0a,0x23,0x65,
0x6e,0x64,0x69,0x66,0x0a,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x70,0x72,0x6f,0x67,0x70,0x6f,0x77,0x5f,0x73,0x65,0x61,0x72,0x63,
0x68,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x64,0x61,0x67,0x5f,0x74,0x20,0x63,0x6f,0x6e,0x73,0x74,0x2a,0x20,0x67,0x5f,0x64,0x61,0x67,0x2c,0x5f,0x5f,
0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x20,0x6a,0x6f,0x62,0x5f,0x62,0x6c,0x6f,0x62,0x2c,0x75,0x6c,0x6f,0x6e,0x67,0x20,0x74,0x61,0x72,0x67,
0x65,0x74,0x2c,0x75,0x69,0x6e,0x74,0x20,0x68,0x61,0x63,0x6b,0x5f,0x66,0x61,0x6c,0x73,0x65,0x2c,0x76,0x6f,0x6c,0x61,0x74,0x69,0x6c,0x65,0x20,0x5f,0x5f,0x67,0x6c,
0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x73,0x2c,0x76,0x6f,0x6c,0x61,0x74,0x69,0x6c,0x65,0x20,0x5f,0x5f,0x67,0x6c,
0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x20,0x73,0x74,0x6f,0x70,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,
0x74,0x20,0x6c,0x69,0x64,0x3d,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,
0x74,0x33,0x32,0x5f,0x74,0x20,0x67,0x69,0x64,0x3d,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x69,0x66,0x28,0x73,
0x74,0x6f,0x70,0x5b,0x30,0x5d,0x29,0x20,0x7b,0x0a,0x69,0x66,0x28,0x6c,0x69,0x64,0x3d,0x3d,0x30,0x29,0x20,0x7b,0x0a,0x61,0x74,0x6f,0x6d,0x69,0x63,0x5f,0x69,0x6e,
0x63,0x28,0x73,0x74,0x6f,0x70,0x2b,0x31,0x29,0x3b,0x0a,0x7d,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0x0a,0x7d,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x73,
0x68,0x75,0x66,0x66,0x6c,0x65,0x5f,0x74,0x20,0x73,0x68,0x61,0x72,0x65,0x5b,0x48,0x41,0x53,0x48,0x45,0x53,0x5f,0x50,0x45,0x52,0x5f,0x47,0x52,0x4f,0x55,0x50,0x5d,
0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x63,0x5f,0x64,0x61,0x67,0x5b,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,
0x5f,0x43,0x41,0x43,0x48,0x45,0x5f,0x57,0x4f,0x52,0x44,0x53,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6c,0x61,
0x6e,0x65,0x5f,0x69,0x64,0x3d,0x6c,0x69,0x64,0x26,0x28,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x4c,0x41,0x4e,0x45,0x53,0x2d,0x31,0x29,0x3b,0x0a,0x63,0x6f,0x6e,
0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x3d,0x6c,0x69,0x64,0x2f,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,
0x5f,0x4c,0x41,0x4e,0x45,0x53,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x77,0x6f,0x72,0x64,0x3d,0x6c,0x69,0x64,0x2a,0x50,
0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x44,0x41,0x47,0x5f,0x4c,0x4f,0x41,0x44,0x53,0x3b,0x20,0x77,0x6f,0x72,0x64,0x3c,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x43,
0x41,0x43,0x48,0x45,0x5f,0x57,0x4f,0x52,0x44,0x53,0x3b,0x20,0x77,0x6f,0x72,0x64,0x2b,0x3d,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x49,0x5a,0x45,0x2a,0x50,0x52,0x4f,
0x47,0x50,0x4f,0x57,0x5f,0x44,0x41,0x47,0x5f,0x4c,0x4f,0x41,0x44,0x53,0x29,0x0a,0x7b,0x0a,0x64,0x61,0x67,0x5f,0x74,0x20,0x6c,0x6f,0x61,0x64,0x3d,0x67,0x5f,0x64,
0x61,0x67,0x5b,0x77,0x6f,0x72,0x64,0x2f,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x44,0x41,0x47,0x5f,0x4c,0x4f,0x41,0x44,0x53,0x5d,0x3b,0x0a,0x66,0x6f,0x72,0x20,
0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x44,0x41,0x47,0x5f,0x4c,0x4f,0x41,0x44,0x53,0x3b,0x20,0x69,
0x2b,0x2b,0x29,0x0a,0x63,0x5f,0x64,0x61,0x67,0x5b,0x77,0x6f,0x72,0x64,0x2b,0x69,0x5d,0x3d,0x6c,0x6f,0x61,0x64,0x2e,0x73,0x5b,0x69,0x5d,0x3b,0x0a,0x7d,0x0a,0x75,
0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x68,0x61,0x73,0x68,0x5f,0x73,0x65,0x65,0x64,0x5b,0x32,0x5d,0x3b,0x20,0x0a,0x68,0x61,0x73,0x68,0x33,0x32,0x5f,0x74,0x20,
0x64,0x69,0x67,0x65,0x73,0x74,0x3b,0x20,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x74,0x61,0x74,0x65,0x32,0x5b,0x38,0x5d,0x3b,0x0a,0x7b,0x0a,0x75,
0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x74,0x61,0x74,0x65,0x5b,0x32,0x35,0x5d,0x3b,0x20,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,
0x3b,0x20,0x69,0x3c,0x31,0x30,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x73,0x74,0x61,0x74,0x65,0x5b,0x69,0x5d,0x3d,0x6a,0x6f,0x62,0x5f,0x62,0x6c,0x6f,0x62,0x5b,0x69,
0x5d,0x3b,0x0a,0x73,0x74,0x61,0x74,0x65,0x5b,0x38,0x5d,0x3d,0x67,0x69,0x64,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x31,0x30,0x3b,0x20,
0x69,0x3c,0x32,0x35,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x73,0x74,0x61,0x74,0x65,0x5b,0x69,0x5d,0x3d,0x72,0x61,0x76,0x65,0x6e,0x63,0x6f,0x69,0x6e,0x5f,0x72,0x6e,
0x64,0x63,0x5b,0x69,0x2d,0x31,0x30,0x5d,0x3b,0x0a,0x6b,0x65,0x63,0x63,0x61,0x6b,0x5f,0x66,0x38,0x30,0x30,0x28,0x73,0x74,0x61,0x74,0x65,0x29,0x3b,0x0a,0x66,0x6f,
0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x38,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x73,0x74,0x61,0x74,0x65,0x32,0x5b,0x69,0x5d,0x3d,
0x73,0x74,0x61,0x74,0x65,0x5b,0x69,0x5d,0x3b,0x0a,0x7d,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x31,0x0a,0x66,0x6f,0x72,
0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x68,0x3d,0x30,0x3b,0x20,0x68,0x3c,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x4c,0x41,0x4e,0x45,0x53,0x3b,
0x20,0x68,0x2b,0x2b,0x29,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6d,0x69,0x78,0x5b,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x52,0x45,0x47,
0x53,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6c,0x61,0x6e,0x65,0x5f,0x69,0x64,0x3d,0x3d,0x68,0x29,0x20,0x7b,0x0a,0x73,0x68,0x61,0x72,0x65,0x5b,0x67,0x72,0x6f,0x75,0x70,
0x5f,0x69,0x64,0x5d,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x30,0x5d,0x3d,0x73,0x74,0x61,0x74,0x65,0x32,0x5b,0x30,0x5d,0x3b,0x0a,0x73,0x68,0x61,0x72,0x65,
0x5b,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x5d,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x31,0x5d,0x3d,0x73,0x74,0x61,0x74,0x65,0x32,0x5b,0x31,0x5d,0x3b,
0x0a,0x7d,0x0a,0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,
0x0a,0x66,0x69,0x6c,0x6c,0x5f,0x6d,0x69,0x78,0x28,0x73,0x68,0x61,0x72,0x65,0x5b,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x5d,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,
0x73,0x2c,0x6c,0x61,0x6e,0x65,0x5f,0x69,0x64,0x2c,0x6d,0x69,0x78,0x29,0x3b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x32,
0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6c,0x6f,0x6f,0x70,0x3d,0x30,0x3b,0x20,0x6c,0x6f,0x6f,0x70,0x3c,0x50,0x52,0x4f,0x47,
0x50,0x4f,0x57,0x5f,0x43,0x4e,0x54,0x5f,0x44,0x41,0x47,0x3b,0x20,0x2b,0x2b,0x6c,0x6f,0x6f,0x70,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x6c,0x61,0x6e,0x65,0x5f,0x69,
0x64,0x3d,0x3d,0x28,0x6c,0x6f,0x6f,0x70,0x20,0x25,0x20,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x4c,0x41,0x4e,0x45,0x53,0x29,0x29,0x0a,0x73,0x68,0x61,0x72,0x65,
0x5b,0x30,0x5d,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x5d,0x3d,0x6d,0x69,0x78,0x5b,0x30,0x5d,0x3b,0x0a,0x62,0x61,
0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0x0a,0x75,0x69,0x6e,0x74,
0x33,0x32,0x5f,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x73,0x68,0x61,0x72,0x65,0x5b,0x30,0x5d,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x67,0x72,0x6f,
0x75,0x70,0x5f,0x69,0x64,0x5d,0x3b,0x0a,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x25,0x3d,0x20,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x44,0x41,0x47,0x5f,0x45,0x4c,
0x45,0x4d,0x45,0x4e,0x54,0x53,0x3b,0x0a,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x4c,0x41,
0x4e,0x45,0x53,0x2b,0x28,0x6c,0x61,0x6e,0x65,0x5f,0x69,0x64,0x5e,0x6c,0x6f,0x6f,0x70,0x29,0x20,0x25,0x20,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x4c,0x41,0x4e,
0x45,0x53,0x3b,0x0a,0x64,0x61,0x67,0x5f,0x74,0x20,0x64,0x61,0x74,0x61,0x5f,0x64,0x61,0x67,0x3d,0x67,0x5f,0x64,0x61,0x67,0x5b,0x6f,0x66,0x66,0x73,0x65,0x74,0x5d,
0x3b,0x0a,0x69,0x66,0x28,0x68,0x61,0x63,0x6b,0x5f,0x66,0x61,0x6c,0x73,0x65,0x29,0x20,0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,
0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x64,0x61,0x74,0x61,0x3b,0x0a,0x58,0x4d,
0x52,0x49,0x47,0x5f,0x49,0x4e,0x43,0x4c,0x55,0x44,0x45,0x5f,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x5f,0x4d,0x41,0x54,0x48,0x0a,
0x69,0x66,0x28,0x68,0x61,0x63,0x6b,0x5f,0x66,0x61,0x6c,0x73,0x65,0x29,0x20,0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,0x41,0x4c,
0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0x0a,0x58,0x4d,0x52,0x49,0x47,0x5f,0x49,0x4e,0x43,0x4c,0x55,0x44,0x45,0x5f,0x50,0x52,0x4f,0x47,0x50,
0x4f,0x57,0x5f,0x44,0x41,0x54,0x41,0x5f,0x4c,0x4f,0x41,0x44,0x53,0x0a,0x7d,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6d,0x69,0x78,0x5f,0x68,0x61,0x73,
0x68,0x3d,0x46,0x4e,0x56,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x5f,0x42,0x41,0x53,0x49,0x53,0x3b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,
0x6c,0x6c,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x52,0x45,0x47,0x53,0x3b,
0x20,0x69,0x2b,0x2b,0x29,0x0a,0x66,0x6e,0x76,0x31,0x61,0x28,0x6d,0x69,0x78,0x5f,0x68,0x61,0x73,0x68,0x2c,0x6d,0x69,0x78,0x5b,0x69,0x5d,0x29,0x3b,0x0a,0x68,0x61,
0x73,0x68,0x33,0x32,0x5f,0x74,0x20,0x64,0x69,0x67,0x65,0x73,0x74,0x5f,0x74,0x65,0x6d,0x70,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,
0x3b,0x20,0x69,0x3c,0x38,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x64,0x69,0x67,0x65,0x73,0x74,0x5f,0x74,0x65,0x6d,0x70,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,
0x69,0x5d,0x3d,0x46,0x4e,0x56,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x5f,0x42,0x41,0x53,0x49,0x53,0x3b,0x0a,0x73,0x68,0x61,0x72,0x65,0x5b,0x67,0x72,0x6f,0x75,0x70,
0x5f,0x69,0x64,0x5d,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x6c,0x61,0x6e,0x65,0x5f,0x69,0x64,0x5d,0x3d,0x6d,0x69,0x78,0x5f,0x68,0x61,0x73,0x68,0x3b,0x0a,
0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0x0a,0x23,0x70,
0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x50,0x52,0x4f,
0x47,0x50,0x4f,0x57,0x5f,0x4c,0x41,0x4e,0x45,0x53,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x66,0x6e,0x76,0x31,0x61,0x28,0x64,0x69,0x67,0x65,0x73,0x74,0x5f,0x74,0x65,
0x6d,0x70,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x69,0x20,0x25,0x20,0x38,0x5d,0x2c,0x73,0x68,0x61,0x72,0x65,0x5b,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,
0x5d,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x69,0x5d,0x29,0x3b,0x0a,0x69,0x66,0x28,0x68,0x3d,0x3d,0x6c,0x61,0x6e,0x65,0x5f,0x69,0x64,0x29,0x0a,0x64,0x69,
0x67,0x65,0x73,0x74,0x3d,0x64,0x69,0x67,0x65,0x73,0x74,0x5f,0x74,0x65,0x6d,0x70,0x3b,0x0a,0x7d,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x72,0x65,0x73,
0x75,0x6c,0x74,0x3b,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x74,0x61,0x74,0x65,0x5b,0x32,0x35,0x5d,0x3d,0x7b,0x30,0x78,0x30,0x7d,0x3b,
0x20,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x38,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x73,0x74,0x61,0x74,0x65,0x5b,
0x69,0x5d,0x3d,0x73,0x74,0x61,0x74,0x65,0x32,0x5b,0x69,0x5d,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x38,0x3b,0x20,0x69,0x3c,0x31,0x36,
0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x73,0x74,0x61,0x74,0x65,0x5b,0x69,0x5d,0x3d,0x64,0x69,0x67,0x65,0x73,0x74,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x69,
0x2d,0x38,0x5d,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x31,0x36,0x3b,0x20,0x69,0x3c,0x32,0x35,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x73,
0x74,0x61,0x74,0x65,0x5b,0x69,0x5d,0x3d,0x72,0x61,0x76,0x65,0x6e,0x63,0x6f,0x69,0x6e,0x5f,0x72,0x6e,0x64,0x63,0x5b,0x69,0x2d,0x31,0x36,0x5d,0x3b,0x0a,0x6b,0x65,
0x63,0x63,0x61,0x6b,0x5f,0x66,0x38,0x30,0x30,0x28,0x73,0x74,0x61,0x74,0x65,0x29,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x72,0x65,0x73,0x3d,0x28,
0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x73,0x74,0x61,0x74,0x65,0x5b,0x31,0x5d,0x3c,0x3c,0x33,0x32,0x7c,0x73,0x74,0x61,0x74,0x65,0x5b,0x30,0x5d,0x3b,0x0a,
0x72,0x65,0x73,0x75,0x6c,0x74,0x3d,0x61,0x73,0x5f,0x75,0x6c,0x6f,0x6e,0x67,0x28,0x61,0x73,0x5f,0x75,0x63,0x68,0x61,0x72,0x38,0x28,0x72,0x65,0x73,0x29,0x2e,0x73,
0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x30,0x29,0x3b,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x72,0x65,0x73,0x75,0x6c,0x74,0x3c,0x3d,0x74,0x61,0x72,0x67,0x65,0x74,0x29,0x0a,
0x7b,0x0a,0x2a,0x73,0x74,0x6f,0x70,0x3d,0x31,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6b,0x3d,0x61,0x74,0x6f,0x6d,0x69,0x63,0x5f,0x69,
0x6e,0x63,0x28,0x72,0x65,0x73,0x75,0x6c,0x74,0x73,0x29,0x2b,0x31,0x3b,0x0a,0x69,0x66,0x28,0x6b,0x3c,0x3d,0x31,0x35,0x29,0x0a,0x72,0x65,0x73,0x75,0x6c,0x74,0x73,
0x5b,0x6b,0x5d,0x3d,0x67,0x69,0x64,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x00
0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x23,0x69,0x66,0x6e,0x64,0x65,0x66,0x20,0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x0a,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x63,
0x6c,0x5f,0x61,0x6d,0x64,0x5f,0x6d,0x65,0x64,0x69,0x61,0x5f,0x6f,0x70,0x73,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,
0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x5f,0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x5f,0x41,0x4d,0x44,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x23,0x64,0x65,0x66,0x69,
0x6e,0x65,0x20,0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x5f,0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x5f,0x55,0x4e,0x4b,0x4e,
0x4f,0x57,0x4e,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x48,0x41,0x53,0x48,0x45,0x53,
0x5f,0x50,0x45,0x52,0x5f,0x47,0x52,0x4f,0x55,0x50,0x20,0x28,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x49,0x5a,0x45,0x20,0x2f,0x20,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,
0x5f,0x4c,0x41,0x4e,0x45,0x53,0x29,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x46,0x4e,0x56,0x5f,0x50,0x52,0x49,0x4d,0x45,0x20,0x30,0x78,0x31,0x30,0x30,0x30,
0x31,0x39,0x33,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x46,0x4e,0x56,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x5f,0x42,0x41,0x53,0x49,0x53,0x20,0x30,0x78,0x38,
0x31,0x31,0x63,0x39,0x64,0x63,0x35,0x0a,0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x73,0x74,0x72,0x75,0x63,0x74,0x20,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,
0x74,0x65,0x5f,0x5f,0x20,0x28,0x28,0x61,0x6c,0x69,0x67,0x6e,0x65,0x64,0x28,0x31,0x36,0x29,0x29,0x29,0x20,0x7b,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,
0x5b,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x44,0x41,0x47,0x5f,0x4c,0x4f,0x41,0x44,0x53,0x5d,0x3b,0x7d,0x20,0x64,0x61,0x67,0x5f,0x74,0x3b,0x0a,0x5f,0x5f,0x63,
0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6b,0x65,0x63,0x63,0x61,0x6b,0x66,0x5f,0x72,
0x6e,0x64,0x63,0x5b,0x32,0x34,0x5d,0x3d,0x7b,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x32,0x2c,0x30,
0x78,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x61,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x62,
0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x38,0x30,0x38,0x31,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x38,0x30,0x30,
0x39,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x61,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x38,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x38,0x30,
0x30,0x39,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x61,0x2c,0x0a,0x30,0x78,0x38,0x30,0x30,0x30,0x38,0x30,0x38,0x62,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,
0x30,0x30,0x38,0x62,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x39,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x33,0x2c,0x30,0x78,0x30,0x30,0x30,
0x30,0x38,0x30,0x30,0x32,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x61,0x2c,0x30,0x78,0x38,0x30,
0x30,0x30,0x30,0x30,0x30,0x61,0x2c,0x0a,0x30,0x78,0x38,0x30,0x30,0x30,0x38,0x30,0x38,0x31,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x30,0x2c,0x30,0x78,
0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x38,0x30,0x30,0x38,0x7d,0x3b,0x0a,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,
0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x72,0x61,0x76,0x65,0x6e,0x63,0x6f,0x69,0x6e,0x5f,0x72,0x6e,0x64,0x63,0x5b,0x31,
0x35,0x5d,0x3d,0x7b,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x37,0x32,0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x34,0x31,0x2c,0x0a,0x30,0x78,0x30,
0x30,0x30,0x30,0x30,0x30,0x35,0x36,0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x34,0x35,0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x34,0x45,0x2c,
0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x34,0x33,0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x34,0x46,0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,
0x30,0x34,0x39,0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x34,0x45,0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x34,0x42,0x2c,0x0a,0x30,0x78,0x30,
0x30,0x30,0x30,0x30,0x30,0x34,0x31,0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x35,0x37,0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x35,0x30,0x2c,
0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x34,0x46,0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x35,0x37,0x2c,0x0a,0x7d,0x3b,0x0a,0x76,0x6f,0x69,0x64,
0x20,0x6b,0x65,0x63,0x63,0x61,0x6b,0x5f,0x66,0x38,0x30,0x30,0x5f,0x72,0x6f,0x75,0x6e,0x64,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x74,0x5b,0x32,
0x35,0x5d,0x2c,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x72,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,
0x20,0x6b,0x65,0x63,0x63,0x61,0x6b,0x66,0x5f,0x72,0x6f,0x74,0x63,0x5b,0x32,0x34,0x5d,0x3d,0x7b,0x0a,0x31,0x2c,0x33,0x2c,0x36,0x2c,0x31,0x30,0x2c,0x31,0x35,0x2c,
0x32,0x31,0x2c,0x32,0x38,0x2c,0x33,0x36,0x2c,0x34,0x35,0x2c,0x35,0x35,0x2c,0x32,0x2c,0x31,0x34,0x2c,0x32,0x37,0x2c,0x34,0x31,0x2c,0x35,0x36,0x2c,0x38,0x2c,0x32,
0x35,0x2c,0x34,0x33,0x2c,0x36,0x32,0x2c,0x31,0x38,0x2c,0x33,0x39,0x2c,0x36,0x31,0x2c,0x32,0x30,0x2c,0x34,0x34,0x7d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,
0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6b,0x65,0x63,0x63,0x61,0x6b,0x66,0x5f,0x70,0x69,0x6c,0x6e,0x5b,0x32,0x34,0x5d,0x3d,0x7b,0x0a,0x31,0x30,0x2c,0x37,0x2c,
0x31,0x31,0x2c,0x31,0x37,0x2c,0x31,0x38,0x2c,0x33,0x2c,0x35,0x2c,0x31,0x36,0x2c,0x38,0x2c,0x32,0x31,0x2c,0x32,0x34,0x2c,0x34,0x2c,0x31,0x35,0x2c,0x32,0x33,0x2c,
0x31,0x39,0x2c,0x31,0x33,0x2c,0x31,0x32,0x2c,0x32,0x2c,0x32,0x30,0x2c,0x31,0x34,0x2c,0x32,0x32,0x2c,0x39,0x2c,0x36,0x2c,0x31,0x7d,0x3b,0x0a,0x75,0x69,0x6e,0x74,
0x33,0x32,0x5f,0x74,0x20,0x74,0x2c,0x62,0x63,0x5b,0x35,0x5d,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x35,0x3b,
0x20,0x69,0x2b,0x2b,0x29,0x0a,0x62,0x63,0x5b,0x69,0x5d,0x3d,0x73,0x74,0x5b,0x69,0x5d,0x5e,0x73,0x74,0x5b,0x69,0x2b,0x35,0x5d,0x5e,0x73,0x74,0x5b,0x69,0x2b,0x31,
0x30,0x5d,0x5e,0x73,0x74,0x5b,0x69,0x2b,0x31,0x35,0x5d,0x5e,0x73,0x74,0x5b,0x69,0x2b,0x32,0x30,0x5d,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,
0x3d,0x30,0x3b,0x20,0x69,0x3c,0x35,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x7b,0x0a,0x74,0x3d,0x62,0x63,0x5b,0x28,0x69,0x2b,0x34,0x29,0x20,0x25,0x20,0x35,0x5d,0x5e,
0x52,0x4f,0x54,0x4c,0x33,0x32,0x28,0x62,0x63,0x5b,0x28,0x69,0x2b,0x31,0x29,0x20,0x25,0x20,0x35,0x5d,0x2c,0x31,0x75,0x29,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,
0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x3d,0x30,0x3b,0x20,0x6a,0x3c,0x32,0x35,0x3b,0x20,0x6a,0x2b,0x3d,0x35,0x29,0x0a,0x73,0x74,0x5b,0x6a,0x2b,0x69,0x5d,
0x20,0x5e,0x3d,0x20,0x74,0x3b,0x0a,0x7d,0x0a,0x74,0x3d,0x73,0x74,0x5b,0x31,0x5d,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,
0x69,0x3c,0x32,0x34,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x3d,0x6b,0x65,0x63,0x63,0x61,0x6b,0x66,0x5f,
0x70,0x69,0x6c,0x6e,0x5b,0x69,0x5d,0x3b,0x0a,0x62,0x63,0x5b,0x30,0x5d,0x3d,0x73,0x74,0x5b,0x6a,0x5d,0x3b,0x0a,0x73,0x74,0x5b,0x6a,0x5d,0x3d,0x52,0x4f,0x54,0x4c,
0x33,0x32,0x28,0x74,0x2c,0x6b,0x65,0x63,0x63,0x61,0x6b,0x66,0x5f,0x72,0x6f,0x74,0x63,0x5b,0x69,0x5d,0x29,0x3b,0x0a,0x74,0x3d,0x62,0x63,0x5b,0x30,0x5d,0x3b,0x0a,
0x7d,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x3d,0x30,0x3b,0x20,0x6a,0x3c,0x32,0x35,0x3b,0x20,0x6a,0x2b,0x3d,0x35,0x29,
0x0a,0x7b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x35,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x62,0x63,0x5b,0x69,0x5d,
0x3d,0x73,0x74,0x5b,0x6a,0x2b,0x69,0x5d,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x35,0x3b,0x20,0x69,0x2b,0x2b,
0x29,0x0a,0x73,0x74,0x5b,0x6a,0x2b,0x69,0x5d,0x20,0x5e,0x3d,0x20,0x28,0x7e,0x62,0x63,0x5b,0x28,0x69,0x2b,0x31,0x29,0x20,0x25,0x20,0x35,0x5d,0x29,0x26,0x62,0x63,
0x5b,0x28,0x69,0x2b,0x32,0x29,0x20,0x25,0x20,0x35,0x5d,0x3b,0x0a,0x7d,0x0a,0x73,0x74,0x5b,0x30,0x5d,0x20,0x5e,0x3d,0x20,0x6b,0x65,0x63,0x63,0x61,0x6b,0x66,0x5f,
0x72,0x6e,0x64,0x63,0x5b,0x72,0x5d,0x3b,0x0a,0x7d,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x6b,0x65,0x63,0x63,0x61,0x6b,0x5f,0x66,0x38,0x30,0x30,0x28,
0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x73,0x74,0x29,0x0a,0x7b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x72,0x3d,0x30,0x3b,0x20,0x72,0x3c,
0x32,0x32,0x3b,0x20,0x72,0x2b,0x2b,0x29,0x20,0x7b,0x0a,0x6b,0x65,0x63,0x63,0x61,0x6b,0x5f,0x66,0x38,0x30,0x30,0x5f,0x72,0x6f,0x75,0x6e,0x64,0x28,0x73,0x74,0x2c,
0x72,0x29,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x66,0x6e,0x76,0x31,0x61,0x28,0x68,0x2c,0x20,0x64,0x29,0x20,0x28,0x68,0x20,0x3d,
0x20,0x28,0x68,0x20,0x5e,0x20,0x64,0x29,0x20,0x2a,0x20,0x46,0x4e,0x56,0x5f,0x50,0x52,0x49,0x4d,0x45,0x29,0x0a,0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x73,0x74,
0x72,0x75,0x63,0x74,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x7a,0x2c,0x77,0x2c,0x6a,0x73,0x72,0x2c,0x6a,0x63,0x6f,0x6e,0x67,0x3b,0x0a,0x7d,
0x20,0x6b,0x69,0x73,0x73,0x39,0x39,0x5f,0x74,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6b,0x69,0x73,0x73,0x39,0x39,0x28,0x6b,0x69,0x73,0x73,0x39,
0x39,0x5f,0x74,0x2a,0x20,0x73,0x74,0x29,0x0a,0x7b,0x0a,0x73,0x74,0x2d,0x3e,0x7a,0x3d,0x33,0x36,0x39,0x36,0x39,0x2a,0x28,0x73,0x74,0x2d,0x3e,0x7a,0x26,0x36,0x35,
0x35,0x33,0x35,0x29,0x2b,0x28,0x73,0x74,0x2d,0x3e,0x7a,0x3e,0x3e,0x31,0x36,0x29,0x3b,0x0a,0x73,0x74,0x2d,0x3e,0x77,0x3d,0x31,0x38,0x30,0x30,0x30,0x2a,0x28,0x73,
0x74,0x2d,0x3e,0x77,0x26,0x36,0x35,0x35,0x33,0x35,0x29,0x2b,0x28,0x73,0x74,0x2d,0x3e,0x77,0x3e,0x3e,0x31,0x36,0x29,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,
0x74,0x20,0x4d,0x57,0x43,0x3d,0x28,0x28,0x73,0x74,0x2d,0x3e,0x7a,0x3c,0x3c,0x31,0x36,0x29,0x2b,0x73,0x74,0x2d,0x3e,0x77,0x29,0x3b,0x0a,0x73,0x74,0x2d,0x3e,0x6a,
0x73,0x72,0x20,0x5e,0x3d,0x20,0x28,0x73,0x74,0x2d,0x3e,0x6a,0x73,0x72,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x0a,0x73,0x74,0x2d,0x3e,0x6a,0x73,0x72,0x20,0x5e,0x3d,0x20,
0x28,0x73,0x74,0x2d,0x3e,0x6a,0x73,0x72,0x3e,0x3e,0x31,0x33,0x29,0x3b,0x0a,0x73,0x74,0x2d,0x3e,0x6a,0x73,0x72,0x20,0x5e,0x3d,0x20,0x28,0x73,0x74,0x2d,0x3e,0x6a,
0x73,0x72,0x3c,0x3c,0x35,0x29,0x3b,0x0a,0x73,0x74,0x2d,0x3e,0x6a,0x63,0x6f,0x6e,0x67,0x3d,0x36,0x39,0x30,0x36,0x39,0x2a,0x73,0x74,0x2d,0x3e,0x6a,0x63,0x6f,0x6e,
0x67,0x2b,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x3b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x28,0x28,0x4d,0x57,0x43,0x5e,0x73,0x74,0x2d,0x3e,0x6a,0x63,0x6f,0x6e,
0x67,0x29,0x2b,0x73,0x74,0x2d,0x3e,0x6a,0x73,0x72,0x29,0x3b,0x0a,0x7d,0x0a,0x76,0x6f,0x69,0x64,0x20,0x66,0x69,0x6c,0x6c,0x5f,0x6d,0x69,0x78,0x28,0x6c,0x6f,0x63,
0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x73,0x65,0x65,0x64,0x2c,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6c,0x61,0x6e,0x65,0x5f,
0x69,0x64,0x2c,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x6d,0x69,0x78,0x29,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x66,0x6e,0x76,
0x5f,0x68,0x61,0x73,0x68,0x3d,0x46,0x4e,0x56,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x5f,0x42,0x41,0x53,0x49,0x53,0x3b,0x0a,0x6b,0x69,0x73,0x73,0x39,0x39,0x5f,0x74,
0x20,0x73,0x74,0x3b,0x0a,0x73,0x74,0x2e,0x7a,0x3d,0x66,0x6e,0x76,0x31,0x61,0x28,0x66,0x6e,0x76,0x5f,0x68,0x61,0x73,0x68,0x2c,0x73,0x65,0x65,0x64,0x5b,0x30,0x5d,
0x29,0x3b,0x0a,0x73,0x74,0x2e,0x77,0x3d,0x66,0x6e,0x76,0x31,0x61,0x28,0x66,0x6e,0x76,0x5f,0x68,0x61,0x73,0x68,0x2c,0x73,0x65,0x65,0x64,0x5b,0x31,0x5d,0x29,0x3b,
0x0a,0x73,0x74,0x2e,0x6a,0x73,0x72,0x3d,0x66,0x6e,0x76,0x31,0x61,0x28,0x66,0x6e,0x76,0x5f,0x68,0x61,0x73,0x68,0x2c,0x6c,0x61,0x6e,0x65,0x5f,0x69,0x64,0x29,0x3b,
0x0a,0x73,0x74,0x2e,0x6a,0x63,0x6f,0x6e,0x67,0x3d,0x66,0x6e,0x76,0x31,0x61,0x28,0x66,0x6e,0x76,0x5f,0x68,0x61,0x73,0x68,0x2c,0x6c,0x61,0x6e,0x65,0x5f,0x69,0x64,
0x29,0x3b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,
0x69,0x3c,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x52,0x45,0x47,0x53,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x6d,0x69,0x78,0x5b,0x69,0x5d,0x3d,0x6b,0x69,0x73,0x73,
0x39,0x39,0x28,0x26,0x73,0x74,0x29,0x3b,0x0a,0x7d,0x0a,0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x73,0x74,0x72,0x75,0x63,0x74,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,
0x33,0x32,0x5f,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x4c,0x41,0x4e,0x45,0x53,0x5d,0x3b,0x0a,0x7d,0x20,0x73,
0x68,0x75,0x66,0x66,0x6c,0x65,0x5f,0x74,0x3b,0x0a,0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x73,0x74,0x72,0x75,0x63,0x74,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x33,
0x32,0x5f,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x33,0x32,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x5d,
0x3b,0x0a,0x7d,0x20,0x68,0x61,0x73,0x68,0x33,0x32,0x5f,0x74,0x3b,0x0a,0x23,0x69,0x66,0x20,0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x20,0x21,0x3d,0x20,0x4f,0x50,
0x45,0x4e,0x43,0x4c,0x5f,0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x5f,0x4e,0x56,0x49,0x44,0x49,0x41,0x20,0x0a,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,
0x65,0x5f,0x5f,0x28,0x28,0x72,0x65,0x71,0x64,0x5f,0x77,0x6f,0x72,0x6b,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x69,0x7a,0x65,0x28,0x47,0x52,0x4f,0x55,0x50,0x5f,
0x53,0x49,0x5a,0x45,0x2c,0x31,0x2c,0x31,0x29,0x29,0x29,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,
0x20,0x70,0x72,0x6f,0x67,0x70,0x6f,0x77,0x5f,0x73,0x65,0x61,0x72,0x63,0x68,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x64,0x61,0x67,0x5f,0x74,0x20,0x63,
0x6f,0x6e,0x73,0x74,0x2a,0x20,0x67,0x5f,0x64,0x61,0x67,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x20,0x6a,0x6f,0x62,0x5f,0x62,
0x6c,0x6f,0x62,0x2c,0x75,0x6c,0x6f,0x6e,0x67,0x20,0x74,0x61,0x72,0x67,0x65,0x74,0x2c,0x75,0x69,0x6e,0x74,0x20,0x68,0x61,0x63,0x6b,0x5f,0x66,0x61,0x6c,0x73,0x65,
0x2c,0x76,0x6f,0x6c,0x61,0x74,0x69,0x6c,0x65,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x73,
0x2c,0x76,0x6f,0x6c,0x61,0x74,0x69,0x6c,0x65,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x20,0x73,0x74,0x6f,0x70,0x29,0x0a,0x7b,
0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6c,0x69,0x64,0x3d,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,
0x28,0x30,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x67,0x69,0x64,0x3d,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,
0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x69,0x66,0x28,0x73,0x74,0x6f,0x70,0x5b,0x30,0x5d,0x29,0x20,0x7b,0x0a,0x69,0x66,0x28,0x6c,0x69,0x64,0x3d,0x3d,
0x30,0x29,0x20,0x7b,0x0a,0x61,0x74,0x6f,0x6d,0x69,0x63,0x5f,0x69,0x6e,0x63,0x28,0x73,0x74,0x6f,0x70,0x2b,0x31,0x29,0x3b,0x0a,0x7d,0x0a,0x72,0x65,0x74,0x75,0x72,
0x6e,0x3b,0x0a,0x7d,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x73,0x68,0x75,0x66,0x66,0x6c,0x65,0x5f,0x74,0x20,0x73,0x68,0x61,0x72,0x65,0x5b,0x48,0x41,0x53,
0x48,0x45,0x53,0x5f,0x50,0x45,0x52,0x5f,0x47,0x52,0x4f,0x55,0x50,0x5d,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,
0x20,0x63,0x5f,0x64,0x61,0x67,0x5b,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x43,0x41,0x43,0x48,0x45,0x5f,0x57,0x4f,0x52,0x44,0x53,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,
0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6c,0x61,0x6e,0x65,0x5f,0x69,0x64,0x3d,0x6c,0x69,0x64,0x26,0x28,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,
0x5f,0x4c,0x41,0x4e,0x45,0x53,0x2d,0x31,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x67,0x72,0x6f,0x75,0x70,0x5f,
0x69,0x64,0x3d,0x6c,0x69,0x64,0x2f,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x4c,0x41,0x4e,0x45,0x53,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,
0x32,0x5f,0x74,0x20,0x77,0x6f,0x72,0x64,0x3d,0x6c,0x69,0x64,0x2a,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x44,0x41,0x47,0x5f,0x4c,0x4f,0x41,0x44,0x53,0x3b,0x20,
0x77,0x6f,0x72,0x64,0x3c,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x43,0x41,0x43,0x48,0x45,0x5f,0x57,0x4f,0x52,0x44,0x53,0x3b,0x20,0x77,0x6f,0x72,0x64,0x2b,0x3d,
0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x49,0x5a,0x45,0x2a,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x44,0x41,0x47,0x5f,0x4c,0x4f,0x41,0x44,0x53,0x29,0x0a,0x7b,0x0a,
0x64,0x61,0x67,0x5f,0x74,0x20,0x6c,0x6f,0x61,0x64,0x3d,0x67,0x5f,0x64,0x61,0x67,0x5b,0x77,0x6f,0x72,0x64,0x2f,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x44,0x41,
0x47,0x5f,0x4c,0x4f,0x41,0x44,0x53,0x5d,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x50,0x52,0x4f,0x47,0x50,0x4f,
0x57,0x5f,0x44,0x41,0x47,0x5f,0x4c,0x4f,0x41,0x44,0x53,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x63,0x5f,0x64,0x61,0x67,0x5b,0x77,0x6f,0x72,0x64,0x2b,0x69,0x5d,0x3d,
0x6c,0x6f,0x61,0x64,0x2e,0x73,0x5b,0x69,0x5d,0x3b,0x0a,0x7d,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x68,0x61,0x73,0x68,0x5f,0x73,0x65,0x65,0x64,0x5b,
0x32,0x5d,0x3b,0x20,0x0a,0x68,0x61,0x73,0x68,0x33,0x32,0x5f,0x74,0x20,0x64,0x69,0x67,0x65,0x73,0x74,0x3b,0x20,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,
0x73,0x74,0x61,0x74,0x65,0x32,0x5b,0x38,0x5d,0x3b,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x74,0x61,0x74,0x65,0x5b,0x32,0x35,0x5d,0x3b,
0x20,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x31,0x30,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x73,0x74,0x61,0x74,0x65,
0x5b,0x69,0x5d,0x3d,0x6a,0x6f,0x62,0x5f,0x62,0x6c,0x6f,0x62,0x5b,0x69,0x5d,0x3b,0x0a,0x73,0x74,0x61,0x74,0x65,0x5b,0x38,0x5d,0x3d,0x67,0x69,0x64,0x3b,0x0a,0x66,
0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x31,0x30,0x3b,0x20,0x69,0x3c,0x32,0x35,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x73,0x74,0x61,0x74,0x65,0x5b,0x69,
0x5d,0x3d,0x72,0x61,0x76,0x65,0x6e,0x63,0x6f,0x69,0x6e,0x5f,0x72,0x6e,0x64,0x63,0x5b,0x69,0x2d,0x31,0x30,0x5d,0x3b,0x0a,0x6b,0x65,0x63,0x63,0x61,0x6b,0x5f,0x66,
0x38,0x30,0x30,0x28,0x73,0x74,0x61,0x74,0x65,0x29,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x38,0x3b,0x20,0x69,
0x2b,0x2b,0x29,0x0a,0x73,0x74,0x61,0x74,0x65,0x32,0x5b,0x69,0x5d,0x3d,0x73,0x74,0x61,0x74,0x65,0x5b,0x69,0x5d,0x3b,0x0a,0x7d,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,
0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x31,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x68,0x3d,0x30,0x3b,0x20,0x68,0x3c,
0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x4c,0x41,0x4e,0x45,0x53,0x3b,0x20,0x68,0x2b,0x2b,0x29,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6d,
0x69,0x78,0x5b,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x52,0x45,0x47,0x53,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6c,0x61,0x6e,0x65,0x5f,0x69,0x64,0x3d,0x3d,0x68,0x29,
0x20,0x7b,0x0a,0x73,0x68,0x61,0x72,0x65,0x5b,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x5d,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x30,0x5d,0x3d,0x73,0x74,
0x61,0x74,0x65,0x32,0x5b,0x30,0x5d,0x3b,0x0a,0x73,0x68,0x61,0x72,0x65,0x5b,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x5d,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,
0x5b,0x31,0x5d,0x3d,0x73,0x74,0x61,0x74,0x65,0x32,0x5b,0x31,0x5d,0x3b,0x0a,0x7d,0x0a,0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,
0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0x0a,0x66,0x69,0x6c,0x6c,0x5f,0x6d,0x69,0x78,0x28,0x73,0x68,0x61,0x72,0x65,0x5b,0x67,0x72,
0x6f,0x75,0x70,0x5f,0x69,0x64,0x5d,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x2c,0x6c,0x61,0x6e,0x65,0x5f,0x69,0x64,0x2c,0x6d,0x69,0x78,0x29,0x3b,0x0a,0x23,0x70,
0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x32,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6c,0x6f,0x6f,
0x70,0x3d,0x30,0x3b,0x20,0x6c,0x6f,0x6f,0x70,0x3c,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x43,0x4e,0x54,0x5f,0x44,0x41,0x47,0x3b,0x20,0x2b,0x2b,0x6c,0x6f,0x6f,
0x70,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x6c,0x61,0x6e,0x65,0x5f,0x69,0x64,0x3d,0x3d,0x28,0x6c,0x6f,0x6f,0x70,0x20,0x25,0x20,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,
0x5f,0x4c,0x41,0x4e,0x45,0x53,0x29,0x29,0x0a,0x73,0x68,0x61,0x72,0x65,0x5b,0x30,0x5d,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x67,0x72,0x6f,0x75,0x70,0x5f,
0x69,0x64,0x5d,0x3d,0x6d,0x69,0x78,0x5b,0x30,0x5d,0x3b,0x0a,0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x4d,0x45,
0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x73,0x68,0x61,0x72,0x65,0x5b,
0x30,0x5d,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x5d,0x3b,0x0a,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x25,0x3d,0x20,
0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x44,0x41,0x47,0x5f,0x45,0x4c,0x45,0x4d,0x45,0x4e,0x54,0x53,0x3b,0x0a,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x6f,0x66,0x66,
0x73,0x65,0x74,0x2a,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x4c,0x41,0x4e,0x45,0x53,0x2b,0x28,0x6c,0x61,0x6e,0x65,0x5f,0x69,0x64,0x5e,0x6c,0x6f,0x6f,0x70,0x29,
0x20,0x25,0x20,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x4c,0x41,0x4e,0x45,0x53,0x3b,0x0a,0x64,0x61,0x67,0x5f,0x74,0x20,0x64,0x61,0x74,0x61,0x5f,0x64,0x61,0x67,
0x3d,0x67,0x5f,0x64,0x61,0x67,0x5b,0x6f,0x66,0x66,0x73,0x65,0x74,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x68,0x61,0x63,0x6b,0x5f,0x66,0x61,0x6c,0x73,0x65,0x29,0x20,0x62,
0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0x0a,0x75,0x69,0x6e,
0x74,0x33,0x32,0x5f,0x74,0x20,0x64,0x61,0x74,0x61,0x3b,0x0a,0x58,0x4d,0x52,0x49,0x47,0x5f,0x49,0x4e,0x43,0x4c,0x55,0x44,0x45,0x5f,0x50,0x52,0x4f,0x47,0x50,0x4f,
0x57,0x5f,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x5f,0x4d,0x41,0x54,0x48,0x0a,0x69,0x66,0x28,0x68,0x61,0x63,0x6b,0x5f,0x66,0x61,0x6c,0x73,0x65,0x29,0x20,0x62,0x61,0x72,
0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0x0a,0x58,0x4d,0x52,0x49,0x47,
0x5f,0x49,0x4e,0x43,0x4c,0x55,0x44,0x45,0x5f,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x44,0x41,0x54,0x41,0x5f,0x4c,0x4f,0x41,0x44,0x53,0x0a,0x7d,0x0a,0x75,0x69,
0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6d,0x69,0x78,0x5f,0x68,0x61,0x73,0x68,0x3d,0x46,0x4e,0x56,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x5f,0x42,0x41,0x53,0x49,0x53,
0x3b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,
0x3c,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x52,0x45,0x47,0x53,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x66,0x6e,0x76,0x31,0x61,0x28,0x6d,0x69,0x78,0x5f,0x68,0x61,
0x73,0x68,0x2c,0x6d,0x69,0x78,0x5b,0x69,0x5d,0x29,0x3b,0x0a,0x68,0x61,0x73,0x68,0x33,0x32,0x5f,0x74,0x20,0x64,0x69,0x67,0x65,0x73,0x74,0x5f,0x74,0x65,0x6d,0x70,
0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x38,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x64,0x69,0x67,0x65,0x73,0x74,
0x5f,0x74,0x65,0x6d,0x70,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x69,0x5d,0x3d,0x46,0x4e,0x56,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x5f,0x42,0x41,0x53,0x49,
0x53,0x3b,0x0a,0x73,0x68,0x61,0x72,0x65,0x5b,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x5d,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x6c,0x61,0x6e,0x65,0x5f,
0x69,0x64,0x5d,0x3d,0x6d,0x69,0x78,0x5f,0x68,0x61,0x73,0x68,0x3b,0x0a,0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,
0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x0a,0x66,0x6f,0x72,0x20,0x28,
0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x4c,0x41,0x4e,0x45,0x53,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x66,
0x6e,0x76,0x31,0x61,0x28,0x64,0x69,0x67,0x65,0x73,0x74,0x5f,0x74,0x65,0x6d,0x70,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x69,0x20,0x25,0x20,0x38,0x5d,0x2c,
0x73,0x68,0x61,0x72,0x65,0x5b,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x5d,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x69,0x5d,0x29,0x3b,0x0a,0x69,0x66,0x28,
0x68,0x3d,0x3d,0x6c,0x61,0x6e,0x65,0x5f,0x69,0x64,0x29,0x0a,0x64,0x69,0x67,0x65,0x73,0x74,0x3d,0x64,0x69,0x67,0x65,0x73,0x74,0x5f,0x74,0x65,0x6d,0x70,0x3b,0x0a,
0x7d,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x3b,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x74,
0x61,0x74,0x65,0x5b,0x32,0x35,0x5d,0x3d,0x7b,0x30,0x78,0x30,0x7d,0x3b,0x20,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,
0x38,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x73,0x74,0x61,0x74,0x65,0x5b,0x69,0x5d,0x3d,0x73,0x74,0x61,0x74,0x65,0x32,0x5b,0x69,0x5d,0x3b,0x0a,0x66,0x6f,0x72,0x20,
0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x38,0x3b,0x20,0x69,0x3c,0x31,0x36,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x73,0x74,0x61,0x74,0x65,0x5b,0x69,0x5d,0x3d,0x64,0x69,
0x67,0x65,0x73,0x74,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x69,0x2d,0x38,0x5d,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x31,0x36,
0x3b,0x20,0x69,0x3c,0x32,0x35,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x73,0x74,0x61,0x74,0x65,0x5b,0x69,0x5d,0x3d,0x72,0x61,0x76,0x65,0x6e,0x63,0x6f,0x69,0x6e,0x5f,
0x72,0x6e,0x64,0x63,0x5b,0x69,0x2d,0x31,0x36,0x5d,0x3b,0x0a,0x6b,0x65,0x63,0x63,0x61,0x6b,0x5f,0x66,0x38,0x30,0x30,0x28,0x73,0x74,0x61,0x74,0x65,0x29,0x3b,0x0a,
0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x72,0x65,0x73,0x3d,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x73,0x74,0x61,0x74,0x65,0x5b,0x31,0x5d,0x3c,
0x3c,0x33,0x32,0x7c,0x73,0x74,0x61,0x74,0x65,0x5b,0x30,0x5d,0x3b,0x0a,0x72,0x65,0x73,0x75,0x6c,0x74,0x3d,0x61,0x73,0x5f,0x75,0x6c,0x6f,0x6e,0x67,0x28,0x61,0x73,
0x5f,0x75,0x63,0x68,0x61,0x72,0x38,0x28,0x72,0x65,0x73,0x29,0x2e,0x73,0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x30,0x29,0x3b,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x72,0x65,
0x73,0x75,0x6c,0x74,0x3c,0x3d,0x74,0x61,0x72,0x67,0x65,0x74,0x29,0x0a,0x7b,0x0a,0x2a,0x73,0x74,0x6f,0x70,0x3d,0x31,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,
0x69,0x6e,0x74,0x20,0x6b,0x3d,0x61,0x74,0x6f,0x6d,0x69,0x63,0x5f,0x69,0x6e,0x63,0x28,0x72,0x65,0x73,0x75,0x6c,0x74,0x73,0x29,0x2b,0x31,0x3b,0x0a,0x69,0x66,0x28,
0x6b,0x3c,0x3d,0x31,0x35,0x29,0x0a,0x72,0x65,0x73,0x75,0x6c,0x74,0x73,0x5b,0x6b,0x5d,0x3d,0x67,0x69,0x64,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x00
};
} // namespace xmrig

View File

@@ -2,7 +2,7 @@
namespace xmrig {
static const char kawpow_dag_cl[5990] = {
static const char kawpow_dag_cl[6068] = {
0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x63,0x6c,0x5f,0x63,0x6c,0x61,0x6e,0x67,0x5f,0x73,0x74,0x6f,0x72,0x61,0x67,0x65,0x5f,0x63,0x6c,0x61,0x73,0x73,0x5f,0x73,0x70,
0x65,0x63,0x69,0x66,0x69,0x65,0x72,0x73,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x20,0x45,0x58,0x54,0x45,0x4e,0x53,0x49,0x4f,
0x4e,0x20,0x63,0x6c,0x5f,0x63,0x6c,0x61,0x6e,0x67,0x5f,0x73,0x74,0x6f,0x72,0x61,0x67,0x65,0x5f,0x63,0x6c,0x61,0x73,0x73,0x5f,0x73,0x70,0x65,0x63,0x69,0x66,0x69,
@@ -25,172 +25,174 @@ static const char kawpow_dag_cl[5990] = {
0x4e,0x43,0x4c,0x5f,0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x5f,0x41,0x4d,0x44,0x20,0x32,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x4f,0x50,0x45,0x4e,0x43,
0x4c,0x5f,0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x5f,0x43,0x4c,0x4f,0x56,0x45,0x52,0x20,0x33,0x0a,0x23,0x69,0x66,0x6e,0x64,0x65,0x66,0x20,0x4d,0x41,0x58,0x5f,
0x4f,0x55,0x54,0x50,0x55,0x54,0x53,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x4d,0x41,0x58,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x53,0x20,0x36,0x33,0x55,0x0a,
0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x23,0x69,0x66,0x6e,0x64,0x65,0x66,0x20,0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,
0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x5f,0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x5f,0x41,0x4d,0x44,0x0a,0x23,0x65,0x6e,
0x64,0x69,0x66,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x48,0x41,0x53,0x48,0x45,0x53,0x5f,0x50,0x45,0x52,0x5f,0x47,0x52,0x4f,0x55,0x50,0x20,0x28,0x47,0x52,
0x4f,0x55,0x50,0x5f,0x53,0x49,0x5a,0x45,0x20,0x2f,0x20,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x4c,0x41,0x4e,0x45,0x53,0x29,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,
0x65,0x20,0x46,0x4e,0x56,0x5f,0x50,0x52,0x49,0x4d,0x45,0x20,0x30,0x78,0x31,0x30,0x30,0x30,0x31,0x39,0x33,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x46,0x4e,
0x56,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x5f,0x42,0x41,0x53,0x49,0x53,0x20,0x30,0x78,0x38,0x31,0x31,0x63,0x39,0x64,0x63,0x35,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,
0x65,0x20,0x45,0x54,0x48,0x41,0x53,0x48,0x5f,0x44,0x41,0x54,0x41,0x53,0x45,0x54,0x5f,0x50,0x41,0x52,0x45,0x4e,0x54,0x53,0x20,0x35,0x31,0x32,0x0a,0x23,0x64,0x65,
0x66,0x69,0x6e,0x65,0x20,0x4e,0x4f,0x44,0x45,0x5f,0x57,0x4f,0x52,0x44,0x53,0x20,0x28,0x36,0x34,0x20,0x2f,0x20,0x34,0x29,0x0a,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,
0x61,0x6e,0x74,0x20,0x75,0x69,0x6e,0x74,0x32,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x4b,0x65,0x63,0x63,0x61,0x6b,0x5f,0x66,0x31,0x36,0x30,0x30,0x5f,0x52,0x43,0x5b,
0x32,0x34,0x5d,0x3d,0x7b,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x32,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x61,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x62,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x38,0x30,0x38,0x31,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x39,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x61,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x38,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x38,0x30,0x30,0x39,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x61,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x38,0x30,0x38,0x62,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x62,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x39,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x33,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x32,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x61,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x61,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x38,0x30,0x38,0x31,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x30,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x38,0x30,0x30,0x38,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x29,0x2c,0x0a,0x7d,0x3b,0x0a,0x23,0x69,0x66,0x20,0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x20,0x3d,0x3d,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x5f,
0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x5f,0x4e,0x56,0x49,0x44,0x49,0x41,0x20,0x26,0x26,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x20,0x3e,0x3d,0x20,0x33,0x35,
0x0a,0x73,0x74,0x61,0x74,0x69,0x63,0x20,0x75,0x69,0x6e,0x74,0x32,0x20,0x52,0x4f,0x4c,0x32,0x28,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x32,0x20,0x61,
0x2c,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x32,0x20,0x72,0x65,0x73,0x75,0x6c,
0x74,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x3e,0x3d,0x33,0x32,0x29,0x0a,0x7b,0x0a,0x61,0x73,0x6d,0x28,0x22,0x73,0x68,0x66,0x2e,0x6c,0x2e,0x77,
0x72,0x61,0x70,0x2e,0x62,0x33,0x32,0x20,0x25,0x30,0x2c,0x25,0x31,0x2c,0x25,0x32,0x2c,0x25,0x33,0x3b,0x22,0x3a,0x22,0x3d,0x72,0x22,0x28,0x72,0x65,0x73,0x75,0x6c,
0x74,0x2e,0x78,0x29,0x3a,0x22,0x72,0x22,0x28,0x61,0x2e,0x78,0x29,0x2c,0x22,0x72,0x22,0x28,0x61,0x2e,0x79,0x29,0x2c,0x22,0x72,0x22,0x28,0x6f,0x66,0x66,0x73,0x65,
0x74,0x29,0x29,0x3b,0x0a,0x61,0x73,0x6d,0x28,0x22,0x73,0x68,0x66,0x2e,0x6c,0x2e,0x77,0x72,0x61,0x70,0x2e,0x62,0x33,0x32,0x20,0x25,0x30,0x2c,0x25,0x31,0x2c,0x25,
0x32,0x2c,0x25,0x33,0x3b,0x22,0x3a,0x22,0x3d,0x72,0x22,0x28,0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x79,0x29,0x3a,0x22,0x72,0x22,0x28,0x61,0x2e,0x79,0x29,0x2c,0x22,
0x72,0x22,0x28,0x61,0x2e,0x78,0x29,0x2c,0x22,0x72,0x22,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x0a,0x7b,0x0a,0x61,
0x73,0x6d,0x28,0x22,0x73,0x68,0x66,0x2e,0x6c,0x2e,0x77,0x72,0x61,0x70,0x2e,0x62,0x33,0x32,0x20,0x25,0x30,0x2c,0x25,0x31,0x2c,0x25,0x32,0x2c,0x25,0x33,0x3b,0x22,
0x3a,0x22,0x3d,0x72,0x22,0x28,0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x78,0x29,0x3a,0x22,0x72,0x22,0x28,0x61,0x2e,0x79,0x29,0x2c,0x22,0x72,0x22,0x28,0x61,0x2e,0x78,
0x29,0x2c,0x22,0x72,0x22,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0x0a,0x61,0x73,0x6d,0x28,0x22,0x73,0x68,0x66,0x2e,0x6c,0x2e,0x77,0x72,0x61,0x70,0x2e,
0x62,0x33,0x32,0x20,0x25,0x30,0x2c,0x25,0x31,0x2c,0x25,0x32,0x2c,0x25,0x33,0x3b,0x22,0x3a,0x22,0x3d,0x72,0x22,0x28,0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x79,0x29,
0x3a,0x22,0x72,0x22,0x28,0x61,0x2e,0x78,0x29,0x2c,0x22,0x72,0x22,0x28,0x61,0x2e,0x79,0x29,0x2c,0x22,0x72,0x22,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,
0x0a,0x7d,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x3b,0x0a,0x7d,0x0a,0x23,0x65,0x6c,0x69,0x66,0x20,0x50,0x4c,0x41,0x54,0x46,0x4f,
0x52,0x4d,0x20,0x3d,0x3d,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x5f,0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x5f,0x41,0x4d,0x44,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,
0x61,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x20,0x45,0x58,0x54,0x45,0x4e,0x53,0x49,0x4f,0x4e,0x20,0x63,0x6c,0x5f,0x61,0x6d,0x64,0x5f,0x6d,0x65,0x64,0x69,0x61,0x5f,
0x6f,0x70,0x73,0x20,0x3a,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0x0a,0x73,0x74,0x61,0x74,0x69,0x63,0x20,0x75,0x69,0x6e,0x74,0x32,0x20,0x52,0x4f,0x4c,0x32,0x28,0x63,
0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x32,0x20,0x76,0x76,0x2c,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x72,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,
0x72,0x3c,0x3d,0x33,0x32,0x29,0x0a,0x7b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x61,0x6d,0x64,0x5f,0x62,0x69,0x74,0x61,0x6c,0x69,0x67,0x6e,0x28,0x28,0x76,0x76,
0x29,0x2e,0x78,0x79,0x2c,0x28,0x76,0x76,0x29,0x2e,0x79,0x78,0x2c,0x33,0x32,0x2d,0x72,0x29,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x0a,0x7b,0x0a,0x72,0x65,0x74,
0x75,0x72,0x6e,0x20,0x61,0x6d,0x64,0x5f,0x62,0x69,0x74,0x61,0x6c,0x69,0x67,0x6e,0x28,0x28,0x76,0x76,0x29,0x2e,0x79,0x78,0x2c,0x28,0x76,0x76,0x29,0x2e,0x78,0x79,
0x2c,0x36,0x34,0x2d,0x72,0x29,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x73,0x74,0x61,0x74,0x69,0x63,0x20,0x75,0x69,0x6e,0x74,0x32,0x20,0x52,
0x4f,0x4c,0x32,0x28,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x32,0x20,0x76,0x2c,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6e,0x29,0x0a,0x7b,
0x0a,0x75,0x69,0x6e,0x74,0x32,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x3b,0x0a,0x69,0x66,0x28,0x6e,0x3c,0x3d,0x33,0x32,0x29,0x0a,0x7b,0x0a,0x72,0x65,0x73,0x75,0x6c,
0x74,0x2e,0x79,0x3d,0x28,0x28,0x76,0x2e,0x79,0x3c,0x3c,0x28,0x6e,0x29,0x29,0x7c,0x28,0x76,0x2e,0x78,0x3e,0x3e,0x28,0x33,0x32,0x2d,0x6e,0x29,0x29,0x29,0x3b,0x0a,
0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x78,0x3d,0x28,0x28,0x76,0x2e,0x78,0x3c,0x3c,0x28,0x6e,0x29,0x29,0x7c,0x28,0x76,0x2e,0x79,0x3e,0x3e,0x28,0x33,0x32,0x2d,0x6e,
0x29,0x29,0x29,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x0a,0x7b,0x0a,0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x79,0x3d,0x28,0x28,0x76,0x2e,0x78,0x3c,0x3c,0x28,0x6e,
0x2d,0x33,0x32,0x29,0x29,0x7c,0x28,0x76,0x2e,0x79,0x3e,0x3e,0x28,0x36,0x34,0x2d,0x6e,0x29,0x29,0x29,0x3b,0x0a,0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x78,0x3d,0x28,
0x28,0x76,0x2e,0x79,0x3c,0x3c,0x28,0x6e,0x2d,0x33,0x32,0x29,0x29,0x7c,0x28,0x76,0x2e,0x78,0x3e,0x3e,0x28,0x36,0x34,0x2d,0x6e,0x29,0x29,0x29,0x3b,0x0a,0x7d,0x0a,
0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x3b,0x0a,0x7d,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x73,0x74,0x61,0x74,0x69,0x63,0x20,0x76,
0x6f,0x69,0x64,0x20,0x63,0x68,0x69,0x28,0x75,0x69,0x6e,0x74,0x32,0x2a,0x20,0x61,0x2c,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6e,0x2c,0x63,0x6f,
0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x32,0x2a,0x20,0x74,0x29,0x0a,0x7b,0x0a,0x61,0x5b,0x6e,0x2b,0x30,0x5d,0x3d,0x62,0x69,0x74,0x73,0x65,0x6c,0x65,0x63,0x74,
0x28,0x74,0x5b,0x6e,0x2b,0x30,0x5d,0x5e,0x74,0x5b,0x6e,0x2b,0x32,0x5d,0x2c,0x74,0x5b,0x6e,0x2b,0x30,0x5d,0x2c,0x74,0x5b,0x6e,0x2b,0x31,0x5d,0x29,0x3b,0x0a,0x61,
0x5b,0x6e,0x2b,0x31,0x5d,0x3d,0x62,0x69,0x74,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x74,0x5b,0x6e,0x2b,0x31,0x5d,0x5e,0x74,0x5b,0x6e,0x2b,0x33,0x5d,0x2c,0x74,0x5b,
0x6e,0x2b,0x31,0x5d,0x2c,0x74,0x5b,0x6e,0x2b,0x32,0x5d,0x29,0x3b,0x0a,0x61,0x5b,0x6e,0x2b,0x32,0x5d,0x3d,0x62,0x69,0x74,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x74,
0x5b,0x6e,0x2b,0x32,0x5d,0x5e,0x74,0x5b,0x6e,0x2b,0x34,0x5d,0x2c,0x74,0x5b,0x6e,0x2b,0x32,0x5d,0x2c,0x74,0x5b,0x6e,0x2b,0x33,0x5d,0x29,0x3b,0x0a,0x61,0x5b,0x6e,
0x2b,0x33,0x5d,0x3d,0x62,0x69,0x74,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x74,0x5b,0x6e,0x2b,0x33,0x5d,0x5e,0x74,0x5b,0x6e,0x2b,0x30,0x5d,0x2c,0x74,0x5b,0x6e,0x2b,
0x33,0x5d,0x2c,0x74,0x5b,0x6e,0x2b,0x34,0x5d,0x29,0x3b,0x0a,0x61,0x5b,0x6e,0x2b,0x34,0x5d,0x3d,0x62,0x69,0x74,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x74,0x5b,0x6e,
0x2b,0x34,0x5d,0x5e,0x74,0x5b,0x6e,0x2b,0x31,0x5d,0x2c,0x74,0x5b,0x6e,0x2b,0x34,0x5d,0x2c,0x74,0x5b,0x6e,0x2b,0x30,0x5d,0x29,0x3b,0x0a,0x7d,0x0a,0x73,0x74,0x61,
0x74,0x69,0x63,0x20,0x76,0x6f,0x69,0x64,0x20,0x6b,0x65,0x63,0x63,0x61,0x6b,0x5f,0x66,0x31,0x36,0x30,0x30,0x5f,0x72,0x6f,0x75,0x6e,0x64,0x28,0x75,0x69,0x6e,0x74,
0x32,0x2a,0x20,0x61,0x2c,0x75,0x69,0x6e,0x74,0x20,0x72,0x29,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x32,0x20,0x74,0x5b,0x32,0x35,0x5d,0x3b,0x0a,0x75,0x69,0x6e,0x74,
0x32,0x20,0x75,0x3b,0x0a,0x74,0x5b,0x30,0x5d,0x3d,0x61,0x5b,0x30,0x5d,0x5e,0x61,0x5b,0x35,0x5d,0x5e,0x61,0x5b,0x31,0x30,0x5d,0x5e,0x61,0x5b,0x31,0x35,0x5d,0x5e,
0x61,0x5b,0x32,0x30,0x5d,0x3b,0x0a,0x74,0x5b,0x31,0x5d,0x3d,0x61,0x5b,0x31,0x5d,0x5e,0x61,0x5b,0x36,0x5d,0x5e,0x61,0x5b,0x31,0x31,0x5d,0x5e,0x61,0x5b,0x31,0x36,
0x5d,0x5e,0x61,0x5b,0x32,0x31,0x5d,0x3b,0x0a,0x74,0x5b,0x32,0x5d,0x3d,0x61,0x5b,0x32,0x5d,0x5e,0x61,0x5b,0x37,0x5d,0x5e,0x61,0x5b,0x31,0x32,0x5d,0x5e,0x61,0x5b,
0x31,0x37,0x5d,0x5e,0x61,0x5b,0x32,0x32,0x5d,0x3b,0x0a,0x74,0x5b,0x33,0x5d,0x3d,0x61,0x5b,0x33,0x5d,0x5e,0x61,0x5b,0x38,0x5d,0x5e,0x61,0x5b,0x31,0x33,0x5d,0x5e,
0x61,0x5b,0x31,0x38,0x5d,0x5e,0x61,0x5b,0x32,0x33,0x5d,0x3b,0x0a,0x74,0x5b,0x34,0x5d,0x3d,0x61,0x5b,0x34,0x5d,0x5e,0x61,0x5b,0x39,0x5d,0x5e,0x61,0x5b,0x31,0x34,
0x5d,0x5e,0x61,0x5b,0x31,0x39,0x5d,0x5e,0x61,0x5b,0x32,0x34,0x5d,0x3b,0x0a,0x75,0x3d,0x74,0x5b,0x34,0x5d,0x5e,0x52,0x4f,0x4c,0x32,0x28,0x74,0x5b,0x31,0x5d,0x2c,
0x31,0x29,0x3b,0x0a,0x61,0x5b,0x30,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x35,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x31,0x30,0x5d,0x20,
0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x31,0x35,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x32,0x30,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x75,0x3d,
0x74,0x5b,0x30,0x5d,0x5e,0x52,0x4f,0x4c,0x32,0x28,0x74,0x5b,0x32,0x5d,0x2c,0x31,0x29,0x3b,0x0a,0x61,0x5b,0x31,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,
0x36,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x31,0x31,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x31,0x36,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,
0x0a,0x61,0x5b,0x32,0x31,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x75,0x3d,0x74,0x5b,0x31,0x5d,0x5e,0x52,0x4f,0x4c,0x32,0x28,0x74,0x5b,0x33,0x5d,0x2c,0x31,0x29,
0x3b,0x0a,0x61,0x5b,0x32,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x37,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x31,0x32,0x5d,0x20,0x5e,0x3d,
0x20,0x75,0x3b,0x0a,0x61,0x5b,0x31,0x37,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x32,0x32,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x75,0x3d,0x74,0x5b,
0x32,0x5d,0x5e,0x52,0x4f,0x4c,0x32,0x28,0x74,0x5b,0x34,0x5d,0x2c,0x31,0x29,0x3b,0x0a,0x61,0x5b,0x33,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x38,0x5d,
0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x31,0x33,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x31,0x38,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,
0x5b,0x32,0x33,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x75,0x3d,0x74,0x5b,0x33,0x5d,0x5e,0x52,0x4f,0x4c,0x32,0x28,0x74,0x5b,0x30,0x5d,0x2c,0x31,0x29,0x3b,0x0a,
0x61,0x5b,0x34,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x39,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x31,0x34,0x5d,0x20,0x5e,0x3d,0x20,0x75,
0x3b,0x0a,0x61,0x5b,0x31,0x39,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x32,0x34,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x74,0x5b,0x30,0x5d,0x3d,0x61,
0x5b,0x30,0x5d,0x3b,0x0a,0x74,0x5b,0x31,0x30,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x31,0x5d,0x2c,0x31,0x29,0x3b,0x0a,0x74,0x5b,0x32,0x30,0x5d,0x3d,0x52,
0x4f,0x4c,0x32,0x28,0x61,0x5b,0x32,0x5d,0x2c,0x36,0x32,0x29,0x3b,0x0a,0x74,0x5b,0x35,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x33,0x5d,0x2c,0x32,0x38,0x29,
0x3b,0x0a,0x74,0x5b,0x31,0x35,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x34,0x5d,0x2c,0x32,0x37,0x29,0x3b,0x0a,0x74,0x5b,0x31,0x36,0x5d,0x3d,0x52,0x4f,0x4c,
0x32,0x28,0x61,0x5b,0x35,0x5d,0x2c,0x33,0x36,0x29,0x3b,0x0a,0x74,0x5b,0x31,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x36,0x5d,0x2c,0x34,0x34,0x29,0x3b,0x0a,
0x74,0x5b,0x31,0x31,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x37,0x5d,0x2c,0x36,0x29,0x3b,0x0a,0x74,0x5b,0x32,0x31,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,
0x5b,0x38,0x5d,0x2c,0x35,0x35,0x29,0x3b,0x0a,0x74,0x5b,0x36,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x39,0x5d,0x2c,0x32,0x30,0x29,0x3b,0x0a,0x74,0x5b,0x37,
0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x31,0x30,0x5d,0x2c,0x33,0x29,0x3b,0x0a,0x74,0x5b,0x31,0x37,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x31,0x31,
0x5d,0x2c,0x31,0x30,0x29,0x3b,0x0a,0x74,0x5b,0x32,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x31,0x32,0x5d,0x2c,0x34,0x33,0x29,0x3b,0x0a,0x74,0x5b,0x31,0x32,
0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x31,0x33,0x5d,0x2c,0x32,0x35,0x29,0x3b,0x0a,0x74,0x5b,0x32,0x32,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x31,
0x34,0x5d,0x2c,0x33,0x39,0x29,0x3b,0x0a,0x74,0x5b,0x32,0x33,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x31,0x35,0x5d,0x2c,0x34,0x31,0x29,0x3b,0x0a,0x74,0x5b,
0x38,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x31,0x36,0x5d,0x2c,0x34,0x35,0x29,0x3b,0x0a,0x74,0x5b,0x31,0x38,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,
0x31,0x37,0x5d,0x2c,0x31,0x35,0x29,0x3b,0x0a,0x74,0x5b,0x33,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x31,0x38,0x5d,0x2c,0x32,0x31,0x29,0x3b,0x0a,0x74,0x5b,
0x31,0x33,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x31,0x39,0x5d,0x2c,0x38,0x29,0x3b,0x0a,0x74,0x5b,0x31,0x34,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,
0x32,0x30,0x5d,0x2c,0x31,0x38,0x29,0x3b,0x0a,0x74,0x5b,0x32,0x34,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x32,0x31,0x5d,0x2c,0x32,0x29,0x3b,0x0a,0x74,0x5b,
0x39,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x32,0x32,0x5d,0x2c,0x36,0x31,0x29,0x3b,0x0a,0x74,0x5b,0x31,0x39,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,
0x32,0x33,0x5d,0x2c,0x35,0x36,0x29,0x3b,0x0a,0x74,0x5b,0x34,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x32,0x34,0x5d,0x2c,0x31,0x34,0x29,0x3b,0x0a,0x63,0x68,
0x69,0x28,0x61,0x2c,0x30,0x2c,0x74,0x29,0x3b,0x0a,0x61,0x5b,0x30,0x5d,0x20,0x5e,0x3d,0x20,0x4b,0x65,0x63,0x63,0x61,0x6b,0x5f,0x66,0x31,0x36,0x30,0x30,0x5f,0x52,
0x43,0x5b,0x72,0x5d,0x3b,0x0a,0x63,0x68,0x69,0x28,0x61,0x2c,0x35,0x2c,0x74,0x29,0x3b,0x0a,0x63,0x68,0x69,0x28,0x61,0x2c,0x31,0x30,0x2c,0x74,0x29,0x3b,0x0a,0x63,
0x68,0x69,0x28,0x61,0x2c,0x31,0x35,0x2c,0x74,0x29,0x3b,0x0a,0x63,0x68,0x69,0x28,0x61,0x2c,0x32,0x30,0x2c,0x74,0x29,0x3b,0x0a,0x7d,0x0a,0x73,0x74,0x61,0x74,0x69,
0x63,0x20,0x76,0x6f,0x69,0x64,0x20,0x6b,0x65,0x63,0x63,0x61,0x6b,0x5f,0x66,0x31,0x36,0x30,0x30,0x5f,0x6e,0x6f,0x5f,0x61,0x62,0x73,0x6f,0x72,0x62,0x28,0x75,0x69,
0x6e,0x74,0x32,0x2a,0x20,0x61,0x2c,0x75,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x2c,0x75,0x69,0x6e,0x74,0x20,0x69,0x73,0x6f,0x6c,0x61,0x74,
0x65,0x29,0x0a,0x7b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x20,0x72,0x3d,0x30,0x3b,0x20,0x72,0x3c,0x32,0x34,0x3b,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,
0x69,0x73,0x6f,0x6c,0x61,0x74,0x65,0x29,0x0a,0x7b,0x0a,0x6b,0x65,0x63,0x63,0x61,0x6b,0x5f,0x66,0x31,0x36,0x30,0x30,0x5f,0x72,0x6f,0x75,0x6e,0x64,0x28,0x61,0x2c,
0x72,0x2b,0x2b,0x29,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x7d,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x63,0x6f,0x70,0x79,0x28,0x64,0x73,0x74,0x2c,0x20,0x73,0x72,
0x63,0x2c,0x20,0x63,0x6f,0x75,0x6e,0x74,0x29,0x20,0x5c,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x21,0x3d,0x63,0x6f,
0x75,0x6e,0x74,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x20,0x5c,0x0a,0x7b,0x20,0x5c,0x0a,0x28,0x64,0x73,0x74,0x29,0x5b,0x69,0x5d,0x3d,0x28,0x73,0x72,0x63,0x29,0x5b,0x69,
0x5d,0x3b,0x20,0x5c,0x0a,0x7d,0x0a,0x73,0x74,0x61,0x74,0x69,0x63,0x20,0x75,0x69,0x6e,0x74,0x20,0x66,0x6e,0x76,0x28,0x75,0x69,0x6e,0x74,0x20,0x78,0x2c,0x75,0x69,
0x6e,0x74,0x20,0x79,0x29,0x0a,0x7b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x78,0x2a,0x46,0x4e,0x56,0x5f,0x50,0x52,0x49,0x4d,0x45,0x5e,0x79,0x3b,0x0a,0x7d,0x0a,
0x73,0x74,0x61,0x74,0x69,0x63,0x20,0x75,0x69,0x6e,0x74,0x34,0x20,0x66,0x6e,0x76,0x34,0x28,0x75,0x69,0x6e,0x74,0x34,0x20,0x78,0x2c,0x75,0x69,0x6e,0x74,0x34,0x20,
0x79,0x29,0x0a,0x7b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x78,0x2a,0x46,0x4e,0x56,0x5f,0x50,0x52,0x49,0x4d,0x45,0x5e,0x79,0x3b,0x0a,0x7d,0x0a,0x74,0x79,0x70,
0x65,0x64,0x65,0x66,0x20,0x75,0x6e,0x69,0x6f,0x6e,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x20,0x77,0x6f,0x72,0x64,0x73,0x5b,0x36,0x34,0x2f,0x73,0x69,0x7a,0x65,0x6f,
0x66,0x28,0x75,0x69,0x6e,0x74,0x29,0x5d,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x32,0x20,0x75,0x69,0x6e,0x74,0x32,0x73,0x5b,0x36,0x34,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,
0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x5d,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x34,0x20,0x75,0x69,0x6e,0x74,0x34,0x73,0x5b,0x36,0x34,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,
0x28,0x75,0x69,0x6e,0x74,0x34,0x29,0x5d,0x3b,0x0a,0x7d,0x20,0x68,0x61,0x73,0x68,0x36,0x34,0x5f,0x74,0x3b,0x0a,0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x75,0x6e,
0x69,0x6f,0x6e,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x20,0x77,0x6f,0x72,0x64,0x73,0x5b,0x32,0x30,0x30,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,
0x29,0x5d,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x32,0x20,0x75,0x69,0x6e,0x74,0x32,0x73,0x5b,0x32,0x30,0x30,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,
0x32,0x29,0x5d,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x34,0x20,0x75,0x69,0x6e,0x74,0x34,0x73,0x5b,0x32,0x30,0x30,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,
0x74,0x34,0x29,0x5d,0x3b,0x0a,0x7d,0x20,0x68,0x61,0x73,0x68,0x32,0x30,0x30,0x5f,0x74,0x3b,0x0a,0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x73,0x74,0x72,0x75,0x63,
0x74,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x34,0x20,0x75,0x69,0x6e,0x74,0x34,0x73,0x5b,0x31,0x32,0x38,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,
0x34,0x29,0x5d,0x3b,0x0a,0x7d,0x20,0x68,0x61,0x73,0x68,0x31,0x32,0x38,0x5f,0x74,0x3b,0x0a,0x73,0x74,0x61,0x74,0x69,0x63,0x20,0x76,0x6f,0x69,0x64,0x20,0x53,0x48,
0x41,0x33,0x5f,0x35,0x31,0x32,0x28,0x75,0x69,0x6e,0x74,0x32,0x2a,0x20,0x73,0x2c,0x75,0x69,0x6e,0x74,0x20,0x69,0x73,0x6f,0x6c,0x61,0x74,0x65,0x29,0x0a,0x7b,0x0a,
0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x20,0x69,0x3d,0x38,0x3b,0x20,0x69,0x21,0x3d,0x32,0x35,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x0a,0x7b,0x0a,0x73,0x5b,0x69,
0x5d,0x3d,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x7b,0x30,0x2c,0x30,0x7d,0x3b,0x0a,0x7d,0x0a,0x73,0x5b,0x38,0x5d,0x2e,0x78,0x3d,0x30,0x78,0x30,0x30,0x30,0x30,0x30,
0x30,0x30,0x31,0x3b,0x0a,0x73,0x5b,0x38,0x5d,0x2e,0x79,0x3d,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x3b,0x0a,0x6b,0x65,0x63,0x63,0x61,0x6b,0x5f,0x66,
0x31,0x36,0x30,0x30,0x5f,0x6e,0x6f,0x5f,0x61,0x62,0x73,0x6f,0x72,0x62,0x28,0x73,0x2c,0x38,0x2c,0x69,0x73,0x6f,0x6c,0x61,0x74,0x65,0x29,0x3b,0x0a,0x7d,0x0a,0x73,
0x74,0x61,0x74,0x69,0x63,0x20,0x75,0x69,0x6e,0x74,0x20,0x66,0x61,0x73,0x74,0x5f,0x6d,0x6f,0x64,0x28,0x75,0x69,0x6e,0x74,0x20,0x61,0x2c,0x75,0x69,0x6e,0x74,0x34,
0x20,0x64,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x6c,0x6f,0x6e,0x67,0x20,0x74,0x3d,0x61,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,
0x74,0x20,0x71,0x3d,0x28,0x28,0x74,0x2b,0x64,0x2e,0x79,0x29,0x2a,0x64,0x2e,0x78,0x29,0x3e,0x3e,0x64,0x2e,0x7a,0x3b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x61,
0x2d,0x71,0x2a,0x64,0x2e,0x77,0x3b,0x0a,0x7d,0x0a,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x65,0x74,0x68,0x61,0x73,0x68,0x5f,0x63,
0x61,0x6c,0x63,0x75,0x6c,0x61,0x74,0x65,0x5f,0x64,0x61,0x67,0x5f,0x69,0x74,0x65,0x6d,0x28,0x75,0x69,0x6e,0x74,0x20,0x73,0x74,0x61,0x72,0x74,0x2c,0x5f,0x5f,0x67,
0x6c,0x6f,0x62,0x61,0x6c,0x20,0x68,0x61,0x73,0x68,0x36,0x34,0x5f,0x74,0x20,0x63,0x6f,0x6e,0x73,0x74,0x2a,0x20,0x67,0x5f,0x6c,0x69,0x67,0x68,0x74,0x2c,0x5f,0x5f,
0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x68,0x61,0x73,0x68,0x36,0x34,0x5f,0x74,0x2a,0x20,0x67,0x5f,0x64,0x61,0x67,0x2c,0x75,0x69,0x6e,0x74,0x20,0x69,0x73,0x6f,0x6c,
0x61,0x74,0x65,0x2c,0x75,0x69,0x6e,0x74,0x20,0x64,0x61,0x67,0x5f,0x77,0x6f,0x72,0x64,0x73,0x2c,0x75,0x69,0x6e,0x74,0x34,0x20,0x6c,0x69,0x67,0x68,0x74,0x5f,0x77,
0x6f,0x72,0x64,0x73,0x29,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x6e,0x6f,0x64,0x65,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3d,0x73,0x74,
0x61,0x72,0x74,0x2b,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x69,0x66,0x28,0x6e,0x6f,0x64,0x65,0x5f,0x69,0x6e,
0x64,0x65,0x78,0x3e,0x3d,0x64,0x61,0x67,0x5f,0x77,0x6f,0x72,0x64,0x73,0x29,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0x0a,0x68,0x61,0x73,0x68,0x32,0x30,0x30,0x5f,
0x74,0x20,0x64,0x61,0x67,0x5f,0x6e,0x6f,0x64,0x65,0x3b,0x0a,0x63,0x6f,0x70,0x79,0x28,0x64,0x61,0x67,0x5f,0x6e,0x6f,0x64,0x65,0x2e,0x75,0x69,0x6e,0x74,0x34,0x73,
0x2c,0x67,0x5f,0x6c,0x69,0x67,0x68,0x74,0x5b,0x66,0x61,0x73,0x74,0x5f,0x6d,0x6f,0x64,0x28,0x6e,0x6f,0x64,0x65,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2c,0x6c,0x69,0x67,
0x68,0x74,0x5f,0x77,0x6f,0x72,0x64,0x73,0x29,0x5d,0x2e,0x75,0x69,0x6e,0x74,0x34,0x73,0x2c,0x34,0x29,0x3b,0x0a,0x64,0x61,0x67,0x5f,0x6e,0x6f,0x64,0x65,0x2e,0x77,
0x6f,0x72,0x64,0x73,0x5b,0x30,0x5d,0x20,0x5e,0x3d,0x20,0x6e,0x6f,0x64,0x65,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3b,0x0a,0x53,0x48,0x41,0x33,0x5f,0x35,0x31,0x32,0x28,
0x64,0x61,0x67,0x5f,0x6e,0x6f,0x64,0x65,0x2e,0x75,0x69,0x6e,0x74,0x32,0x73,0x2c,0x69,0x73,0x6f,0x6c,0x61,0x74,0x65,0x29,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,
0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x21,0x3d,0x45,0x54,0x48,0x41,0x53,0x48,0x5f,0x44,0x41,0x54,0x41,0x53,0x45,0x54,0x5f,0x50,0x41,0x52,0x45,0x4e,
0x54,0x53,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x20,0x70,0x61,0x72,0x65,0x6e,0x74,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3d,0x66,0x61,0x73,
0x74,0x5f,0x6d,0x6f,0x64,0x28,0x66,0x6e,0x76,0x28,0x6e,0x6f,0x64,0x65,0x5f,0x69,0x6e,0x64,0x65,0x78,0x5e,0x69,0x2c,0x64,0x61,0x67,0x5f,0x6e,0x6f,0x64,0x65,0x2e,
0x77,0x6f,0x72,0x64,0x73,0x5b,0x69,0x20,0x25,0x20,0x4e,0x4f,0x44,0x45,0x5f,0x57,0x4f,0x52,0x44,0x53,0x5d,0x29,0x2c,0x6c,0x69,0x67,0x68,0x74,0x5f,0x77,0x6f,0x72,
0x64,0x73,0x29,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x20,0x77,0x3d,0x30,0x3b,0x20,0x77,0x21,0x3d,0x34,0x3b,0x20,0x2b,0x2b,0x77,0x29,0x0a,0x64,
0x61,0x67,0x5f,0x6e,0x6f,0x64,0x65,0x2e,0x75,0x69,0x6e,0x74,0x34,0x73,0x5b,0x77,0x5d,0x3d,0x66,0x6e,0x76,0x34,0x28,0x64,0x61,0x67,0x5f,0x6e,0x6f,0x64,0x65,0x2e,
0x75,0x69,0x6e,0x74,0x34,0x73,0x5b,0x77,0x5d,0x2c,0x67,0x5f,0x6c,0x69,0x67,0x68,0x74,0x5b,0x70,0x61,0x72,0x65,0x6e,0x74,0x5f,0x69,0x6e,0x64,0x65,0x78,0x5d,0x2e,
0x75,0x69,0x6e,0x74,0x34,0x73,0x5b,0x77,0x5d,0x29,0x3b,0x0a,0x7d,0x0a,0x53,0x48,0x41,0x33,0x5f,0x35,0x31,0x32,0x28,0x64,0x61,0x67,0x5f,0x6e,0x6f,0x64,0x65,0x2e,
0x75,0x69,0x6e,0x74,0x32,0x73,0x2c,0x69,0x73,0x6f,0x6c,0x61,0x74,0x65,0x29,0x3b,0x0a,0x63,0x6f,0x70,0x79,0x28,0x67,0x5f,0x64,0x61,0x67,0x5b,0x6e,0x6f,0x64,0x65,
0x5f,0x69,0x6e,0x64,0x65,0x78,0x5d,0x2e,0x75,0x69,0x6e,0x74,0x34,0x73,0x2c,0x64,0x61,0x67,0x5f,0x6e,0x6f,0x64,0x65,0x2e,0x75,0x69,0x6e,0x74,0x34,0x73,0x2c,0x34,
0x29,0x3b,0x0a,0x7d,0x0a,0x00
0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x23,0x69,0x66,0x6e,0x64,0x65,0x66,0x20,0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x0a,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x63,
0x6c,0x5f,0x61,0x6d,0x64,0x5f,0x6d,0x65,0x64,0x69,0x61,0x5f,0x6f,0x70,0x73,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,
0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x5f,0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x5f,0x41,0x4d,0x44,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x23,0x64,0x65,0x66,0x69,
0x6e,0x65,0x20,0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x5f,0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x5f,0x55,0x4e,0x4b,0x4e,
0x4f,0x57,0x4e,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x48,0x41,0x53,0x48,0x45,0x53,
0x5f,0x50,0x45,0x52,0x5f,0x47,0x52,0x4f,0x55,0x50,0x20,0x28,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x49,0x5a,0x45,0x20,0x2f,0x20,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,
0x5f,0x4c,0x41,0x4e,0x45,0x53,0x29,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x46,0x4e,0x56,0x5f,0x50,0x52,0x49,0x4d,0x45,0x20,0x30,0x78,0x31,0x30,0x30,0x30,
0x31,0x39,0x33,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x46,0x4e,0x56,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x5f,0x42,0x41,0x53,0x49,0x53,0x20,0x30,0x78,0x38,
0x31,0x31,0x63,0x39,0x64,0x63,0x35,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x45,0x54,0x48,0x41,0x53,0x48,0x5f,0x44,0x41,0x54,0x41,0x53,0x45,0x54,0x5f,0x50,
0x41,0x52,0x45,0x4e,0x54,0x53,0x20,0x35,0x31,0x32,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x4e,0x4f,0x44,0x45,0x5f,0x57,0x4f,0x52,0x44,0x53,0x20,0x28,0x36,
0x34,0x20,0x2f,0x20,0x34,0x29,0x0a,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x75,0x69,0x6e,0x74,0x32,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x4b,0x65,
0x63,0x63,0x61,0x6b,0x5f,0x66,0x31,0x36,0x30,0x30,0x5f,0x52,0x43,0x5b,0x32,0x34,0x5d,0x3d,0x7b,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x30,0x30,
0x30,0x30,0x30,0x30,0x30,0x31,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x30,0x30,
0x30,0x30,0x38,0x30,0x38,0x32,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x30,0x30,
0x30,0x30,0x38,0x30,0x38,0x61,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x38,0x30,
0x30,0x30,0x38,0x30,0x30,0x30,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x30,0x30,
0x30,0x30,0x38,0x30,0x38,0x62,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x38,0x30,
0x30,0x30,0x30,0x30,0x30,0x31,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x38,0x30,
0x30,0x30,0x38,0x30,0x38,0x31,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x30,0x30,
0x30,0x30,0x38,0x30,0x30,0x39,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x30,0x30,
0x30,0x30,0x30,0x30,0x38,0x61,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x30,0x30,
0x30,0x30,0x30,0x30,0x38,0x38,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x38,0x30,
0x30,0x30,0x38,0x30,0x30,0x39,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x38,0x30,
0x30,0x30,0x30,0x30,0x30,0x61,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x38,0x30,
0x30,0x30,0x38,0x30,0x38,0x62,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x30,0x30,
0x30,0x30,0x30,0x30,0x38,0x62,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x30,0x30,
0x30,0x30,0x38,0x30,0x38,0x39,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x30,0x30,
0x30,0x30,0x38,0x30,0x30,0x33,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x30,0x30,
0x30,0x30,0x38,0x30,0x30,0x32,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x30,0x30,
0x30,0x30,0x30,0x30,0x38,0x30,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x30,0x30,
0x30,0x30,0x38,0x30,0x30,0x61,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x38,0x30,
0x30,0x30,0x30,0x30,0x30,0x61,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x38,0x30,
0x30,0x30,0x38,0x30,0x38,0x31,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x30,0x30,
0x30,0x30,0x38,0x30,0x38,0x30,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x38,0x30,
0x30,0x30,0x30,0x30,0x30,0x31,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x38,0x30,
0x30,0x30,0x38,0x30,0x30,0x38,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x29,0x2c,0x0a,0x7d,0x3b,0x0a,0x23,0x69,0x66,0x20,0x50,0x4c,0x41,0x54,0x46,
0x4f,0x52,0x4d,0x20,0x3d,0x3d,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x5f,0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x5f,0x4e,0x56,0x49,0x44,0x49,0x41,0x20,0x26,0x26,
0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x20,0x3e,0x3d,0x20,0x33,0x35,0x0a,0x73,0x74,0x61,0x74,0x69,0x63,0x20,0x75,0x69,0x6e,0x74,0x32,0x20,0x52,0x4f,0x4c,0x32,
0x28,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x32,0x20,0x61,0x2c,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,
0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x32,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x3e,0x3d,0x33,0x32,0x29,0x0a,
0x7b,0x0a,0x61,0x73,0x6d,0x28,0x22,0x73,0x68,0x66,0x2e,0x6c,0x2e,0x77,0x72,0x61,0x70,0x2e,0x62,0x33,0x32,0x20,0x25,0x30,0x2c,0x25,0x31,0x2c,0x25,0x32,0x2c,0x25,
0x33,0x3b,0x22,0x3a,0x22,0x3d,0x72,0x22,0x28,0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x78,0x29,0x3a,0x22,0x72,0x22,0x28,0x61,0x2e,0x78,0x29,0x2c,0x22,0x72,0x22,0x28,
0x61,0x2e,0x79,0x29,0x2c,0x22,0x72,0x22,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0x0a,0x61,0x73,0x6d,0x28,0x22,0x73,0x68,0x66,0x2e,0x6c,0x2e,0x77,0x72,
0x61,0x70,0x2e,0x62,0x33,0x32,0x20,0x25,0x30,0x2c,0x25,0x31,0x2c,0x25,0x32,0x2c,0x25,0x33,0x3b,0x22,0x3a,0x22,0x3d,0x72,0x22,0x28,0x72,0x65,0x73,0x75,0x6c,0x74,
0x2e,0x79,0x29,0x3a,0x22,0x72,0x22,0x28,0x61,0x2e,0x79,0x29,0x2c,0x22,0x72,0x22,0x28,0x61,0x2e,0x78,0x29,0x2c,0x22,0x72,0x22,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,
0x29,0x29,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x0a,0x7b,0x0a,0x61,0x73,0x6d,0x28,0x22,0x73,0x68,0x66,0x2e,0x6c,0x2e,0x77,0x72,0x61,0x70,0x2e,0x62,0x33,0x32,
0x20,0x25,0x30,0x2c,0x25,0x31,0x2c,0x25,0x32,0x2c,0x25,0x33,0x3b,0x22,0x3a,0x22,0x3d,0x72,0x22,0x28,0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x78,0x29,0x3a,0x22,0x72,
0x22,0x28,0x61,0x2e,0x79,0x29,0x2c,0x22,0x72,0x22,0x28,0x61,0x2e,0x78,0x29,0x2c,0x22,0x72,0x22,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0x0a,0x61,0x73,
0x6d,0x28,0x22,0x73,0x68,0x66,0x2e,0x6c,0x2e,0x77,0x72,0x61,0x70,0x2e,0x62,0x33,0x32,0x20,0x25,0x30,0x2c,0x25,0x31,0x2c,0x25,0x32,0x2c,0x25,0x33,0x3b,0x22,0x3a,
0x22,0x3d,0x72,0x22,0x28,0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x79,0x29,0x3a,0x22,0x72,0x22,0x28,0x61,0x2e,0x78,0x29,0x2c,0x22,0x72,0x22,0x28,0x61,0x2e,0x79,0x29,
0x2c,0x22,0x72,0x22,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0x0a,0x7d,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x3b,0x0a,
0x7d,0x0a,0x23,0x65,0x6c,0x69,0x66,0x20,0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x20,0x3d,0x3d,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x5f,0x50,0x4c,0x41,0x54,0x46,
0x4f,0x52,0x4d,0x5f,0x41,0x4d,0x44,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x20,0x45,0x58,0x54,0x45,0x4e,0x53,0x49,0x4f,0x4e,
0x20,0x63,0x6c,0x5f,0x61,0x6d,0x64,0x5f,0x6d,0x65,0x64,0x69,0x61,0x5f,0x6f,0x70,0x73,0x20,0x3a,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0x0a,0x73,0x74,0x61,0x74,0x69,
0x63,0x20,0x75,0x69,0x6e,0x74,0x32,0x20,0x52,0x4f,0x4c,0x32,0x28,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x32,0x20,0x76,0x76,0x2c,0x63,0x6f,0x6e,0x73,
0x74,0x20,0x69,0x6e,0x74,0x20,0x72,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x72,0x3c,0x3d,0x33,0x32,0x29,0x0a,0x7b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x61,0x6d,
0x64,0x5f,0x62,0x69,0x74,0x61,0x6c,0x69,0x67,0x6e,0x28,0x28,0x76,0x76,0x29,0x2e,0x78,0x79,0x2c,0x28,0x76,0x76,0x29,0x2e,0x79,0x78,0x2c,0x33,0x32,0x2d,0x72,0x29,
0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x0a,0x7b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x61,0x6d,0x64,0x5f,0x62,0x69,0x74,0x61,0x6c,0x69,0x67,0x6e,0x28,0x28,
0x76,0x76,0x29,0x2e,0x79,0x78,0x2c,0x28,0x76,0x76,0x29,0x2e,0x78,0x79,0x2c,0x36,0x34,0x2d,0x72,0x29,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,
0x73,0x74,0x61,0x74,0x69,0x63,0x20,0x75,0x69,0x6e,0x74,0x32,0x20,0x52,0x4f,0x4c,0x32,0x28,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x32,0x20,0x76,0x2c,
0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6e,0x29,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x32,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x3b,0x0a,0x69,0x66,0x28,
0x6e,0x3c,0x3d,0x33,0x32,0x29,0x0a,0x7b,0x0a,0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x79,0x3d,0x28,0x28,0x76,0x2e,0x79,0x3c,0x3c,0x28,0x6e,0x29,0x29,0x7c,0x28,0x76,
0x2e,0x78,0x3e,0x3e,0x28,0x33,0x32,0x2d,0x6e,0x29,0x29,0x29,0x3b,0x0a,0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x78,0x3d,0x28,0x28,0x76,0x2e,0x78,0x3c,0x3c,0x28,0x6e,
0x29,0x29,0x7c,0x28,0x76,0x2e,0x79,0x3e,0x3e,0x28,0x33,0x32,0x2d,0x6e,0x29,0x29,0x29,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x0a,0x7b,0x0a,0x72,0x65,0x73,0x75,
0x6c,0x74,0x2e,0x79,0x3d,0x28,0x28,0x76,0x2e,0x78,0x3c,0x3c,0x28,0x6e,0x2d,0x33,0x32,0x29,0x29,0x7c,0x28,0x76,0x2e,0x79,0x3e,0x3e,0x28,0x36,0x34,0x2d,0x6e,0x29,
0x29,0x29,0x3b,0x0a,0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x78,0x3d,0x28,0x28,0x76,0x2e,0x79,0x3c,0x3c,0x28,0x6e,0x2d,0x33,0x32,0x29,0x29,0x7c,0x28,0x76,0x2e,0x78,
0x3e,0x3e,0x28,0x36,0x34,0x2d,0x6e,0x29,0x29,0x29,0x3b,0x0a,0x7d,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x3b,0x0a,0x7d,0x0a,0x23,
0x65,0x6e,0x64,0x69,0x66,0x0a,0x73,0x74,0x61,0x74,0x69,0x63,0x20,0x76,0x6f,0x69,0x64,0x20,0x63,0x68,0x69,0x28,0x75,0x69,0x6e,0x74,0x32,0x2a,0x20,0x61,0x2c,0x63,
0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6e,0x2c,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x32,0x2a,0x20,0x74,0x29,0x0a,0x7b,0x0a,0x61,0x5b,
0x6e,0x2b,0x30,0x5d,0x3d,0x62,0x69,0x74,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x74,0x5b,0x6e,0x2b,0x30,0x5d,0x5e,0x74,0x5b,0x6e,0x2b,0x32,0x5d,0x2c,0x74,0x5b,0x6e,
0x2b,0x30,0x5d,0x2c,0x74,0x5b,0x6e,0x2b,0x31,0x5d,0x29,0x3b,0x0a,0x61,0x5b,0x6e,0x2b,0x31,0x5d,0x3d,0x62,0x69,0x74,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x74,0x5b,
0x6e,0x2b,0x31,0x5d,0x5e,0x74,0x5b,0x6e,0x2b,0x33,0x5d,0x2c,0x74,0x5b,0x6e,0x2b,0x31,0x5d,0x2c,0x74,0x5b,0x6e,0x2b,0x32,0x5d,0x29,0x3b,0x0a,0x61,0x5b,0x6e,0x2b,
0x32,0x5d,0x3d,0x62,0x69,0x74,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x74,0x5b,0x6e,0x2b,0x32,0x5d,0x5e,0x74,0x5b,0x6e,0x2b,0x34,0x5d,0x2c,0x74,0x5b,0x6e,0x2b,0x32,
0x5d,0x2c,0x74,0x5b,0x6e,0x2b,0x33,0x5d,0x29,0x3b,0x0a,0x61,0x5b,0x6e,0x2b,0x33,0x5d,0x3d,0x62,0x69,0x74,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x74,0x5b,0x6e,0x2b,
0x33,0x5d,0x5e,0x74,0x5b,0x6e,0x2b,0x30,0x5d,0x2c,0x74,0x5b,0x6e,0x2b,0x33,0x5d,0x2c,0x74,0x5b,0x6e,0x2b,0x34,0x5d,0x29,0x3b,0x0a,0x61,0x5b,0x6e,0x2b,0x34,0x5d,
0x3d,0x62,0x69,0x74,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x74,0x5b,0x6e,0x2b,0x34,0x5d,0x5e,0x74,0x5b,0x6e,0x2b,0x31,0x5d,0x2c,0x74,0x5b,0x6e,0x2b,0x34,0x5d,0x2c,
0x74,0x5b,0x6e,0x2b,0x30,0x5d,0x29,0x3b,0x0a,0x7d,0x0a,0x73,0x74,0x61,0x74,0x69,0x63,0x20,0x76,0x6f,0x69,0x64,0x20,0x6b,0x65,0x63,0x63,0x61,0x6b,0x5f,0x66,0x31,
0x36,0x30,0x30,0x5f,0x72,0x6f,0x75,0x6e,0x64,0x28,0x75,0x69,0x6e,0x74,0x32,0x2a,0x20,0x61,0x2c,0x75,0x69,0x6e,0x74,0x20,0x72,0x29,0x0a,0x7b,0x0a,0x75,0x69,0x6e,
0x74,0x32,0x20,0x74,0x5b,0x32,0x35,0x5d,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x32,0x20,0x75,0x3b,0x0a,0x74,0x5b,0x30,0x5d,0x3d,0x61,0x5b,0x30,0x5d,0x5e,0x61,0x5b,0x35,
0x5d,0x5e,0x61,0x5b,0x31,0x30,0x5d,0x5e,0x61,0x5b,0x31,0x35,0x5d,0x5e,0x61,0x5b,0x32,0x30,0x5d,0x3b,0x0a,0x74,0x5b,0x31,0x5d,0x3d,0x61,0x5b,0x31,0x5d,0x5e,0x61,
0x5b,0x36,0x5d,0x5e,0x61,0x5b,0x31,0x31,0x5d,0x5e,0x61,0x5b,0x31,0x36,0x5d,0x5e,0x61,0x5b,0x32,0x31,0x5d,0x3b,0x0a,0x74,0x5b,0x32,0x5d,0x3d,0x61,0x5b,0x32,0x5d,
0x5e,0x61,0x5b,0x37,0x5d,0x5e,0x61,0x5b,0x31,0x32,0x5d,0x5e,0x61,0x5b,0x31,0x37,0x5d,0x5e,0x61,0x5b,0x32,0x32,0x5d,0x3b,0x0a,0x74,0x5b,0x33,0x5d,0x3d,0x61,0x5b,
0x33,0x5d,0x5e,0x61,0x5b,0x38,0x5d,0x5e,0x61,0x5b,0x31,0x33,0x5d,0x5e,0x61,0x5b,0x31,0x38,0x5d,0x5e,0x61,0x5b,0x32,0x33,0x5d,0x3b,0x0a,0x74,0x5b,0x34,0x5d,0x3d,
0x61,0x5b,0x34,0x5d,0x5e,0x61,0x5b,0x39,0x5d,0x5e,0x61,0x5b,0x31,0x34,0x5d,0x5e,0x61,0x5b,0x31,0x39,0x5d,0x5e,0x61,0x5b,0x32,0x34,0x5d,0x3b,0x0a,0x75,0x3d,0x74,
0x5b,0x34,0x5d,0x5e,0x52,0x4f,0x4c,0x32,0x28,0x74,0x5b,0x31,0x5d,0x2c,0x31,0x29,0x3b,0x0a,0x61,0x5b,0x30,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x35,
0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x31,0x30,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x31,0x35,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,
0x61,0x5b,0x32,0x30,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x75,0x3d,0x74,0x5b,0x30,0x5d,0x5e,0x52,0x4f,0x4c,0x32,0x28,0x74,0x5b,0x32,0x5d,0x2c,0x31,0x29,0x3b,
0x0a,0x61,0x5b,0x31,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x36,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x31,0x31,0x5d,0x20,0x5e,0x3d,0x20,
0x75,0x3b,0x0a,0x61,0x5b,0x31,0x36,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x32,0x31,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x75,0x3d,0x74,0x5b,0x31,
0x5d,0x5e,0x52,0x4f,0x4c,0x32,0x28,0x74,0x5b,0x33,0x5d,0x2c,0x31,0x29,0x3b,0x0a,0x61,0x5b,0x32,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x37,0x5d,0x20,
0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x31,0x32,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x31,0x37,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,
0x32,0x32,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x75,0x3d,0x74,0x5b,0x32,0x5d,0x5e,0x52,0x4f,0x4c,0x32,0x28,0x74,0x5b,0x34,0x5d,0x2c,0x31,0x29,0x3b,0x0a,0x61,
0x5b,0x33,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x38,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x31,0x33,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,
0x0a,0x61,0x5b,0x31,0x38,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x32,0x33,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x75,0x3d,0x74,0x5b,0x33,0x5d,0x5e,
0x52,0x4f,0x4c,0x32,0x28,0x74,0x5b,0x30,0x5d,0x2c,0x31,0x29,0x3b,0x0a,0x61,0x5b,0x34,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x39,0x5d,0x20,0x5e,0x3d,
0x20,0x75,0x3b,0x0a,0x61,0x5b,0x31,0x34,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x31,0x39,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x32,0x34,
0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x74,0x5b,0x30,0x5d,0x3d,0x61,0x5b,0x30,0x5d,0x3b,0x0a,0x74,0x5b,0x31,0x30,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,
0x31,0x5d,0x2c,0x31,0x29,0x3b,0x0a,0x74,0x5b,0x32,0x30,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x32,0x5d,0x2c,0x36,0x32,0x29,0x3b,0x0a,0x74,0x5b,0x35,0x5d,
0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x33,0x5d,0x2c,0x32,0x38,0x29,0x3b,0x0a,0x74,0x5b,0x31,0x35,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x34,0x5d,0x2c,
0x32,0x37,0x29,0x3b,0x0a,0x74,0x5b,0x31,0x36,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x35,0x5d,0x2c,0x33,0x36,0x29,0x3b,0x0a,0x74,0x5b,0x31,0x5d,0x3d,0x52,
0x4f,0x4c,0x32,0x28,0x61,0x5b,0x36,0x5d,0x2c,0x34,0x34,0x29,0x3b,0x0a,0x74,0x5b,0x31,0x31,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x37,0x5d,0x2c,0x36,0x29,
0x3b,0x0a,0x74,0x5b,0x32,0x31,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x38,0x5d,0x2c,0x35,0x35,0x29,0x3b,0x0a,0x74,0x5b,0x36,0x5d,0x3d,0x52,0x4f,0x4c,0x32,
0x28,0x61,0x5b,0x39,0x5d,0x2c,0x32,0x30,0x29,0x3b,0x0a,0x74,0x5b,0x37,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x31,0x30,0x5d,0x2c,0x33,0x29,0x3b,0x0a,0x74,
0x5b,0x31,0x37,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x31,0x31,0x5d,0x2c,0x31,0x30,0x29,0x3b,0x0a,0x74,0x5b,0x32,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,
0x5b,0x31,0x32,0x5d,0x2c,0x34,0x33,0x29,0x3b,0x0a,0x74,0x5b,0x31,0x32,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x31,0x33,0x5d,0x2c,0x32,0x35,0x29,0x3b,0x0a,
0x74,0x5b,0x32,0x32,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x31,0x34,0x5d,0x2c,0x33,0x39,0x29,0x3b,0x0a,0x74,0x5b,0x32,0x33,0x5d,0x3d,0x52,0x4f,0x4c,0x32,
0x28,0x61,0x5b,0x31,0x35,0x5d,0x2c,0x34,0x31,0x29,0x3b,0x0a,0x74,0x5b,0x38,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x31,0x36,0x5d,0x2c,0x34,0x35,0x29,0x3b,
0x0a,0x74,0x5b,0x31,0x38,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x31,0x37,0x5d,0x2c,0x31,0x35,0x29,0x3b,0x0a,0x74,0x5b,0x33,0x5d,0x3d,0x52,0x4f,0x4c,0x32,
0x28,0x61,0x5b,0x31,0x38,0x5d,0x2c,0x32,0x31,0x29,0x3b,0x0a,0x74,0x5b,0x31,0x33,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x31,0x39,0x5d,0x2c,0x38,0x29,0x3b,
0x0a,0x74,0x5b,0x31,0x34,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x32,0x30,0x5d,0x2c,0x31,0x38,0x29,0x3b,0x0a,0x74,0x5b,0x32,0x34,0x5d,0x3d,0x52,0x4f,0x4c,
0x32,0x28,0x61,0x5b,0x32,0x31,0x5d,0x2c,0x32,0x29,0x3b,0x0a,0x74,0x5b,0x39,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x32,0x32,0x5d,0x2c,0x36,0x31,0x29,0x3b,
0x0a,0x74,0x5b,0x31,0x39,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x32,0x33,0x5d,0x2c,0x35,0x36,0x29,0x3b,0x0a,0x74,0x5b,0x34,0x5d,0x3d,0x52,0x4f,0x4c,0x32,
0x28,0x61,0x5b,0x32,0x34,0x5d,0x2c,0x31,0x34,0x29,0x3b,0x0a,0x63,0x68,0x69,0x28,0x61,0x2c,0x30,0x2c,0x74,0x29,0x3b,0x0a,0x61,0x5b,0x30,0x5d,0x20,0x5e,0x3d,0x20,
0x4b,0x65,0x63,0x63,0x61,0x6b,0x5f,0x66,0x31,0x36,0x30,0x30,0x5f,0x52,0x43,0x5b,0x72,0x5d,0x3b,0x0a,0x63,0x68,0x69,0x28,0x61,0x2c,0x35,0x2c,0x74,0x29,0x3b,0x0a,
0x63,0x68,0x69,0x28,0x61,0x2c,0x31,0x30,0x2c,0x74,0x29,0x3b,0x0a,0x63,0x68,0x69,0x28,0x61,0x2c,0x31,0x35,0x2c,0x74,0x29,0x3b,0x0a,0x63,0x68,0x69,0x28,0x61,0x2c,
0x32,0x30,0x2c,0x74,0x29,0x3b,0x0a,0x7d,0x0a,0x73,0x74,0x61,0x74,0x69,0x63,0x20,0x76,0x6f,0x69,0x64,0x20,0x6b,0x65,0x63,0x63,0x61,0x6b,0x5f,0x66,0x31,0x36,0x30,
0x30,0x5f,0x6e,0x6f,0x5f,0x61,0x62,0x73,0x6f,0x72,0x62,0x28,0x75,0x69,0x6e,0x74,0x32,0x2a,0x20,0x61,0x2c,0x75,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x73,0x69,
0x7a,0x65,0x2c,0x75,0x69,0x6e,0x74,0x20,0x69,0x73,0x6f,0x6c,0x61,0x74,0x65,0x29,0x0a,0x7b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x20,0x72,0x3d,0x30,
0x3b,0x20,0x72,0x3c,0x32,0x34,0x3b,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x69,0x73,0x6f,0x6c,0x61,0x74,0x65,0x29,0x0a,0x7b,0x0a,0x6b,0x65,0x63,0x63,0x61,0x6b,0x5f,
0x66,0x31,0x36,0x30,0x30,0x5f,0x72,0x6f,0x75,0x6e,0x64,0x28,0x61,0x2c,0x72,0x2b,0x2b,0x29,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x7d,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,
0x65,0x20,0x63,0x6f,0x70,0x79,0x28,0x64,0x73,0x74,0x2c,0x20,0x73,0x72,0x63,0x2c,0x20,0x63,0x6f,0x75,0x6e,0x74,0x29,0x20,0x5c,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,
0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x21,0x3d,0x63,0x6f,0x75,0x6e,0x74,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x20,0x5c,0x0a,0x7b,0x20,0x5c,0x0a,0x28,0x64,
0x73,0x74,0x29,0x5b,0x69,0x5d,0x3d,0x28,0x73,0x72,0x63,0x29,0x5b,0x69,0x5d,0x3b,0x20,0x5c,0x0a,0x7d,0x0a,0x73,0x74,0x61,0x74,0x69,0x63,0x20,0x75,0x69,0x6e,0x74,
0x20,0x66,0x6e,0x76,0x28,0x75,0x69,0x6e,0x74,0x20,0x78,0x2c,0x75,0x69,0x6e,0x74,0x20,0x79,0x29,0x0a,0x7b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x78,0x2a,0x46,
0x4e,0x56,0x5f,0x50,0x52,0x49,0x4d,0x45,0x5e,0x79,0x3b,0x0a,0x7d,0x0a,0x73,0x74,0x61,0x74,0x69,0x63,0x20,0x75,0x69,0x6e,0x74,0x34,0x20,0x66,0x6e,0x76,0x34,0x28,
0x75,0x69,0x6e,0x74,0x34,0x20,0x78,0x2c,0x75,0x69,0x6e,0x74,0x34,0x20,0x79,0x29,0x0a,0x7b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x78,0x2a,0x46,0x4e,0x56,0x5f,
0x50,0x52,0x49,0x4d,0x45,0x5e,0x79,0x3b,0x0a,0x7d,0x0a,0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x75,0x6e,0x69,0x6f,0x6e,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x20,
0x77,0x6f,0x72,0x64,0x73,0x5b,0x36,0x34,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x29,0x5d,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x32,0x20,0x75,0x69,
0x6e,0x74,0x32,0x73,0x5b,0x36,0x34,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x5d,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x34,0x20,0x75,0x69,
0x6e,0x74,0x34,0x73,0x5b,0x36,0x34,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x34,0x29,0x5d,0x3b,0x0a,0x7d,0x20,0x68,0x61,0x73,0x68,0x36,0x34,
0x5f,0x74,0x3b,0x0a,0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x75,0x6e,0x69,0x6f,0x6e,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x20,0x77,0x6f,0x72,0x64,0x73,0x5b,0x32,
0x30,0x30,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x29,0x5d,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x32,0x20,0x75,0x69,0x6e,0x74,0x32,0x73,0x5b,0x32,
0x30,0x30,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x5d,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x34,0x20,0x75,0x69,0x6e,0x74,0x34,0x73,0x5b,
0x32,0x30,0x30,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x34,0x29,0x5d,0x3b,0x0a,0x7d,0x20,0x68,0x61,0x73,0x68,0x32,0x30,0x30,0x5f,0x74,0x3b,
0x0a,0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x73,0x74,0x72,0x75,0x63,0x74,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x34,0x20,0x75,0x69,0x6e,0x74,0x34,0x73,0x5b,0x31,
0x32,0x38,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x34,0x29,0x5d,0x3b,0x0a,0x7d,0x20,0x68,0x61,0x73,0x68,0x31,0x32,0x38,0x5f,0x74,0x3b,0x0a,
0x73,0x74,0x61,0x74,0x69,0x63,0x20,0x76,0x6f,0x69,0x64,0x20,0x53,0x48,0x41,0x33,0x5f,0x35,0x31,0x32,0x28,0x75,0x69,0x6e,0x74,0x32,0x2a,0x20,0x73,0x2c,0x75,0x69,
0x6e,0x74,0x20,0x69,0x73,0x6f,0x6c,0x61,0x74,0x65,0x29,0x0a,0x7b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x20,0x69,0x3d,0x38,0x3b,0x20,0x69,0x21,0x3d,
0x32,0x35,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x0a,0x7b,0x0a,0x73,0x5b,0x69,0x5d,0x3d,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x7b,0x30,0x2c,0x30,0x7d,0x3b,0x0a,0x7d,0x0a,
0x73,0x5b,0x38,0x5d,0x2e,0x78,0x3d,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x3b,0x0a,0x73,0x5b,0x38,0x5d,0x2e,0x79,0x3d,0x30,0x78,0x38,0x30,0x30,0x30,
0x30,0x30,0x30,0x30,0x3b,0x0a,0x6b,0x65,0x63,0x63,0x61,0x6b,0x5f,0x66,0x31,0x36,0x30,0x30,0x5f,0x6e,0x6f,0x5f,0x61,0x62,0x73,0x6f,0x72,0x62,0x28,0x73,0x2c,0x38,
0x2c,0x69,0x73,0x6f,0x6c,0x61,0x74,0x65,0x29,0x3b,0x0a,0x7d,0x0a,0x73,0x74,0x61,0x74,0x69,0x63,0x20,0x75,0x69,0x6e,0x74,0x20,0x66,0x61,0x73,0x74,0x5f,0x6d,0x6f,
0x64,0x28,0x75,0x69,0x6e,0x74,0x20,0x61,0x2c,0x75,0x69,0x6e,0x74,0x34,0x20,0x64,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x6c,0x6f,0x6e,0x67,0x20,
0x74,0x3d,0x61,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x71,0x3d,0x28,0x28,0x74,0x2b,0x64,0x2e,0x79,0x29,0x2a,0x64,0x2e,0x78,0x29,0x3e,
0x3e,0x64,0x2e,0x7a,0x3b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x61,0x2d,0x71,0x2a,0x64,0x2e,0x77,0x3b,0x0a,0x7d,0x0a,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,
0x20,0x76,0x6f,0x69,0x64,0x20,0x65,0x74,0x68,0x61,0x73,0x68,0x5f,0x63,0x61,0x6c,0x63,0x75,0x6c,0x61,0x74,0x65,0x5f,0x64,0x61,0x67,0x5f,0x69,0x74,0x65,0x6d,0x28,
0x75,0x69,0x6e,0x74,0x20,0x73,0x74,0x61,0x72,0x74,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x68,0x61,0x73,0x68,0x36,0x34,0x5f,0x74,0x20,0x63,0x6f,0x6e,
0x73,0x74,0x2a,0x20,0x67,0x5f,0x6c,0x69,0x67,0x68,0x74,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x68,0x61,0x73,0x68,0x36,0x34,0x5f,0x74,0x2a,0x20,0x67,
0x5f,0x64,0x61,0x67,0x2c,0x75,0x69,0x6e,0x74,0x20,0x69,0x73,0x6f,0x6c,0x61,0x74,0x65,0x2c,0x75,0x69,0x6e,0x74,0x20,0x64,0x61,0x67,0x5f,0x77,0x6f,0x72,0x64,0x73,
0x2c,0x75,0x69,0x6e,0x74,0x34,0x20,0x6c,0x69,0x67,0x68,0x74,0x5f,0x77,0x6f,0x72,0x64,0x73,0x29,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x20,0x63,0x6f,0x6e,0x73,0x74,
0x20,0x6e,0x6f,0x64,0x65,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3d,0x73,0x74,0x61,0x72,0x74,0x2b,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,
0x30,0x29,0x3b,0x0a,0x69,0x66,0x28,0x6e,0x6f,0x64,0x65,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3e,0x3d,0x64,0x61,0x67,0x5f,0x77,0x6f,0x72,0x64,0x73,0x29,0x0a,0x72,0x65,
0x74,0x75,0x72,0x6e,0x3b,0x0a,0x68,0x61,0x73,0x68,0x32,0x30,0x30,0x5f,0x74,0x20,0x64,0x61,0x67,0x5f,0x6e,0x6f,0x64,0x65,0x3b,0x0a,0x63,0x6f,0x70,0x79,0x28,0x64,
0x61,0x67,0x5f,0x6e,0x6f,0x64,0x65,0x2e,0x75,0x69,0x6e,0x74,0x34,0x73,0x2c,0x67,0x5f,0x6c,0x69,0x67,0x68,0x74,0x5b,0x66,0x61,0x73,0x74,0x5f,0x6d,0x6f,0x64,0x28,
0x6e,0x6f,0x64,0x65,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2c,0x6c,0x69,0x67,0x68,0x74,0x5f,0x77,0x6f,0x72,0x64,0x73,0x29,0x5d,0x2e,0x75,0x69,0x6e,0x74,0x34,0x73,0x2c,
0x34,0x29,0x3b,0x0a,0x64,0x61,0x67,0x5f,0x6e,0x6f,0x64,0x65,0x2e,0x77,0x6f,0x72,0x64,0x73,0x5b,0x30,0x5d,0x20,0x5e,0x3d,0x20,0x6e,0x6f,0x64,0x65,0x5f,0x69,0x6e,
0x64,0x65,0x78,0x3b,0x0a,0x53,0x48,0x41,0x33,0x5f,0x35,0x31,0x32,0x28,0x64,0x61,0x67,0x5f,0x6e,0x6f,0x64,0x65,0x2e,0x75,0x69,0x6e,0x74,0x32,0x73,0x2c,0x69,0x73,
0x6f,0x6c,0x61,0x74,0x65,0x29,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x21,0x3d,0x45,0x54,0x48,0x41,0x53,0x48,
0x5f,0x44,0x41,0x54,0x41,0x53,0x45,0x54,0x5f,0x50,0x41,0x52,0x45,0x4e,0x54,0x53,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x20,0x70,0x61,
0x72,0x65,0x6e,0x74,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3d,0x66,0x61,0x73,0x74,0x5f,0x6d,0x6f,0x64,0x28,0x66,0x6e,0x76,0x28,0x6e,0x6f,0x64,0x65,0x5f,0x69,0x6e,0x64,
0x65,0x78,0x5e,0x69,0x2c,0x64,0x61,0x67,0x5f,0x6e,0x6f,0x64,0x65,0x2e,0x77,0x6f,0x72,0x64,0x73,0x5b,0x69,0x20,0x25,0x20,0x4e,0x4f,0x44,0x45,0x5f,0x57,0x4f,0x52,
0x44,0x53,0x5d,0x29,0x2c,0x6c,0x69,0x67,0x68,0x74,0x5f,0x77,0x6f,0x72,0x64,0x73,0x29,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x20,0x77,0x3d,0x30,
0x3b,0x20,0x77,0x21,0x3d,0x34,0x3b,0x20,0x2b,0x2b,0x77,0x29,0x0a,0x64,0x61,0x67,0x5f,0x6e,0x6f,0x64,0x65,0x2e,0x75,0x69,0x6e,0x74,0x34,0x73,0x5b,0x77,0x5d,0x3d,
0x66,0x6e,0x76,0x34,0x28,0x64,0x61,0x67,0x5f,0x6e,0x6f,0x64,0x65,0x2e,0x75,0x69,0x6e,0x74,0x34,0x73,0x5b,0x77,0x5d,0x2c,0x67,0x5f,0x6c,0x69,0x67,0x68,0x74,0x5b,
0x70,0x61,0x72,0x65,0x6e,0x74,0x5f,0x69,0x6e,0x64,0x65,0x78,0x5d,0x2e,0x75,0x69,0x6e,0x74,0x34,0x73,0x5b,0x77,0x5d,0x29,0x3b,0x0a,0x7d,0x0a,0x53,0x48,0x41,0x33,
0x5f,0x35,0x31,0x32,0x28,0x64,0x61,0x67,0x5f,0x6e,0x6f,0x64,0x65,0x2e,0x75,0x69,0x6e,0x74,0x32,0x73,0x2c,0x69,0x73,0x6f,0x6c,0x61,0x74,0x65,0x29,0x3b,0x0a,0x63,
0x6f,0x70,0x79,0x28,0x67,0x5f,0x64,0x61,0x67,0x5b,0x6e,0x6f,0x64,0x65,0x5f,0x69,0x6e,0x64,0x65,0x78,0x5d,0x2e,0x75,0x69,0x6e,0x74,0x34,0x73,0x2c,0x64,0x61,0x67,
0x5f,0x6e,0x6f,0x64,0x65,0x2e,0x75,0x69,0x6e,0x74,0x34,0x73,0x2c,0x34,0x29,0x3b,0x0a,0x7d,0x0a,0x00
};
} // namespace xmrig

File diff suppressed because it is too large Load Diff

View File

@@ -88,7 +88,8 @@ static inline uint32_t getIntensity(const OclDevice &device, const Algorithm &al
static inline uint32_t getWorksize(const Algorithm &algorithm)
{
if (algorithm.family() == Algorithm::CN_PICO) {
Algorithm::Family f = algorithm.family();
if (f == Algorithm::CN_PICO || f == Algorithm::CN_FEMTO) {
return 64;
}

View File

@@ -39,10 +39,12 @@
xmrig::OclCnRunner::OclCnRunner(size_t index, const OclLaunchData &data) : OclBaseRunner(index, data)
{
uint32_t stridedIndex = data.thread.stridedIndex();
Algorithm::Family f = m_algorithm.family();
if (data.device.vendorId() == OCL_VENDOR_NVIDIA) {
stridedIndex = 0;
}
else if (stridedIndex == 1 && (m_algorithm.family() == Algorithm::CN_PICO || (m_algorithm.family() == Algorithm::CN && CnAlgo<>::base(m_algorithm) == Algorithm::CN_2))) {
else if (stridedIndex == 1 && (f == Algorithm::CN_PICO || f == Algorithm::CN_FEMTO || (f == Algorithm::CN && CnAlgo<>::base(m_algorithm) == Algorithm::CN_2))) {
stridedIndex = 2;
}

View File

@@ -24,6 +24,7 @@
#include "backend/opencl/wrappers/OclDevice.h"
#include <limits.h>
#include <dirent.h>
#include <fstream>
#include <map>

View File

@@ -1,6 +1,6 @@
/* XMRig
* Copyright 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,7 +21,6 @@
#include "base/api/Api.h"
#include "3rdparty/http-parser/http_parser.h"
#include "base/api/interfaces/IApiListener.h"
#include "base/api/requests/HttpApiRequest.h"
#include "base/crypto/keccak.h"
@@ -186,7 +185,7 @@ void xmrig::Api::exec(IApiRequest &request)
}
}
request.done(request.isNew() ? HTTP_STATUS_NOT_FOUND : HTTP_STATUS_OK);
request.done(request.isNew() ? 404 : 200);
}

View File

@@ -1,6 +1,6 @@
/* XMRig
* Copyright 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@@ -1,12 +1,6 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,9 +16,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "base/api/Httpd.h"
#include "3rdparty/http-parser/http_parser.h"
#include "3rdparty/llhttp/llhttp.h"
#include "base/api/Api.h"
#include "base/io/log/Log.h"
#include "base/net/http/HttpApiResponse.h"
@@ -155,25 +148,25 @@ void xmrig::Httpd::onHttpData(const HttpData &data)
}
# endif
return HttpResponse(data.id(), HTTP_STATUS_NOT_FOUND).end();
return HttpResponse(data.id(), 404 /* NOT_FOUND */).end();
}
if (data.method > 4) {
return HttpApiResponse(data.id(), HTTP_STATUS_METHOD_NOT_ALLOWED).end();
return HttpApiResponse(data.id(), 405 /* METHOD_NOT_ALLOWED */).end();
}
const int status = auth(data);
if (status != HTTP_STATUS_OK) {
if (status != 200) {
return HttpApiResponse(data.id(), status).end();
}
if (data.method != HTTP_GET) {
if (m_base->config()->http().isRestricted()) {
return HttpApiResponse(data.id(), HTTP_STATUS_FORBIDDEN).end();
return HttpApiResponse(data.id(), 403 /* FORBIDDEN */).end();
}
if (!data.headers.count(HttpData::kContentTypeL) || data.headers.at(HttpData::kContentTypeL) != HttpData::kApplicationJson) {
return HttpApiResponse(data.id(), HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE).end();
return HttpApiResponse(data.id(), 415 /* UNSUPPORTED_MEDIA_TYPE */).end();
}
}
@@ -186,19 +179,19 @@ int xmrig::Httpd::auth(const HttpData &req) const
const Http &config = m_base->config()->http();
if (!req.headers.count(kAuthorization)) {
return config.isAuthRequired() ? HTTP_STATUS_UNAUTHORIZED : HTTP_STATUS_OK;
return config.isAuthRequired() ? 401 /* UNAUTHORIZED */ : 200;
}
if (config.token().isNull()) {
return HTTP_STATUS_UNAUTHORIZED;
return 401 /* UNAUTHORIZED */;
}
const std::string &token = req.headers.at(kAuthorization);
const size_t size = token.size();
if (token.size() < 8 || config.token().size() != size - 7 || memcmp("Bearer ", token.c_str(), 7) != 0) {
return HTTP_STATUS_FORBIDDEN;
return 403 /* FORBIDDEN */;
}
return strncmp(config.token().data(), token.c_str() + 7, config.token().size()) == 0 ? HTTP_STATUS_OK : HTTP_STATUS_FORBIDDEN;
return strncmp(config.token().data(), token.c_str() + 7, config.token().size()) == 0 ? 200 : 403 /* FORBIDDEN */;
}

View File

@@ -1,12 +1,6 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@@ -1,12 +1,6 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -24,7 +18,7 @@
#include "base/api/requests/HttpApiRequest.h"
#include "3rdparty/http-parser/http_parser.h"
#include "3rdparty/llhttp/llhttp.h"
#include "3rdparty/rapidjson/error/en.h"
#include "base/io/json/Json.h"
#include "base/net/http/HttpData.h"
@@ -53,8 +47,8 @@ static inline const char *rpcError(int code) {
return "Invalid params";
}
if (code >= HTTP_STATUS_BAD_REQUEST && code <= HTTP_STATUS_NETWORK_AUTHENTICATION_REQUIRED) {
return http_status_str(static_cast<http_status>(code));
if (code >= 400 && code < 600) {
return HttpData::statusName(code);
}
return "Internal error";
@@ -155,10 +149,10 @@ void xmrig::HttpApiRequest::done(int status)
using namespace rapidjson;
auto &allocator = doc().GetAllocator();
m_res.setStatus(HTTP_STATUS_OK);
m_res.setStatus(200);
if (status != HTTP_STATUS_OK) {
setRpcError(status == HTTP_STATUS_NOT_FOUND ? RPC_METHOD_NOT_FOUND : status);
if (status != 200) {
setRpcError(status == 404 /* NOT_FOUND */ ? RPC_METHOD_NOT_FOUND : status);
}
else if (!reply().HasMember(kResult)) {
Value result(kObjectType);
@@ -205,6 +199,6 @@ void xmrig::HttpApiRequest::rpcDone(const char *key, rapidjson::Value &value)
reply().AddMember("jsonrpc", "2.0", allocator);
reply().AddMember(StringRef(kId), Value().CopyFrom(Json::getValue(m_body, kId), allocator), allocator);
m_res.setStatus(HTTP_STATUS_OK);
m_res.setStatus(200);
m_res.end();
}

View File

@@ -1,12 +1,6 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@@ -32,6 +32,7 @@ set(HEADERS_BASE
src/base/kernel/interfaces/IConfigListener.h
src/base/kernel/interfaces/IConfigTransform.h
src/base/kernel/interfaces/IConsoleListener.h
src/base/kernel/interfaces/IDnsBackend.h
src/base/kernel/interfaces/IDnsListener.h
src/base/kernel/interfaces/ILineListener.h
src/base/kernel/interfaces/ILogBackend.h
@@ -43,7 +44,11 @@ set(HEADERS_BASE
src/base/kernel/Platform.h
src/base/kernel/Process.h
src/base/net/dns/Dns.h
src/base/net/dns/DnsConfig.h
src/base/net/dns/DnsRecord.h
src/base/net/dns/DnsRecords.h
src/base/net/dns/DnsRequest.h
src/base/net/dns/DnsUvBackend.h
src/base/net/http/Http.h
src/base/net/http/HttpListener.h
src/base/net/stratum/BaseClient.h
@@ -71,6 +76,12 @@ set(HEADERS_BASE
src/base/tools/Handle.h
src/base/tools/String.h
src/base/tools/Timer.h
src/base/tools/cryptonote/BlobReader.h
src/base/tools/cryptonote/BlockTemplate.h
src/base/tools/cryptonote/Signatures.h
src/base/tools/cryptonote/WalletAddress.h
src/base/tools/cryptonote/crypto-ops.h
src/base/tools/cryptonote/umul128.h
)
set(SOURCES_BASE
@@ -99,7 +110,10 @@ set(SOURCES_BASE
src/base/kernel/Platform.cpp
src/base/kernel/Process.cpp
src/base/net/dns/Dns.cpp
src/base/net/dns/DnsConfig.cpp
src/base/net/dns/DnsRecord.cpp
src/base/net/dns/DnsRecords.cpp
src/base/net/dns/DnsUvBackend.cpp
src/base/net/http/Http.cpp
src/base/net/stratum/BaseClient.cpp
src/base/net/stratum/Client.cpp
@@ -118,6 +132,11 @@ set(SOURCES_BASE
src/base/tools/Cvt.cpp
src/base/tools/String.cpp
src/base/tools/Timer.cpp
src/base/tools/cryptonote/BlockTemplate.cpp
src/base/tools/cryptonote/Signatures.cpp
src/base/tools/cryptonote/WalletAddress.cpp
src/base/tools/cryptonote/crypto-ops.c
src/base/tools/cryptonote/crypto-ops-data.c
)
@@ -160,7 +179,7 @@ endif()
if (WITH_HTTP)
set(HEADERS_BASE_HTTP
src/3rdparty/http-parser/http_parser.h
src/3rdparty/llhttp/llhttp.h
src/base/api/Api.h
src/base/api/Httpd.h
src/base/api/interfaces/IApiRequest.h
@@ -181,7 +200,9 @@ if (WITH_HTTP)
)
set(SOURCES_BASE_HTTP
src/3rdparty/http-parser/http_parser.c
src/3rdparty/llhttp/llhttp.c
src/3rdparty/llhttp/api.c
src/3rdparty/llhttp/http.c
src/base/api/Api.cpp
src/base/api/Httpd.cpp
src/base/api/requests/ApiRequest.cpp

View File

@@ -6,8 +6,8 @@
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -117,6 +117,7 @@ static AlgoName const algorithm_names[] = {
{ "chukwa", nullptr, Algorithm::AR2_CHUKWA },
{ "argon2/chukwav2", nullptr, Algorithm::AR2_CHUKWA_V2 },
{ "chukwav2", nullptr, Algorithm::AR2_CHUKWA_V2 },
{ "argon2/ninja", nullptr, Algorithm::AR2_WRKZ },
{ "argon2/wrkz", nullptr, Algorithm::AR2_WRKZ },
# endif
# ifdef XMRIG_ALGO_ASTROBWT
@@ -129,6 +130,11 @@ static AlgoName const algorithm_names[] = {
# endif
{ "cryptonight/ccx", "cn/ccx", Algorithm::CN_CCX },
{ "cryptonight/conceal", "cn/conceal", Algorithm::CN_CCX },
# ifdef XMRIG_ALGO_CN_FEMTO
{ "cryptonight/upx2", "cn/upx2", Algorithm::CN_UPX2 },
{ "cn-extremelite/upx2", nullptr, Algorithm::CN_UPX2 },
{ "cryptonight-upx/2", nullptr, Algorithm::CN_UPX2 },
# endif
};
@@ -199,6 +205,9 @@ size_t xmrig::Algorithm::l3() const
case CN_PICO:
return oneMiB / 4;
case CN_FEMTO:
return oneMiB / 8;
default:
break;
}
@@ -329,6 +338,11 @@ xmrig::Algorithm::Family xmrig::Algorithm::family(Id id)
return CN_PICO;
# endif
# ifdef XMRIG_ALGO_CN_FEMTO
case CN_UPX2:
return CN_FEMTO;
# endif
# ifdef XMRIG_ALGO_RANDOMX
case RX_0:
case RX_WOW:

View File

@@ -6,8 +6,8 @@
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -64,6 +64,7 @@ public:
CN_PICO_0, // "cn-pico" CryptoNight-Pico
CN_PICO_TLO, // "cn-pico/tlo" CryptoNight-Pico (TLO)
CN_CCX, // "cn/ccx" Conceal (CCX)
CN_UPX2, // "cn/upx2" Uplexa (UPX2)
RX_0, // "rx/0" RandomX (reference configuration).
RX_WOW, // "rx/wow" RandomWOW (Wownero).
RX_ARQ, // "rx/arq" RandomARQ (Arqma).
@@ -83,6 +84,7 @@ public:
CN_LITE,
CN_HEAVY,
CN_PICO,
CN_FEMTO,
RANDOM_X,
ARGON2,
ASTROBWT,
@@ -94,7 +96,7 @@ public:
inline Algorithm(Id id) : m_id(id) {}
Algorithm(const rapidjson::Value &value);
inline bool isCN() const { auto f = family(); return f == CN || f == CN_LITE || f == CN_HEAVY || f == CN_PICO; }
inline bool isCN() const { auto f = family(); return f == CN || f == CN_LITE || f == CN_HEAVY || f == CN_PICO || f == CN_FEMTO; }
inline bool isEqual(const Algorithm &other) const { return m_id == other.m_id; }
inline bool isValid() const { return m_id != INVALID && family() != UNKNOWN; }
inline const char *name() const { return name(false); }

View File

@@ -56,7 +56,8 @@ static CoinName const coin_names[] = {
{ "ravencoin", Coin::RAVEN },
{ "raven", Coin::RAVEN },
{ "rvn", Coin::RAVEN },
{ "conceal", Coin::CONCEAL }
{ "conceal", Coin::CONCEAL },
{ "wownero", Coin::WOWNERO }
};
@@ -85,6 +86,9 @@ xmrig::Algorithm::Id xmrig::Coin::algorithm(uint8_t blobVersion) const
case CONCEAL:
return Algorithm::CN_CCX;
case WOWNERO:
return Algorithm::RX_WOW;
case INVALID:
break;
}

View File

@@ -44,7 +44,8 @@ public:
DERO,
KEVA,
RAVEN,
CONCEAL
CONCEAL,
WOWNERO
};

View File

@@ -1,6 +1,6 @@
/* XMRig
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -37,9 +37,6 @@ static void fsWriteCallback(uv_fs_t *req)
}
static const char *kNewLine = "\n";
} // namespace xmrig
@@ -50,11 +47,24 @@ bool xmrig::FileLogWriter::open(const char *fileName)
return false;
}
uv_fs_t req;
m_file = uv_fs_open(uv_default_loop(), &req, Env::expand(fileName), O_CREAT | O_APPEND | O_WRONLY, 0644, nullptr);
uv_fs_t req{};
const auto path = Env::expand(fileName);
m_file = uv_fs_open(uv_default_loop(), &req, path, O_CREAT | O_WRONLY, 0644, nullptr);
if (req.result < 0 || !isOpen()) {
uv_fs_req_cleanup(&req);
m_file = -1;
return false;
}
uv_fs_req_cleanup(&req);
return isOpen();
uv_fs_stat(uv_default_loop(), &req, path, nullptr);
m_pos = req.statbuf.st_size;
uv_fs_req_cleanup(&req);
return true;
}
@@ -70,7 +80,8 @@ bool xmrig::FileLogWriter::write(const char *data, size_t size)
auto req = new uv_fs_t;
req->data = buf.base;
uv_fs_write(uv_default_loop(), req, m_file, &buf, 1, -1, fsWriteCallback);
uv_fs_write(uv_default_loop(), req, m_file, &buf, 1, m_pos, fsWriteCallback);
m_pos += size;
return true;
}
@@ -78,9 +89,9 @@ bool xmrig::FileLogWriter::write(const char *data, size_t size)
bool xmrig::FileLogWriter::writeLine(const char *data, size_t size)
{
uv_buf_t buf[2] = {
const uv_buf_t buf[2] = {
uv_buf_init(new char[size], size),
uv_buf_init(const_cast<char *>(kNewLine), 1)
uv_buf_init(const_cast<char *>(m_endl), sizeof(m_endl) - 1)
};
memcpy(buf[0].base, data, size);
@@ -88,7 +99,8 @@ bool xmrig::FileLogWriter::writeLine(const char *data, size_t size)
auto req = new uv_fs_t;
req->data = buf[0].base;
uv_fs_write(uv_default_loop(), req, m_file, buf, 2, -1, fsWriteCallback);
uv_fs_write(uv_default_loop(), req, m_file, buf, 2, m_pos, fsWriteCallback);
m_pos += (buf[0].len + buf[1].len);
return true;
}

View File

@@ -1,6 +1,6 @@
/* XMRig
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,6 +21,7 @@
#include <cstddef>
#include <cstdint>
namespace xmrig {
@@ -33,13 +34,21 @@ public:
FileLogWriter(const char *fileName) { open(fileName); }
inline bool isOpen() const { return m_file >= 0; }
inline int64_t pos() const { return m_pos; }
bool open(const char *fileName);
bool write(const char *data, size_t size);
bool writeLine(const char *data, size_t size);
private:
int m_file = -1;
# ifdef XMRIG_OS_WIN
const char m_endl[3] = {'\r', '\n', 0};
# else
const char m_endl[2] = {'\n', 0};
# endif
int m_file = -1;
int64_t m_pos = 0;
};

View File

@@ -1,6 +1,6 @@
/* XMRig
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -37,6 +37,14 @@ const char *xmrig::Tags::network()
}
const char* xmrig::Tags::origin()
{
static const char* tag = YELLOW_BG_BOLD(WHITE_BOLD_S " origin ");
return tag;
}
const char *xmrig::Tags::signal()
{
static const char *tag = YELLOW_BG_BOLD(WHITE_BOLD_S " signal ");

View File

@@ -1,6 +1,6 @@
/* XMRig
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -32,6 +32,7 @@ class Tags
public:
static const char *config();
static const char *network();
static const char *origin();
static const char *signal();
# ifdef XMRIG_MINER_PROJECT

View File

@@ -1,6 +1,6 @@
/* XMRig
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@@ -1,6 +1,6 @@
/* XMRig
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -46,9 +46,11 @@ public:
static void setProcessPriority(int priority);
static void setThreadPriority(int priority);
static inline const String &userAgent() { return m_userAgent; }
static inline bool isUserActive(uint64_t ms) { return idleTime() < ms; }
static inline const String &userAgent() { return m_userAgent; }
static bool isOnBatteryPower();
static uint64_t idleTime();
private:
static char *createUserAgent();

View File

@@ -1,6 +1,6 @@
/* XMRig
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -107,3 +107,18 @@ bool xmrig::Platform::isOnBatteryPower()
{
return IOPSGetTimeRemainingEstimate() != kIOPSTimeRemainingUnlimited;
}
uint64_t xmrig::Platform::idleTime()
{
uint64_t idle_time = 0;
const auto service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOHIDSystem"));
const auto property = IORegistryEntryCreateCFProperty(service, CFSTR("HIDIdleTime"), kCFAllocatorDefault, 0);
CFNumberGetValue((CFNumberRef)property, kCFNumberSInt64Type, &idle_time);
CFRelease(property);
IOObjectRelease(service);
return idle_time / 1000000U;
}

View File

@@ -1,6 +1,6 @@
/* XMRig
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -34,6 +34,7 @@
#include <uv.h>
#include <thread>
#include <fstream>
#include <limits>
#include "base/kernel/Platform.h"
@@ -158,3 +159,9 @@ bool xmrig::Platform::isOnBatteryPower()
}
return false;
}
uint64_t xmrig::Platform::idleTime()
{
return std::numeric_limits<uint64_t>::max();
}

View File

@@ -1,6 +1,6 @@
/* XMRig
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,6 +21,7 @@
#include <winsock2.h>
#include <windows.h>
#include <uv.h>
#include <limits>
#include "base/kernel/Platform.h"
@@ -161,3 +162,16 @@ bool xmrig::Platform::isOnBatteryPower()
}
return false;
}
uint64_t xmrig::Platform::idleTime()
{
LASTINPUTINFO info{};
info.cbSize = sizeof(LASTINPUTINFO);
if (!GetLastInputInfo(&info)) {
return std::numeric_limits<uint64_t>::max();
}
return static_cast<uint64_t>(GetTickCount() - info.dwTime);
}

View File

@@ -1,12 +1,6 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -29,6 +23,7 @@
#include "base/io/log/Log.h"
#include "base/io/log/Tags.h"
#include "base/kernel/interfaces/IJsonReader.h"
#include "base/net/dns/Dns.h"
#include "version.h"
@@ -61,7 +56,6 @@ const char *BaseConfig::kColors = "colors";
const char *BaseConfig::kDryRun = "dry-run";
const char *BaseConfig::kHttp = "http";
const char *BaseConfig::kLogFile = "log-file";
const char *BaseConfig::kPauseOnBattery = "pause-on-battery";
const char *BaseConfig::kPrintTime = "print-time";
const char *BaseConfig::kSyslog = "syslog";
const char *BaseConfig::kTitle = "title";
@@ -91,7 +85,6 @@ bool xmrig::BaseConfig::read(const IJsonReader &reader, const char *fileName)
m_dryRun = reader.getBool(kDryRun, m_dryRun);
m_syslog = reader.getBool(kSyslog, m_syslog);
m_watch = reader.getBool(kWatch, m_watch);
m_pauseOnBattery = reader.getBool(kPauseOnBattery, m_pauseOnBattery);
m_logFile = reader.getString(kLogFile);
m_userAgent = reader.getString(kUserAgent);
m_printTime = std::min(reader.getUint(kPrintTime, m_printTime), 3600U);
@@ -113,6 +106,8 @@ bool xmrig::BaseConfig::read(const IJsonReader &reader, const char *fileName)
m_http.load(reader.getObject(kHttp));
m_pools.load(reader);
Dns::set(reader.getObject(DnsConfig::kField));
return m_pools.active() > 0;
}

View File

@@ -1,12 +1,6 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -55,7 +49,6 @@ public:
static const char *kDryRun;
static const char *kHttp;
static const char *kLogFile;
static const char *kPauseOnBattery;
static const char *kPrintTime;
static const char *kSyslog;
static const char *kTitle;
@@ -72,7 +65,6 @@ public:
inline bool isAutoSave() const { return m_autoSave; }
inline bool isBackground() const { return m_background; }
inline bool isDryRun() const { return m_dryRun; }
inline bool isPauseOnBattery() const { return m_pauseOnBattery; }
inline bool isSyslog() const { return m_syslog; }
inline const char *logFile() const { return m_logFile.data(); }
inline const char *userAgent() const { return m_userAgent.data(); }
@@ -100,7 +92,6 @@ protected:
bool m_autoSave = true;
bool m_background = false;
bool m_dryRun = false;
bool m_pauseOnBattery = false;
bool m_syslog = false;
bool m_upgrade = false;
bool m_watch = true;
@@ -112,7 +103,7 @@ protected:
String m_logFile;
String m_userAgent;
Title m_title;
uint32_t m_printTime = 60;
uint32_t m_printTime = 60;
# ifdef XMRIG_FEATURE_TLS
TlsConfig m_tls;

View File

@@ -1,12 +1,6 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -39,6 +33,7 @@
#include "base/kernel/config/BaseConfig.h"
#include "base/kernel/interfaces/IConfig.h"
#include "base/kernel/Process.h"
#include "base/net/dns/DnsConfig.h"
#include "base/net/stratum/Pool.h"
#include "base/net/stratum/Pools.h"
#include "core/config/Config_platform.h"
@@ -186,6 +181,9 @@ void xmrig::BaseTransform::transform(rapidjson::Document &doc, int key, const ch
case IConfig::PasswordKey: /* --pass */
return add(doc, Pools::kPools, Pool::kPass, arg);
case IConfig::SpendSecretKey: /* --spend-secret-key */
return add(doc, Pools::kPools, Pool::kSpendSecretKey, arg);
case IConfig::RigIdKey: /* --rig-id */
return add(doc, Pools::kPools, Pool::kRigId, arg);
@@ -250,6 +248,7 @@ void xmrig::BaseTransform::transform(rapidjson::Document &doc, int key, const ch
case IConfig::HttpPort: /* --http-port */
case IConfig::DonateLevelKey: /* --donate-level */
case IConfig::DaemonPollKey: /* --daemon-poll-interval */
case IConfig::DnsTtlKey: /* --dns-ttl */
return transformUint64(doc, key, static_cast<uint64_t>(strtol(arg, nullptr, 10)));
case IConfig::BackgroundKey: /* --background */
@@ -260,8 +259,9 @@ void xmrig::BaseTransform::transform(rapidjson::Document &doc, int key, const ch
case IConfig::DryRunKey: /* --dry-run */
case IConfig::HttpEnabledKey: /* --http-enabled */
case IConfig::DaemonKey: /* --daemon */
case IConfig::SubmitToOriginKey: /* --submit-to-origin */
case IConfig::VerboseKey: /* --verbose */
case IConfig::PauseOnBatteryKey: /* --pause-on-battery */
case IConfig::DnsIPv6Key: /* --dns-ipv6 */
return transformBoolean(doc, key, true);
case IConfig::ColorKey: /* --no-color */
@@ -290,6 +290,8 @@ void xmrig::BaseTransform::transformBoolean(rapidjson::Document &doc, int key, b
case IConfig::TlsKey: /* --tls */
return add(doc, Pools::kPools, Pool::kTls, enable);
case IConfig::SubmitToOriginKey: /* --submit-to-origin */
return add(doc, Pools::kPools, Pool::kSubmitToOrigin, enable);
# ifdef XMRIG_FEATURE_HTTP
case IConfig::DaemonKey: /* --daemon */
return add(doc, Pools::kPools, Pool::kDaemon, enable);
@@ -320,8 +322,8 @@ void xmrig::BaseTransform::transformBoolean(rapidjson::Document &doc, int key, b
case IConfig::NoTitleKey: /* --no-title */
return set(doc, BaseConfig::kTitle, enable);
case IConfig::PauseOnBatteryKey: /* --pause-on-battery */
return set(doc, BaseConfig::kPauseOnBattery, enable);
case IConfig::DnsIPv6Key: /* --dns-ipv6 */
return set(doc, DnsConfig::kField, DnsConfig::kIPv6, enable);
default:
break;
@@ -351,6 +353,9 @@ void xmrig::BaseTransform::transformUint64(rapidjson::Document &doc, int key, ui
case IConfig::PrintTimeKey: /* --print-time */
return set(doc, BaseConfig::kPrintTime, arg);
case IConfig::DnsTtlKey: /* --dns-ttl */
return set(doc, DnsConfig::kField, DnsConfig::kTTL, arg);
# ifdef XMRIG_FEATURE_HTTP
case IConfig::DaemonPollKey: /* --daemon-poll-interval */
return add(doc, Pools::kPools, Pool::kDaemonPollInterval, arg);

View File

@@ -1,12 +1,6 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@@ -1,12 +1,6 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -86,6 +80,11 @@ public:
BenchTokenKey = 1048,
DmiKey = 1049,
HugePageSizeKey = 1050,
PauseOnActiveKey = 1051,
SubmitToOriginKey = 1052,
DnsIPv6Key = 1053,
DnsTtlKey = 1054,
SpendSecretKey = 1055,
// xmrig common
CPUPriorityKey = 1021,

View File

@@ -0,0 +1,54 @@
/* XMRig
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_IDNSBACKEND_H
#define XMRIG_IDNSBACKEND_H
#include "base/tools/Object.h"
#include <memory>
namespace xmrig {
class DnsRecords;
class DnsRequest;
class IDnsListener;
class String;
class IDnsBackend
{
public:
XMRIG_DISABLE_COPY_MOVE(IDnsBackend)
IDnsBackend() = default;
virtual ~IDnsBackend() = default;
virtual const DnsRecords &records() const = 0;
virtual std::shared_ptr<DnsRequest> resolve(const String &host, IDnsListener *listener, uint64_t ttl) = 0;
};
} /* namespace xmrig */
#endif // XMRIG_IDNSBACKEND_H

View File

@@ -1,6 +1,6 @@
/* XMRig
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -26,7 +26,7 @@
namespace xmrig {
class Dns;
class DnsRecords;
class IDnsListener
@@ -37,7 +37,7 @@ public:
IDnsListener() = default;
virtual ~IDnsListener() = default;
virtual void onResolved(const Dns &dns, int status) = 0;
virtual void onResolved(const DnsRecords &records, int status, const char *error) = 0;
};

View File

@@ -1,6 +1,6 @@
/* XMRig
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -18,136 +18,24 @@
#include "base/net/dns/Dns.h"
#include "base/kernel/interfaces/IDnsListener.h"
#include "base/net/dns/DnsUvBackend.h"
namespace xmrig {
Storage<Dns> Dns::m_storage;
static const DnsRecord defaultRecord;
}
xmrig::Dns::Dns(IDnsListener *listener) :
m_listener(listener)
DnsConfig Dns::m_config;
std::map<String, std::shared_ptr<IDnsBackend> > Dns::m_backends;
} // namespace xmrig
std::shared_ptr<xmrig::DnsRequest> xmrig::Dns::resolve(const String &host, IDnsListener *listener, uint64_t ttl)
{
m_key = m_storage.add(this);
if (m_backends.find(host) == m_backends.end()) {
m_backends.insert({ host, std::make_shared<DnsUvBackend>() });
}
m_resolver = new uv_getaddrinfo_t;
m_resolver->data = m_storage.ptr(m_key);
m_hints.ai_family = AF_UNSPEC;
m_hints.ai_socktype = SOCK_STREAM;
m_hints.ai_protocol = IPPROTO_TCP;
}
xmrig::Dns::~Dns()
{
m_storage.release(m_key);
delete m_resolver;
}
bool xmrig::Dns::resolve(const String &host)
{
if (m_host != host) {
m_host = host;
clear();
}
m_status = uv_getaddrinfo(uv_default_loop(), m_resolver, Dns::onResolved, m_host.data(), nullptr, &m_hints);
return m_status == 0;
}
const char *xmrig::Dns::error() const
{
return uv_strerror(m_status);
}
const xmrig::DnsRecord &xmrig::Dns::get(DnsRecord::Type prefered) const
{
if (count() == 0) {
return defaultRecord;
}
const size_t ipv4 = m_ipv4.size();
const size_t ipv6 = m_ipv6.size();
if (ipv6 && (prefered == DnsRecord::AAAA || !ipv4)) {
return m_ipv6[ipv6 == 1 ? 0 : static_cast<size_t>(rand()) % ipv6];
}
if (ipv4) {
return m_ipv4[ipv4 == 1 ? 0 : static_cast<size_t>(rand()) % ipv4];
}
return defaultRecord;
}
size_t xmrig::Dns::count(DnsRecord::Type type) const
{
if (type == DnsRecord::A) {
return m_ipv4.size();
}
if (type == DnsRecord::AAAA) {
return m_ipv6.size();
}
return m_ipv4.size() + m_ipv6.size();
}
void xmrig::Dns::clear()
{
m_ipv4.clear();
m_ipv6.clear();
}
void xmrig::Dns::onResolved(int status, addrinfo *res)
{
m_status = status;
if (m_status < 0) {
return m_listener->onResolved(*this, status);
}
clear();
addrinfo *ptr = res;
while (ptr != nullptr) {
if (ptr->ai_family == AF_INET) {
m_ipv4.emplace_back(ptr);
}
if (ptr->ai_family == AF_INET6) {
m_ipv6.emplace_back(ptr);
}
ptr = ptr->ai_next;
}
if (isEmpty()) {
m_status = UV_EAI_NONAME;
}
m_listener->onResolved(*this, m_status);
}
void xmrig::Dns::onResolved(uv_getaddrinfo_t *req, int status, addrinfo *res)
{
Dns *dns = m_storage.get(req->data);
if (dns) {
dns->onResolved(status, res);
}
uv_freeaddrinfo(res);
return m_backends.at(host)->resolve(host, listener, ttl == 0 ? m_config.ttl() : ttl);
}

View File

@@ -1,6 +1,6 @@
/* XMRig
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,55 +20,34 @@
#define XMRIG_DNS_H
#include <vector>
#include <uv.h>
#include "base/net/dns/DnsRecord.h"
#include "base/net/tools/Storage.h"
#include "base/tools/Object.h"
#include "base/net/dns/DnsConfig.h"
#include "base/tools/String.h"
#include <map>
#include <memory>
namespace xmrig {
class DnsConfig;
class DnsRequest;
class IDnsBackend;
class IDnsListener;
class Dns
{
public:
XMRIG_DISABLE_COPY_MOVE_DEFAULT(Dns)
inline static const DnsConfig &config() { return m_config; }
inline static void set(const DnsConfig &config) { m_config = config; }
Dns(IDnsListener *listener);
~Dns();
inline bool isEmpty() const { return m_ipv4.empty() && m_ipv6.empty(); }
inline const String &host() const { return m_host; }
inline int status() const { return m_status; }
bool resolve(const String &host);
const char *error() const;
const DnsRecord &get(DnsRecord::Type prefered = DnsRecord::A) const;
size_t count(DnsRecord::Type type = DnsRecord::Unknown) const;
static std::shared_ptr<DnsRequest> resolve(const String &host, IDnsListener *listener, uint64_t ttl = 0);
private:
void clear();
void onResolved(int status, addrinfo *res);
static void onResolved(uv_getaddrinfo_t *req, int status, addrinfo *res);
addrinfo m_hints{};
IDnsListener *m_listener;
int m_status = 0;
std::vector<DnsRecord> m_ipv4;
std::vector<DnsRecord> m_ipv6;
String m_host;
uintptr_t m_key;
uv_getaddrinfo_t *m_resolver = nullptr;
static Storage<Dns> m_storage;
static DnsConfig m_config;
static std::map<String, std::shared_ptr<IDnsBackend> > m_backends;
};

View File

@@ -0,0 +1,57 @@
/* XMRig
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "base/net/dns/DnsConfig.h"
#include "3rdparty/rapidjson/document.h"
#include "base/io/json/Json.h"
#include <algorithm>
namespace xmrig {
const char *DnsConfig::kField = "dns";
const char *DnsConfig::kIPv6 = "ipv6";
const char *DnsConfig::kTTL = "ttl";
} // namespace xmrig
xmrig::DnsConfig::DnsConfig(const rapidjson::Value &value)
{
m_ipv6 = Json::getBool(value, kIPv6, m_ipv6);
m_ttl = std::max(Json::getUint(value, kTTL, m_ttl), 1U);
}
rapidjson::Value xmrig::DnsConfig::toJSON(rapidjson::Document &doc) const
{
using namespace rapidjson;
auto &allocator = doc.GetAllocator();
Value obj(kObjectType);
obj.AddMember(StringRef(kIPv6), m_ipv6, allocator);
obj.AddMember(StringRef(kTTL), m_ttl, allocator);
return obj;
}

View File

@@ -0,0 +1,54 @@
/* XMRig
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_DNSCONFIG_H
#define XMRIG_DNSCONFIG_H
#include "3rdparty/rapidjson/fwd.h"
namespace xmrig {
class DnsConfig
{
public:
static const char *kField;
static const char *kIPv6;
static const char *kTTL;
DnsConfig() = default;
DnsConfig(const rapidjson::Value &object);
inline bool isIPv6() const { return m_ipv6; }
inline uint32_t ttl() const { return m_ttl * 1000U; }
rapidjson::Value toJSON(rapidjson::Document &doc) const;
private:
bool m_ipv6 = false;
uint32_t m_ttl = 30U;
};
} /* namespace xmrig */
#endif /* XMRIG_DNSCONFIG_H */

View File

@@ -1,6 +1,6 @@
/* XMRig
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -24,38 +24,34 @@
xmrig::DnsRecord::DnsRecord(const addrinfo *addr) :
m_type(addr->ai_family == AF_INET6 ? AAAA : A)
m_type(addr->ai_family == AF_INET6 ? AAAA : (addr->ai_family == AF_INET ? A : Unknown))
{
static_assert(sizeof(m_data) >= sizeof(sockaddr_in6), "Not enough storage for IPv6 address.");
memcpy(m_data, addr->ai_addr, m_type == AAAA ? sizeof(sockaddr_in6) : sizeof(sockaddr_in));
}
const sockaddr *xmrig::DnsRecord::addr(uint16_t port) const
{
reinterpret_cast<sockaddr_in*>(m_data)->sin_port = htons(port);
return reinterpret_cast<const sockaddr *>(m_data);
}
xmrig::String xmrig::DnsRecord::ip() const
{
char *buf = nullptr;
if (m_type == AAAA) {
buf = new char[45]();
uv_ip6_name(reinterpret_cast<sockaddr_in6*>(addr->ai_addr), buf, 45);
uv_ip6_name(reinterpret_cast<sockaddr_in6*>(m_data), buf, 45);
}
else {
buf = new char[16]();
uv_ip4_name(reinterpret_cast<sockaddr_in*>(addr->ai_addr), buf, 16);
uv_ip4_name(reinterpret_cast<sockaddr_in*>(m_data), buf, 16);
}
m_ip = buf;
}
sockaddr *xmrig::DnsRecord::addr(uint16_t port) const
{
if (m_type == A) {
auto addr = new sockaddr_in();
uv_ip4_addr(m_ip.data(), port, addr);
return reinterpret_cast<sockaddr *>(addr);
}
if (m_type == AAAA) {
auto addr = new sockaddr_in6();
uv_ip6_addr(m_ip.data(), port, addr);
return reinterpret_cast<sockaddr *>(addr);
}
return nullptr;
return buf;
}

View File

@@ -1,6 +1,6 @@
/* XMRig
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -33,7 +33,7 @@ namespace xmrig {
class DnsRecord
{
public:
enum Type {
enum Type : uint32_t {
Unknown,
A,
AAAA
@@ -42,15 +42,15 @@ public:
DnsRecord() {}
DnsRecord(const addrinfo *addr);
sockaddr *addr(uint16_t port = 0) const;
const sockaddr *addr(uint16_t port = 0) const;
String ip() const;
inline bool isValid() const { return m_type != Unknown; }
inline const String &ip() const { return m_ip; }
inline Type type() const { return m_type; }
private:
Type m_type = Unknown;
String m_ip;
mutable uint8_t m_data[28]{};
const Type m_type = Unknown;
};

View File

@@ -0,0 +1,108 @@
/* XMRig
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <uv.h>
#include "base/net/dns/DnsRecords.h"
#include "base/net/dns/Dns.h"
const xmrig::DnsRecord &xmrig::DnsRecords::get(DnsRecord::Type prefered) const
{
static const DnsRecord defaultRecord;
if (isEmpty()) {
return defaultRecord;
}
const size_t ipv4 = m_ipv4.size();
const size_t ipv6 = m_ipv6.size();
if (ipv6 && (prefered == DnsRecord::AAAA || Dns::config().isIPv6() || !ipv4)) {
return m_ipv6[ipv6 == 1 ? 0 : static_cast<size_t>(rand()) % ipv6];
}
if (ipv4) {
return m_ipv4[ipv4 == 1 ? 0 : static_cast<size_t>(rand()) % ipv4];
}
return defaultRecord;
}
size_t xmrig::DnsRecords::count(DnsRecord::Type type) const
{
if (type == DnsRecord::A) {
return m_ipv4.size();
}
if (type == DnsRecord::AAAA) {
return m_ipv6.size();
}
return m_ipv4.size() + m_ipv6.size();
}
void xmrig::DnsRecords::clear()
{
m_ipv4.clear();
m_ipv6.clear();
}
void xmrig::DnsRecords::parse(addrinfo *res)
{
clear();
addrinfo *ptr = res;
size_t ipv4 = 0;
size_t ipv6 = 0;
while (ptr != nullptr) {
if (ptr->ai_family == AF_INET) {
++ipv4;
}
else if (ptr->ai_family == AF_INET6) {
++ipv6;
}
ptr = ptr->ai_next;
}
if (ipv4 == 0 && ipv6 == 0) {
return;
}
m_ipv4.reserve(ipv4);
m_ipv6.reserve(ipv6);
ptr = res;
while (ptr != nullptr) {
if (ptr->ai_family == AF_INET) {
m_ipv4.emplace_back(ptr);
}
else if (ptr->ai_family == AF_INET6) {
m_ipv6.emplace_back(ptr);
}
ptr = ptr->ai_next;
}
}

View File

@@ -0,0 +1,48 @@
/* XMRig
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_DNSRECORDS_H
#define XMRIG_DNSRECORDS_H
#include "base/net/dns/DnsRecord.h"
namespace xmrig {
class DnsRecords
{
public:
inline bool isEmpty() const { return m_ipv4.empty() && m_ipv6.empty(); }
const DnsRecord &get(DnsRecord::Type prefered = DnsRecord::Unknown) const;
size_t count(DnsRecord::Type type = DnsRecord::Unknown) const;
void clear();
void parse(addrinfo *res);
private:
std::vector<DnsRecord> m_ipv4;
std::vector<DnsRecord> m_ipv6;
};
} /* namespace xmrig */
#endif /* XMRIG_DNSRECORDS_H */

View File

@@ -0,0 +1,50 @@
/* XMRig
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_DNSREQUEST_H
#define XMRIG_DNSREQUEST_H
#include "base/tools/Object.h"
#include <cstdint>
namespace xmrig {
class IDnsListener;
class DnsRequest
{
public:
XMRIG_DISABLE_COPY_MOVE_DEFAULT(DnsRequest)
DnsRequest(IDnsListener *listener) : listener(listener) {}
~DnsRequest() = default;
IDnsListener *listener;
};
} /* namespace xmrig */
#endif /* XMRIG_DNSREQUEST_H */

View File

@@ -0,0 +1,134 @@
/* XMRig
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <uv.h>
#include "base/net/dns/DnsUvBackend.h"
#include "base/kernel/interfaces/IDnsListener.h"
#include "base/net/dns/DnsRequest.h"
#include "base/tools/Chrono.h"
namespace xmrig {
Storage<DnsUvBackend>& DnsUvBackend::getStorage()
{
static Storage<DnsUvBackend>* storage = new Storage<DnsUvBackend>();
return *storage;
}
static addrinfo hints{};
} // namespace xmrig
xmrig::DnsUvBackend::DnsUvBackend()
{
if (!hints.ai_protocol) {
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
}
m_key = getStorage().add(this);
}
xmrig::DnsUvBackend::~DnsUvBackend()
{
getStorage().release(m_key);
}
std::shared_ptr<xmrig::DnsRequest> xmrig::DnsUvBackend::resolve(const String &host, IDnsListener *listener, uint64_t ttl)
{
auto req = std::make_shared<DnsRequest>(listener);
if (Chrono::currentMSecsSinceEpoch() - m_ts <= ttl && !m_records.isEmpty()) {
req->listener->onResolved(m_records, 0, nullptr);
} else {
m_queue.emplace(req);
}
if (m_queue.size() == 1 && !resolve(host)) {
done();
}
return req;
}
bool xmrig::DnsUvBackend::resolve(const String &host)
{
m_req = std::make_shared<uv_getaddrinfo_t>();
m_req->data = getStorage().ptr(m_key);
m_status = uv_getaddrinfo(uv_default_loop(), m_req.get(), DnsUvBackend::onResolved, host.data(), nullptr, &hints);
return m_status == 0;
}
void xmrig::DnsUvBackend::done()
{
const char *error = m_status < 0 ? uv_strerror(m_status) : nullptr;
while (!m_queue.empty()) {
auto req = std::move(m_queue.front()).lock();
if (req) {
req->listener->onResolved(m_records, m_status, error);
}
m_queue.pop();
}
m_req.reset();
}
void xmrig::DnsUvBackend::onResolved(int status, addrinfo *res)
{
m_ts = Chrono::currentMSecsSinceEpoch();
if ((m_status = status) < 0) {
return done();
}
m_records.parse(res);
if (m_records.isEmpty()) {
m_status = UV_EAI_NONAME;
}
done();
}
void xmrig::DnsUvBackend::onResolved(uv_getaddrinfo_t *req, int status, addrinfo *res)
{
auto backend = getStorage().get(req->data);
if (backend) {
backend->onResolved(status, res);
}
uv_freeaddrinfo(res);
}

View File

@@ -0,0 +1,71 @@
/* XMRig
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_DNSUVBACKEND_H
#define XMRIG_DNSUVBACKEND_H
#include "base/kernel/interfaces/IDnsBackend.h"
#include "base/net/dns/DnsRecords.h"
#include "base/net/tools/Storage.h"
#include <queue>
using uv_getaddrinfo_t = struct uv_getaddrinfo_s;
namespace xmrig {
class DnsUvBackend : public IDnsBackend
{
public:
XMRIG_DISABLE_COPY_MOVE(DnsUvBackend)
DnsUvBackend();
~DnsUvBackend() override;
protected:
inline const DnsRecords &records() const override { return m_records; }
std::shared_ptr<DnsRequest> resolve(const String &host, IDnsListener *listener, uint64_t ttl) override;
private:
bool resolve(const String &host);
void done();
void onResolved(int status, addrinfo *res);
static void onResolved(uv_getaddrinfo_t *req, int status, addrinfo *res);
DnsRecords m_records;
int m_status = 0;
std::queue<std::weak_ptr<DnsRequest> > m_queue;
std::shared_ptr<uv_getaddrinfo_t> m_req;
uint64_t m_ts = 0;
uintptr_t m_key;
static Storage<DnsUvBackend>& getStorage();
};
} /* namespace xmrig */
#endif /* XMRIG_DNSUVBACKEND_H */

View File

@@ -1,6 +1,6 @@
/* XMRig
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -30,7 +30,7 @@
#endif
xmrig::FetchRequest::FetchRequest(http_method method, const String &host, uint16_t port, const String &path, bool tls, bool quiet, const char *data, size_t size, const char *contentType) :
xmrig::FetchRequest::FetchRequest(llhttp_method method, const String &host, uint16_t port, const String &path, bool tls, bool quiet, const char *data, size_t size, const char *contentType) :
quiet(quiet),
tls(tls),
method(method),
@@ -44,7 +44,7 @@ xmrig::FetchRequest::FetchRequest(http_method method, const String &host, uint16
}
xmrig::FetchRequest::FetchRequest(http_method method, const String &host, uint16_t port, const String &path, const rapidjson::Value &value, bool tls, bool quiet) :
xmrig::FetchRequest::FetchRequest(llhttp_method method, const String &host, uint16_t port, const String &path, const rapidjson::Value &value, bool tls, bool quiet) :
quiet(quiet),
tls(tls),
method(method),
@@ -99,7 +99,7 @@ void xmrig::fetch(const char *tag, FetchRequest &&req, const std::weak_ptr<IHttp
{
# ifdef APP_DEBUG
LOG_DEBUG(CYAN("http%s://%s:%u ") MAGENTA_BOLD("\"%s %s\"") BLACK_BOLD(" body: ") CYAN_BOLD("%zu") BLACK_BOLD(" bytes"),
req.tls ? "s" : "", req.host.data(), req.port, http_method_str(req.method), req.path.data(), req.body.size());
req.tls ? "s" : "", req.host.data(), req.port, llhttp_method_name(req.method), req.path.data(), req.body.size());
if (req.hasBody() && req.body.size() < (Log::kMaxBufferSize - 1024) && req.headers.count(HttpData::kContentType) && req.headers.at(HttpData::kContentType) == HttpData::kApplicationJson) {
Log::print(BLUE_BG_BOLD("%s:") BLACK_BOLD_S " %.*s", req.headers.at(HttpData::kContentType).c_str(), static_cast<int>(req.body.size()), req.body.c_str());

View File

@@ -1,6 +1,6 @@
/* XMRig
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,7 +21,7 @@
#define XMRIG_FETCH_H
#include "3rdparty/http-parser/http_parser.h"
#include "3rdparty/llhttp/llhttp.h"
#include "3rdparty/rapidjson/fwd.h"
#include "base/tools/String.h"
@@ -41,24 +41,24 @@ class FetchRequest
{
public:
FetchRequest() = default;
FetchRequest(http_method method, const String &host, uint16_t port, const String &path, bool tls = false, bool quiet = false, const char *data = nullptr, size_t size = 0, const char *contentType = nullptr);
FetchRequest(http_method method, const String &host, uint16_t port, const String &path, const rapidjson::Value &value, bool tls = false, bool quiet = false);
FetchRequest(llhttp_method method, const String &host, uint16_t port, const String &path, bool tls = false, bool quiet = false, const char *data = nullptr, size_t size = 0, const char *contentType = nullptr);
FetchRequest(llhttp_method method, const String &host, uint16_t port, const String &path, const rapidjson::Value &value, bool tls = false, bool quiet = false);
void setBody(const char *data, size_t size, const char *contentType = nullptr);
void setBody(const rapidjson::Value &value);
inline bool hasBody() const { return method != HTTP_GET && method != HTTP_HEAD && !body.empty(); }
bool quiet = false;
bool tls = false;
http_method method = HTTP_GET;
bool quiet = false;
bool tls = false;
llhttp_method method = HTTP_GET;
std::map<const std::string, const std::string> headers;
std::string body;
String fingerprint;
String host;
String path;
uint16_t port = 0;
uint64_t timeout = 0;
uint16_t port = 0;
uint64_t timeout = 0;
};

View File

@@ -1,13 +1,7 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2014-2019 heapwolf <https://github.com/heapwolf>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright (c) 2014-2019 heapwolf <https://github.com/heapwolf>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,7 +19,6 @@
#include "base/net/http/HttpApiResponse.h"
#include "3rdparty/http-parser/http_parser.h"
#include "3rdparty/rapidjson/prettywriter.h"
#include "3rdparty/rapidjson/stringbuffer.h"
#include "base/net/http/HttpData.h"
@@ -68,7 +61,7 @@ void xmrig::HttpApiResponse::end()
}
if (!m_doc.HasMember(kError)) {
m_doc.AddMember(StringRef(kError), StringRef(http_status_str(static_cast<http_status>(statusCode()))), m_doc.GetAllocator());
m_doc.AddMember(StringRef(kError), StringRef(HttpData::statusName(statusCode())), m_doc.GetAllocator());
}
}

View File

@@ -1,13 +1,7 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2014-2019 heapwolf <https://github.com/heapwolf>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright (c) 2014-2019 heapwolf <https://github.com/heapwolf>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,7 +17,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_HTTPAPIRESPONSE_H
#define XMRIG_HTTPAPIRESPONSE_H

View File

@@ -1,7 +1,7 @@
/* XMRig
* Copyright (c) 2014-2019 heapwolf <https://github.com/heapwolf>
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,15 +19,17 @@
#include "base/net/http/HttpClient.h"
#include "3rdparty/http-parser/http_parser.h"
#include "3rdparty/llhttp/llhttp.h"
#include "base/io/log/Log.h"
#include "base/kernel/Platform.h"
#include "base/net/dns/Dns.h"
#include "base/net/dns/DnsRecords.h"
#include "base/net/tools/NetBuffer.h"
#include "base/tools/Timer.h"
#include <sstream>
#include <uv.h>
namespace xmrig {
@@ -48,7 +50,6 @@ xmrig::HttpClient::HttpClient(const char *tag, FetchRequest &&req, const std::we
url = std::move(m_req.path);
body = std::move(m_req.body);
headers = std::move(m_req.headers);
m_dns = std::make_shared<Dns>(this);
if (m_req.timeout) {
m_timer = std::make_shared<Timer>(this, m_req.timeout, 0);
@@ -58,30 +59,29 @@ xmrig::HttpClient::HttpClient(const char *tag, FetchRequest &&req, const std::we
bool xmrig::HttpClient::connect()
{
return m_dns->resolve(m_req.host);
m_dns = Dns::resolve(m_req.host, this);
return true;
}
void xmrig::HttpClient::onResolved(const Dns &dns, int status)
void xmrig::HttpClient::onResolved(const DnsRecords &records, int status, const char *error)
{
this->status = status;
m_dns.reset();
if (status < 0 && dns.isEmpty()) {
if (status < 0 && records.isEmpty()) {
if (!isQuiet()) {
LOG_ERR("%s " RED("DNS error: ") RED_BOLD("\"%s\""), tag(), uv_strerror(status));
LOG_ERR("%s " RED("DNS error: ") RED_BOLD("\"%s\""), tag(), error);
}
return;
}
sockaddr *addr = dns.get().addr(port());
auto req = new uv_connect_t;
req->data = this;
uv_tcp_connect(req, m_tcp, addr, onConnect);
delete addr;
uv_tcp_connect(req, m_tcp, records.get().addr(port()), onConnect);
}
@@ -102,7 +102,7 @@ void xmrig::HttpClient::handshake()
}
std::stringstream ss;
ss << http_method_str(static_cast<http_method>(method)) << " " << url << " HTTP/1.1" << kCRLF;
ss << llhttp_method_name(static_cast<llhttp_method>(method)) << " " << url << " HTTP/1.1" << kCRLF;
for (auto &header : headers) {
ss << header.first << ": " << header.second << kCRLF;
@@ -119,7 +119,7 @@ void xmrig::HttpClient::handshake()
void xmrig::HttpClient::read(const char *data, size_t size)
{
if (parse(data, size) < size) {
if (!parse(data, size)) {
close(UV_EPROTO);
}
}

View File

@@ -1,7 +1,7 @@
/* XMRig
* Copyright (c) 2014-2019 heapwolf <https://github.com/heapwolf>
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -32,7 +32,7 @@
namespace xmrig {
class String;
class DnsRequest;
class HttpClient : public HttpContext, public IDnsListener, public ITimerListener
@@ -51,7 +51,7 @@ public:
bool connect();
protected:
void onResolved(const Dns &dns, int status) override;
void onResolved(const DnsRecords &records, int status, const char *error) override;
void onTimer(const Timer *timer) override;
virtual void handshake();
@@ -65,7 +65,7 @@ private:
const char *m_tag;
FetchRequest m_req;
std::shared_ptr<Dns> m_dns;
std::shared_ptr<DnsRequest> m_dns;
std::shared_ptr<Timer> m_timer;
};

View File

@@ -1,7 +1,7 @@
/* XMRig
* Copyright (c) 2014-2019 heapwolf <https://github.com/heapwolf>
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,7 +19,7 @@
#include "base/net/http/HttpContext.h"
#include "3rdparty/http-parser/http_parser.h"
#include "3rdparty/llhttp/llhttp.h"
#include "base/kernel/interfaces/IHttpListener.h"
#include "base/tools/Baton.h"
#include "base/tools/Chrono.h"
@@ -32,7 +32,7 @@
namespace xmrig {
static http_parser_settings http_settings;
static llhttp_settings_t http_settings;
static std::map<uint64_t, HttpContext *> storage;
static uint64_t SEQUENCE = 0;
@@ -78,13 +78,13 @@ xmrig::HttpContext::HttpContext(int parser_type, const std::weak_ptr<IHttpListen
{
storage[id()] = this;
m_parser = new http_parser;
m_parser = new llhttp_t;
m_tcp = new uv_tcp_t;
uv_tcp_init(uv_default_loop(), m_tcp);
uv_tcp_nodelay(m_tcp, 1);
http_parser_init(m_parser, static_cast<http_parser_type>(parser_type));
llhttp_init(m_parser, static_cast<llhttp_type_t>(parser_type), &http_settings);
m_parser->data = m_tcp->data = this;
@@ -118,13 +118,13 @@ bool xmrig::HttpContext::isRequest() const
}
size_t xmrig::HttpContext::parse(const char *data, size_t size)
bool xmrig::HttpContext::parse(const char *data, size_t size)
{
if (size == 0) {
return size;
return true;
}
return http_parser_execute(m_parser, &http_settings, data, size);
return llhttp_execute(m_parser, data, size) == HPE_OK;
}
@@ -175,11 +175,9 @@ void xmrig::HttpContext::close(int status)
xmrig::HttpContext *xmrig::HttpContext::get(uint64_t id)
{
if (storage.count(id) == 0) {
return nullptr;
}
const auto it = storage.find(id);
return storage[id];
return it == storage.end() ? nullptr : it->second;
}
@@ -193,7 +191,7 @@ void xmrig::HttpContext::closeAll()
}
int xmrig::HttpContext::onHeaderField(http_parser *parser, const char *at, size_t length)
int xmrig::HttpContext::onHeaderField(llhttp_t *parser, const char *at, size_t length)
{
auto ctx = static_cast<HttpContext*>(parser->data);
@@ -212,7 +210,7 @@ int xmrig::HttpContext::onHeaderField(http_parser *parser, const char *at, size_
}
int xmrig::HttpContext::onHeaderValue(http_parser *parser, const char *at, size_t length)
int xmrig::HttpContext::onHeaderValue(llhttp_t *parser, const char *at, size_t length)
{
auto ctx = static_cast<HttpContext*>(parser->data);
@@ -227,14 +225,14 @@ int xmrig::HttpContext::onHeaderValue(http_parser *parser, const char *at, size_
}
void xmrig::HttpContext::attach(http_parser_settings *settings)
void xmrig::HttpContext::attach(llhttp_settings_t *settings)
{
settings->on_message_begin = nullptr;
settings->on_status = nullptr;
settings->on_chunk_header = nullptr;
settings->on_chunk_complete = nullptr;
settings->on_url = [](http_parser *parser, const char *at, size_t length) -> int
settings->on_url = [](llhttp_t *parser, const char *at, size_t length) -> int
{
static_cast<HttpContext*>(parser->data)->url = std::string(at, length);
return 0;
@@ -243,7 +241,7 @@ void xmrig::HttpContext::attach(http_parser_settings *settings)
settings->on_header_field = onHeaderField;
settings->on_header_value = onHeaderValue;
settings->on_headers_complete = [](http_parser* parser) -> int {
settings->on_headers_complete = [](llhttp_t *parser) -> int {
auto ctx = static_cast<HttpContext*>(parser->data);
ctx->status = parser->status_code;
@@ -258,14 +256,14 @@ void xmrig::HttpContext::attach(http_parser_settings *settings)
return 0;
};
settings->on_body = [](http_parser *parser, const char *at, size_t len) -> int
settings->on_body = [](llhttp_t *parser, const char *at, size_t len) -> int
{
static_cast<HttpContext*>(parser->data)->body.append(at, len);
return 0;
};
settings->on_message_complete = [](http_parser *parser) -> int
settings->on_message_complete = [](llhttp_t *parser) -> int
{
auto ctx = static_cast<HttpContext*>(parser->data);
auto listener = ctx->httpListener();

Some files were not shown because too many files have changed in this diff Show More