quantumcoin 6.14.2 → 6.14.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +442 -442
- package/FUNDING.json +10 -10
- package/LICENSE.md +21 -21
- package/README.md +132 -142
- package/SECURITY.md +34 -34
- package/dist/README.md +22 -22
- package/dist/quantumcoin.js +1127 -1324
- package/dist/quantumcoin.js.map +1 -1
- package/dist/quantumcoin.min.js +1 -1
- package/dist/quantumcoin.umd.js +1128 -1327
- package/dist/quantumcoin.umd.js.map +1 -1
- package/dist/quantumcoin.umd.min.js +1 -1
- package/dist/wordlists-extra.js +1 -1
- package/dist/wordlists-extra.js.map +1 -1
- package/dist/wordlists-extra.min.js +1 -1
- package/lib.commonjs/README.md +16 -16
- package/lib.commonjs/_version.js +1 -1
- package/lib.commonjs/crypto/signature.d.ts +3 -76
- package/lib.commonjs/crypto/signature.d.ts.map +1 -1
- package/lib.commonjs/crypto/signature.js +15 -199
- package/lib.commonjs/crypto/signature.js.map +1 -1
- package/lib.commonjs/crypto/signing-key.d.ts +1 -1
- package/lib.commonjs/crypto/signing-key.d.ts.map +1 -1
- package/lib.commonjs/crypto/signing-key.js +19 -10
- package/lib.commonjs/crypto/signing-key.js.map +1 -1
- package/lib.commonjs/package.json +12 -12
- package/lib.commonjs/providers/provider-jsonrpc.d.ts +0 -1
- package/lib.commonjs/providers/provider-jsonrpc.d.ts.map +1 -1
- package/lib.commonjs/providers/provider-jsonrpc.js +0 -1
- package/lib.commonjs/providers/provider-jsonrpc.js.map +1 -1
- package/lib.commonjs/quantumcoin.d.ts +2 -0
- package/lib.commonjs/quantumcoin.d.ts.map +1 -1
- package/lib.commonjs/quantumcoin.js +11 -5
- package/lib.commonjs/quantumcoin.js.map +1 -1
- package/lib.commonjs/transaction/address.d.ts.map +1 -1
- package/lib.commonjs/transaction/address.js +8 -3
- package/lib.commonjs/transaction/address.js.map +1 -1
- package/lib.commonjs/transaction/transaction.d.ts.map +1 -1
- package/lib.commonjs/transaction/transaction.js +7 -40
- package/lib.commonjs/transaction/transaction.js.map +1 -1
- package/lib.commonjs/wallet/json-keystore.d.ts.map +1 -1
- package/lib.commonjs/wallet/json-keystore.js +7 -7
- package/lib.commonjs/wallet/json-keystore.js.map +1 -1
- package/lib.commonjs/wallet/wallet.d.ts.map +1 -1
- package/lib.commonjs/wallet/wallet.js +2 -2
- package/lib.commonjs/wallet/wallet.js.map +1 -1
- package/lib.esm/README.md +16 -16
- package/lib.esm/_version.js +1 -1
- package/lib.esm/crypto/signature.d.ts +3 -76
- package/lib.esm/crypto/signature.d.ts.map +1 -1
- package/lib.esm/crypto/signature.js +16 -202
- package/lib.esm/crypto/signature.js.map +1 -1
- package/lib.esm/crypto/signing-key.d.ts +1 -1
- package/lib.esm/crypto/signing-key.d.ts.map +1 -1
- package/lib.esm/crypto/signing-key.js +20 -9
- package/lib.esm/crypto/signing-key.js.map +1 -1
- package/lib.esm/package.json +12 -12
- package/lib.esm/providers/provider-jsonrpc.d.ts +0 -1
- package/lib.esm/providers/provider-jsonrpc.d.ts.map +1 -1
- package/lib.esm/providers/provider-jsonrpc.js +0 -1
- package/lib.esm/providers/provider-jsonrpc.js.map +1 -1
- package/lib.esm/quantumcoin.d.ts +2 -0
- package/lib.esm/quantumcoin.d.ts.map +1 -1
- package/lib.esm/quantumcoin.js +6 -0
- package/lib.esm/quantumcoin.js.map +1 -1
- package/lib.esm/transaction/address.d.ts.map +1 -1
- package/lib.esm/transaction/address.js +8 -2
- package/lib.esm/transaction/address.js.map +1 -1
- package/lib.esm/transaction/transaction.d.ts.map +1 -1
- package/lib.esm/transaction/transaction.js +7 -40
- package/lib.esm/transaction/transaction.js.map +1 -1
- package/lib.esm/wallet/json-keystore.d.ts.map +1 -1
- package/lib.esm/wallet/json-keystore.js +11 -5
- package/lib.esm/wallet/json-keystore.js.map +1 -1
- package/lib.esm/wallet/wallet.d.ts.map +1 -1
- package/lib.esm/wallet/wallet.js +3 -1
- package/lib.esm/wallet/wallet.js.map +1 -1
- package/package.json +6 -5
- package/rollup.config.mjs +50 -50
- package/src.ts/_version.ts +1 -1
- package/src.ts/abi/abi-coder.ts +237 -237
- package/src.ts/abi/bytes32.ts +45 -45
- package/src.ts/abi/coders/abstract-coder.ts +541 -541
- package/src.ts/abi/coders/address.ts +36 -36
- package/src.ts/abi/coders/anonymous.ts +29 -29
- package/src.ts/abi/coders/array.ts +199 -199
- package/src.ts/abi/coders/boolean.ts +27 -27
- package/src.ts/abi/coders/bytes.ts +43 -43
- package/src.ts/abi/coders/fixed-bytes.ts +37 -37
- package/src.ts/abi/coders/null.ts +28 -28
- package/src.ts/abi/coders/number.ts +63 -63
- package/src.ts/abi/coders/string.ts +29 -29
- package/src.ts/abi/coders/tuple.ts +69 -69
- package/src.ts/abi/fragments.ts +1617 -1617
- package/src.ts/abi/index.ts +41 -41
- package/src.ts/abi/interface.ts +1271 -1271
- package/src.ts/abi/typed.ts +796 -796
- package/src.ts/address/address.ts +148 -148
- package/src.ts/address/checks.ts +123 -123
- package/src.ts/address/contract-address.ts +80 -80
- package/src.ts/address/index.ts +57 -57
- package/src.ts/constants/addresses.ts +8 -8
- package/src.ts/constants/hashes.ts +7 -7
- package/src.ts/constants/index.ts +16 -16
- package/src.ts/constants/numbers.ts +35 -35
- package/src.ts/constants/strings.ts +16 -16
- package/src.ts/contract/contract.ts +1120 -1120
- package/src.ts/contract/factory.ts +143 -143
- package/src.ts/contract/index.ts +31 -31
- package/src.ts/contract/types.ts +236 -236
- package/src.ts/contract/wrappers.ts +225 -225
- package/src.ts/crypto/crypto-browser.ts +64 -64
- package/src.ts/crypto/crypto.ts +4 -4
- package/src.ts/crypto/hmac.ts +51 -51
- package/src.ts/crypto/index.ts +59 -59
- package/src.ts/crypto/keccak.ts +54 -54
- package/src.ts/crypto/pbkdf2.ts +55 -55
- package/src.ts/crypto/random.ts +36 -36
- package/src.ts/crypto/ripemd160.ts +43 -43
- package/src.ts/crypto/scrypt.ts +114 -114
- package/src.ts/crypto/sha2.ts +78 -78
- package/src.ts/crypto/signature.ts +145 -349
- package/src.ts/crypto/signing-key.ts +126 -118
- package/src.ts/hash/authorization.ts +38 -38
- package/src.ts/hash/id.ts +17 -17
- package/src.ts/hash/index.ts +18 -18
- package/src.ts/hash/message.ts +51 -51
- package/src.ts/hash/namehash.ts +101 -101
- package/src.ts/hash/solidity.ts +117 -117
- package/src.ts/hash/typed-data.ts +658 -658
- package/src.ts/index.ts +12 -12
- package/src.ts/providers/abstract-provider.ts +1761 -1761
- package/src.ts/providers/abstract-signer.ts +314 -314
- package/src.ts/providers/community.ts +49 -49
- package/src.ts/providers/contracts.ts +42 -42
- package/src.ts/providers/default-provider.ts +96 -96
- package/src.ts/providers/ens-resolver.ts +606 -606
- package/src.ts/providers/format.ts +320 -320
- package/src.ts/providers/formatting.ts +418 -418
- package/src.ts/providers/index.ts +125 -125
- package/src.ts/providers/network.ts +327 -327
- package/src.ts/providers/pagination.ts +8 -8
- package/src.ts/providers/plugin-fallback.ts +35 -35
- package/src.ts/providers/plugins-network.ts +281 -281
- package/src.ts/providers/provider-browser.ts +334 -334
- package/src.ts/providers/provider-fallback.ts +801 -801
- package/src.ts/providers/provider-ipcsocket-browser.ts +3 -3
- package/src.ts/providers/provider-ipcsocket.ts +81 -81
- package/src.ts/providers/provider-jsonrpc.ts +1334 -1335
- package/src.ts/providers/provider-socket.ts +352 -352
- package/src.ts/providers/provider-websocket.ts +103 -103
- package/src.ts/providers/provider.ts +2136 -2136
- package/src.ts/providers/signer-noncemanager.ts +98 -98
- package/src.ts/providers/signer.ts +166 -166
- package/src.ts/providers/subscriber-connection.ts +74 -74
- package/src.ts/providers/subscriber-filterid.ts +199 -199
- package/src.ts/providers/subscriber-polling.ts +321 -321
- package/src.ts/providers/ws-browser.ts +11 -11
- package/src.ts/providers/ws.ts +3 -3
- package/src.ts/quantumcoin.ts +219 -211
- package/src.ts/thirdparty.d.ts +16 -16
- package/src.ts/transaction/accesslist.ts +43 -43
- package/src.ts/transaction/address.ts +35 -31
- package/src.ts/transaction/authorization.ts +14 -14
- package/src.ts/transaction/index.ts +51 -51
- package/src.ts/transaction/transaction.ts +1349 -1379
- package/src.ts/utils/base58.ts +73 -73
- package/src.ts/utils/base64-browser.ts +25 -25
- package/src.ts/utils/base64.ts +56 -56
- package/src.ts/utils/data.ts +199 -199
- package/src.ts/utils/errors.ts +793 -793
- package/src.ts/utils/events.ts +105 -105
- package/src.ts/utils/fetch.ts +970 -970
- package/src.ts/utils/fixednumber.ts +643 -643
- package/src.ts/utils/geturl-browser.ts +81 -81
- package/src.ts/utils/geturl.ts +134 -134
- package/src.ts/utils/index.ts +95 -95
- package/src.ts/utils/maths.ts +240 -240
- package/src.ts/utils/properties.ts +60 -60
- package/src.ts/utils/rlp-decode.ts +104 -104
- package/src.ts/utils/rlp-encode.ts +64 -64
- package/src.ts/utils/rlp.ts +20 -20
- package/src.ts/utils/units.ts +91 -91
- package/src.ts/utils/utf8.ts +325 -325
- package/src.ts/utils/uuid.ts +36 -36
- package/src.ts/wallet/base-wallet.ts +160 -160
- package/src.ts/wallet/index.ts +32 -32
- package/src.ts/wallet/json-keystore.ts +108 -106
- package/src.ts/wallet/utils.ts +147 -147
- package/src.ts/wallet/wallet.ts +138 -139
- package/src.ts/wordlists/bit-reader.ts +35 -35
- package/src.ts/wordlists/decode-owl.ts +58 -58
- package/src.ts/wordlists/decode-owla.ts +33 -33
- package/src.ts/wordlists/generation/encode-latin.ts +370 -370
- package/src.ts/wordlists/index.ts +26 -26
- package/src.ts/wordlists/lang-cz.ts +33 -33
- package/src.ts/wordlists/lang-en.ts +33 -33
- package/src.ts/wordlists/lang-es.ts +35 -35
- package/src.ts/wordlists/lang-fr.ts +34 -34
- package/src.ts/wordlists/lang-it.ts +33 -33
- package/src.ts/wordlists/lang-ja.ts +181 -181
- package/src.ts/wordlists/lang-ko.ts +104 -104
- package/src.ts/wordlists/lang-pt.ts +34 -34
- package/src.ts/wordlists/lang-zh.ts +112 -112
- package/src.ts/wordlists/wordlist-owl.ts +77 -77
- package/src.ts/wordlists/wordlist-owla.ts +41 -41
- package/src.ts/wordlists/wordlist.ts +59 -59
- package/src.ts/wordlists/wordlists-browser.ts +8 -8
- package/src.ts/wordlists/wordlists-extra.ts +9 -9
- package/src.ts/wordlists/wordlists.ts +38 -38
- package/dist/quantumcoin.min.js'.gz' +0 -0
- package/dist/quantumcoin.umd.min.js'.gz' +0 -0
- package/dist/wordlists-extra.min.js'.gz' +0 -0
- package/lib.commonjs/providers/provider-alchemy.d.ts +0 -50
- package/lib.commonjs/providers/provider-alchemy.d.ts.map +0 -1
- package/lib.commonjs/providers/provider-alchemy.js +0 -151
- package/lib.commonjs/providers/provider-alchemy.js.map +0 -1
- package/lib.commonjs/providers/provider-ankr.d.ts +0 -61
- package/lib.commonjs/providers/provider-ankr.d.ts.map +0 -1
- package/lib.commonjs/providers/provider-ankr.js +0 -137
- package/lib.commonjs/providers/provider-ankr.js.map +0 -1
- package/lib.commonjs/providers/provider-blockscout.d.ts +0 -59
- package/lib.commonjs/providers/provider-blockscout.d.ts.map +0 -1
- package/lib.commonjs/providers/provider-blockscout.js +0 -145
- package/lib.commonjs/providers/provider-blockscout.js.map +0 -1
- package/lib.commonjs/providers/provider-chainstack.d.ts +0 -46
- package/lib.commonjs/providers/provider-chainstack.d.ts.map +0 -1
- package/lib.commonjs/providers/provider-chainstack.js +0 -102
- package/lib.commonjs/providers/provider-chainstack.js.map +0 -1
- package/lib.commonjs/providers/provider-cloudflare.d.ts +0 -14
- package/lib.commonjs/providers/provider-cloudflare.d.ts.map +0 -1
- package/lib.commonjs/providers/provider-cloudflare.js +0 -26
- package/lib.commonjs/providers/provider-cloudflare.js.map +0 -1
- package/lib.commonjs/providers/provider-etherscan.d.ts +0 -147
- package/lib.commonjs/providers/provider-etherscan.d.ts.map +0 -1
- package/lib.commonjs/providers/provider-etherscan.js +0 -587
- package/lib.commonjs/providers/provider-etherscan.js.map +0 -1
- package/lib.commonjs/providers/provider-infura.d.ts +0 -101
- package/lib.commonjs/providers/provider-infura.d.ts.map +0 -1
- package/lib.commonjs/providers/provider-infura.js +0 -206
- package/lib.commonjs/providers/provider-infura.js.map +0 -1
- package/lib.commonjs/providers/provider-pocket.d.ts +0 -54
- package/lib.commonjs/providers/provider-pocket.d.ts.map +0 -1
- package/lib.commonjs/providers/provider-pocket.js +0 -109
- package/lib.commonjs/providers/provider-pocket.js.map +0 -1
- package/lib.commonjs/providers/provider-quicknode.d.ts +0 -59
- package/lib.commonjs/providers/provider-quicknode.d.ts.map +0 -1
- package/lib.commonjs/providers/provider-quicknode.js +0 -163
- package/lib.commonjs/providers/provider-quicknode.js.map +0 -1
- package/lib.commonjs/wallet/hdwallet.d.ts +0 -248
- package/lib.commonjs/wallet/hdwallet.d.ts.map +0 -1
- package/lib.commonjs/wallet/hdwallet.js +0 -505
- package/lib.commonjs/wallet/hdwallet.js.map +0 -1
- package/lib.commonjs/wallet/json-crowdsale.d.ts +0 -27
- package/lib.commonjs/wallet/json-crowdsale.d.ts.map +0 -1
- package/lib.commonjs/wallet/json-crowdsale.js +0 -60
- package/lib.commonjs/wallet/json-crowdsale.js.map +0 -1
- package/lib.commonjs/wallet/mnemonic.d.ts +0 -65
- package/lib.commonjs/wallet/mnemonic.d.ts.map +0 -1
- package/lib.commonjs/wallet/mnemonic.js +0 -169
- package/lib.commonjs/wallet/mnemonic.js.map +0 -1
- package/lib.commonjs/wallet/seedwallet.d.ts +0 -4
- package/lib.commonjs/wallet/seedwallet.d.ts.map +0 -1
- package/lib.commonjs/wallet/seedwallet.js +0 -8
- package/lib.commonjs/wallet/seedwallet.js.map +0 -1
- package/lib.esm/providers/provider-alchemy.d.ts +0 -50
- package/lib.esm/providers/provider-alchemy.d.ts.map +0 -1
- package/lib.esm/providers/provider-alchemy.js +0 -147
- package/lib.esm/providers/provider-alchemy.js.map +0 -1
- package/lib.esm/providers/provider-ankr.d.ts +0 -61
- package/lib.esm/providers/provider-ankr.d.ts.map +0 -1
- package/lib.esm/providers/provider-ankr.js +0 -133
- package/lib.esm/providers/provider-ankr.js.map +0 -1
- package/lib.esm/providers/provider-blockscout.d.ts +0 -59
- package/lib.esm/providers/provider-blockscout.d.ts.map +0 -1
- package/lib.esm/providers/provider-blockscout.js +0 -141
- package/lib.esm/providers/provider-blockscout.js.map +0 -1
- package/lib.esm/providers/provider-chainstack.d.ts +0 -46
- package/lib.esm/providers/provider-chainstack.d.ts.map +0 -1
- package/lib.esm/providers/provider-chainstack.js +0 -98
- package/lib.esm/providers/provider-chainstack.js.map +0 -1
- package/lib.esm/providers/provider-cloudflare.d.ts +0 -14
- package/lib.esm/providers/provider-cloudflare.d.ts.map +0 -1
- package/lib.esm/providers/provider-cloudflare.js +0 -22
- package/lib.esm/providers/provider-cloudflare.js.map +0 -1
- package/lib.esm/providers/provider-etherscan.d.ts +0 -147
- package/lib.esm/providers/provider-etherscan.d.ts.map +0 -1
- package/lib.esm/providers/provider-etherscan.js +0 -584
- package/lib.esm/providers/provider-etherscan.js.map +0 -1
- package/lib.esm/providers/provider-infura.d.ts +0 -101
- package/lib.esm/providers/provider-infura.d.ts.map +0 -1
- package/lib.esm/providers/provider-infura.js +0 -201
- package/lib.esm/providers/provider-infura.js.map +0 -1
- package/lib.esm/providers/provider-pocket.d.ts +0 -54
- package/lib.esm/providers/provider-pocket.d.ts.map +0 -1
- package/lib.esm/providers/provider-pocket.js +0 -105
- package/lib.esm/providers/provider-pocket.js.map +0 -1
- package/lib.esm/providers/provider-quicknode.d.ts +0 -59
- package/lib.esm/providers/provider-quicknode.d.ts.map +0 -1
- package/lib.esm/providers/provider-quicknode.js +0 -159
- package/lib.esm/providers/provider-quicknode.js.map +0 -1
- package/lib.esm/wallet/hdwallet.d.ts +0 -248
- package/lib.esm/wallet/hdwallet.d.ts.map +0 -1
- package/lib.esm/wallet/hdwallet.js +0 -498
- package/lib.esm/wallet/hdwallet.js.map +0 -1
- package/lib.esm/wallet/json-crowdsale.d.ts +0 -27
- package/lib.esm/wallet/json-crowdsale.d.ts.map +0 -1
- package/lib.esm/wallet/json-crowdsale.js +0 -55
- package/lib.esm/wallet/json-crowdsale.js.map +0 -1
- package/lib.esm/wallet/mnemonic.d.ts +0 -65
- package/lib.esm/wallet/mnemonic.d.ts.map +0 -1
- package/lib.esm/wallet/mnemonic.js +0 -165
- package/lib.esm/wallet/mnemonic.js.map +0 -1
- package/lib.esm/wallet/seedwallet.d.ts +0 -4
- package/lib.esm/wallet/seedwallet.d.ts.map +0 -1
- package/lib.esm/wallet/seedwallet.js +0 -4
- package/lib.esm/wallet/seedwallet.js.map +0 -1
package/dist/quantumcoin.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
const __$G = (typeof globalThis !== 'undefined' ? globalThis: typeof window !== 'undefined' ? window: typeof global !== 'undefined' ? global: typeof self !== 'undefined' ? self: {});
|
|
2
|
+
import { combinePublicKeySignature, publicKeyFromPrivateKey, publicKeyFromSignature, addressFromPublicKey, deserializeEncryptedWallet, Wallet as Wallet$1, serializeEncryptedWallet, newWallet, Config, initialize } from 'quantum-coin-js-sdk';
|
|
3
|
+
import { cryptoSign } from 'quantum-coin-pqc-js-sdk';
|
|
4
|
+
|
|
2
5
|
/* Do NOT modify this file; see /src.ts/_admin/update-version.ts */
|
|
3
6
|
/**
|
|
4
7
|
* The current version of Ethers.
|
|
5
8
|
*/
|
|
6
|
-
const version = "6.14.
|
|
9
|
+
const version = "6.14.3";
|
|
7
10
|
|
|
8
11
|
/**
|
|
9
12
|
* Property helper functions.
|
|
@@ -455,7 +458,7 @@ function zeroPadBytes(data, length) {
|
|
|
455
458
|
*
|
|
456
459
|
* @_subsection: api/utils:Math Helpers [about-maths]
|
|
457
460
|
*/
|
|
458
|
-
const BN_0$
|
|
461
|
+
const BN_0$9 = BigInt(0);
|
|
459
462
|
const BN_1$4 = BigInt(1);
|
|
460
463
|
//const BN_Max256 = (BN_1 << BigInt(256)) - BN_1;
|
|
461
464
|
// IEEE 754 support 53-bits of mantissa
|
|
@@ -469,7 +472,7 @@ const maxValue = 0x1fffffffffffff;
|
|
|
469
472
|
function fromTwos(_value, _width) {
|
|
470
473
|
const value = getUint(_value, "value");
|
|
471
474
|
const width = BigInt(getNumber(_width, "width"));
|
|
472
|
-
assert((value >> width) === BN_0$
|
|
475
|
+
assert((value >> width) === BN_0$9, "overflow", "NUMERIC_FAULT", {
|
|
473
476
|
operation: "fromTwos", fault: "overflow", value: _value
|
|
474
477
|
});
|
|
475
478
|
// Top bit set; treat as a negative value
|
|
@@ -489,7 +492,7 @@ function toTwos(_value, _width) {
|
|
|
489
492
|
let value = getBigInt(_value, "value");
|
|
490
493
|
const width = BigInt(getNumber(_width, "width"));
|
|
491
494
|
const limit = (BN_1$4 << (width - BN_1$4));
|
|
492
|
-
if (value < BN_0$
|
|
495
|
+
if (value < BN_0$9) {
|
|
493
496
|
value = -value;
|
|
494
497
|
assert(value <= limit, "too low", "NUMERIC_FAULT", {
|
|
495
498
|
operation: "toTwos", fault: "overflow", value: _value
|
|
@@ -545,7 +548,7 @@ function getBigInt(value, name) {
|
|
|
545
548
|
*/
|
|
546
549
|
function getUint(value, name) {
|
|
547
550
|
const result = getBigInt(value, name);
|
|
548
|
-
assert(result >= BN_0$
|
|
551
|
+
assert(result >= BN_0$9, "unsigned value cannot be negative", "NUMERIC_FAULT", {
|
|
549
552
|
fault: "overflow", operation: "getUint", value
|
|
550
553
|
});
|
|
551
554
|
return result;
|
|
@@ -631,7 +634,7 @@ function toBeHex(_value, _width) {
|
|
|
631
634
|
*/
|
|
632
635
|
function toBeArray(_value) {
|
|
633
636
|
const value = getUint(_value, "value");
|
|
634
|
-
if (value === BN_0$
|
|
637
|
+
if (value === BN_0$9) {
|
|
635
638
|
return new Uint8Array([]);
|
|
636
639
|
}
|
|
637
640
|
let hex = value.toString(16);
|
|
@@ -689,7 +692,7 @@ function getAlpha(letter) {
|
|
|
689
692
|
assertArgument(result != null, `invalid base58 value`, "letter", letter);
|
|
690
693
|
return result;
|
|
691
694
|
}
|
|
692
|
-
const BN_0$
|
|
695
|
+
const BN_0$8 = BigInt(0);
|
|
693
696
|
const BN_58 = BigInt(58);
|
|
694
697
|
/**
|
|
695
698
|
* Encode %%value%% as a Base58-encoded string.
|
|
@@ -715,7 +718,7 @@ function encodeBase58(_value) {
|
|
|
715
718
|
* Decode the Base58-encoded %%value%%.
|
|
716
719
|
*/
|
|
717
720
|
function decodeBase58(value) {
|
|
718
|
-
let result = BN_0$
|
|
721
|
+
let result = BN_0$8;
|
|
719
722
|
for (let i = 0; i < value.length; i++) {
|
|
720
723
|
result *= BN_58;
|
|
721
724
|
result += getAlpha(value[i]);
|
|
@@ -1909,7 +1912,7 @@ function wait(delay) {
|
|
|
1909
1912
|
* @_section: api/utils/fixed-point-math:Fixed-Point Maths [about-fixed-point-math]
|
|
1910
1913
|
*/
|
|
1911
1914
|
const BN_N1 = BigInt(-1);
|
|
1912
|
-
const BN_0$
|
|
1915
|
+
const BN_0$7 = BigInt(0);
|
|
1913
1916
|
const BN_1$3 = BigInt(1);
|
|
1914
1917
|
const BN_5 = BigInt(5);
|
|
1915
1918
|
const _guard$3 = {};
|
|
@@ -1933,7 +1936,7 @@ function checkValue(val, format, safeOp) {
|
|
|
1933
1936
|
assert(safeOp == null || (val >= -limit && val < limit), "overflow", "NUMERIC_FAULT", {
|
|
1934
1937
|
operation: safeOp, fault: "overflow", value: val
|
|
1935
1938
|
});
|
|
1936
|
-
if (val > BN_0$
|
|
1939
|
+
if (val > BN_0$7) {
|
|
1937
1940
|
val = fromTwos(mask(val, width), width);
|
|
1938
1941
|
}
|
|
1939
1942
|
else {
|
|
@@ -1991,7 +1994,7 @@ function getFormat(value) {
|
|
|
1991
1994
|
}
|
|
1992
1995
|
function toString(val, decimals) {
|
|
1993
1996
|
let negative = "";
|
|
1994
|
-
if (val < BN_0$
|
|
1997
|
+
if (val < BN_0$7) {
|
|
1995
1998
|
negative = "-";
|
|
1996
1999
|
val *= BN_N1;
|
|
1997
2000
|
}
|
|
@@ -2182,13 +2185,13 @@ class FixedNumber {
|
|
|
2182
2185
|
mulSignal(other) {
|
|
2183
2186
|
this.#checkFormat(other);
|
|
2184
2187
|
const value = this.#val * other.#val;
|
|
2185
|
-
assert((value % this.#tens) === BN_0$
|
|
2188
|
+
assert((value % this.#tens) === BN_0$7, "precision lost during signalling mul", "NUMERIC_FAULT", {
|
|
2186
2189
|
operation: "mulSignal", fault: "underflow", value: this
|
|
2187
2190
|
});
|
|
2188
2191
|
return this.#checkValue(value / this.#tens, "mulSignal");
|
|
2189
2192
|
}
|
|
2190
2193
|
#div(o, safeOp) {
|
|
2191
|
-
assert(o.#val !== BN_0$
|
|
2194
|
+
assert(o.#val !== BN_0$7, "division by zero", "NUMERIC_FAULT", {
|
|
2192
2195
|
operation: "div", fault: "divide-by-zero", value: this
|
|
2193
2196
|
});
|
|
2194
2197
|
this.#checkFormat(o);
|
|
@@ -2212,12 +2215,12 @@ class FixedNumber {
|
|
|
2212
2215
|
* (precision loss) occurs.
|
|
2213
2216
|
*/
|
|
2214
2217
|
divSignal(other) {
|
|
2215
|
-
assert(other.#val !== BN_0$
|
|
2218
|
+
assert(other.#val !== BN_0$7, "division by zero", "NUMERIC_FAULT", {
|
|
2216
2219
|
operation: "div", fault: "divide-by-zero", value: this
|
|
2217
2220
|
});
|
|
2218
2221
|
this.#checkFormat(other);
|
|
2219
2222
|
const value = (this.#val * this.#tens);
|
|
2220
|
-
assert((value % other.#val) === BN_0$
|
|
2223
|
+
assert((value % other.#val) === BN_0$7, "precision lost during signalling div", "NUMERIC_FAULT", {
|
|
2221
2224
|
operation: "divSignal", fault: "underflow", value: this
|
|
2222
2225
|
});
|
|
2223
2226
|
return this.#checkValue(value / other.#val, "divSignal");
|
|
@@ -2276,7 +2279,7 @@ class FixedNumber {
|
|
|
2276
2279
|
*/
|
|
2277
2280
|
floor() {
|
|
2278
2281
|
let val = this.#val;
|
|
2279
|
-
if (this.#val < BN_0$
|
|
2282
|
+
if (this.#val < BN_0$7) {
|
|
2280
2283
|
val -= this.#tens - BN_1$3;
|
|
2281
2284
|
}
|
|
2282
2285
|
val = (this.#val / this.#tens) * this.#tens;
|
|
@@ -2290,7 +2293,7 @@ class FixedNumber {
|
|
|
2290
2293
|
*/
|
|
2291
2294
|
ceiling() {
|
|
2292
2295
|
let val = this.#val;
|
|
2293
|
-
if (this.#val > BN_0$
|
|
2296
|
+
if (this.#val > BN_0$7) {
|
|
2294
2297
|
val += this.#tens - BN_1$3;
|
|
2295
2298
|
}
|
|
2296
2299
|
val = (this.#val / this.#tens) * this.#tens;
|
|
@@ -2319,11 +2322,11 @@ class FixedNumber {
|
|
|
2319
2322
|
/**
|
|
2320
2323
|
* Returns true if %%this%% is equal to ``0``.
|
|
2321
2324
|
*/
|
|
2322
|
-
isZero() { return (this.#val === BN_0$
|
|
2325
|
+
isZero() { return (this.#val === BN_0$7); }
|
|
2323
2326
|
/**
|
|
2324
2327
|
* Returns true if %%this%% is less than ``0``.
|
|
2325
2328
|
*/
|
|
2326
|
-
isNegative() { return (this.#val < BN_0$
|
|
2329
|
+
isNegative() { return (this.#val < BN_0$7); }
|
|
2327
2330
|
/**
|
|
2328
2331
|
* Returns the string representation of %%this%%.
|
|
2329
2332
|
*/
|
|
@@ -2360,7 +2363,7 @@ class FixedNumber {
|
|
|
2360
2363
|
const delta = decimals - format.decimals;
|
|
2361
2364
|
if (delta > 0) {
|
|
2362
2365
|
const tens = getTens(delta);
|
|
2363
|
-
assert((value % tens) === BN_0$
|
|
2366
|
+
assert((value % tens) === BN_0$7, "value loses precision for format", "NUMERIC_FAULT", {
|
|
2364
2367
|
operation: "fromValue", fault: "underflow", value: _value
|
|
2365
2368
|
});
|
|
2366
2369
|
value /= tens;
|
|
@@ -4773,11 +4776,6 @@ const EtherSymbol = "\u039e"; // "\uD835\uDF63";
|
|
|
4773
4776
|
const MessagePrefix = "\x19Ethereum Signed Message:\n";
|
|
4774
4777
|
|
|
4775
4778
|
// Constants
|
|
4776
|
-
const BN_0$7 = BigInt(0);
|
|
4777
|
-
//const BN_1 = BigInt(1);
|
|
4778
|
-
const BN_2$3 = BigInt(2);
|
|
4779
|
-
const BN_28$1 = BigInt(28);
|
|
4780
|
-
const BN_35$1 = BigInt(35);
|
|
4781
4779
|
const _guard$1 = {};
|
|
4782
4780
|
/*
|
|
4783
4781
|
function toUint256(value: BigNumberish): string {
|
|
@@ -4793,7 +4791,6 @@ class Signature {
|
|
|
4793
4791
|
#r;
|
|
4794
4792
|
#s;
|
|
4795
4793
|
#v;
|
|
4796
|
-
#networkV;
|
|
4797
4794
|
/**
|
|
4798
4795
|
* The ``r`` value for a signature.
|
|
4799
4796
|
*
|
|
@@ -4814,67 +4811,22 @@ class Signature {
|
|
|
4814
4811
|
}
|
|
4815
4812
|
/**
|
|
4816
4813
|
* The ``v`` value for a signature.
|
|
4817
|
-
*
|
|
4818
|
-
* Since a given ``x`` value for ``r`` has two possible values for
|
|
4819
|
-
* its correspondin ``y``, the ``v`` indicates which of the two ``y``
|
|
4820
|
-
* values to use.
|
|
4821
|
-
*
|
|
4822
|
-
* It is normalized to the values ``28`` or ``28`` for legacy
|
|
4823
|
-
* purposes.
|
|
4824
4814
|
*/
|
|
4825
4815
|
get v() { return this.#v; }
|
|
4826
4816
|
set v(value) {
|
|
4827
4817
|
const v = getNumber(value, "value");
|
|
4828
|
-
assertArgument(v ===
|
|
4818
|
+
assertArgument(v === 1, "invalid v", "v", value);
|
|
4829
4819
|
this.#v = v;
|
|
4830
4820
|
}
|
|
4831
|
-
/**
|
|
4832
|
-
* The EIP-155 ``v`` for legacy transactions. For non-legacy
|
|
4833
|
-
* transactions, this value is ``null``.
|
|
4834
|
-
*/
|
|
4835
|
-
get networkV() { return this.#networkV; }
|
|
4836
|
-
/**
|
|
4837
|
-
* The chain ID for EIP-155 legacy transactions. For non-legacy
|
|
4838
|
-
* transactions, this value is ``null``.
|
|
4839
|
-
*/
|
|
4840
|
-
get legacyChainId() {
|
|
4841
|
-
const v = this.networkV;
|
|
4842
|
-
if (v == null) {
|
|
4843
|
-
return null;
|
|
4844
|
-
}
|
|
4845
|
-
return Signature.getChainId(v);
|
|
4846
|
-
}
|
|
4847
|
-
/**
|
|
4848
|
-
* The ``yParity`` for the signature.
|
|
4849
|
-
*
|
|
4850
|
-
* See ``v`` for more details on how this value is used.
|
|
4851
|
-
*/
|
|
4852
|
-
get yParity() {
|
|
4853
|
-
return (this.v === 28) ? 0 : 1;
|
|
4854
|
-
}
|
|
4855
|
-
/**
|
|
4856
|
-
* The [[link-eip-2098]] compact representation of the ``yParity``
|
|
4857
|
-
* and ``s`` compacted into a single ``bytes32``.
|
|
4858
|
-
*/
|
|
4859
|
-
get yParityAndS() {
|
|
4860
|
-
// The EIP-2098 compact representation
|
|
4861
|
-
const yParityAndS = getBytes(this.s);
|
|
4862
|
-
if (this.yParity) {
|
|
4863
|
-
yParityAndS[0] |= 0x80;
|
|
4864
|
-
}
|
|
4865
|
-
return hexlify(yParityAndS);
|
|
4866
|
-
}
|
|
4867
|
-
/**
|
|
4868
|
-
* The [[link-eip-2098]] compact representation.
|
|
4869
|
-
*/
|
|
4870
|
-
get compactSerialized() {
|
|
4871
|
-
return concat([this.r, this.yParityAndS]);
|
|
4872
|
-
}
|
|
4873
4821
|
/**
|
|
4874
4822
|
* The serialized representation.
|
|
4875
4823
|
*/
|
|
4876
4824
|
get serialized() {
|
|
4877
|
-
return
|
|
4825
|
+
return JSON.stringify({
|
|
4826
|
+
r: this.r,
|
|
4827
|
+
s: this.s,
|
|
4828
|
+
v: this.v
|
|
4829
|
+
});
|
|
4878
4830
|
}
|
|
4879
4831
|
/**
|
|
4880
4832
|
* @private
|
|
@@ -4884,94 +4836,26 @@ class Signature {
|
|
|
4884
4836
|
this.#r = r;
|
|
4885
4837
|
this.#s = s;
|
|
4886
4838
|
this.#v = v;
|
|
4887
|
-
this.#networkV = null;
|
|
4888
4839
|
}
|
|
4889
4840
|
[Symbol.for('nodejs.util.inspect.custom')]() {
|
|
4890
|
-
return `Signature { r: "${this.r}", s: "${this.s}"
|
|
4841
|
+
return `Signature { r: "${this.r}", s: "${this.s}" }`;
|
|
4891
4842
|
}
|
|
4892
4843
|
/**
|
|
4893
4844
|
* Returns a new identical [[Signature]].
|
|
4894
4845
|
*/
|
|
4895
4846
|
clone() {
|
|
4896
4847
|
const clone = new Signature(_guard$1, this.r, this.s, this.v);
|
|
4897
|
-
if (this.networkV) {
|
|
4898
|
-
clone.#networkV = this.networkV;
|
|
4899
|
-
}
|
|
4900
4848
|
return clone;
|
|
4901
4849
|
}
|
|
4902
4850
|
/**
|
|
4903
4851
|
* Returns a representation that is compatible with ``JSON.stringify``.
|
|
4904
4852
|
*/
|
|
4905
4853
|
toJSON() {
|
|
4906
|
-
const networkV = this.networkV;
|
|
4907
4854
|
return {
|
|
4908
4855
|
_type: "signature",
|
|
4909
|
-
networkV: ((networkV != null) ? networkV.toString() : null),
|
|
4910
4856
|
r: this.r, s: this.s, v: this.v,
|
|
4911
4857
|
};
|
|
4912
4858
|
}
|
|
4913
|
-
/**
|
|
4914
|
-
* Compute the chain ID from the ``v`` in a legacy EIP-155 transactions.
|
|
4915
|
-
*
|
|
4916
|
-
* @example:
|
|
4917
|
-
* Signature.getChainId(45)
|
|
4918
|
-
* //_result:
|
|
4919
|
-
*
|
|
4920
|
-
* Signature.getChainId(46)
|
|
4921
|
-
* //_result:
|
|
4922
|
-
*/
|
|
4923
|
-
static getChainId(v) {
|
|
4924
|
-
const bv = getBigInt(v, "v");
|
|
4925
|
-
// The v is not an EIP-155 v, so it is the unspecified chain ID
|
|
4926
|
-
if ((bv == BN_28$1) || (bv == BN_28$1)) {
|
|
4927
|
-
return BN_0$7;
|
|
4928
|
-
}
|
|
4929
|
-
// Bad value for an EIP-155 v
|
|
4930
|
-
assertArgument(bv >= BN_35$1, "invalid EIP-155 v", "v", v);
|
|
4931
|
-
return (bv - BN_35$1) / BN_2$3;
|
|
4932
|
-
}
|
|
4933
|
-
/**
|
|
4934
|
-
* Compute the ``v`` for a chain ID for a legacy EIP-155 transactions.
|
|
4935
|
-
*
|
|
4936
|
-
* Legacy transactions which use [[link-eip-155]] hijack the ``v``
|
|
4937
|
-
* property to include the chain ID.
|
|
4938
|
-
*
|
|
4939
|
-
* @example:
|
|
4940
|
-
*
|
|
4941
|
-
* Signature.getChainIdV(5, 28)
|
|
4942
|
-
* //_result:
|
|
4943
|
-
*
|
|
4944
|
-
*/
|
|
4945
|
-
static getChainIdV(chainId, v) {
|
|
4946
|
-
return (getBigInt(chainId) * BN_2$3) + BigInt(35 + v - 28);
|
|
4947
|
-
}
|
|
4948
|
-
/**
|
|
4949
|
-
* Compute the normalized legacy transaction ``v`` from a ``yParirty``,
|
|
4950
|
-
* a legacy transaction ``v`` or a legacy [[link-eip-155]] transaction.
|
|
4951
|
-
*
|
|
4952
|
-
* @example:
|
|
4953
|
-
* // The values 0 and 1 imply v is actually yParity
|
|
4954
|
-
* Signature.getNormalizedV(0)
|
|
4955
|
-
* //_result:
|
|
4956
|
-
*
|
|
4957
|
-
* // Legacy EIP-155 transaction (i.e. >= 35)
|
|
4958
|
-
* Signature.getNormalizedV(46)
|
|
4959
|
-
* //_result:
|
|
4960
|
-
*
|
|
4961
|
-
* // Invalid values throw
|
|
4962
|
-
* Signature.getNormalizedV(5)
|
|
4963
|
-
* //_error:
|
|
4964
|
-
*/
|
|
4965
|
-
/*static getNormalizedV(v: BigNumberish): 28 {
|
|
4966
|
-
const bv = getBigInt(v);
|
|
4967
|
-
|
|
4968
|
-
if (bv === BN_1 || bv === BN_28) { return 28; }
|
|
4969
|
-
|
|
4970
|
-
assertArgument(bv >= BN_35, "invalid v", "v", v);
|
|
4971
|
-
|
|
4972
|
-
// Otherwise, EIP-155 v means odd is 28 and even is 28
|
|
4973
|
-
return (bv & BN_1) ? 28: 28;
|
|
4974
|
-
}*/
|
|
4975
4859
|
/**
|
|
4976
4860
|
* Creates a new [[Signature]].
|
|
4977
4861
|
*
|
|
@@ -4985,85 +4869,20 @@ class Signature {
|
|
|
4985
4869
|
assertArgument(check, message, "signature", sig);
|
|
4986
4870
|
}
|
|
4987
4871
|
if (sig == null) {
|
|
4988
|
-
return new Signature(_guard$1, ZeroHash, ZeroHash,
|
|
4872
|
+
return new Signature(_guard$1, ZeroHash, ZeroHash, 1);
|
|
4989
4873
|
}
|
|
4990
4874
|
if (typeof (sig) === "string") {
|
|
4991
|
-
|
|
4992
|
-
if (bytes.length === 64) {
|
|
4993
|
-
const r = hexlify(bytes.slice(0, 32));
|
|
4994
|
-
const s = bytes.slice(32, 64);
|
|
4995
|
-
const v = (s[0] & 0x80) ? 28: 28;
|
|
4996
|
-
s[0] &= 0x7f;
|
|
4997
|
-
return new Signature(_guard, r, hexlify(s), v);
|
|
4998
|
-
}
|
|
4999
|
-
|
|
5000
|
-
if (bytes.length === 65) {
|
|
5001
|
-
const r = hexlify(bytes.slice(0, 32));
|
|
5002
|
-
const s = bytes.slice(32, 64);
|
|
5003
|
-
assertError((s[0] & 0x80) === 0, "non-canonical s");
|
|
5004
|
-
const v = Signature.getNormalizedV(bytes[64]);
|
|
5005
|
-
return new Signature(_guard, r, hexlify(s), v);
|
|
5006
|
-
}*/
|
|
5007
|
-
assertError(false, "invalid raw signature length");
|
|
4875
|
+
assertError(false, "invalid raw signature");
|
|
5008
4876
|
}
|
|
5009
4877
|
if (sig instanceof Signature) {
|
|
5010
4878
|
return sig.clone();
|
|
5011
4879
|
}
|
|
5012
|
-
|
|
5013
|
-
|
|
5014
|
-
const
|
|
5015
|
-
assertError(
|
|
5016
|
-
|
|
5017
|
-
|
|
5018
|
-
// Get s; by any means necessary (we check consistency below)
|
|
5019
|
-
const s = (function(s?: string, yParityAndS?: string) {
|
|
5020
|
-
if (s != null) { return toUint256(s); }
|
|
5021
|
-
|
|
5022
|
-
if (yParityAndS != null) {
|
|
5023
|
-
assertError(isHexString(yParityAndS, 32), "invalid yParityAndS");
|
|
5024
|
-
const bytes = getBytes(yParityAndS);
|
|
5025
|
-
bytes[0] &= 0x7f;
|
|
5026
|
-
return hexlify(bytes);
|
|
5027
|
-
}
|
|
5028
|
-
|
|
5029
|
-
assertError(false, "missing s");
|
|
5030
|
-
})(sig.s, sig.yParityAndS);
|
|
5031
|
-
assertError((getBytes(s)[0] & 0x80) == 0, "non-canonical s");
|
|
5032
|
-
|
|
5033
|
-
// Get v; by any means necessary (we check consistency below)
|
|
5034
|
-
const { networkV, v } = (function(_v?: BigNumberish, yParityAndS?: string, yParity?: Numeric): { networkV?: bigint, v: 28 | 28 } {
|
|
5035
|
-
if (_v != null) {
|
|
5036
|
-
const v = getBigInt(_v);
|
|
5037
|
-
return {
|
|
5038
|
-
networkV: ((v >= BN_35) ? v: undefined),
|
|
5039
|
-
v: Signature.getNormalizedV(v)
|
|
5040
|
-
};
|
|
5041
|
-
}
|
|
5042
|
-
|
|
5043
|
-
if (yParityAndS != null) {
|
|
5044
|
-
assertError(isHexString(yParityAndS, 32), "invalid yParityAndS");
|
|
5045
|
-
return { v: ((getBytes(yParityAndS)[0] & 0x80) ? 28: 28) };
|
|
5046
|
-
}
|
|
5047
|
-
|
|
5048
|
-
if (yParity != null) {
|
|
5049
|
-
switch (getNumber(yParity, "sig.yParity")) {
|
|
5050
|
-
case 0: return { v: 28 };
|
|
5051
|
-
case 1: return { v: 28 };
|
|
5052
|
-
}
|
|
5053
|
-
assertError(false, "invalid yParity");
|
|
5054
|
-
}
|
|
5055
|
-
|
|
5056
|
-
assertError(false, "missing v");
|
|
5057
|
-
})(sig.v, sig.yParityAndS, sig.yParity);
|
|
5058
|
-
|
|
5059
|
-
const result = new Signature(_guard, r, s, v);
|
|
5060
|
-
if (networkV) { result.#networkV = networkV; }
|
|
5061
|
-
|
|
5062
|
-
// If multiple of v, yParity, yParityAndS we given, check they match
|
|
5063
|
-
assertError(sig.yParity == null || getNumber(sig.yParity, "sig.yParity") === result.yParity, "yParity mismatch");
|
|
5064
|
-
assertError(sig.yParityAndS == null || sig.yParityAndS === result.yParityAndS, "yParityAndS mismatch");
|
|
5065
|
-
|
|
5066
|
-
return result;*/
|
|
4880
|
+
assertError(sig.r != null, "missing r");
|
|
4881
|
+
assertError(sig.s != null, "missing s");
|
|
4882
|
+
const _v = sig.v;
|
|
4883
|
+
assertError(_v != null, "missing v");
|
|
4884
|
+
assertArgument(_v === 1, "invalid v", "v", sig.v);
|
|
4885
|
+
return new Signature(_guard$1, sig.r, sig.s, 1);
|
|
5067
4886
|
}
|
|
5068
4887
|
}
|
|
5069
4888
|
|
|
@@ -5074,7 +4893,7 @@ class Signature {
|
|
|
5074
4893
|
*/
|
|
5075
4894
|
const CRYPTO_MESSAGE_LENGTH = 32;
|
|
5076
4895
|
const CRYPTO_SECRETKEY_BYTES = 64 + 2560 + 1312 + 128;
|
|
5077
|
-
|
|
4896
|
+
const CRYPTO_PUBLICKEY_BYTES = 32 + 1312 + 64;
|
|
5078
4897
|
/**
|
|
5079
4898
|
* A **SigningKey** provides high-level access to cryptography operations and key management.
|
|
5080
4899
|
*/
|
|
@@ -5101,9 +4920,10 @@ class SigningKey {
|
|
|
5101
4920
|
*/
|
|
5102
4921
|
sign(digest) {
|
|
5103
4922
|
assertArgument(dataLength(digest) === CRYPTO_MESSAGE_LENGTH, "invalid digest length", "digest", digest);
|
|
5104
|
-
const sig =
|
|
4923
|
+
const sig = cryptoSign(getBytesCopy(digest), getBytesCopy(this.#privateKey));
|
|
5105
4924
|
const pubBytes = getBytes(this.publicKey);
|
|
5106
|
-
|
|
4925
|
+
let combinedSig = combinePublicKeySignature(pubBytes, sig);
|
|
4926
|
+
combinedSig = "0x" + combinedSig;
|
|
5107
4927
|
return Signature.from({
|
|
5108
4928
|
r: this.publicKey,
|
|
5109
4929
|
s: combinedSig,
|
|
@@ -5111,7 +4931,7 @@ class SigningKey {
|
|
|
5111
4931
|
});
|
|
5112
4932
|
}
|
|
5113
4933
|
/**
|
|
5114
|
-
* Compute the public key for a private %%key%%.
|
|
4934
|
+
* Compute the public key for a private %%key%%. If a publicKey is passed, it is returned as is. for backward compatibility.
|
|
5115
4935
|
*
|
|
5116
4936
|
*
|
|
5117
4937
|
* @example:
|
|
@@ -5122,9 +4942,17 @@ class SigningKey {
|
|
|
5122
4942
|
* //_result:
|
|
5123
4943
|
*/
|
|
5124
4944
|
static computePublicKey(key) {
|
|
5125
|
-
|
|
5126
|
-
let
|
|
5127
|
-
|
|
4945
|
+
let keyBytes = getBytes(key, "key");
|
|
4946
|
+
let pubKey;
|
|
4947
|
+
if (keyBytes.length == CRYPTO_SECRETKEY_BYTES) {
|
|
4948
|
+
pubKey = publicKeyFromPrivateKey(keyBytes);
|
|
4949
|
+
assertArgument(pubKey !== null && pubKey !== undefined, "invalid key", "key", "[REDACTED]");
|
|
4950
|
+
pubKey = '0x' + pubKey;
|
|
4951
|
+
}
|
|
4952
|
+
else if (keyBytes.length == CRYPTO_PUBLICKEY_BYTES) {
|
|
4953
|
+
pubKey = keyBytes;
|
|
4954
|
+
}
|
|
4955
|
+
assertArgument(pubKey !== null && pubKey !== undefined, "invalid key", "key", "[REDACTED]");
|
|
5128
4956
|
return pubKey;
|
|
5129
4957
|
}
|
|
5130
4958
|
/**
|
|
@@ -5150,7 +4978,7 @@ class SigningKey {
|
|
|
5150
4978
|
const sig = Signature.from(signature);
|
|
5151
4979
|
let sigBytes = getBytes(sig.s);
|
|
5152
4980
|
let digestBytes = digest;
|
|
5153
|
-
let publicKey =
|
|
4981
|
+
let publicKey = publicKeyFromSignature(digestBytes, sigBytes);
|
|
5154
4982
|
return publicKey;
|
|
5155
4983
|
}
|
|
5156
4984
|
}
|
|
@@ -6554,13 +6382,18 @@ function authorizationify(auth) {
|
|
|
6554
6382
|
function computeAddress(key) {
|
|
6555
6383
|
let pubkey;
|
|
6556
6384
|
if (typeof (key) === "string") {
|
|
6557
|
-
|
|
6385
|
+
if (key.startsWith("0x")) {
|
|
6386
|
+
pubkey = SigningKey.computePublicKey(key);
|
|
6387
|
+
}
|
|
6388
|
+
else {
|
|
6389
|
+
pubkey = SigningKey.computePublicKey("0x" + key);
|
|
6390
|
+
}
|
|
6558
6391
|
}
|
|
6559
6392
|
else {
|
|
6560
6393
|
pubkey = key.publicKey;
|
|
6561
6394
|
}
|
|
6562
6395
|
let pubKeyBytes = getBytes(pubkey);
|
|
6563
|
-
return
|
|
6396
|
+
return addressFromPublicKey(pubKeyBytes);
|
|
6564
6397
|
}
|
|
6565
6398
|
/**
|
|
6566
6399
|
* Returns the recovered address for the private key that was
|
|
@@ -6657,9 +6490,9 @@ function handleAuthorizationList(value, param) {
|
|
|
6657
6490
|
nonce: handleUint(auth[2], "nonce"),
|
|
6658
6491
|
chainId: handleUint(auth[0], "chainId"),
|
|
6659
6492
|
signature: Signature.from({
|
|
6660
|
-
|
|
6661
|
-
|
|
6662
|
-
|
|
6493
|
+
r: auth[4],
|
|
6494
|
+
s: auth[5],
|
|
6495
|
+
v: 1
|
|
6663
6496
|
})
|
|
6664
6497
|
});
|
|
6665
6498
|
}
|
|
@@ -6698,7 +6531,6 @@ function formatAuthorizationList(value) {
|
|
|
6698
6531
|
formatNumber(a.chainId, "chainId"),
|
|
6699
6532
|
a.address,
|
|
6700
6533
|
formatNumber(a.nonce, "nonce"),
|
|
6701
|
-
formatNumber(a.signature.yParity, "yParity"),
|
|
6702
6534
|
a.signature.r,
|
|
6703
6535
|
a.signature.s
|
|
6704
6536
|
];
|
|
@@ -6766,17 +6598,8 @@ function _serializeLegacy(tx, sig) {
|
|
|
6766
6598
|
if (tx.chainId != BN_0$4) {
|
|
6767
6599
|
// A chainId was provided; if non-zero we'll use EIP-155
|
|
6768
6600
|
chainId = getBigInt(tx.chainId, "tx.chainId");
|
|
6769
|
-
// We have a chainId in the tx and an EIP-155 v in the signature,
|
|
6770
|
-
// make sure they agree with each other
|
|
6771
|
-
assertArgument(!sig || sig.networkV == null || sig.legacyChainId === chainId, "tx.chainId/sig.v mismatch", "sig", sig);
|
|
6772
|
-
}
|
|
6773
|
-
else if (tx.signature) {
|
|
6774
|
-
// No explicit chainId, but EIP-155 have a derived implicit chainId
|
|
6775
|
-
const legacy = tx.signature.legacyChainId;
|
|
6776
|
-
if (legacy != null) {
|
|
6777
|
-
chainId = legacy;
|
|
6778
|
-
}
|
|
6779
6601
|
}
|
|
6602
|
+
else if (tx.signature) ;
|
|
6780
6603
|
// Requesting an unsigned transaction
|
|
6781
6604
|
if (!sig) {
|
|
6782
6605
|
// We have an EIP-155 transaction (chainId was specified and non-zero)
|
|
@@ -6787,17 +6610,7 @@ function _serializeLegacy(tx, sig) {
|
|
|
6787
6610
|
}
|
|
6788
6611
|
return encodeRlp(fields);
|
|
6789
6612
|
}
|
|
6790
|
-
|
|
6791
|
-
// match but that logic could break existing code, so schedule
|
|
6792
|
-
// this for the next major bump.
|
|
6793
|
-
// Compute the EIP-155 v
|
|
6794
|
-
let v = BigInt(27 + sig.yParity);
|
|
6795
|
-
if (chainId !== BN_0$4) {
|
|
6796
|
-
v = Signature.getChainIdV(chainId, sig.v);
|
|
6797
|
-
}
|
|
6798
|
-
else if (BigInt(sig.v) !== v) {
|
|
6799
|
-
assertArgument(false, "tx.chainId/sig.v mismatch", "sig", sig);
|
|
6800
|
-
}
|
|
6613
|
+
let v = sig.v;
|
|
6801
6614
|
// Add the signature
|
|
6802
6615
|
fields.push(toBeArray(v));
|
|
6803
6616
|
fields.push(toBeArray(sig.r));
|
|
@@ -6805,19 +6618,9 @@ function _serializeLegacy(tx, sig) {
|
|
|
6805
6618
|
return encodeRlp(fields);
|
|
6806
6619
|
}
|
|
6807
6620
|
function _parseEipSignature(tx, fields) {
|
|
6808
|
-
|
|
6809
|
-
|
|
6810
|
-
|
|
6811
|
-
if (yParity !== 0 && yParity !== 1) {
|
|
6812
|
-
throw new Error("bad yParity");
|
|
6813
|
-
}
|
|
6814
|
-
}
|
|
6815
|
-
catch (error) {
|
|
6816
|
-
assertArgument(false, "invalid yParity", "yParity", fields[0]);
|
|
6817
|
-
}
|
|
6818
|
-
const r = zeroPadValue(fields[1], 32);
|
|
6819
|
-
const s = zeroPadValue(fields[2], 32);
|
|
6820
|
-
const signature = Signature.from({ r, s, yParity });
|
|
6621
|
+
const r = fields[1];
|
|
6622
|
+
const s = fields[2];
|
|
6623
|
+
const signature = Signature.from({ r, s });
|
|
6821
6624
|
tx.signature = signature;
|
|
6822
6625
|
}
|
|
6823
6626
|
function _parseEip1559(data) {
|
|
@@ -6857,7 +6660,6 @@ function _serializeEip1559(tx, sig) {
|
|
|
6857
6660
|
formatAccessList(tx.accessList || [])
|
|
6858
6661
|
];
|
|
6859
6662
|
if (sig) {
|
|
6860
|
-
fields.push(formatNumber(sig.yParity, "yParity"));
|
|
6861
6663
|
fields.push(toBeArray(sig.r));
|
|
6862
6664
|
fields.push(toBeArray(sig.s));
|
|
6863
6665
|
}
|
|
@@ -6897,7 +6699,6 @@ function _serializeEip2930(tx, sig) {
|
|
|
6897
6699
|
formatAccessList(tx.accessList || [])
|
|
6898
6700
|
];
|
|
6899
6701
|
if (sig) {
|
|
6900
|
-
fields.push(formatNumber(sig.yParity, "recoveryParam"));
|
|
6901
6702
|
fields.push(toBeArray(sig.r));
|
|
6902
6703
|
fields.push(toBeArray(sig.s));
|
|
6903
6704
|
}
|
|
@@ -6975,7 +6776,6 @@ function _serializeEip4844(tx, sig, blobs) {
|
|
|
6975
6776
|
formatHashes(tx.blobVersionedHashes || [], "blobVersionedHashes")
|
|
6976
6777
|
];
|
|
6977
6778
|
if (sig) {
|
|
6978
|
-
fields.push(formatNumber(sig.yParity, "yParity"));
|
|
6979
6779
|
fields.push(toBeArray(sig.r));
|
|
6980
6780
|
fields.push(toBeArray(sig.s));
|
|
6981
6781
|
// We have blobs; return the network wrapped format
|
|
@@ -7031,7 +6831,6 @@ function _serializeEip7702(tx, sig) {
|
|
|
7031
6831
|
formatAuthorizationList(tx.authorizationList || [])
|
|
7032
6832
|
];
|
|
7033
6833
|
if (sig) {
|
|
7034
|
-
fields.push(formatNumber(sig.yParity, "yParity"));
|
|
7035
6834
|
fields.push(toBeArray(sig.r));
|
|
7036
6835
|
fields.push(toBeArray(sig.s));
|
|
7037
6836
|
}
|
|
@@ -7752,276 +7551,276 @@ var COMPRESSED$1 = 'AEEUdwmgDS8BxQKKAP4BOgDjATAAngDUAIMAoABoAOAAagCOAEQAhABMAHIA
|
|
|
7752
7551
|
const FENCED = new Map([[8217,"apostrophe"],[8260,"fraction slash"],[12539,"middle dot"]]);
|
|
7753
7552
|
const NSM_MAX = 4;
|
|
7754
7553
|
|
|
7755
|
-
function decode_arithmetic(bytes) {
|
|
7756
|
-
let pos = 0;
|
|
7757
|
-
function u16() { return (bytes[pos++] << 8) | bytes[pos++]; }
|
|
7758
|
-
|
|
7759
|
-
// decode the frequency table
|
|
7760
|
-
let symbol_count = u16();
|
|
7761
|
-
let total = 1;
|
|
7762
|
-
let acc = [0, 1]; // first symbol has frequency 1
|
|
7763
|
-
for (let i = 1; i < symbol_count; i++) {
|
|
7764
|
-
acc.push(total += u16());
|
|
7765
|
-
}
|
|
7766
|
-
|
|
7767
|
-
// skip the sized-payload that the last 3 symbols index into
|
|
7768
|
-
let skip = u16();
|
|
7769
|
-
let pos_payload = pos;
|
|
7770
|
-
pos += skip;
|
|
7771
|
-
|
|
7772
|
-
let read_width = 0;
|
|
7773
|
-
let read_buffer = 0;
|
|
7774
|
-
function read_bit() {
|
|
7775
|
-
if (read_width == 0) {
|
|
7776
|
-
// this will read beyond end of buffer
|
|
7777
|
-
// but (undefined|0) => zero pad
|
|
7778
|
-
read_buffer = (read_buffer << 8) | bytes[pos++];
|
|
7779
|
-
read_width = 8;
|
|
7780
|
-
}
|
|
7781
|
-
return (read_buffer >> --read_width) & 1;
|
|
7782
|
-
}
|
|
7783
|
-
|
|
7784
|
-
const N = 31;
|
|
7785
|
-
const FULL = 2**N;
|
|
7786
|
-
const HALF = FULL >>> 1;
|
|
7787
|
-
const QRTR = HALF >> 1;
|
|
7788
|
-
const MASK = FULL - 1;
|
|
7789
|
-
|
|
7790
|
-
// fill register
|
|
7791
|
-
let register = 0;
|
|
7792
|
-
for (let i = 0; i < N; i++) register = (register << 1) | read_bit();
|
|
7793
|
-
|
|
7794
|
-
let symbols = [];
|
|
7795
|
-
let low = 0;
|
|
7796
|
-
let range = FULL; // treat like a float
|
|
7797
|
-
while (true) {
|
|
7798
|
-
let value = Math.floor((((register - low + 1) * total) - 1) / range);
|
|
7799
|
-
let start = 0;
|
|
7800
|
-
let end = symbol_count;
|
|
7801
|
-
while (end - start > 1) { // binary search
|
|
7802
|
-
let mid = (start + end) >>> 1;
|
|
7803
|
-
if (value < acc[mid]) {
|
|
7804
|
-
end = mid;
|
|
7805
|
-
} else {
|
|
7806
|
-
start = mid;
|
|
7807
|
-
}
|
|
7808
|
-
}
|
|
7809
|
-
if (start == 0) break; // first symbol is end mark
|
|
7810
|
-
symbols.push(start);
|
|
7811
|
-
let a = low + Math.floor(range * acc[start] / total);
|
|
7812
|
-
let b = low + Math.floor(range * acc[start+1] / total) - 1;
|
|
7813
|
-
while (((a ^ b) & HALF) == 0) {
|
|
7814
|
-
register = (register << 1) & MASK | read_bit();
|
|
7815
|
-
a = (a << 1) & MASK;
|
|
7816
|
-
b = (b << 1) & MASK | 1;
|
|
7817
|
-
}
|
|
7818
|
-
while (a & ~b & QRTR) {
|
|
7819
|
-
register = (register & HALF) | ((register << 1) & (MASK >>> 1)) | read_bit();
|
|
7820
|
-
a = (a << 1) ^ HALF;
|
|
7821
|
-
b = ((b ^ HALF) << 1) | HALF | 1;
|
|
7822
|
-
}
|
|
7823
|
-
low = a;
|
|
7824
|
-
range = 1 + b - a;
|
|
7825
|
-
}
|
|
7826
|
-
let offset = symbol_count - 4;
|
|
7827
|
-
return symbols.map(x => { // index into payload
|
|
7828
|
-
switch (x - offset) {
|
|
7829
|
-
case 3: return offset + 0x10100 + ((bytes[pos_payload++] << 16) | (bytes[pos_payload++] << 8) | bytes[pos_payload++]);
|
|
7830
|
-
case 2: return offset + 0x100 + ((bytes[pos_payload++] << 8) | bytes[pos_payload++]);
|
|
7831
|
-
case 1: return offset + bytes[pos_payload++];
|
|
7832
|
-
default: return x - 1;
|
|
7833
|
-
}
|
|
7834
|
-
});
|
|
7835
|
-
}
|
|
7836
|
-
|
|
7837
|
-
// returns an iterator which returns the next symbol
|
|
7838
|
-
function read_payload(v) {
|
|
7839
|
-
let pos = 0;
|
|
7840
|
-
return () => v[pos++];
|
|
7841
|
-
}
|
|
7842
|
-
function read_compressed_payload(s) {
|
|
7843
|
-
return read_payload(decode_arithmetic(unsafe_atob(s)));
|
|
7844
|
-
}
|
|
7845
|
-
|
|
7846
|
-
// unsafe in the sense:
|
|
7847
|
-
// expected well-formed Base64 w/o padding
|
|
7848
|
-
// 20220922: added for https://github.com/adraffy/ens-normalize.js/issues/4
|
|
7849
|
-
function unsafe_atob(s) {
|
|
7850
|
-
let lookup = [];
|
|
7851
|
-
[...'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'].forEach((c, i) => lookup[c.charCodeAt(0)] = i);
|
|
7852
|
-
let n = s.length;
|
|
7853
|
-
let ret = new Uint8Array((6 * n) >> 3);
|
|
7854
|
-
for (let i = 0, pos = 0, width = 0, carry = 0; i < n; i++) {
|
|
7855
|
-
carry = (carry << 6) | lookup[s.charCodeAt(i)];
|
|
7856
|
-
width += 6;
|
|
7857
|
-
if (width >= 8) {
|
|
7858
|
-
ret[pos++] = (carry >> (width -= 8));
|
|
7859
|
-
}
|
|
7860
|
-
}
|
|
7861
|
-
return ret;
|
|
7862
|
-
}
|
|
7863
|
-
|
|
7864
|
-
// eg. [0,1,2,3...] => [0,-1,1,-2,...]
|
|
7865
|
-
function signed(i) {
|
|
7866
|
-
return (i & 1) ? (~i >> 1) : (i >> 1);
|
|
7867
|
-
}
|
|
7868
|
-
|
|
7869
|
-
function read_deltas(n, next) {
|
|
7870
|
-
let v = Array(n);
|
|
7871
|
-
for (let i = 0, x = 0; i < n; i++) v[i] = x += signed(next());
|
|
7872
|
-
return v;
|
|
7873
|
-
}
|
|
7874
|
-
|
|
7875
|
-
// [123][5] => [0 3] [1 1] [0 0]
|
|
7876
|
-
function read_sorted(next, prev = 0) {
|
|
7877
|
-
let ret = [];
|
|
7878
|
-
while (true) {
|
|
7879
|
-
let x = next();
|
|
7880
|
-
let n = next();
|
|
7881
|
-
if (!n) break;
|
|
7882
|
-
prev += x;
|
|
7883
|
-
for (let i = 0; i < n; i++) {
|
|
7884
|
-
ret.push(prev + i);
|
|
7885
|
-
}
|
|
7886
|
-
prev += n + 1;
|
|
7887
|
-
}
|
|
7888
|
-
return ret;
|
|
7889
|
-
}
|
|
7890
|
-
|
|
7891
|
-
function read_sorted_arrays(next) {
|
|
7892
|
-
return read_array_while(() => {
|
|
7893
|
-
let v = read_sorted(next);
|
|
7894
|
-
if (v.length) return v;
|
|
7895
|
-
});
|
|
7896
|
-
}
|
|
7897
|
-
|
|
7898
|
-
// returns map of x => ys
|
|
7899
|
-
function read_mapped(next) {
|
|
7900
|
-
let ret = [];
|
|
7901
|
-
while (true) {
|
|
7902
|
-
let w = next();
|
|
7903
|
-
if (w == 0) break;
|
|
7904
|
-
ret.push(read_linear_table(w, next));
|
|
7905
|
-
}
|
|
7906
|
-
while (true) {
|
|
7907
|
-
let w = next() - 1;
|
|
7908
|
-
if (w < 0) break;
|
|
7909
|
-
ret.push(read_replacement_table(w, next));
|
|
7910
|
-
}
|
|
7911
|
-
return ret.flat();
|
|
7554
|
+
function decode_arithmetic(bytes) {
|
|
7555
|
+
let pos = 0;
|
|
7556
|
+
function u16() { return (bytes[pos++] << 8) | bytes[pos++]; }
|
|
7557
|
+
|
|
7558
|
+
// decode the frequency table
|
|
7559
|
+
let symbol_count = u16();
|
|
7560
|
+
let total = 1;
|
|
7561
|
+
let acc = [0, 1]; // first symbol has frequency 1
|
|
7562
|
+
for (let i = 1; i < symbol_count; i++) {
|
|
7563
|
+
acc.push(total += u16());
|
|
7564
|
+
}
|
|
7565
|
+
|
|
7566
|
+
// skip the sized-payload that the last 3 symbols index into
|
|
7567
|
+
let skip = u16();
|
|
7568
|
+
let pos_payload = pos;
|
|
7569
|
+
pos += skip;
|
|
7570
|
+
|
|
7571
|
+
let read_width = 0;
|
|
7572
|
+
let read_buffer = 0;
|
|
7573
|
+
function read_bit() {
|
|
7574
|
+
if (read_width == 0) {
|
|
7575
|
+
// this will read beyond end of buffer
|
|
7576
|
+
// but (undefined|0) => zero pad
|
|
7577
|
+
read_buffer = (read_buffer << 8) | bytes[pos++];
|
|
7578
|
+
read_width = 8;
|
|
7579
|
+
}
|
|
7580
|
+
return (read_buffer >> --read_width) & 1;
|
|
7581
|
+
}
|
|
7582
|
+
|
|
7583
|
+
const N = 31;
|
|
7584
|
+
const FULL = 2**N;
|
|
7585
|
+
const HALF = FULL >>> 1;
|
|
7586
|
+
const QRTR = HALF >> 1;
|
|
7587
|
+
const MASK = FULL - 1;
|
|
7588
|
+
|
|
7589
|
+
// fill register
|
|
7590
|
+
let register = 0;
|
|
7591
|
+
for (let i = 0; i < N; i++) register = (register << 1) | read_bit();
|
|
7592
|
+
|
|
7593
|
+
let symbols = [];
|
|
7594
|
+
let low = 0;
|
|
7595
|
+
let range = FULL; // treat like a float
|
|
7596
|
+
while (true) {
|
|
7597
|
+
let value = Math.floor((((register - low + 1) * total) - 1) / range);
|
|
7598
|
+
let start = 0;
|
|
7599
|
+
let end = symbol_count;
|
|
7600
|
+
while (end - start > 1) { // binary search
|
|
7601
|
+
let mid = (start + end) >>> 1;
|
|
7602
|
+
if (value < acc[mid]) {
|
|
7603
|
+
end = mid;
|
|
7604
|
+
} else {
|
|
7605
|
+
start = mid;
|
|
7606
|
+
}
|
|
7607
|
+
}
|
|
7608
|
+
if (start == 0) break; // first symbol is end mark
|
|
7609
|
+
symbols.push(start);
|
|
7610
|
+
let a = low + Math.floor(range * acc[start] / total);
|
|
7611
|
+
let b = low + Math.floor(range * acc[start+1] / total) - 1;
|
|
7612
|
+
while (((a ^ b) & HALF) == 0) {
|
|
7613
|
+
register = (register << 1) & MASK | read_bit();
|
|
7614
|
+
a = (a << 1) & MASK;
|
|
7615
|
+
b = (b << 1) & MASK | 1;
|
|
7616
|
+
}
|
|
7617
|
+
while (a & ~b & QRTR) {
|
|
7618
|
+
register = (register & HALF) | ((register << 1) & (MASK >>> 1)) | read_bit();
|
|
7619
|
+
a = (a << 1) ^ HALF;
|
|
7620
|
+
b = ((b ^ HALF) << 1) | HALF | 1;
|
|
7621
|
+
}
|
|
7622
|
+
low = a;
|
|
7623
|
+
range = 1 + b - a;
|
|
7624
|
+
}
|
|
7625
|
+
let offset = symbol_count - 4;
|
|
7626
|
+
return symbols.map(x => { // index into payload
|
|
7627
|
+
switch (x - offset) {
|
|
7628
|
+
case 3: return offset + 0x10100 + ((bytes[pos_payload++] << 16) | (bytes[pos_payload++] << 8) | bytes[pos_payload++]);
|
|
7629
|
+
case 2: return offset + 0x100 + ((bytes[pos_payload++] << 8) | bytes[pos_payload++]);
|
|
7630
|
+
case 1: return offset + bytes[pos_payload++];
|
|
7631
|
+
default: return x - 1;
|
|
7632
|
+
}
|
|
7633
|
+
});
|
|
7634
|
+
}
|
|
7635
|
+
|
|
7636
|
+
// returns an iterator which returns the next symbol
|
|
7637
|
+
function read_payload(v) {
|
|
7638
|
+
let pos = 0;
|
|
7639
|
+
return () => v[pos++];
|
|
7640
|
+
}
|
|
7641
|
+
function read_compressed_payload(s) {
|
|
7642
|
+
return read_payload(decode_arithmetic(unsafe_atob(s)));
|
|
7643
|
+
}
|
|
7644
|
+
|
|
7645
|
+
// unsafe in the sense:
|
|
7646
|
+
// expected well-formed Base64 w/o padding
|
|
7647
|
+
// 20220922: added for https://github.com/adraffy/ens-normalize.js/issues/4
|
|
7648
|
+
function unsafe_atob(s) {
|
|
7649
|
+
let lookup = [];
|
|
7650
|
+
[...'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'].forEach((c, i) => lookup[c.charCodeAt(0)] = i);
|
|
7651
|
+
let n = s.length;
|
|
7652
|
+
let ret = new Uint8Array((6 * n) >> 3);
|
|
7653
|
+
for (let i = 0, pos = 0, width = 0, carry = 0; i < n; i++) {
|
|
7654
|
+
carry = (carry << 6) | lookup[s.charCodeAt(i)];
|
|
7655
|
+
width += 6;
|
|
7656
|
+
if (width >= 8) {
|
|
7657
|
+
ret[pos++] = (carry >> (width -= 8));
|
|
7658
|
+
}
|
|
7659
|
+
}
|
|
7660
|
+
return ret;
|
|
7661
|
+
}
|
|
7662
|
+
|
|
7663
|
+
// eg. [0,1,2,3...] => [0,-1,1,-2,...]
|
|
7664
|
+
function signed(i) {
|
|
7665
|
+
return (i & 1) ? (~i >> 1) : (i >> 1);
|
|
7666
|
+
}
|
|
7667
|
+
|
|
7668
|
+
function read_deltas(n, next) {
|
|
7669
|
+
let v = Array(n);
|
|
7670
|
+
for (let i = 0, x = 0; i < n; i++) v[i] = x += signed(next());
|
|
7671
|
+
return v;
|
|
7672
|
+
}
|
|
7673
|
+
|
|
7674
|
+
// [123][5] => [0 3] [1 1] [0 0]
|
|
7675
|
+
function read_sorted(next, prev = 0) {
|
|
7676
|
+
let ret = [];
|
|
7677
|
+
while (true) {
|
|
7678
|
+
let x = next();
|
|
7679
|
+
let n = next();
|
|
7680
|
+
if (!n) break;
|
|
7681
|
+
prev += x;
|
|
7682
|
+
for (let i = 0; i < n; i++) {
|
|
7683
|
+
ret.push(prev + i);
|
|
7684
|
+
}
|
|
7685
|
+
prev += n + 1;
|
|
7686
|
+
}
|
|
7687
|
+
return ret;
|
|
7688
|
+
}
|
|
7689
|
+
|
|
7690
|
+
function read_sorted_arrays(next) {
|
|
7691
|
+
return read_array_while(() => {
|
|
7692
|
+
let v = read_sorted(next);
|
|
7693
|
+
if (v.length) return v;
|
|
7694
|
+
});
|
|
7695
|
+
}
|
|
7696
|
+
|
|
7697
|
+
// returns map of x => ys
|
|
7698
|
+
function read_mapped(next) {
|
|
7699
|
+
let ret = [];
|
|
7700
|
+
while (true) {
|
|
7701
|
+
let w = next();
|
|
7702
|
+
if (w == 0) break;
|
|
7703
|
+
ret.push(read_linear_table(w, next));
|
|
7704
|
+
}
|
|
7705
|
+
while (true) {
|
|
7706
|
+
let w = next() - 1;
|
|
7707
|
+
if (w < 0) break;
|
|
7708
|
+
ret.push(read_replacement_table(w, next));
|
|
7709
|
+
}
|
|
7710
|
+
return ret.flat();
|
|
7711
|
+
}
|
|
7712
|
+
|
|
7713
|
+
// read until next is falsy
|
|
7714
|
+
// return array of read values
|
|
7715
|
+
function read_array_while(next) {
|
|
7716
|
+
let v = [];
|
|
7717
|
+
while (true) {
|
|
7718
|
+
let x = next(v.length);
|
|
7719
|
+
if (!x) break;
|
|
7720
|
+
v.push(x);
|
|
7721
|
+
}
|
|
7722
|
+
return v;
|
|
7723
|
+
}
|
|
7724
|
+
|
|
7725
|
+
// read w columns of length n
|
|
7726
|
+
// return as n rows of length w
|
|
7727
|
+
function read_transposed(n, w, next) {
|
|
7728
|
+
let m = Array(n).fill().map(() => []);
|
|
7729
|
+
for (let i = 0; i < w; i++) {
|
|
7730
|
+
read_deltas(n, next).forEach((x, j) => m[j].push(x));
|
|
7731
|
+
}
|
|
7732
|
+
return m;
|
|
7733
|
+
}
|
|
7734
|
+
|
|
7735
|
+
// returns [[x, ys], [x+dx, ys+dy], [x+2*dx, ys+2*dy], ...]
|
|
7736
|
+
// where dx/dy = steps, n = run size, w = length of y
|
|
7737
|
+
function read_linear_table(w, next) {
|
|
7738
|
+
let dx = 1 + next();
|
|
7739
|
+
let dy = next();
|
|
7740
|
+
let vN = read_array_while(next);
|
|
7741
|
+
let m = read_transposed(vN.length, 1+w, next);
|
|
7742
|
+
return m.flatMap((v, i) => {
|
|
7743
|
+
let [x, ...ys] = v;
|
|
7744
|
+
return Array(vN[i]).fill().map((_, j) => {
|
|
7745
|
+
let j_dy = j * dy;
|
|
7746
|
+
return [x + j * dx, ys.map(y => y + j_dy)];
|
|
7747
|
+
});
|
|
7748
|
+
});
|
|
7749
|
+
}
|
|
7750
|
+
|
|
7751
|
+
// return [[x, ys...], ...]
|
|
7752
|
+
// where w = length of y
|
|
7753
|
+
function read_replacement_table(w, next) {
|
|
7754
|
+
let n = 1 + next();
|
|
7755
|
+
let m = read_transposed(n, 1+w, next);
|
|
7756
|
+
return m.map(v => [v[0], v.slice(1)]);
|
|
7757
|
+
}
|
|
7758
|
+
|
|
7759
|
+
|
|
7760
|
+
function read_trie(next) {
|
|
7761
|
+
let ret = [];
|
|
7762
|
+
let sorted = read_sorted(next);
|
|
7763
|
+
expand(decode([]), []);
|
|
7764
|
+
return ret; // not sorted
|
|
7765
|
+
function decode(Q) { // characters that lead into this node
|
|
7766
|
+
let S = next(); // state: valid, save, check
|
|
7767
|
+
let B = read_array_while(() => { // buckets leading to new nodes
|
|
7768
|
+
let cps = read_sorted(next).map(i => sorted[i]);
|
|
7769
|
+
if (cps.length) return decode(cps);
|
|
7770
|
+
});
|
|
7771
|
+
return {S, B, Q};
|
|
7772
|
+
}
|
|
7773
|
+
function expand({S, B}, cps, saved) {
|
|
7774
|
+
if (S & 4 && saved === cps[cps.length-1]) return;
|
|
7775
|
+
if (S & 2) saved = cps[cps.length-1];
|
|
7776
|
+
if (S & 1) ret.push(cps);
|
|
7777
|
+
for (let br of B) {
|
|
7778
|
+
for (let cp of br.Q) {
|
|
7779
|
+
expand(br, [...cps, cp], saved);
|
|
7780
|
+
}
|
|
7781
|
+
}
|
|
7782
|
+
}
|
|
7912
7783
|
}
|
|
7913
7784
|
|
|
7914
|
-
|
|
7915
|
-
|
|
7916
|
-
|
|
7917
|
-
|
|
7918
|
-
|
|
7919
|
-
|
|
7920
|
-
|
|
7921
|
-
|
|
7922
|
-
|
|
7923
|
-
|
|
7924
|
-
|
|
7925
|
-
|
|
7926
|
-
|
|
7927
|
-
|
|
7928
|
-
|
|
7929
|
-
let
|
|
7930
|
-
|
|
7931
|
-
|
|
7932
|
-
|
|
7933
|
-
|
|
7934
|
-
|
|
7935
|
-
|
|
7936
|
-
|
|
7937
|
-
|
|
7938
|
-
|
|
7939
|
-
let
|
|
7940
|
-
|
|
7941
|
-
let
|
|
7942
|
-
let
|
|
7943
|
-
|
|
7944
|
-
|
|
7945
|
-
|
|
7946
|
-
|
|
7947
|
-
|
|
7948
|
-
|
|
7949
|
-
|
|
7950
|
-
|
|
7951
|
-
|
|
7952
|
-
|
|
7953
|
-
// where w = length of y
|
|
7954
|
-
function read_replacement_table(w, next) {
|
|
7955
|
-
let n = 1 + next();
|
|
7956
|
-
let m = read_transposed(n, 1+w, next);
|
|
7957
|
-
return m.map(v => [v[0], v.slice(1)]);
|
|
7958
|
-
}
|
|
7959
|
-
|
|
7960
|
-
|
|
7961
|
-
function read_trie(next) {
|
|
7962
|
-
let ret = [];
|
|
7963
|
-
let sorted = read_sorted(next);
|
|
7964
|
-
expand(decode([]), []);
|
|
7965
|
-
return ret; // not sorted
|
|
7966
|
-
function decode(Q) { // characters that lead into this node
|
|
7967
|
-
let S = next(); // state: valid, save, check
|
|
7968
|
-
let B = read_array_while(() => { // buckets leading to new nodes
|
|
7969
|
-
let cps = read_sorted(next).map(i => sorted[i]);
|
|
7970
|
-
if (cps.length) return decode(cps);
|
|
7971
|
-
});
|
|
7972
|
-
return {S, B, Q};
|
|
7973
|
-
}
|
|
7974
|
-
function expand({S, B}, cps, saved) {
|
|
7975
|
-
if (S & 4 && saved === cps[cps.length-1]) return;
|
|
7976
|
-
if (S & 2) saved = cps[cps.length-1];
|
|
7977
|
-
if (S & 1) ret.push(cps);
|
|
7978
|
-
for (let br of B) {
|
|
7979
|
-
for (let cp of br.Q) {
|
|
7980
|
-
expand(br, [...cps, cp], saved);
|
|
7981
|
-
}
|
|
7982
|
-
}
|
|
7983
|
-
}
|
|
7984
|
-
}
|
|
7985
|
-
|
|
7986
|
-
function hex_cp(cp) {
|
|
7987
|
-
return cp.toString(16).toUpperCase().padStart(2, '0');
|
|
7988
|
-
}
|
|
7989
|
-
|
|
7990
|
-
function quote_cp(cp) {
|
|
7991
|
-
return `{${hex_cp(cp)}}`; // raffy convention: like "\u{X}" w/o the "\u"
|
|
7992
|
-
}
|
|
7993
|
-
|
|
7994
|
-
/*
|
|
7995
|
-
export function explode_cp(s) {
|
|
7996
|
-
return [...s].map(c => c.codePointAt(0));
|
|
7997
|
-
}
|
|
7998
|
-
*/
|
|
7999
|
-
function explode_cp(s) { // this is about 2x faster
|
|
8000
|
-
let cps = [];
|
|
8001
|
-
for (let pos = 0, len = s.length; pos < len; ) {
|
|
8002
|
-
let cp = s.codePointAt(pos);
|
|
8003
|
-
pos += cp < 0x10000 ? 1 : 2;
|
|
8004
|
-
cps.push(cp);
|
|
8005
|
-
}
|
|
8006
|
-
return cps;
|
|
8007
|
-
}
|
|
8008
|
-
|
|
8009
|
-
function str_from_cps(cps) {
|
|
8010
|
-
const chunk = 4096;
|
|
8011
|
-
let len = cps.length;
|
|
8012
|
-
if (len < chunk) return String.fromCodePoint(...cps);
|
|
8013
|
-
let buf = [];
|
|
8014
|
-
for (let i = 0; i < len; ) {
|
|
8015
|
-
buf.push(String.fromCodePoint(...cps.slice(i, i += chunk)));
|
|
8016
|
-
}
|
|
8017
|
-
return buf.join('');
|
|
8018
|
-
}
|
|
8019
|
-
|
|
8020
|
-
function compare_arrays(a, b) {
|
|
8021
|
-
let n = a.length;
|
|
8022
|
-
let c = n - b.length;
|
|
8023
|
-
for (let i = 0; c == 0 && i < n; i++) c = a[i] - b[i];
|
|
8024
|
-
return c;
|
|
7785
|
+
function hex_cp(cp) {
|
|
7786
|
+
return cp.toString(16).toUpperCase().padStart(2, '0');
|
|
7787
|
+
}
|
|
7788
|
+
|
|
7789
|
+
function quote_cp(cp) {
|
|
7790
|
+
return `{${hex_cp(cp)}}`; // raffy convention: like "\u{X}" w/o the "\u"
|
|
7791
|
+
}
|
|
7792
|
+
|
|
7793
|
+
/*
|
|
7794
|
+
export function explode_cp(s) {
|
|
7795
|
+
return [...s].map(c => c.codePointAt(0));
|
|
7796
|
+
}
|
|
7797
|
+
*/
|
|
7798
|
+
function explode_cp(s) { // this is about 2x faster
|
|
7799
|
+
let cps = [];
|
|
7800
|
+
for (let pos = 0, len = s.length; pos < len; ) {
|
|
7801
|
+
let cp = s.codePointAt(pos);
|
|
7802
|
+
pos += cp < 0x10000 ? 1 : 2;
|
|
7803
|
+
cps.push(cp);
|
|
7804
|
+
}
|
|
7805
|
+
return cps;
|
|
7806
|
+
}
|
|
7807
|
+
|
|
7808
|
+
function str_from_cps(cps) {
|
|
7809
|
+
const chunk = 4096;
|
|
7810
|
+
let len = cps.length;
|
|
7811
|
+
if (len < chunk) return String.fromCodePoint(...cps);
|
|
7812
|
+
let buf = [];
|
|
7813
|
+
for (let i = 0; i < len; ) {
|
|
7814
|
+
buf.push(String.fromCodePoint(...cps.slice(i, i += chunk)));
|
|
7815
|
+
}
|
|
7816
|
+
return buf.join('');
|
|
7817
|
+
}
|
|
7818
|
+
|
|
7819
|
+
function compare_arrays(a, b) {
|
|
7820
|
+
let n = a.length;
|
|
7821
|
+
let c = n - b.length;
|
|
7822
|
+
for (let i = 0; c == 0 && i < n; i++) c = a[i] - b[i];
|
|
7823
|
+
return c;
|
|
8025
7824
|
}
|
|
8026
7825
|
|
|
8027
7826
|
// created 2023-09-25T01:01:55.148Z
|
|
@@ -8031,786 +7830,786 @@ function compare_arrays(a, b) {
|
|
|
8031
7830
|
// SHA-256: a974b6f8541fc29d919bc85118af0a44015851fab5343f8679cb31be2bdb209e
|
|
8032
7831
|
var COMPRESSED = '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';
|
|
8033
7832
|
|
|
8034
|
-
// https://unicode.org/reports/tr15/
|
|
8035
|
-
// for reference implementation
|
|
8036
|
-
// see: /derive/nf.js
|
|
8037
|
-
|
|
8038
|
-
|
|
8039
|
-
// algorithmic hangul
|
|
8040
|
-
// https://www.unicode.org/versions/Unicode15.0.0/ch03.pdf (page 144)
|
|
8041
|
-
const S0 = 0xAC00;
|
|
8042
|
-
const L0 = 0x1100;
|
|
8043
|
-
const V0 = 0x1161;
|
|
8044
|
-
const T0 = 0x11A7;
|
|
8045
|
-
const L_COUNT = 19;
|
|
8046
|
-
const V_COUNT = 21;
|
|
8047
|
-
const T_COUNT = 28;
|
|
8048
|
-
const N_COUNT = V_COUNT * T_COUNT;
|
|
8049
|
-
const S_COUNT = L_COUNT * N_COUNT;
|
|
8050
|
-
const S1 = S0 + S_COUNT;
|
|
8051
|
-
const L1 = L0 + L_COUNT;
|
|
8052
|
-
const V1 = V0 + V_COUNT;
|
|
8053
|
-
const T1 = T0 + T_COUNT;
|
|
8054
|
-
|
|
8055
|
-
function unpack_cc(packed) {
|
|
8056
|
-
return (packed >> 24) & 0xFF;
|
|
8057
|
-
}
|
|
8058
|
-
function unpack_cp(packed) {
|
|
8059
|
-
return packed & 0xFFFFFF;
|
|
8060
|
-
}
|
|
8061
|
-
|
|
8062
|
-
let SHIFTED_RANK, EXCLUSIONS, DECOMP, RECOMP;
|
|
8063
|
-
|
|
8064
|
-
function init$1() {
|
|
8065
|
-
//console.time('nf');
|
|
8066
|
-
let r = read_compressed_payload(COMPRESSED);
|
|
8067
|
-
SHIFTED_RANK = new Map(read_sorted_arrays(r).flatMap((v, i) => v.map(x => [x, (i+1) << 24]))); // pre-shifted
|
|
8068
|
-
EXCLUSIONS = new Set(read_sorted(r));
|
|
8069
|
-
DECOMP = new Map();
|
|
8070
|
-
RECOMP = new Map();
|
|
8071
|
-
for (let [cp, cps] of read_mapped(r)) {
|
|
8072
|
-
if (!EXCLUSIONS.has(cp) && cps.length == 2) {
|
|
8073
|
-
let [a, b] = cps;
|
|
8074
|
-
let bucket = RECOMP.get(a);
|
|
8075
|
-
if (!bucket) {
|
|
8076
|
-
bucket = new Map();
|
|
8077
|
-
RECOMP.set(a, bucket);
|
|
8078
|
-
}
|
|
8079
|
-
bucket.set(b, cp);
|
|
8080
|
-
}
|
|
8081
|
-
DECOMP.set(cp, cps.reverse()); // stored reversed
|
|
8082
|
-
}
|
|
8083
|
-
//console.timeEnd('nf');
|
|
8084
|
-
// 20230905: 11ms
|
|
8085
|
-
}
|
|
8086
|
-
|
|
8087
|
-
function is_hangul(cp) {
|
|
8088
|
-
return cp >= S0 && cp < S1;
|
|
8089
|
-
}
|
|
8090
|
-
|
|
8091
|
-
function compose_pair(a, b) {
|
|
8092
|
-
if (a >= L0 && a < L1 && b >= V0 && b < V1) {
|
|
8093
|
-
return S0 + (a - L0) * N_COUNT + (b - V0) * T_COUNT;
|
|
8094
|
-
} else if (is_hangul(a) && b > T0 && b < T1 && (a - S0) % T_COUNT == 0) {
|
|
8095
|
-
return a + (b - T0);
|
|
8096
|
-
} else {
|
|
8097
|
-
let recomp = RECOMP.get(a);
|
|
8098
|
-
if (recomp) {
|
|
8099
|
-
recomp = recomp.get(b);
|
|
8100
|
-
if (recomp) {
|
|
8101
|
-
return recomp;
|
|
8102
|
-
}
|
|
8103
|
-
}
|
|
8104
|
-
return -1;
|
|
8105
|
-
}
|
|
8106
|
-
}
|
|
8107
|
-
|
|
8108
|
-
function decomposed(cps) {
|
|
8109
|
-
if (!SHIFTED_RANK) init$1();
|
|
8110
|
-
let ret = [];
|
|
8111
|
-
let buf = [];
|
|
8112
|
-
let check_order = false;
|
|
8113
|
-
function add(cp) {
|
|
8114
|
-
let cc = SHIFTED_RANK.get(cp);
|
|
8115
|
-
if (cc) {
|
|
8116
|
-
check_order = true;
|
|
8117
|
-
cp |= cc;
|
|
8118
|
-
}
|
|
8119
|
-
ret.push(cp);
|
|
8120
|
-
}
|
|
8121
|
-
for (let cp of cps) {
|
|
8122
|
-
while (true) {
|
|
8123
|
-
if (cp < 0x80) {
|
|
8124
|
-
ret.push(cp);
|
|
8125
|
-
} else if (is_hangul(cp)) {
|
|
8126
|
-
let s_index = cp - S0;
|
|
8127
|
-
let l_index = s_index / N_COUNT | 0;
|
|
8128
|
-
let v_index = (s_index % N_COUNT) / T_COUNT | 0;
|
|
8129
|
-
let t_index = s_index % T_COUNT;
|
|
8130
|
-
add(L0 + l_index);
|
|
8131
|
-
add(V0 + v_index);
|
|
8132
|
-
if (t_index > 0) add(T0 + t_index);
|
|
8133
|
-
} else {
|
|
8134
|
-
let mapped = DECOMP.get(cp);
|
|
8135
|
-
if (mapped) {
|
|
8136
|
-
buf.push(...mapped);
|
|
8137
|
-
} else {
|
|
8138
|
-
add(cp);
|
|
8139
|
-
}
|
|
8140
|
-
}
|
|
8141
|
-
if (!buf.length) break;
|
|
8142
|
-
cp = buf.pop();
|
|
8143
|
-
}
|
|
8144
|
-
}
|
|
8145
|
-
if (check_order && ret.length > 1) {
|
|
8146
|
-
let prev_cc = unpack_cc(ret[0]);
|
|
8147
|
-
for (let i = 1; i < ret.length; i++) {
|
|
8148
|
-
let cc = unpack_cc(ret[i]);
|
|
8149
|
-
if (cc == 0 || prev_cc <= cc) {
|
|
8150
|
-
prev_cc = cc;
|
|
8151
|
-
continue;
|
|
8152
|
-
}
|
|
8153
|
-
let j = i-1;
|
|
8154
|
-
while (true) {
|
|
8155
|
-
let tmp = ret[j+1];
|
|
8156
|
-
ret[j+1] = ret[j];
|
|
8157
|
-
ret[j] = tmp;
|
|
8158
|
-
if (!j) break;
|
|
8159
|
-
prev_cc = unpack_cc(ret[--j]);
|
|
8160
|
-
if (prev_cc <= cc) break;
|
|
8161
|
-
}
|
|
8162
|
-
prev_cc = unpack_cc(ret[i]);
|
|
8163
|
-
}
|
|
8164
|
-
}
|
|
8165
|
-
return ret;
|
|
8166
|
-
}
|
|
8167
|
-
|
|
8168
|
-
function composed_from_decomposed(v) {
|
|
8169
|
-
let ret = [];
|
|
8170
|
-
let stack = [];
|
|
8171
|
-
let prev_cp = -1;
|
|
8172
|
-
let prev_cc = 0;
|
|
8173
|
-
for (let packed of v) {
|
|
8174
|
-
let cc = unpack_cc(packed);
|
|
8175
|
-
let cp = unpack_cp(packed);
|
|
8176
|
-
if (prev_cp == -1) {
|
|
8177
|
-
if (cc == 0) {
|
|
8178
|
-
prev_cp = cp;
|
|
8179
|
-
} else {
|
|
8180
|
-
ret.push(cp);
|
|
8181
|
-
}
|
|
8182
|
-
} else if (prev_cc > 0 && prev_cc >= cc) {
|
|
8183
|
-
if (cc == 0) {
|
|
8184
|
-
ret.push(prev_cp, ...stack);
|
|
8185
|
-
stack.length = 0;
|
|
8186
|
-
prev_cp = cp;
|
|
8187
|
-
} else {
|
|
8188
|
-
stack.push(cp);
|
|
8189
|
-
}
|
|
8190
|
-
prev_cc = cc;
|
|
8191
|
-
} else {
|
|
8192
|
-
let composed = compose_pair(prev_cp, cp);
|
|
8193
|
-
if (composed >= 0) {
|
|
8194
|
-
prev_cp = composed;
|
|
8195
|
-
} else if (prev_cc == 0 && cc == 0) {
|
|
8196
|
-
ret.push(prev_cp);
|
|
8197
|
-
prev_cp = cp;
|
|
8198
|
-
} else {
|
|
8199
|
-
stack.push(cp);
|
|
8200
|
-
prev_cc = cc;
|
|
8201
|
-
}
|
|
8202
|
-
}
|
|
8203
|
-
}
|
|
8204
|
-
if (prev_cp >= 0) {
|
|
8205
|
-
ret.push(prev_cp, ...stack);
|
|
8206
|
-
}
|
|
8207
|
-
return ret;
|
|
8208
|
-
}
|
|
8209
|
-
|
|
8210
|
-
// note: cps can be iterable
|
|
8211
|
-
function nfd(cps) {
|
|
8212
|
-
return decomposed(cps).map(unpack_cp);
|
|
8213
|
-
}
|
|
8214
|
-
function nfc(cps) {
|
|
8215
|
-
return composed_from_decomposed(decomposed(cps));
|
|
7833
|
+
// https://unicode.org/reports/tr15/
|
|
7834
|
+
// for reference implementation
|
|
7835
|
+
// see: /derive/nf.js
|
|
7836
|
+
|
|
7837
|
+
|
|
7838
|
+
// algorithmic hangul
|
|
7839
|
+
// https://www.unicode.org/versions/Unicode15.0.0/ch03.pdf (page 144)
|
|
7840
|
+
const S0 = 0xAC00;
|
|
7841
|
+
const L0 = 0x1100;
|
|
7842
|
+
const V0 = 0x1161;
|
|
7843
|
+
const T0 = 0x11A7;
|
|
7844
|
+
const L_COUNT = 19;
|
|
7845
|
+
const V_COUNT = 21;
|
|
7846
|
+
const T_COUNT = 28;
|
|
7847
|
+
const N_COUNT = V_COUNT * T_COUNT;
|
|
7848
|
+
const S_COUNT = L_COUNT * N_COUNT;
|
|
7849
|
+
const S1 = S0 + S_COUNT;
|
|
7850
|
+
const L1 = L0 + L_COUNT;
|
|
7851
|
+
const V1 = V0 + V_COUNT;
|
|
7852
|
+
const T1 = T0 + T_COUNT;
|
|
7853
|
+
|
|
7854
|
+
function unpack_cc(packed) {
|
|
7855
|
+
return (packed >> 24) & 0xFF;
|
|
7856
|
+
}
|
|
7857
|
+
function unpack_cp(packed) {
|
|
7858
|
+
return packed & 0xFFFFFF;
|
|
7859
|
+
}
|
|
7860
|
+
|
|
7861
|
+
let SHIFTED_RANK, EXCLUSIONS, DECOMP, RECOMP;
|
|
7862
|
+
|
|
7863
|
+
function init$1() {
|
|
7864
|
+
//console.time('nf');
|
|
7865
|
+
let r = read_compressed_payload(COMPRESSED);
|
|
7866
|
+
SHIFTED_RANK = new Map(read_sorted_arrays(r).flatMap((v, i) => v.map(x => [x, (i+1) << 24]))); // pre-shifted
|
|
7867
|
+
EXCLUSIONS = new Set(read_sorted(r));
|
|
7868
|
+
DECOMP = new Map();
|
|
7869
|
+
RECOMP = new Map();
|
|
7870
|
+
for (let [cp, cps] of read_mapped(r)) {
|
|
7871
|
+
if (!EXCLUSIONS.has(cp) && cps.length == 2) {
|
|
7872
|
+
let [a, b] = cps;
|
|
7873
|
+
let bucket = RECOMP.get(a);
|
|
7874
|
+
if (!bucket) {
|
|
7875
|
+
bucket = new Map();
|
|
7876
|
+
RECOMP.set(a, bucket);
|
|
7877
|
+
}
|
|
7878
|
+
bucket.set(b, cp);
|
|
7879
|
+
}
|
|
7880
|
+
DECOMP.set(cp, cps.reverse()); // stored reversed
|
|
7881
|
+
}
|
|
7882
|
+
//console.timeEnd('nf');
|
|
7883
|
+
// 20230905: 11ms
|
|
7884
|
+
}
|
|
7885
|
+
|
|
7886
|
+
function is_hangul(cp) {
|
|
7887
|
+
return cp >= S0 && cp < S1;
|
|
7888
|
+
}
|
|
7889
|
+
|
|
7890
|
+
function compose_pair(a, b) {
|
|
7891
|
+
if (a >= L0 && a < L1 && b >= V0 && b < V1) {
|
|
7892
|
+
return S0 + (a - L0) * N_COUNT + (b - V0) * T_COUNT;
|
|
7893
|
+
} else if (is_hangul(a) && b > T0 && b < T1 && (a - S0) % T_COUNT == 0) {
|
|
7894
|
+
return a + (b - T0);
|
|
7895
|
+
} else {
|
|
7896
|
+
let recomp = RECOMP.get(a);
|
|
7897
|
+
if (recomp) {
|
|
7898
|
+
recomp = recomp.get(b);
|
|
7899
|
+
if (recomp) {
|
|
7900
|
+
return recomp;
|
|
7901
|
+
}
|
|
7902
|
+
}
|
|
7903
|
+
return -1;
|
|
7904
|
+
}
|
|
7905
|
+
}
|
|
7906
|
+
|
|
7907
|
+
function decomposed(cps) {
|
|
7908
|
+
if (!SHIFTED_RANK) init$1();
|
|
7909
|
+
let ret = [];
|
|
7910
|
+
let buf = [];
|
|
7911
|
+
let check_order = false;
|
|
7912
|
+
function add(cp) {
|
|
7913
|
+
let cc = SHIFTED_RANK.get(cp);
|
|
7914
|
+
if (cc) {
|
|
7915
|
+
check_order = true;
|
|
7916
|
+
cp |= cc;
|
|
7917
|
+
}
|
|
7918
|
+
ret.push(cp);
|
|
7919
|
+
}
|
|
7920
|
+
for (let cp of cps) {
|
|
7921
|
+
while (true) {
|
|
7922
|
+
if (cp < 0x80) {
|
|
7923
|
+
ret.push(cp);
|
|
7924
|
+
} else if (is_hangul(cp)) {
|
|
7925
|
+
let s_index = cp - S0;
|
|
7926
|
+
let l_index = s_index / N_COUNT | 0;
|
|
7927
|
+
let v_index = (s_index % N_COUNT) / T_COUNT | 0;
|
|
7928
|
+
let t_index = s_index % T_COUNT;
|
|
7929
|
+
add(L0 + l_index);
|
|
7930
|
+
add(V0 + v_index);
|
|
7931
|
+
if (t_index > 0) add(T0 + t_index);
|
|
7932
|
+
} else {
|
|
7933
|
+
let mapped = DECOMP.get(cp);
|
|
7934
|
+
if (mapped) {
|
|
7935
|
+
buf.push(...mapped);
|
|
7936
|
+
} else {
|
|
7937
|
+
add(cp);
|
|
7938
|
+
}
|
|
7939
|
+
}
|
|
7940
|
+
if (!buf.length) break;
|
|
7941
|
+
cp = buf.pop();
|
|
7942
|
+
}
|
|
7943
|
+
}
|
|
7944
|
+
if (check_order && ret.length > 1) {
|
|
7945
|
+
let prev_cc = unpack_cc(ret[0]);
|
|
7946
|
+
for (let i = 1; i < ret.length; i++) {
|
|
7947
|
+
let cc = unpack_cc(ret[i]);
|
|
7948
|
+
if (cc == 0 || prev_cc <= cc) {
|
|
7949
|
+
prev_cc = cc;
|
|
7950
|
+
continue;
|
|
7951
|
+
}
|
|
7952
|
+
let j = i-1;
|
|
7953
|
+
while (true) {
|
|
7954
|
+
let tmp = ret[j+1];
|
|
7955
|
+
ret[j+1] = ret[j];
|
|
7956
|
+
ret[j] = tmp;
|
|
7957
|
+
if (!j) break;
|
|
7958
|
+
prev_cc = unpack_cc(ret[--j]);
|
|
7959
|
+
if (prev_cc <= cc) break;
|
|
7960
|
+
}
|
|
7961
|
+
prev_cc = unpack_cc(ret[i]);
|
|
7962
|
+
}
|
|
7963
|
+
}
|
|
7964
|
+
return ret;
|
|
7965
|
+
}
|
|
7966
|
+
|
|
7967
|
+
function composed_from_decomposed(v) {
|
|
7968
|
+
let ret = [];
|
|
7969
|
+
let stack = [];
|
|
7970
|
+
let prev_cp = -1;
|
|
7971
|
+
let prev_cc = 0;
|
|
7972
|
+
for (let packed of v) {
|
|
7973
|
+
let cc = unpack_cc(packed);
|
|
7974
|
+
let cp = unpack_cp(packed);
|
|
7975
|
+
if (prev_cp == -1) {
|
|
7976
|
+
if (cc == 0) {
|
|
7977
|
+
prev_cp = cp;
|
|
7978
|
+
} else {
|
|
7979
|
+
ret.push(cp);
|
|
7980
|
+
}
|
|
7981
|
+
} else if (prev_cc > 0 && prev_cc >= cc) {
|
|
7982
|
+
if (cc == 0) {
|
|
7983
|
+
ret.push(prev_cp, ...stack);
|
|
7984
|
+
stack.length = 0;
|
|
7985
|
+
prev_cp = cp;
|
|
7986
|
+
} else {
|
|
7987
|
+
stack.push(cp);
|
|
7988
|
+
}
|
|
7989
|
+
prev_cc = cc;
|
|
7990
|
+
} else {
|
|
7991
|
+
let composed = compose_pair(prev_cp, cp);
|
|
7992
|
+
if (composed >= 0) {
|
|
7993
|
+
prev_cp = composed;
|
|
7994
|
+
} else if (prev_cc == 0 && cc == 0) {
|
|
7995
|
+
ret.push(prev_cp);
|
|
7996
|
+
prev_cp = cp;
|
|
7997
|
+
} else {
|
|
7998
|
+
stack.push(cp);
|
|
7999
|
+
prev_cc = cc;
|
|
8000
|
+
}
|
|
8001
|
+
}
|
|
8002
|
+
}
|
|
8003
|
+
if (prev_cp >= 0) {
|
|
8004
|
+
ret.push(prev_cp, ...stack);
|
|
8005
|
+
}
|
|
8006
|
+
return ret;
|
|
8007
|
+
}
|
|
8008
|
+
|
|
8009
|
+
// note: cps can be iterable
|
|
8010
|
+
function nfd(cps) {
|
|
8011
|
+
return decomposed(cps).map(unpack_cp);
|
|
8012
|
+
}
|
|
8013
|
+
function nfc(cps) {
|
|
8014
|
+
return composed_from_decomposed(decomposed(cps));
|
|
8216
8015
|
}
|
|
8217
8016
|
|
|
8218
|
-
const HYPHEN = 0x2D;
|
|
8219
|
-
const STOP_CH = '.';
|
|
8220
|
-
const FE0F = 0xFE0F;
|
|
8221
|
-
const UNIQUE_PH = 1;
|
|
8222
|
-
|
|
8223
|
-
// 20230913: replace [...v] with Array_from(v) to avoid large spreads
|
|
8224
|
-
const Array_from = x => Array.from(x); // Array.from.bind(Array);
|
|
8225
|
-
|
|
8226
|
-
function group_has_cp(g, cp) {
|
|
8227
|
-
// 20230913: keep primary and secondary distinct instead of creating valid union
|
|
8228
|
-
return g.P.has(cp) || g.Q.has(cp);
|
|
8229
|
-
}
|
|
8230
|
-
|
|
8231
|
-
class Emoji extends Array {
|
|
8232
|
-
get is_emoji() { return true; } // free tagging system
|
|
8233
|
-
}
|
|
8234
|
-
|
|
8235
|
-
let MAPPED, IGNORED, CM, NSM, ESCAPE, GROUPS, WHOLE_VALID, WHOLE_MAP, VALID, EMOJI_LIST, EMOJI_ROOT;
|
|
8236
|
-
|
|
8237
|
-
function init() {
|
|
8238
|
-
if (MAPPED) return;
|
|
8239
|
-
|
|
8240
|
-
let r = read_compressed_payload(COMPRESSED$1);
|
|
8241
|
-
const read_sorted_array = () => read_sorted(r);
|
|
8242
|
-
const read_sorted_set = () => new Set(read_sorted_array());
|
|
8243
|
-
const set_add_many = (set, v) => v.forEach(x => set.add(x));
|
|
8244
|
-
|
|
8245
|
-
MAPPED = new Map(read_mapped(r));
|
|
8246
|
-
IGNORED = read_sorted_set(); // ignored characters are not valid, so just read raw codepoints
|
|
8247
|
-
|
|
8248
|
-
/*
|
|
8249
|
-
// direct include from payload is smaller than the decompression code
|
|
8250
|
-
const FENCED = new Map(read_array_while(() => {
|
|
8251
|
-
let cp = r();
|
|
8252
|
-
if (cp) return [cp, read_str(r())];
|
|
8253
|
-
}));
|
|
8254
|
-
*/
|
|
8255
|
-
// 20230217: we still need all CM for proper error formatting
|
|
8256
|
-
// but norm only needs NSM subset that are potentially-valid
|
|
8257
|
-
CM = read_sorted_array();
|
|
8258
|
-
NSM = new Set(read_sorted_array().map(i => CM[i]));
|
|
8259
|
-
CM = new Set(CM);
|
|
8260
|
-
|
|
8261
|
-
ESCAPE = read_sorted_set(); // characters that should not be printed
|
|
8262
|
-
read_sorted_set(); // only needed to illustrate ens_tokenize() transformations
|
|
8263
|
-
|
|
8264
|
-
let chunks = read_sorted_arrays(r);
|
|
8265
|
-
let unrestricted = r();
|
|
8266
|
-
//const read_chunked = () => new Set(read_sorted_array().flatMap(i => chunks[i]).concat(read_sorted_array()));
|
|
8267
|
-
const read_chunked = () => {
|
|
8268
|
-
// 20230921: build set in parts, 2x faster
|
|
8269
|
-
let set = new Set();
|
|
8270
|
-
read_sorted_array().forEach(i => set_add_many(set, chunks[i]));
|
|
8271
|
-
set_add_many(set, read_sorted_array());
|
|
8272
|
-
return set;
|
|
8273
|
-
};
|
|
8274
|
-
GROUPS = read_array_while(i => {
|
|
8275
|
-
// minifier property mangling seems unsafe
|
|
8276
|
-
// so these are manually renamed to single chars
|
|
8277
|
-
let N = read_array_while(r).map(x => x+0x60);
|
|
8278
|
-
if (N.length) {
|
|
8279
|
-
let R = i >= unrestricted; // unrestricted then restricted
|
|
8280
|
-
N[0] -= 32; // capitalize
|
|
8281
|
-
N = str_from_cps(N);
|
|
8282
|
-
if (R) N=`Restricted[${N}]`;
|
|
8283
|
-
let P = read_chunked(); // primary
|
|
8284
|
-
let Q = read_chunked(); // secondary
|
|
8285
|
-
let M = !r(); // not-whitelisted, check for NSM
|
|
8286
|
-
// *** this code currently isn't needed ***
|
|
8287
|
-
/*
|
|
8288
|
-
let V = [...P, ...Q].sort((a, b) => a-b); // derive: sorted valid
|
|
8289
|
-
let M = r()-1; // number of combining mark
|
|
8290
|
-
if (M < 0) { // whitelisted
|
|
8291
|
-
M = new Map(read_array_while(() => {
|
|
8292
|
-
let i = r();
|
|
8293
|
-
if (i) return [V[i-1], read_array_while(() => {
|
|
8294
|
-
let v = read_array_while(r);
|
|
8295
|
-
if (v.length) return v.map(x => x-1);
|
|
8296
|
-
})];
|
|
8297
|
-
}));
|
|
8298
|
-
}*/
|
|
8299
|
-
return {N, P, Q, M, R};
|
|
8300
|
-
}
|
|
8301
|
-
});
|
|
8302
|
-
|
|
8303
|
-
// decode compressed wholes
|
|
8304
|
-
WHOLE_VALID = read_sorted_set();
|
|
8305
|
-
WHOLE_MAP = new Map();
|
|
8306
|
-
let wholes = read_sorted_array().concat(Array_from(WHOLE_VALID)).sort((a, b) => a-b); // must be sorted
|
|
8307
|
-
wholes.forEach((cp, i) => {
|
|
8308
|
-
let d = r();
|
|
8309
|
-
let w = wholes[i] = d ? wholes[i-d] : {V: [], M: new Map()};
|
|
8310
|
-
w.V.push(cp); // add to member set
|
|
8311
|
-
if (!WHOLE_VALID.has(cp)) {
|
|
8312
|
-
WHOLE_MAP.set(cp, w); // register with whole map
|
|
8313
|
-
}
|
|
8314
|
-
});
|
|
8315
|
-
|
|
8316
|
-
// compute confusable-extent complements
|
|
8317
|
-
// usage: WHOLE_MAP.get(cp).M.get(cp) = complement set
|
|
8318
|
-
for (let {V, M} of new Set(WHOLE_MAP.values())) {
|
|
8319
|
-
// connect all groups that have each whole character
|
|
8320
|
-
let recs = [];
|
|
8321
|
-
for (let cp of V) {
|
|
8322
|
-
let gs = GROUPS.filter(g => group_has_cp(g, cp));
|
|
8323
|
-
let rec = recs.find(({G}) => gs.some(g => G.has(g)));
|
|
8324
|
-
if (!rec) {
|
|
8325
|
-
rec = {G: new Set(), V: []};
|
|
8326
|
-
recs.push(rec);
|
|
8327
|
-
}
|
|
8328
|
-
rec.V.push(cp);
|
|
8329
|
-
set_add_many(rec.G, gs);
|
|
8330
|
-
}
|
|
8331
|
-
// per character cache groups which are not a member of the extent
|
|
8332
|
-
let union = recs.flatMap(x => Array_from(x.G)); // all of the groups used by this whole
|
|
8333
|
-
for (let {G, V} of recs) {
|
|
8334
|
-
let complement = new Set(union.filter(g => !G.has(g))); // groups not covered by the extent
|
|
8335
|
-
for (let cp of V) {
|
|
8336
|
-
M.set(cp, complement); // this is the same reference
|
|
8337
|
-
}
|
|
8338
|
-
}
|
|
8339
|
-
}
|
|
8340
|
-
|
|
8341
|
-
// compute valid set
|
|
8342
|
-
// 20230924: VALID was union but can be re-used
|
|
8343
|
-
VALID = new Set(); // exists in 1+ groups
|
|
8344
|
-
let multi = new Set(); // exists in 2+ groups
|
|
8345
|
-
const add_to_union = cp => VALID.has(cp) ? multi.add(cp) : VALID.add(cp);
|
|
8346
|
-
for (let g of GROUPS) {
|
|
8347
|
-
for (let cp of g.P) add_to_union(cp);
|
|
8348
|
-
for (let cp of g.Q) add_to_union(cp);
|
|
8349
|
-
}
|
|
8350
|
-
// dual purpose WHOLE_MAP: return placeholder if unique non-confusable
|
|
8351
|
-
for (let cp of VALID) {
|
|
8352
|
-
if (!WHOLE_MAP.has(cp) && !multi.has(cp)) {
|
|
8353
|
-
WHOLE_MAP.set(cp, UNIQUE_PH);
|
|
8354
|
-
}
|
|
8355
|
-
}
|
|
8356
|
-
// add all decomposed parts
|
|
8357
|
-
// see derive: "Valid is Closed (via Brute-force)"
|
|
8358
|
-
set_add_many(VALID, nfd(VALID));
|
|
8359
|
-
|
|
8360
|
-
// decode emoji
|
|
8361
|
-
// 20230719: emoji are now fully-expanded to avoid quirk logic
|
|
8362
|
-
EMOJI_LIST = read_trie(r).map(v => Emoji.from(v)).sort(compare_arrays);
|
|
8363
|
-
EMOJI_ROOT = new Map(); // this has approx 7K nodes (2+ per emoji)
|
|
8364
|
-
for (let cps of EMOJI_LIST) {
|
|
8365
|
-
// 20230719: change to *slightly* stricter algorithm which disallows
|
|
8366
|
-
// insertion of misplaced FE0F in emoji sequences (matching ENSIP-15)
|
|
8367
|
-
// example: beautified [A B] (eg. flag emoji)
|
|
8368
|
-
// before: allow: [A FE0F B], error: [A FE0F FE0F B]
|
|
8369
|
-
// after: error: both
|
|
8370
|
-
// note: this code now matches ENSNormalize.{cs,java} logic
|
|
8371
|
-
let prev = [EMOJI_ROOT];
|
|
8372
|
-
for (let cp of cps) {
|
|
8373
|
-
let next = prev.map(node => {
|
|
8374
|
-
let child = node.get(cp);
|
|
8375
|
-
if (!child) {
|
|
8376
|
-
// should this be object?
|
|
8377
|
-
// (most have 1-2 items, few have many)
|
|
8378
|
-
// 20230719: no, v8 default map is 4?
|
|
8379
|
-
child = new Map();
|
|
8380
|
-
node.set(cp, child);
|
|
8381
|
-
}
|
|
8382
|
-
return child;
|
|
8383
|
-
});
|
|
8384
|
-
if (cp === FE0F) {
|
|
8385
|
-
prev.push(...next); // less than 20 elements
|
|
8386
|
-
} else {
|
|
8387
|
-
prev = next;
|
|
8388
|
-
}
|
|
8389
|
-
}
|
|
8390
|
-
for (let x of prev) {
|
|
8391
|
-
x.V = cps;
|
|
8392
|
-
}
|
|
8393
|
-
}
|
|
8394
|
-
}
|
|
8395
|
-
|
|
8396
|
-
// if escaped: {HEX}
|
|
8397
|
-
// else: "x" {HEX}
|
|
8398
|
-
function quoted_cp(cp) {
|
|
8399
|
-
return (should_escape(cp) ? '' : `${bidi_qq(safe_str_from_cps([cp]))} `) + quote_cp(cp);
|
|
8400
|
-
}
|
|
8401
|
-
|
|
8402
|
-
// 20230211: some messages can be mixed-directional and result in spillover
|
|
8403
|
-
// use 200E after a quoted string to force the remainder of a string from
|
|
8404
|
-
// acquring the direction of the quote
|
|
8405
|
-
// https://www.w3.org/International/questions/qa-bidi-unicode-controls#exceptions
|
|
8406
|
-
function bidi_qq(s) {
|
|
8407
|
-
return `"${s}"\u200E`; // strong LTR
|
|
8408
|
-
}
|
|
8409
|
-
|
|
8410
|
-
function check_label_extension(cps) {
|
|
8411
|
-
if (cps.length >= 4 && cps[2] == HYPHEN && cps[3] == HYPHEN) {
|
|
8412
|
-
throw new Error(`invalid label extension: "${str_from_cps(cps.slice(0, 4))}"`); // this can only be ascii so cant be bidi
|
|
8413
|
-
}
|
|
8414
|
-
}
|
|
8415
|
-
function check_leading_underscore(cps) {
|
|
8416
|
-
const UNDERSCORE = 0x5F;
|
|
8417
|
-
for (let i = cps.lastIndexOf(UNDERSCORE); i > 0; ) {
|
|
8418
|
-
if (cps[--i] !== UNDERSCORE) {
|
|
8419
|
-
throw new Error('underscore allowed only at start');
|
|
8420
|
-
}
|
|
8421
|
-
}
|
|
8422
|
-
}
|
|
8423
|
-
// check that a fenced cp is not leading, trailing, or touching another fenced cp
|
|
8424
|
-
function check_fenced(cps) {
|
|
8425
|
-
let cp = cps[0];
|
|
8426
|
-
let prev = FENCED.get(cp);
|
|
8427
|
-
if (prev) throw error_placement(`leading ${prev}`);
|
|
8428
|
-
let n = cps.length;
|
|
8429
|
-
let last = -1; // prevents trailing from throwing
|
|
8430
|
-
for (let i = 1; i < n; i++) {
|
|
8431
|
-
cp = cps[i];
|
|
8432
|
-
let match = FENCED.get(cp);
|
|
8433
|
-
if (match) {
|
|
8434
|
-
// since cps[0] isn't fenced, cps[1] cannot throw
|
|
8435
|
-
if (last == i) throw error_placement(`${prev} + ${match}`);
|
|
8436
|
-
last = i + 1;
|
|
8437
|
-
prev = match;
|
|
8438
|
-
}
|
|
8439
|
-
}
|
|
8440
|
-
if (last == n) throw error_placement(`trailing ${prev}`);
|
|
8441
|
-
}
|
|
8442
|
-
|
|
8443
|
-
// create a safe to print string
|
|
8444
|
-
// invisibles are escaped
|
|
8445
|
-
// leading cm uses placeholder
|
|
8446
|
-
// if cps exceed max, middle truncate with ellipsis
|
|
8447
|
-
// quoter(cp) => string, eg. 3000 => "{3000}"
|
|
8448
|
-
// note: in html, you'd call this function then replace [<>&] with entities
|
|
8449
|
-
function safe_str_from_cps(cps, max = Infinity, quoter = quote_cp) {
|
|
8450
|
-
//if (Number.isInteger(cps)) cps = [cps];
|
|
8451
|
-
//if (!Array.isArray(cps)) throw new TypeError(`expected codepoints`);
|
|
8452
|
-
let buf = [];
|
|
8453
|
-
if (is_combining_mark(cps[0])) buf.push('◌');
|
|
8454
|
-
if (cps.length > max) {
|
|
8455
|
-
max >>= 1;
|
|
8456
|
-
cps = [...cps.slice(0, max), 0x2026, ...cps.slice(-max)];
|
|
8457
|
-
}
|
|
8458
|
-
let prev = 0;
|
|
8459
|
-
let n = cps.length;
|
|
8460
|
-
for (let i = 0; i < n; i++) {
|
|
8461
|
-
let cp = cps[i];
|
|
8462
|
-
if (should_escape(cp)) {
|
|
8463
|
-
buf.push(str_from_cps(cps.slice(prev, i)));
|
|
8464
|
-
buf.push(quoter(cp));
|
|
8465
|
-
prev = i + 1;
|
|
8466
|
-
}
|
|
8467
|
-
}
|
|
8468
|
-
buf.push(str_from_cps(cps.slice(prev, n)));
|
|
8469
|
-
return buf.join('');
|
|
8470
|
-
}
|
|
8471
|
-
|
|
8472
|
-
// note: set(s) cannot be exposed because they can be modified
|
|
8473
|
-
// note: Object.freeze() doesn't work
|
|
8474
|
-
function is_combining_mark(cp) {
|
|
8475
|
-
init();
|
|
8476
|
-
return CM.has(cp);
|
|
8477
|
-
}
|
|
8478
|
-
function should_escape(cp) {
|
|
8479
|
-
init();
|
|
8480
|
-
return ESCAPE.has(cp);
|
|
8481
|
-
}
|
|
8482
|
-
|
|
8483
|
-
function ens_normalize(name) {
|
|
8484
|
-
return flatten(split(name, nfc, filter_fe0f));
|
|
8485
|
-
}
|
|
8486
|
-
|
|
8487
|
-
function split(name, nf, ef) {
|
|
8488
|
-
if (!name) return []; // 20230719: empty name allowance
|
|
8489
|
-
init();
|
|
8490
|
-
let offset = 0;
|
|
8491
|
-
// https://unicode.org/reports/tr46/#Validity_Criteria
|
|
8492
|
-
// 4.) "The label must not contain a U+002E ( . ) FULL STOP."
|
|
8493
|
-
return name.split(STOP_CH).map(label => {
|
|
8494
|
-
let input = explode_cp(label);
|
|
8495
|
-
let info = {
|
|
8496
|
-
input,
|
|
8497
|
-
offset, // codepoint, not substring!
|
|
8498
|
-
};
|
|
8499
|
-
offset += input.length + 1; // + stop
|
|
8500
|
-
try {
|
|
8501
|
-
// 1.) "The label must be in Unicode Normalization Form NFC"
|
|
8502
|
-
let tokens = info.tokens = tokens_from_str(input, nf, ef);
|
|
8503
|
-
let token_count = tokens.length;
|
|
8504
|
-
let type;
|
|
8505
|
-
if (!token_count) { // the label was effectively empty (could of had ignored characters)
|
|
8506
|
-
//norm = [];
|
|
8507
|
-
//type = 'None'; // use this instead of next match, "ASCII"
|
|
8508
|
-
// 20230120: change to strict
|
|
8509
|
-
// https://discuss.ens.domains/t/ens-name-normalization-2nd/14564/59
|
|
8510
|
-
throw new Error(`empty label`);
|
|
8511
|
-
}
|
|
8512
|
-
let norm = info.output = tokens.flat();
|
|
8513
|
-
check_leading_underscore(norm);
|
|
8514
|
-
let emoji = info.emoji = token_count > 1 || tokens[0].is_emoji; // same as: tokens.some(x => x.is_emoji);
|
|
8515
|
-
if (!emoji && norm.every(cp => cp < 0x80)) { // special case for ascii
|
|
8516
|
-
// 20230123: matches matches WHATWG, see note 3.3
|
|
8517
|
-
check_label_extension(norm); // only needed for ascii
|
|
8518
|
-
// cant have fenced
|
|
8519
|
-
// cant have cm
|
|
8520
|
-
// cant have wholes
|
|
8521
|
-
// see derive: "Fastpath ASCII"
|
|
8522
|
-
type = 'ASCII';
|
|
8523
|
-
} else {
|
|
8524
|
-
let chars = tokens.flatMap(x => x.is_emoji ? [] : x); // all of the nfc tokens concat together
|
|
8525
|
-
if (!chars.length) { // theres no text, just emoji
|
|
8526
|
-
type = 'Emoji';
|
|
8527
|
-
} else {
|
|
8528
|
-
// 5.) "The label must not begin with a combining mark, that is: General_Category=Mark."
|
|
8529
|
-
if (CM.has(norm[0])) throw error_placement('leading combining mark');
|
|
8530
|
-
for (let i = 1; i < token_count; i++) { // we've already checked the first token
|
|
8531
|
-
let cps = tokens[i];
|
|
8532
|
-
if (!cps.is_emoji && CM.has(cps[0])) { // every text token has emoji neighbors, eg. EtEEEtEt...
|
|
8533
|
-
// bidi_qq() not needed since emoji is LTR and cps is a CM
|
|
8534
|
-
throw error_placement(`emoji + combining mark: "${str_from_cps(tokens[i-1])} + ${safe_str_from_cps([cps[0]])}"`);
|
|
8535
|
-
}
|
|
8536
|
-
}
|
|
8537
|
-
check_fenced(norm);
|
|
8538
|
-
let unique = Array_from(new Set(chars));
|
|
8539
|
-
let [g] = determine_group(unique); // take the first match
|
|
8540
|
-
// see derive: "Matching Groups have Same CM Style"
|
|
8541
|
-
// alternative: could form a hybrid type: Latin/Japanese/...
|
|
8542
|
-
check_group(g, chars); // need text in order
|
|
8543
|
-
check_whole(g, unique); // only need unique text (order would be required for multiple-char confusables)
|
|
8544
|
-
type = g.N;
|
|
8545
|
-
// 20230121: consider exposing restricted flag
|
|
8546
|
-
// it's simpler to just check for 'Restricted'
|
|
8547
|
-
// or even better: type.endsWith(']')
|
|
8548
|
-
//if (g.R) info.restricted = true;
|
|
8549
|
-
}
|
|
8550
|
-
}
|
|
8551
|
-
info.type = type;
|
|
8552
|
-
} catch (err) {
|
|
8553
|
-
info.error = err; // use full error object
|
|
8554
|
-
}
|
|
8555
|
-
return info;
|
|
8556
|
-
});
|
|
8557
|
-
}
|
|
8558
|
-
|
|
8559
|
-
function check_whole(group, unique) {
|
|
8560
|
-
let maker;
|
|
8561
|
-
let shared = [];
|
|
8562
|
-
for (let cp of unique) {
|
|
8563
|
-
let whole = WHOLE_MAP.get(cp);
|
|
8564
|
-
if (whole === UNIQUE_PH) return; // unique, non-confusable
|
|
8565
|
-
if (whole) {
|
|
8566
|
-
let set = whole.M.get(cp); // groups which have a character that look-like this character
|
|
8567
|
-
maker = maker ? maker.filter(g => set.has(g)) : Array_from(set);
|
|
8568
|
-
if (!maker.length) return; // confusable intersection is empty
|
|
8569
|
-
} else {
|
|
8570
|
-
shared.push(cp);
|
|
8571
|
-
}
|
|
8572
|
-
}
|
|
8573
|
-
if (maker) {
|
|
8574
|
-
// we have 1+ confusable
|
|
8575
|
-
// check if any of the remaining groups
|
|
8576
|
-
// contain the shared characters too
|
|
8577
|
-
for (let g of maker) {
|
|
8578
|
-
if (shared.every(cp => group_has_cp(g, cp))) {
|
|
8579
|
-
throw new Error(`whole-script confusable: ${group.N}/${g.N}`);
|
|
8580
|
-
}
|
|
8581
|
-
}
|
|
8582
|
-
}
|
|
8583
|
-
}
|
|
8584
|
-
|
|
8585
|
-
// assumption: unique.size > 0
|
|
8586
|
-
// returns list of matching groups
|
|
8587
|
-
function determine_group(unique) {
|
|
8588
|
-
let groups = GROUPS;
|
|
8589
|
-
for (let cp of unique) {
|
|
8590
|
-
// note: we need to dodge CM that are whitelisted
|
|
8591
|
-
// but that code isn't currently necessary
|
|
8592
|
-
let gs = groups.filter(g => group_has_cp(g, cp));
|
|
8593
|
-
if (!gs.length) {
|
|
8594
|
-
if (!GROUPS.some(g => group_has_cp(g, cp))) {
|
|
8595
|
-
// the character was composed of valid parts
|
|
8596
|
-
// but it's NFC form is invalid
|
|
8597
|
-
// 20230716: change to more exact statement, see: ENSNormalize.{cs,java}
|
|
8598
|
-
// note: this doesn't have to be a composition
|
|
8599
|
-
// 20230720: change to full check
|
|
8600
|
-
throw error_disallowed(cp); // this should be rare
|
|
8601
|
-
} else {
|
|
8602
|
-
// there is no group that contains all these characters
|
|
8603
|
-
// throw using the highest priority group that matched
|
|
8604
|
-
// https://www.unicode.org/reports/tr39/#mixed_script_confusables
|
|
8605
|
-
throw error_group_member(groups[0], cp);
|
|
8606
|
-
}
|
|
8607
|
-
}
|
|
8608
|
-
groups = gs;
|
|
8609
|
-
if (gs.length == 1) break; // there is only one group left
|
|
8610
|
-
}
|
|
8611
|
-
// there are at least 1 group(s) with all of these characters
|
|
8612
|
-
return groups;
|
|
8613
|
-
}
|
|
8614
|
-
|
|
8615
|
-
// throw on first error
|
|
8616
|
-
function flatten(split) {
|
|
8617
|
-
return split.map(({input, error, output}) => {
|
|
8618
|
-
if (error) {
|
|
8619
|
-
// don't print label again if just a single label
|
|
8620
|
-
let msg = error.message;
|
|
8621
|
-
// bidi_qq() only necessary if msg is digits
|
|
8622
|
-
throw new Error(split.length == 1 ? msg : `Invalid label ${bidi_qq(safe_str_from_cps(input, 63))}: ${msg}`);
|
|
8623
|
-
}
|
|
8624
|
-
return str_from_cps(output);
|
|
8625
|
-
}).join(STOP_CH);
|
|
8626
|
-
}
|
|
8627
|
-
|
|
8628
|
-
function error_disallowed(cp) {
|
|
8629
|
-
// TODO: add cp to error?
|
|
8630
|
-
return new Error(`disallowed character: ${quoted_cp(cp)}`);
|
|
8631
|
-
}
|
|
8632
|
-
function error_group_member(g, cp) {
|
|
8633
|
-
let quoted = quoted_cp(cp);
|
|
8634
|
-
let gg = GROUPS.find(g => g.P.has(cp)); // only check primary
|
|
8635
|
-
if (gg) {
|
|
8636
|
-
quoted = `${gg.N} ${quoted}`;
|
|
8637
|
-
}
|
|
8638
|
-
return new Error(`illegal mixture: ${g.N} + ${quoted}`);
|
|
8639
|
-
}
|
|
8640
|
-
function error_placement(where) {
|
|
8641
|
-
return new Error(`illegal placement: ${where}`);
|
|
8642
|
-
}
|
|
8643
|
-
|
|
8644
|
-
// assumption: cps.length > 0
|
|
8645
|
-
// assumption: cps[0] isn't a CM
|
|
8646
|
-
// assumption: the previous character isn't an emoji
|
|
8647
|
-
function check_group(g, cps) {
|
|
8648
|
-
for (let cp of cps) {
|
|
8649
|
-
if (!group_has_cp(g, cp)) {
|
|
8650
|
-
// for whitelisted scripts, this will throw illegal mixture on invalid cm, eg. "e{300}{300}"
|
|
8651
|
-
// at the moment, it's unnecessary to introduce an extra error type
|
|
8652
|
-
// until there exists a whitelisted multi-character
|
|
8653
|
-
// eg. if (M < 0 && is_combining_mark(cp)) { ... }
|
|
8654
|
-
// there are 3 cases:
|
|
8655
|
-
// 1. illegal cm for wrong group => mixture error
|
|
8656
|
-
// 2. illegal cm for same group => cm error
|
|
8657
|
-
// requires set of whitelist cm per group:
|
|
8658
|
-
// eg. new Set([...g.P, ...g.Q].flatMap(nfc).filter(cp => CM.has(cp)))
|
|
8659
|
-
// 3. wrong group => mixture error
|
|
8660
|
-
throw error_group_member(g, cp);
|
|
8661
|
-
}
|
|
8662
|
-
}
|
|
8663
|
-
//if (M >= 0) { // we have a known fixed cm count
|
|
8664
|
-
if (g.M) { // we need to check for NSM
|
|
8665
|
-
let decomposed = nfd(cps);
|
|
8666
|
-
for (let i = 1, e = decomposed.length; i < e; i++) { // see: assumption
|
|
8667
|
-
// 20230210: bugfix: using cps instead of decomposed h/t Carbon225
|
|
8668
|
-
/*
|
|
8669
|
-
if (CM.has(decomposed[i])) {
|
|
8670
|
-
let j = i + 1;
|
|
8671
|
-
while (j < e && CM.has(decomposed[j])) j++;
|
|
8672
|
-
if (j - i > M) {
|
|
8673
|
-
throw new Error(`too many combining marks: ${g.N} ${bidi_qq(str_from_cps(decomposed.slice(i-1, j)))} (${j-i}/${M})`);
|
|
8674
|
-
}
|
|
8675
|
-
i = j;
|
|
8676
|
-
}
|
|
8677
|
-
*/
|
|
8678
|
-
// 20230217: switch to NSM counting
|
|
8679
|
-
// https://www.unicode.org/reports/tr39/#Optional_Detection
|
|
8680
|
-
if (NSM.has(decomposed[i])) {
|
|
8681
|
-
let j = i + 1;
|
|
8682
|
-
for (let cp; j < e && NSM.has(cp = decomposed[j]); j++) {
|
|
8683
|
-
// a. Forbid sequences of the same nonspacing mark.
|
|
8684
|
-
for (let k = i; k < j; k++) { // O(n^2) but n < 100
|
|
8685
|
-
if (decomposed[k] == cp) {
|
|
8686
|
-
throw new Error(`duplicate non-spacing marks: ${quoted_cp(cp)}`);
|
|
8687
|
-
}
|
|
8688
|
-
}
|
|
8689
|
-
}
|
|
8690
|
-
// parse to end so we have full nsm count
|
|
8691
|
-
// b. Forbid sequences of more than 4 nonspacing marks (gc=Mn or gc=Me).
|
|
8692
|
-
if (j - i > NSM_MAX) {
|
|
8693
|
-
// note: this slice starts with a base char or spacing-mark cm
|
|
8694
|
-
throw new Error(`excessive non-spacing marks: ${bidi_qq(safe_str_from_cps(decomposed.slice(i-1, j)))} (${j-i}/${NSM_MAX})`);
|
|
8695
|
-
}
|
|
8696
|
-
i = j;
|
|
8697
|
-
}
|
|
8698
|
-
}
|
|
8699
|
-
}
|
|
8700
|
-
// *** this code currently isn't needed ***
|
|
8701
|
-
/*
|
|
8702
|
-
let cm_whitelist = M instanceof Map;
|
|
8703
|
-
for (let i = 0, e = cps.length; i < e; ) {
|
|
8704
|
-
let cp = cps[i++];
|
|
8705
|
-
let seqs = cm_whitelist && M.get(cp);
|
|
8706
|
-
if (seqs) {
|
|
8707
|
-
// list of codepoints that can follow
|
|
8708
|
-
// if this exists, this will always be 1+
|
|
8709
|
-
let j = i;
|
|
8710
|
-
while (j < e && CM.has(cps[j])) j++;
|
|
8711
|
-
let cms = cps.slice(i, j);
|
|
8712
|
-
let match = seqs.find(seq => !compare_arrays(seq, cms));
|
|
8713
|
-
if (!match) throw new Error(`disallowed combining mark sequence: "${safe_str_from_cps([cp, ...cms])}"`);
|
|
8714
|
-
i = j;
|
|
8715
|
-
} else if (!V.has(cp)) {
|
|
8716
|
-
// https://www.unicode.org/reports/tr39/#mixed_script_confusables
|
|
8717
|
-
let quoted = quoted_cp(cp);
|
|
8718
|
-
for (let cp of cps) {
|
|
8719
|
-
let u = UNIQUE.get(cp);
|
|
8720
|
-
if (u && u !== g) {
|
|
8721
|
-
// if both scripts are restricted this error is confusing
|
|
8722
|
-
// because we don't differentiate RestrictedA from RestrictedB
|
|
8723
|
-
if (!u.R) quoted = `${quoted} is ${u.N}`;
|
|
8724
|
-
break;
|
|
8725
|
-
}
|
|
8726
|
-
}
|
|
8727
|
-
throw new Error(`disallowed ${g.N} character: ${quoted}`);
|
|
8728
|
-
//throw new Error(`disallowed character: ${quoted} (expected ${g.N})`);
|
|
8729
|
-
//throw new Error(`${g.N} does not allow: ${quoted}`);
|
|
8730
|
-
}
|
|
8731
|
-
}
|
|
8732
|
-
if (!cm_whitelist) {
|
|
8733
|
-
let decomposed = nfd(cps);
|
|
8734
|
-
for (let i = 1, e = decomposed.length; i < e; i++) { // we know it can't be cm leading
|
|
8735
|
-
if (CM.has(decomposed[i])) {
|
|
8736
|
-
let j = i + 1;
|
|
8737
|
-
while (j < e && CM.has(decomposed[j])) j++;
|
|
8738
|
-
if (j - i > M) {
|
|
8739
|
-
throw new Error(`too many combining marks: "${str_from_cps(decomposed.slice(i-1, j))}" (${j-i}/${M})`);
|
|
8740
|
-
}
|
|
8741
|
-
i = j;
|
|
8742
|
-
}
|
|
8743
|
-
}
|
|
8744
|
-
}
|
|
8745
|
-
*/
|
|
8746
|
-
}
|
|
8747
|
-
|
|
8748
|
-
// given a list of codepoints
|
|
8749
|
-
// returns a list of lists, where emoji are a fully-qualified (as Array subclass)
|
|
8750
|
-
// eg. explode_cp("abc💩d") => [[61, 62, 63], Emoji[1F4A9, FE0F], [64]]
|
|
8751
|
-
// 20230818: rename for 'process' name collision h/t Javarome
|
|
8752
|
-
// https://github.com/adraffy/ens-normalize.js/issues/23
|
|
8753
|
-
function tokens_from_str(input, nf, ef) {
|
|
8754
|
-
let ret = [];
|
|
8755
|
-
let chars = [];
|
|
8756
|
-
input = input.slice().reverse(); // flip so we can pop
|
|
8757
|
-
while (input.length) {
|
|
8758
|
-
let emoji = consume_emoji_reversed(input);
|
|
8759
|
-
if (emoji) {
|
|
8760
|
-
if (chars.length) {
|
|
8761
|
-
ret.push(nf(chars));
|
|
8762
|
-
chars = [];
|
|
8763
|
-
}
|
|
8764
|
-
ret.push(ef(emoji));
|
|
8765
|
-
} else {
|
|
8766
|
-
let cp = input.pop();
|
|
8767
|
-
if (VALID.has(cp)) {
|
|
8768
|
-
chars.push(cp);
|
|
8769
|
-
} else {
|
|
8770
|
-
let cps = MAPPED.get(cp);
|
|
8771
|
-
if (cps) {
|
|
8772
|
-
chars.push(...cps); // less than 10 elements
|
|
8773
|
-
} else if (!IGNORED.has(cp)) {
|
|
8774
|
-
// 20230912: unicode 15.1 changed the order of processing such that
|
|
8775
|
-
// disallowed parts are only rejected after NFC
|
|
8776
|
-
// https://unicode.org/reports/tr46/#Validity_Criteria
|
|
8777
|
-
// this doesn't impact normalization as of today
|
|
8778
|
-
// technically, this error can be removed as the group logic will apply similar logic
|
|
8779
|
-
// however the error type might be less clear
|
|
8780
|
-
throw error_disallowed(cp);
|
|
8781
|
-
}
|
|
8782
|
-
}
|
|
8783
|
-
}
|
|
8784
|
-
}
|
|
8785
|
-
if (chars.length) {
|
|
8786
|
-
ret.push(nf(chars));
|
|
8787
|
-
}
|
|
8788
|
-
return ret;
|
|
8789
|
-
}
|
|
8790
|
-
|
|
8791
|
-
function filter_fe0f(cps) {
|
|
8792
|
-
return cps.filter(cp => cp != FE0F);
|
|
8793
|
-
}
|
|
8794
|
-
|
|
8795
|
-
// given array of codepoints
|
|
8796
|
-
// returns the longest valid emoji sequence (or undefined if no match)
|
|
8797
|
-
// *MUTATES* the supplied array
|
|
8798
|
-
// disallows interleaved ignored characters
|
|
8799
|
-
// fills (optional) eaten array with matched codepoints
|
|
8800
|
-
function consume_emoji_reversed(cps, eaten) {
|
|
8801
|
-
let node = EMOJI_ROOT;
|
|
8802
|
-
let emoji;
|
|
8803
|
-
let pos = cps.length;
|
|
8804
|
-
while (pos) {
|
|
8805
|
-
node = node.get(cps[--pos]);
|
|
8806
|
-
if (!node) break;
|
|
8807
|
-
let {V} = node;
|
|
8808
|
-
if (V) { // this is a valid emoji (so far)
|
|
8809
|
-
emoji = V;
|
|
8810
|
-
cps.length = pos; // truncate
|
|
8811
|
-
}
|
|
8812
|
-
}
|
|
8813
|
-
return emoji;
|
|
8017
|
+
const HYPHEN = 0x2D;
|
|
8018
|
+
const STOP_CH = '.';
|
|
8019
|
+
const FE0F = 0xFE0F;
|
|
8020
|
+
const UNIQUE_PH = 1;
|
|
8021
|
+
|
|
8022
|
+
// 20230913: replace [...v] with Array_from(v) to avoid large spreads
|
|
8023
|
+
const Array_from = x => Array.from(x); // Array.from.bind(Array);
|
|
8024
|
+
|
|
8025
|
+
function group_has_cp(g, cp) {
|
|
8026
|
+
// 20230913: keep primary and secondary distinct instead of creating valid union
|
|
8027
|
+
return g.P.has(cp) || g.Q.has(cp);
|
|
8028
|
+
}
|
|
8029
|
+
|
|
8030
|
+
class Emoji extends Array {
|
|
8031
|
+
get is_emoji() { return true; } // free tagging system
|
|
8032
|
+
}
|
|
8033
|
+
|
|
8034
|
+
let MAPPED, IGNORED, CM, NSM, ESCAPE, GROUPS, WHOLE_VALID, WHOLE_MAP, VALID, EMOJI_LIST, EMOJI_ROOT;
|
|
8035
|
+
|
|
8036
|
+
function init() {
|
|
8037
|
+
if (MAPPED) return;
|
|
8038
|
+
|
|
8039
|
+
let r = read_compressed_payload(COMPRESSED$1);
|
|
8040
|
+
const read_sorted_array = () => read_sorted(r);
|
|
8041
|
+
const read_sorted_set = () => new Set(read_sorted_array());
|
|
8042
|
+
const set_add_many = (set, v) => v.forEach(x => set.add(x));
|
|
8043
|
+
|
|
8044
|
+
MAPPED = new Map(read_mapped(r));
|
|
8045
|
+
IGNORED = read_sorted_set(); // ignored characters are not valid, so just read raw codepoints
|
|
8046
|
+
|
|
8047
|
+
/*
|
|
8048
|
+
// direct include from payload is smaller than the decompression code
|
|
8049
|
+
const FENCED = new Map(read_array_while(() => {
|
|
8050
|
+
let cp = r();
|
|
8051
|
+
if (cp) return [cp, read_str(r())];
|
|
8052
|
+
}));
|
|
8053
|
+
*/
|
|
8054
|
+
// 20230217: we still need all CM for proper error formatting
|
|
8055
|
+
// but norm only needs NSM subset that are potentially-valid
|
|
8056
|
+
CM = read_sorted_array();
|
|
8057
|
+
NSM = new Set(read_sorted_array().map(i => CM[i]));
|
|
8058
|
+
CM = new Set(CM);
|
|
8059
|
+
|
|
8060
|
+
ESCAPE = read_sorted_set(); // characters that should not be printed
|
|
8061
|
+
read_sorted_set(); // only needed to illustrate ens_tokenize() transformations
|
|
8062
|
+
|
|
8063
|
+
let chunks = read_sorted_arrays(r);
|
|
8064
|
+
let unrestricted = r();
|
|
8065
|
+
//const read_chunked = () => new Set(read_sorted_array().flatMap(i => chunks[i]).concat(read_sorted_array()));
|
|
8066
|
+
const read_chunked = () => {
|
|
8067
|
+
// 20230921: build set in parts, 2x faster
|
|
8068
|
+
let set = new Set();
|
|
8069
|
+
read_sorted_array().forEach(i => set_add_many(set, chunks[i]));
|
|
8070
|
+
set_add_many(set, read_sorted_array());
|
|
8071
|
+
return set;
|
|
8072
|
+
};
|
|
8073
|
+
GROUPS = read_array_while(i => {
|
|
8074
|
+
// minifier property mangling seems unsafe
|
|
8075
|
+
// so these are manually renamed to single chars
|
|
8076
|
+
let N = read_array_while(r).map(x => x+0x60);
|
|
8077
|
+
if (N.length) {
|
|
8078
|
+
let R = i >= unrestricted; // unrestricted then restricted
|
|
8079
|
+
N[0] -= 32; // capitalize
|
|
8080
|
+
N = str_from_cps(N);
|
|
8081
|
+
if (R) N=`Restricted[${N}]`;
|
|
8082
|
+
let P = read_chunked(); // primary
|
|
8083
|
+
let Q = read_chunked(); // secondary
|
|
8084
|
+
let M = !r(); // not-whitelisted, check for NSM
|
|
8085
|
+
// *** this code currently isn't needed ***
|
|
8086
|
+
/*
|
|
8087
|
+
let V = [...P, ...Q].sort((a, b) => a-b); // derive: sorted valid
|
|
8088
|
+
let M = r()-1; // number of combining mark
|
|
8089
|
+
if (M < 0) { // whitelisted
|
|
8090
|
+
M = new Map(read_array_while(() => {
|
|
8091
|
+
let i = r();
|
|
8092
|
+
if (i) return [V[i-1], read_array_while(() => {
|
|
8093
|
+
let v = read_array_while(r);
|
|
8094
|
+
if (v.length) return v.map(x => x-1);
|
|
8095
|
+
})];
|
|
8096
|
+
}));
|
|
8097
|
+
}*/
|
|
8098
|
+
return {N, P, Q, M, R};
|
|
8099
|
+
}
|
|
8100
|
+
});
|
|
8101
|
+
|
|
8102
|
+
// decode compressed wholes
|
|
8103
|
+
WHOLE_VALID = read_sorted_set();
|
|
8104
|
+
WHOLE_MAP = new Map();
|
|
8105
|
+
let wholes = read_sorted_array().concat(Array_from(WHOLE_VALID)).sort((a, b) => a-b); // must be sorted
|
|
8106
|
+
wholes.forEach((cp, i) => {
|
|
8107
|
+
let d = r();
|
|
8108
|
+
let w = wholes[i] = d ? wholes[i-d] : {V: [], M: new Map()};
|
|
8109
|
+
w.V.push(cp); // add to member set
|
|
8110
|
+
if (!WHOLE_VALID.has(cp)) {
|
|
8111
|
+
WHOLE_MAP.set(cp, w); // register with whole map
|
|
8112
|
+
}
|
|
8113
|
+
});
|
|
8114
|
+
|
|
8115
|
+
// compute confusable-extent complements
|
|
8116
|
+
// usage: WHOLE_MAP.get(cp).M.get(cp) = complement set
|
|
8117
|
+
for (let {V, M} of new Set(WHOLE_MAP.values())) {
|
|
8118
|
+
// connect all groups that have each whole character
|
|
8119
|
+
let recs = [];
|
|
8120
|
+
for (let cp of V) {
|
|
8121
|
+
let gs = GROUPS.filter(g => group_has_cp(g, cp));
|
|
8122
|
+
let rec = recs.find(({G}) => gs.some(g => G.has(g)));
|
|
8123
|
+
if (!rec) {
|
|
8124
|
+
rec = {G: new Set(), V: []};
|
|
8125
|
+
recs.push(rec);
|
|
8126
|
+
}
|
|
8127
|
+
rec.V.push(cp);
|
|
8128
|
+
set_add_many(rec.G, gs);
|
|
8129
|
+
}
|
|
8130
|
+
// per character cache groups which are not a member of the extent
|
|
8131
|
+
let union = recs.flatMap(x => Array_from(x.G)); // all of the groups used by this whole
|
|
8132
|
+
for (let {G, V} of recs) {
|
|
8133
|
+
let complement = new Set(union.filter(g => !G.has(g))); // groups not covered by the extent
|
|
8134
|
+
for (let cp of V) {
|
|
8135
|
+
M.set(cp, complement); // this is the same reference
|
|
8136
|
+
}
|
|
8137
|
+
}
|
|
8138
|
+
}
|
|
8139
|
+
|
|
8140
|
+
// compute valid set
|
|
8141
|
+
// 20230924: VALID was union but can be re-used
|
|
8142
|
+
VALID = new Set(); // exists in 1+ groups
|
|
8143
|
+
let multi = new Set(); // exists in 2+ groups
|
|
8144
|
+
const add_to_union = cp => VALID.has(cp) ? multi.add(cp) : VALID.add(cp);
|
|
8145
|
+
for (let g of GROUPS) {
|
|
8146
|
+
for (let cp of g.P) add_to_union(cp);
|
|
8147
|
+
for (let cp of g.Q) add_to_union(cp);
|
|
8148
|
+
}
|
|
8149
|
+
// dual purpose WHOLE_MAP: return placeholder if unique non-confusable
|
|
8150
|
+
for (let cp of VALID) {
|
|
8151
|
+
if (!WHOLE_MAP.has(cp) && !multi.has(cp)) {
|
|
8152
|
+
WHOLE_MAP.set(cp, UNIQUE_PH);
|
|
8153
|
+
}
|
|
8154
|
+
}
|
|
8155
|
+
// add all decomposed parts
|
|
8156
|
+
// see derive: "Valid is Closed (via Brute-force)"
|
|
8157
|
+
set_add_many(VALID, nfd(VALID));
|
|
8158
|
+
|
|
8159
|
+
// decode emoji
|
|
8160
|
+
// 20230719: emoji are now fully-expanded to avoid quirk logic
|
|
8161
|
+
EMOJI_LIST = read_trie(r).map(v => Emoji.from(v)).sort(compare_arrays);
|
|
8162
|
+
EMOJI_ROOT = new Map(); // this has approx 7K nodes (2+ per emoji)
|
|
8163
|
+
for (let cps of EMOJI_LIST) {
|
|
8164
|
+
// 20230719: change to *slightly* stricter algorithm which disallows
|
|
8165
|
+
// insertion of misplaced FE0F in emoji sequences (matching ENSIP-15)
|
|
8166
|
+
// example: beautified [A B] (eg. flag emoji)
|
|
8167
|
+
// before: allow: [A FE0F B], error: [A FE0F FE0F B]
|
|
8168
|
+
// after: error: both
|
|
8169
|
+
// note: this code now matches ENSNormalize.{cs,java} logic
|
|
8170
|
+
let prev = [EMOJI_ROOT];
|
|
8171
|
+
for (let cp of cps) {
|
|
8172
|
+
let next = prev.map(node => {
|
|
8173
|
+
let child = node.get(cp);
|
|
8174
|
+
if (!child) {
|
|
8175
|
+
// should this be object?
|
|
8176
|
+
// (most have 1-2 items, few have many)
|
|
8177
|
+
// 20230719: no, v8 default map is 4?
|
|
8178
|
+
child = new Map();
|
|
8179
|
+
node.set(cp, child);
|
|
8180
|
+
}
|
|
8181
|
+
return child;
|
|
8182
|
+
});
|
|
8183
|
+
if (cp === FE0F) {
|
|
8184
|
+
prev.push(...next); // less than 20 elements
|
|
8185
|
+
} else {
|
|
8186
|
+
prev = next;
|
|
8187
|
+
}
|
|
8188
|
+
}
|
|
8189
|
+
for (let x of prev) {
|
|
8190
|
+
x.V = cps;
|
|
8191
|
+
}
|
|
8192
|
+
}
|
|
8193
|
+
}
|
|
8194
|
+
|
|
8195
|
+
// if escaped: {HEX}
|
|
8196
|
+
// else: "x" {HEX}
|
|
8197
|
+
function quoted_cp(cp) {
|
|
8198
|
+
return (should_escape(cp) ? '' : `${bidi_qq(safe_str_from_cps([cp]))} `) + quote_cp(cp);
|
|
8199
|
+
}
|
|
8200
|
+
|
|
8201
|
+
// 20230211: some messages can be mixed-directional and result in spillover
|
|
8202
|
+
// use 200E after a quoted string to force the remainder of a string from
|
|
8203
|
+
// acquring the direction of the quote
|
|
8204
|
+
// https://www.w3.org/International/questions/qa-bidi-unicode-controls#exceptions
|
|
8205
|
+
function bidi_qq(s) {
|
|
8206
|
+
return `"${s}"\u200E`; // strong LTR
|
|
8207
|
+
}
|
|
8208
|
+
|
|
8209
|
+
function check_label_extension(cps) {
|
|
8210
|
+
if (cps.length >= 4 && cps[2] == HYPHEN && cps[3] == HYPHEN) {
|
|
8211
|
+
throw new Error(`invalid label extension: "${str_from_cps(cps.slice(0, 4))}"`); // this can only be ascii so cant be bidi
|
|
8212
|
+
}
|
|
8213
|
+
}
|
|
8214
|
+
function check_leading_underscore(cps) {
|
|
8215
|
+
const UNDERSCORE = 0x5F;
|
|
8216
|
+
for (let i = cps.lastIndexOf(UNDERSCORE); i > 0; ) {
|
|
8217
|
+
if (cps[--i] !== UNDERSCORE) {
|
|
8218
|
+
throw new Error('underscore allowed only at start');
|
|
8219
|
+
}
|
|
8220
|
+
}
|
|
8221
|
+
}
|
|
8222
|
+
// check that a fenced cp is not leading, trailing, or touching another fenced cp
|
|
8223
|
+
function check_fenced(cps) {
|
|
8224
|
+
let cp = cps[0];
|
|
8225
|
+
let prev = FENCED.get(cp);
|
|
8226
|
+
if (prev) throw error_placement(`leading ${prev}`);
|
|
8227
|
+
let n = cps.length;
|
|
8228
|
+
let last = -1; // prevents trailing from throwing
|
|
8229
|
+
for (let i = 1; i < n; i++) {
|
|
8230
|
+
cp = cps[i];
|
|
8231
|
+
let match = FENCED.get(cp);
|
|
8232
|
+
if (match) {
|
|
8233
|
+
// since cps[0] isn't fenced, cps[1] cannot throw
|
|
8234
|
+
if (last == i) throw error_placement(`${prev} + ${match}`);
|
|
8235
|
+
last = i + 1;
|
|
8236
|
+
prev = match;
|
|
8237
|
+
}
|
|
8238
|
+
}
|
|
8239
|
+
if (last == n) throw error_placement(`trailing ${prev}`);
|
|
8240
|
+
}
|
|
8241
|
+
|
|
8242
|
+
// create a safe to print string
|
|
8243
|
+
// invisibles are escaped
|
|
8244
|
+
// leading cm uses placeholder
|
|
8245
|
+
// if cps exceed max, middle truncate with ellipsis
|
|
8246
|
+
// quoter(cp) => string, eg. 3000 => "{3000}"
|
|
8247
|
+
// note: in html, you'd call this function then replace [<>&] with entities
|
|
8248
|
+
function safe_str_from_cps(cps, max = Infinity, quoter = quote_cp) {
|
|
8249
|
+
//if (Number.isInteger(cps)) cps = [cps];
|
|
8250
|
+
//if (!Array.isArray(cps)) throw new TypeError(`expected codepoints`);
|
|
8251
|
+
let buf = [];
|
|
8252
|
+
if (is_combining_mark(cps[0])) buf.push('◌');
|
|
8253
|
+
if (cps.length > max) {
|
|
8254
|
+
max >>= 1;
|
|
8255
|
+
cps = [...cps.slice(0, max), 0x2026, ...cps.slice(-max)];
|
|
8256
|
+
}
|
|
8257
|
+
let prev = 0;
|
|
8258
|
+
let n = cps.length;
|
|
8259
|
+
for (let i = 0; i < n; i++) {
|
|
8260
|
+
let cp = cps[i];
|
|
8261
|
+
if (should_escape(cp)) {
|
|
8262
|
+
buf.push(str_from_cps(cps.slice(prev, i)));
|
|
8263
|
+
buf.push(quoter(cp));
|
|
8264
|
+
prev = i + 1;
|
|
8265
|
+
}
|
|
8266
|
+
}
|
|
8267
|
+
buf.push(str_from_cps(cps.slice(prev, n)));
|
|
8268
|
+
return buf.join('');
|
|
8269
|
+
}
|
|
8270
|
+
|
|
8271
|
+
// note: set(s) cannot be exposed because they can be modified
|
|
8272
|
+
// note: Object.freeze() doesn't work
|
|
8273
|
+
function is_combining_mark(cp) {
|
|
8274
|
+
init();
|
|
8275
|
+
return CM.has(cp);
|
|
8276
|
+
}
|
|
8277
|
+
function should_escape(cp) {
|
|
8278
|
+
init();
|
|
8279
|
+
return ESCAPE.has(cp);
|
|
8280
|
+
}
|
|
8281
|
+
|
|
8282
|
+
function ens_normalize(name) {
|
|
8283
|
+
return flatten(split(name, nfc, filter_fe0f));
|
|
8284
|
+
}
|
|
8285
|
+
|
|
8286
|
+
function split(name, nf, ef) {
|
|
8287
|
+
if (!name) return []; // 20230719: empty name allowance
|
|
8288
|
+
init();
|
|
8289
|
+
let offset = 0;
|
|
8290
|
+
// https://unicode.org/reports/tr46/#Validity_Criteria
|
|
8291
|
+
// 4.) "The label must not contain a U+002E ( . ) FULL STOP."
|
|
8292
|
+
return name.split(STOP_CH).map(label => {
|
|
8293
|
+
let input = explode_cp(label);
|
|
8294
|
+
let info = {
|
|
8295
|
+
input,
|
|
8296
|
+
offset, // codepoint, not substring!
|
|
8297
|
+
};
|
|
8298
|
+
offset += input.length + 1; // + stop
|
|
8299
|
+
try {
|
|
8300
|
+
// 1.) "The label must be in Unicode Normalization Form NFC"
|
|
8301
|
+
let tokens = info.tokens = tokens_from_str(input, nf, ef);
|
|
8302
|
+
let token_count = tokens.length;
|
|
8303
|
+
let type;
|
|
8304
|
+
if (!token_count) { // the label was effectively empty (could of had ignored characters)
|
|
8305
|
+
//norm = [];
|
|
8306
|
+
//type = 'None'; // use this instead of next match, "ASCII"
|
|
8307
|
+
// 20230120: change to strict
|
|
8308
|
+
// https://discuss.ens.domains/t/ens-name-normalization-2nd/14564/59
|
|
8309
|
+
throw new Error(`empty label`);
|
|
8310
|
+
}
|
|
8311
|
+
let norm = info.output = tokens.flat();
|
|
8312
|
+
check_leading_underscore(norm);
|
|
8313
|
+
let emoji = info.emoji = token_count > 1 || tokens[0].is_emoji; // same as: tokens.some(x => x.is_emoji);
|
|
8314
|
+
if (!emoji && norm.every(cp => cp < 0x80)) { // special case for ascii
|
|
8315
|
+
// 20230123: matches matches WHATWG, see note 3.3
|
|
8316
|
+
check_label_extension(norm); // only needed for ascii
|
|
8317
|
+
// cant have fenced
|
|
8318
|
+
// cant have cm
|
|
8319
|
+
// cant have wholes
|
|
8320
|
+
// see derive: "Fastpath ASCII"
|
|
8321
|
+
type = 'ASCII';
|
|
8322
|
+
} else {
|
|
8323
|
+
let chars = tokens.flatMap(x => x.is_emoji ? [] : x); // all of the nfc tokens concat together
|
|
8324
|
+
if (!chars.length) { // theres no text, just emoji
|
|
8325
|
+
type = 'Emoji';
|
|
8326
|
+
} else {
|
|
8327
|
+
// 5.) "The label must not begin with a combining mark, that is: General_Category=Mark."
|
|
8328
|
+
if (CM.has(norm[0])) throw error_placement('leading combining mark');
|
|
8329
|
+
for (let i = 1; i < token_count; i++) { // we've already checked the first token
|
|
8330
|
+
let cps = tokens[i];
|
|
8331
|
+
if (!cps.is_emoji && CM.has(cps[0])) { // every text token has emoji neighbors, eg. EtEEEtEt...
|
|
8332
|
+
// bidi_qq() not needed since emoji is LTR and cps is a CM
|
|
8333
|
+
throw error_placement(`emoji + combining mark: "${str_from_cps(tokens[i-1])} + ${safe_str_from_cps([cps[0]])}"`);
|
|
8334
|
+
}
|
|
8335
|
+
}
|
|
8336
|
+
check_fenced(norm);
|
|
8337
|
+
let unique = Array_from(new Set(chars));
|
|
8338
|
+
let [g] = determine_group(unique); // take the first match
|
|
8339
|
+
// see derive: "Matching Groups have Same CM Style"
|
|
8340
|
+
// alternative: could form a hybrid type: Latin/Japanese/...
|
|
8341
|
+
check_group(g, chars); // need text in order
|
|
8342
|
+
check_whole(g, unique); // only need unique text (order would be required for multiple-char confusables)
|
|
8343
|
+
type = g.N;
|
|
8344
|
+
// 20230121: consider exposing restricted flag
|
|
8345
|
+
// it's simpler to just check for 'Restricted'
|
|
8346
|
+
// or even better: type.endsWith(']')
|
|
8347
|
+
//if (g.R) info.restricted = true;
|
|
8348
|
+
}
|
|
8349
|
+
}
|
|
8350
|
+
info.type = type;
|
|
8351
|
+
} catch (err) {
|
|
8352
|
+
info.error = err; // use full error object
|
|
8353
|
+
}
|
|
8354
|
+
return info;
|
|
8355
|
+
});
|
|
8356
|
+
}
|
|
8357
|
+
|
|
8358
|
+
function check_whole(group, unique) {
|
|
8359
|
+
let maker;
|
|
8360
|
+
let shared = [];
|
|
8361
|
+
for (let cp of unique) {
|
|
8362
|
+
let whole = WHOLE_MAP.get(cp);
|
|
8363
|
+
if (whole === UNIQUE_PH) return; // unique, non-confusable
|
|
8364
|
+
if (whole) {
|
|
8365
|
+
let set = whole.M.get(cp); // groups which have a character that look-like this character
|
|
8366
|
+
maker = maker ? maker.filter(g => set.has(g)) : Array_from(set);
|
|
8367
|
+
if (!maker.length) return; // confusable intersection is empty
|
|
8368
|
+
} else {
|
|
8369
|
+
shared.push(cp);
|
|
8370
|
+
}
|
|
8371
|
+
}
|
|
8372
|
+
if (maker) {
|
|
8373
|
+
// we have 1+ confusable
|
|
8374
|
+
// check if any of the remaining groups
|
|
8375
|
+
// contain the shared characters too
|
|
8376
|
+
for (let g of maker) {
|
|
8377
|
+
if (shared.every(cp => group_has_cp(g, cp))) {
|
|
8378
|
+
throw new Error(`whole-script confusable: ${group.N}/${g.N}`);
|
|
8379
|
+
}
|
|
8380
|
+
}
|
|
8381
|
+
}
|
|
8382
|
+
}
|
|
8383
|
+
|
|
8384
|
+
// assumption: unique.size > 0
|
|
8385
|
+
// returns list of matching groups
|
|
8386
|
+
function determine_group(unique) {
|
|
8387
|
+
let groups = GROUPS;
|
|
8388
|
+
for (let cp of unique) {
|
|
8389
|
+
// note: we need to dodge CM that are whitelisted
|
|
8390
|
+
// but that code isn't currently necessary
|
|
8391
|
+
let gs = groups.filter(g => group_has_cp(g, cp));
|
|
8392
|
+
if (!gs.length) {
|
|
8393
|
+
if (!GROUPS.some(g => group_has_cp(g, cp))) {
|
|
8394
|
+
// the character was composed of valid parts
|
|
8395
|
+
// but it's NFC form is invalid
|
|
8396
|
+
// 20230716: change to more exact statement, see: ENSNormalize.{cs,java}
|
|
8397
|
+
// note: this doesn't have to be a composition
|
|
8398
|
+
// 20230720: change to full check
|
|
8399
|
+
throw error_disallowed(cp); // this should be rare
|
|
8400
|
+
} else {
|
|
8401
|
+
// there is no group that contains all these characters
|
|
8402
|
+
// throw using the highest priority group that matched
|
|
8403
|
+
// https://www.unicode.org/reports/tr39/#mixed_script_confusables
|
|
8404
|
+
throw error_group_member(groups[0], cp);
|
|
8405
|
+
}
|
|
8406
|
+
}
|
|
8407
|
+
groups = gs;
|
|
8408
|
+
if (gs.length == 1) break; // there is only one group left
|
|
8409
|
+
}
|
|
8410
|
+
// there are at least 1 group(s) with all of these characters
|
|
8411
|
+
return groups;
|
|
8412
|
+
}
|
|
8413
|
+
|
|
8414
|
+
// throw on first error
|
|
8415
|
+
function flatten(split) {
|
|
8416
|
+
return split.map(({input, error, output}) => {
|
|
8417
|
+
if (error) {
|
|
8418
|
+
// don't print label again if just a single label
|
|
8419
|
+
let msg = error.message;
|
|
8420
|
+
// bidi_qq() only necessary if msg is digits
|
|
8421
|
+
throw new Error(split.length == 1 ? msg : `Invalid label ${bidi_qq(safe_str_from_cps(input, 63))}: ${msg}`);
|
|
8422
|
+
}
|
|
8423
|
+
return str_from_cps(output);
|
|
8424
|
+
}).join(STOP_CH);
|
|
8425
|
+
}
|
|
8426
|
+
|
|
8427
|
+
function error_disallowed(cp) {
|
|
8428
|
+
// TODO: add cp to error?
|
|
8429
|
+
return new Error(`disallowed character: ${quoted_cp(cp)}`);
|
|
8430
|
+
}
|
|
8431
|
+
function error_group_member(g, cp) {
|
|
8432
|
+
let quoted = quoted_cp(cp);
|
|
8433
|
+
let gg = GROUPS.find(g => g.P.has(cp)); // only check primary
|
|
8434
|
+
if (gg) {
|
|
8435
|
+
quoted = `${gg.N} ${quoted}`;
|
|
8436
|
+
}
|
|
8437
|
+
return new Error(`illegal mixture: ${g.N} + ${quoted}`);
|
|
8438
|
+
}
|
|
8439
|
+
function error_placement(where) {
|
|
8440
|
+
return new Error(`illegal placement: ${where}`);
|
|
8441
|
+
}
|
|
8442
|
+
|
|
8443
|
+
// assumption: cps.length > 0
|
|
8444
|
+
// assumption: cps[0] isn't a CM
|
|
8445
|
+
// assumption: the previous character isn't an emoji
|
|
8446
|
+
function check_group(g, cps) {
|
|
8447
|
+
for (let cp of cps) {
|
|
8448
|
+
if (!group_has_cp(g, cp)) {
|
|
8449
|
+
// for whitelisted scripts, this will throw illegal mixture on invalid cm, eg. "e{300}{300}"
|
|
8450
|
+
// at the moment, it's unnecessary to introduce an extra error type
|
|
8451
|
+
// until there exists a whitelisted multi-character
|
|
8452
|
+
// eg. if (M < 0 && is_combining_mark(cp)) { ... }
|
|
8453
|
+
// there are 3 cases:
|
|
8454
|
+
// 1. illegal cm for wrong group => mixture error
|
|
8455
|
+
// 2. illegal cm for same group => cm error
|
|
8456
|
+
// requires set of whitelist cm per group:
|
|
8457
|
+
// eg. new Set([...g.P, ...g.Q].flatMap(nfc).filter(cp => CM.has(cp)))
|
|
8458
|
+
// 3. wrong group => mixture error
|
|
8459
|
+
throw error_group_member(g, cp);
|
|
8460
|
+
}
|
|
8461
|
+
}
|
|
8462
|
+
//if (M >= 0) { // we have a known fixed cm count
|
|
8463
|
+
if (g.M) { // we need to check for NSM
|
|
8464
|
+
let decomposed = nfd(cps);
|
|
8465
|
+
for (let i = 1, e = decomposed.length; i < e; i++) { // see: assumption
|
|
8466
|
+
// 20230210: bugfix: using cps instead of decomposed h/t Carbon225
|
|
8467
|
+
/*
|
|
8468
|
+
if (CM.has(decomposed[i])) {
|
|
8469
|
+
let j = i + 1;
|
|
8470
|
+
while (j < e && CM.has(decomposed[j])) j++;
|
|
8471
|
+
if (j - i > M) {
|
|
8472
|
+
throw new Error(`too many combining marks: ${g.N} ${bidi_qq(str_from_cps(decomposed.slice(i-1, j)))} (${j-i}/${M})`);
|
|
8473
|
+
}
|
|
8474
|
+
i = j;
|
|
8475
|
+
}
|
|
8476
|
+
*/
|
|
8477
|
+
// 20230217: switch to NSM counting
|
|
8478
|
+
// https://www.unicode.org/reports/tr39/#Optional_Detection
|
|
8479
|
+
if (NSM.has(decomposed[i])) {
|
|
8480
|
+
let j = i + 1;
|
|
8481
|
+
for (let cp; j < e && NSM.has(cp = decomposed[j]); j++) {
|
|
8482
|
+
// a. Forbid sequences of the same nonspacing mark.
|
|
8483
|
+
for (let k = i; k < j; k++) { // O(n^2) but n < 100
|
|
8484
|
+
if (decomposed[k] == cp) {
|
|
8485
|
+
throw new Error(`duplicate non-spacing marks: ${quoted_cp(cp)}`);
|
|
8486
|
+
}
|
|
8487
|
+
}
|
|
8488
|
+
}
|
|
8489
|
+
// parse to end so we have full nsm count
|
|
8490
|
+
// b. Forbid sequences of more than 4 nonspacing marks (gc=Mn or gc=Me).
|
|
8491
|
+
if (j - i > NSM_MAX) {
|
|
8492
|
+
// note: this slice starts with a base char or spacing-mark cm
|
|
8493
|
+
throw new Error(`excessive non-spacing marks: ${bidi_qq(safe_str_from_cps(decomposed.slice(i-1, j)))} (${j-i}/${NSM_MAX})`);
|
|
8494
|
+
}
|
|
8495
|
+
i = j;
|
|
8496
|
+
}
|
|
8497
|
+
}
|
|
8498
|
+
}
|
|
8499
|
+
// *** this code currently isn't needed ***
|
|
8500
|
+
/*
|
|
8501
|
+
let cm_whitelist = M instanceof Map;
|
|
8502
|
+
for (let i = 0, e = cps.length; i < e; ) {
|
|
8503
|
+
let cp = cps[i++];
|
|
8504
|
+
let seqs = cm_whitelist && M.get(cp);
|
|
8505
|
+
if (seqs) {
|
|
8506
|
+
// list of codepoints that can follow
|
|
8507
|
+
// if this exists, this will always be 1+
|
|
8508
|
+
let j = i;
|
|
8509
|
+
while (j < e && CM.has(cps[j])) j++;
|
|
8510
|
+
let cms = cps.slice(i, j);
|
|
8511
|
+
let match = seqs.find(seq => !compare_arrays(seq, cms));
|
|
8512
|
+
if (!match) throw new Error(`disallowed combining mark sequence: "${safe_str_from_cps([cp, ...cms])}"`);
|
|
8513
|
+
i = j;
|
|
8514
|
+
} else if (!V.has(cp)) {
|
|
8515
|
+
// https://www.unicode.org/reports/tr39/#mixed_script_confusables
|
|
8516
|
+
let quoted = quoted_cp(cp);
|
|
8517
|
+
for (let cp of cps) {
|
|
8518
|
+
let u = UNIQUE.get(cp);
|
|
8519
|
+
if (u && u !== g) {
|
|
8520
|
+
// if both scripts are restricted this error is confusing
|
|
8521
|
+
// because we don't differentiate RestrictedA from RestrictedB
|
|
8522
|
+
if (!u.R) quoted = `${quoted} is ${u.N}`;
|
|
8523
|
+
break;
|
|
8524
|
+
}
|
|
8525
|
+
}
|
|
8526
|
+
throw new Error(`disallowed ${g.N} character: ${quoted}`);
|
|
8527
|
+
//throw new Error(`disallowed character: ${quoted} (expected ${g.N})`);
|
|
8528
|
+
//throw new Error(`${g.N} does not allow: ${quoted}`);
|
|
8529
|
+
}
|
|
8530
|
+
}
|
|
8531
|
+
if (!cm_whitelist) {
|
|
8532
|
+
let decomposed = nfd(cps);
|
|
8533
|
+
for (let i = 1, e = decomposed.length; i < e; i++) { // we know it can't be cm leading
|
|
8534
|
+
if (CM.has(decomposed[i])) {
|
|
8535
|
+
let j = i + 1;
|
|
8536
|
+
while (j < e && CM.has(decomposed[j])) j++;
|
|
8537
|
+
if (j - i > M) {
|
|
8538
|
+
throw new Error(`too many combining marks: "${str_from_cps(decomposed.slice(i-1, j))}" (${j-i}/${M})`);
|
|
8539
|
+
}
|
|
8540
|
+
i = j;
|
|
8541
|
+
}
|
|
8542
|
+
}
|
|
8543
|
+
}
|
|
8544
|
+
*/
|
|
8545
|
+
}
|
|
8546
|
+
|
|
8547
|
+
// given a list of codepoints
|
|
8548
|
+
// returns a list of lists, where emoji are a fully-qualified (as Array subclass)
|
|
8549
|
+
// eg. explode_cp("abc💩d") => [[61, 62, 63], Emoji[1F4A9, FE0F], [64]]
|
|
8550
|
+
// 20230818: rename for 'process' name collision h/t Javarome
|
|
8551
|
+
// https://github.com/adraffy/ens-normalize.js/issues/23
|
|
8552
|
+
function tokens_from_str(input, nf, ef) {
|
|
8553
|
+
let ret = [];
|
|
8554
|
+
let chars = [];
|
|
8555
|
+
input = input.slice().reverse(); // flip so we can pop
|
|
8556
|
+
while (input.length) {
|
|
8557
|
+
let emoji = consume_emoji_reversed(input);
|
|
8558
|
+
if (emoji) {
|
|
8559
|
+
if (chars.length) {
|
|
8560
|
+
ret.push(nf(chars));
|
|
8561
|
+
chars = [];
|
|
8562
|
+
}
|
|
8563
|
+
ret.push(ef(emoji));
|
|
8564
|
+
} else {
|
|
8565
|
+
let cp = input.pop();
|
|
8566
|
+
if (VALID.has(cp)) {
|
|
8567
|
+
chars.push(cp);
|
|
8568
|
+
} else {
|
|
8569
|
+
let cps = MAPPED.get(cp);
|
|
8570
|
+
if (cps) {
|
|
8571
|
+
chars.push(...cps); // less than 10 elements
|
|
8572
|
+
} else if (!IGNORED.has(cp)) {
|
|
8573
|
+
// 20230912: unicode 15.1 changed the order of processing such that
|
|
8574
|
+
// disallowed parts are only rejected after NFC
|
|
8575
|
+
// https://unicode.org/reports/tr46/#Validity_Criteria
|
|
8576
|
+
// this doesn't impact normalization as of today
|
|
8577
|
+
// technically, this error can be removed as the group logic will apply similar logic
|
|
8578
|
+
// however the error type might be less clear
|
|
8579
|
+
throw error_disallowed(cp);
|
|
8580
|
+
}
|
|
8581
|
+
}
|
|
8582
|
+
}
|
|
8583
|
+
}
|
|
8584
|
+
if (chars.length) {
|
|
8585
|
+
ret.push(nf(chars));
|
|
8586
|
+
}
|
|
8587
|
+
return ret;
|
|
8588
|
+
}
|
|
8589
|
+
|
|
8590
|
+
function filter_fe0f(cps) {
|
|
8591
|
+
return cps.filter(cp => cp != FE0F);
|
|
8592
|
+
}
|
|
8593
|
+
|
|
8594
|
+
// given array of codepoints
|
|
8595
|
+
// returns the longest valid emoji sequence (or undefined if no match)
|
|
8596
|
+
// *MUTATES* the supplied array
|
|
8597
|
+
// disallows interleaved ignored characters
|
|
8598
|
+
// fills (optional) eaten array with matched codepoints
|
|
8599
|
+
function consume_emoji_reversed(cps, eaten) {
|
|
8600
|
+
let node = EMOJI_ROOT;
|
|
8601
|
+
let emoji;
|
|
8602
|
+
let pos = cps.length;
|
|
8603
|
+
while (pos) {
|
|
8604
|
+
node = node.get(cps[--pos]);
|
|
8605
|
+
if (!node) break;
|
|
8606
|
+
let {V} = node;
|
|
8607
|
+
if (V) { // this is a valid emoji (so far)
|
|
8608
|
+
emoji = V;
|
|
8609
|
+
cps.length = pos; // truncate
|
|
8610
|
+
}
|
|
8611
|
+
}
|
|
8612
|
+
return emoji;
|
|
8814
8613
|
}
|
|
8815
8614
|
|
|
8816
8615
|
const Zeros = new Uint8Array(32);
|
|
@@ -19229,7 +19028,6 @@ class JsonRpcApiProvider extends AbstractProvider {
|
|
|
19229
19028
|
address: a.address,
|
|
19230
19029
|
nonce: toQuantity(a.nonce),
|
|
19231
19030
|
chainId: toQuantity(a.chainId),
|
|
19232
|
-
yParity: toQuantity(a.signature.yParity),
|
|
19233
19031
|
r: toQuantity(a.signature.r),
|
|
19234
19032
|
s: toQuantity(a.signature.s),
|
|
19235
19033
|
};
|
|
@@ -20544,7 +20342,7 @@ function decryptKeystoreJsonSync(json, _password) {
|
|
|
20544
20342
|
else {
|
|
20545
20343
|
pass = toUtf8String(_password);
|
|
20546
20344
|
}
|
|
20547
|
-
let wal =
|
|
20345
|
+
let wal = deserializeEncryptedWallet(json, pass);
|
|
20548
20346
|
let privKey = wal.privateKey;
|
|
20549
20347
|
let ks = {
|
|
20550
20348
|
address: wal.address,
|
|
@@ -20564,13 +20362,13 @@ function encryptKeystoreJsonSync(account, password) {
|
|
|
20564
20362
|
const signingKey = new SigningKey(account.privateKey);
|
|
20565
20363
|
const privateKey = getBytes(signingKey.privateKey);
|
|
20566
20364
|
const publicKey = getBytes(signingKey.publicKey);
|
|
20567
|
-
const wal = new
|
|
20365
|
+
const wal = new Wallet$1(account.address, privateKey, publicKey);
|
|
20568
20366
|
if (typeof password === 'string') {
|
|
20569
|
-
return
|
|
20367
|
+
return serializeEncryptedWallet(wal, password);
|
|
20570
20368
|
}
|
|
20571
20369
|
else {
|
|
20572
20370
|
let passPhrase = toUtf8String(password);
|
|
20573
|
-
return
|
|
20371
|
+
return serializeEncryptedWallet(wal, passPhrase);
|
|
20574
20372
|
}
|
|
20575
20373
|
}
|
|
20576
20374
|
|
|
@@ -20666,7 +20464,7 @@ class Wallet extends BaseWallet {
|
|
|
20666
20464
|
* If there is no crytographic random source, this will throw.
|
|
20667
20465
|
*/
|
|
20668
20466
|
static createRandom(provider) {
|
|
20669
|
-
let wal =
|
|
20467
|
+
let wal = newWallet();
|
|
20670
20468
|
let privKey = wal.privateKey;
|
|
20671
20469
|
return new Wallet(hexlify(privKey));
|
|
20672
20470
|
}
|
|
@@ -20956,6 +20754,10 @@ const wordlists = {
|
|
|
20956
20754
|
|
|
20957
20755
|
/////////////////////////////
|
|
20958
20756
|
//
|
|
20757
|
+
async function initQuantum() {
|
|
20758
|
+
let clientConfigVal = new Config("https://sdk.readrelay.quantumcoinapi.com", "https://sdk.writerelay.quantumcoinapi.com", 123123, "", ""); //Mainnet
|
|
20759
|
+
return await initialize(clientConfigVal);
|
|
20760
|
+
}
|
|
20959
20761
|
// dummy change; to pick-up ws security issue changes
|
|
20960
20762
|
|
|
20961
20763
|
var quantumcoin = /*#__PURE__*/Object.freeze({
|
|
@@ -21084,6 +20886,7 @@ var quantumcoin = /*#__PURE__*/Object.freeze({
|
|
|
21084
20886
|
hashMessage: hashMessage,
|
|
21085
20887
|
hexlify: hexlify,
|
|
21086
20888
|
id: id,
|
|
20889
|
+
initQuantum: initQuantum,
|
|
21087
20890
|
isAddress: isAddress,
|
|
21088
20891
|
isAddressable: isAddressable,
|
|
21089
20892
|
isBytesLike: isBytesLike,
|
|
@@ -21133,5 +20936,5 @@ var quantumcoin = /*#__PURE__*/Object.freeze({
|
|
|
21133
20936
|
zeroPadValue: zeroPadValue
|
|
21134
20937
|
});
|
|
21135
20938
|
|
|
21136
|
-
export { AbiCoder, AbstractProvider, AbstractSigner, BaseContract, BaseWallet, Block, BrowserProvider, ConstructorFragment, Contract, ContractEventPayload, ContractFactory, ContractTransactionReceipt, ContractTransactionResponse, ContractUnknownEventPayload, EnsPlugin, EnsResolver, ErrorDescription, ErrorFragment, EtherSymbol, EventFragment, EventLog, EventPayload, FallbackFragment, FallbackProvider, FeeData, FeeDataNetworkPlugin, FetchCancelSignal, FetchRequest, FetchResponse, FetchUrlFeeDataNetworkPlugin, FixedNumber, Fragment, FunctionFragment, GasCostPlugin, Indexed, Interface, IpcSocketProvider, JsonRpcApiProvider, JsonRpcProvider, JsonRpcSigner, LangEn, Log, LogDescription, MaxInt256, MaxUint256, MessagePrefix, MinInt256, MulticoinProviderPlugin, N, NamedFragment, Network, NetworkPlugin, NonceManager, ParamType, Result, Signature, SigningKey, SocketBlockSubscriber, SocketEventSubscriber, SocketPendingSubscriber, SocketProvider, SocketSubscriber, StructFragment, Transaction, TransactionDescription, TransactionReceipt, TransactionResponse, Typed, TypedDataEncoder, UndecodedEventLog, UnmanagedSubscriber, Utf8ErrorFuncs, VoidSigner, Wallet, WebSocketProvider, WeiPerEther, Wordlist, WordlistOwl, WordlistOwlA, ZeroAddress, ZeroHash, accessListify, assert, assertArgument, assertArgumentCount, assertNormalize, assertPrivate, authorizationify, checkResultErrors, computeAddress, computeHmac, concat, copyRequest, dataLength, dataSlice, decodeBase58, decodeBase64, decodeBytes32String, decodeRlp, decryptKeystoreJsonSync, defineProperties, dnsEncode, encodeBase58, encodeBase64, encodeBytes32String, encodeRlp, encryptKeystoreJsonSync, ensNormalize, quantumcoin as ethers, formatEther, formatUnits, fromTwos, getAddress, getBigInt, getBytes, getBytesCopy, getCreate2Address, getCreateAddress, getDefaultProvider, getNumber, getUint, hashAuthorization, hashMessage, hexlify, id, isAddress, isAddressable, isBytesLike, isCallException, isError, isHexString, isKeystoreJson, isValidName, keccak256, lock, makeError, mask, namehash, parseEther, parseUnits, pbkdf2, randomBytes, recoverAddress, resolveAddress, resolveProperties, ripemd160, scrypt, scryptSync, sha256, sha512, showThrottleMessage, solidityPacked, solidityPackedKeccak256, solidityPackedSha256, stripZerosLeft, toBeArray, toBeHex, toBigInt, toNumber, toQuantity, toTwos, toUtf8Bytes, toUtf8CodePoints, toUtf8String, uuidV4, verifyAuthorization, verifyMessage, verifyTypedData, version, wordlists, zeroPadBytes, zeroPadValue };
|
|
20939
|
+
export { AbiCoder, AbstractProvider, AbstractSigner, BaseContract, BaseWallet, Block, BrowserProvider, ConstructorFragment, Contract, ContractEventPayload, ContractFactory, ContractTransactionReceipt, ContractTransactionResponse, ContractUnknownEventPayload, EnsPlugin, EnsResolver, ErrorDescription, ErrorFragment, EtherSymbol, EventFragment, EventLog, EventPayload, FallbackFragment, FallbackProvider, FeeData, FeeDataNetworkPlugin, FetchCancelSignal, FetchRequest, FetchResponse, FetchUrlFeeDataNetworkPlugin, FixedNumber, Fragment, FunctionFragment, GasCostPlugin, Indexed, Interface, IpcSocketProvider, JsonRpcApiProvider, JsonRpcProvider, JsonRpcSigner, LangEn, Log, LogDescription, MaxInt256, MaxUint256, MessagePrefix, MinInt256, MulticoinProviderPlugin, N, NamedFragment, Network, NetworkPlugin, NonceManager, ParamType, Result, Signature, SigningKey, SocketBlockSubscriber, SocketEventSubscriber, SocketPendingSubscriber, SocketProvider, SocketSubscriber, StructFragment, Transaction, TransactionDescription, TransactionReceipt, TransactionResponse, Typed, TypedDataEncoder, UndecodedEventLog, UnmanagedSubscriber, Utf8ErrorFuncs, VoidSigner, Wallet, WebSocketProvider, WeiPerEther, Wordlist, WordlistOwl, WordlistOwlA, ZeroAddress, ZeroHash, accessListify, assert, assertArgument, assertArgumentCount, assertNormalize, assertPrivate, authorizationify, checkResultErrors, computeAddress, computeHmac, concat, copyRequest, dataLength, dataSlice, decodeBase58, decodeBase64, decodeBytes32String, decodeRlp, decryptKeystoreJsonSync, defineProperties, dnsEncode, encodeBase58, encodeBase64, encodeBytes32String, encodeRlp, encryptKeystoreJsonSync, ensNormalize, quantumcoin as ethers, formatEther, formatUnits, fromTwos, getAddress, getBigInt, getBytes, getBytesCopy, getCreate2Address, getCreateAddress, getDefaultProvider, getNumber, getUint, hashAuthorization, hashMessage, hexlify, id, initQuantum, isAddress, isAddressable, isBytesLike, isCallException, isError, isHexString, isKeystoreJson, isValidName, keccak256, lock, makeError, mask, namehash, parseEther, parseUnits, pbkdf2, randomBytes, recoverAddress, resolveAddress, resolveProperties, ripemd160, scrypt, scryptSync, sha256, sha512, showThrottleMessage, solidityPacked, solidityPackedKeccak256, solidityPackedSha256, stripZerosLeft, toBeArray, toBeHex, toBigInt, toNumber, toQuantity, toTwos, toUtf8Bytes, toUtf8CodePoints, toUtf8String, uuidV4, verifyAuthorization, verifyMessage, verifyTypedData, version, wordlists, zeroPadBytes, zeroPadValue };
|
|
21137
20940
|
//# sourceMappingURL=quantumcoin.js.map
|