@rosen-bridge/rosen-extractor 12.0.2 → 12.1.0
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 +13 -0
- package/dist/getRosenData/const.d.ts +1 -0
- package/dist/getRosenData/const.d.ts.map +1 -1
- package/dist/getRosenData/const.js +3 -1
- package/dist/getRosenData/firo/utils.d.ts.map +1 -1
- package/dist/getRosenData/firo/utils.js +55 -10
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +5 -2
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# @rosen-bridge/rosen-extractor
|
|
2
2
|
|
|
3
|
+
## 12.1.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Add support for Base chain
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Fix Firo OP_RETURN parsing for OP_PUSHDATA1 payloads.
|
|
12
|
+
- Improve the `parseRosenData` to throw error if address slice length does not match the given length
|
|
13
|
+
- Update dependencies
|
|
14
|
+
- @rosen-bridge/tokens@6.0.2
|
|
15
|
+
|
|
3
16
|
## 12.0.2
|
|
4
17
|
|
|
5
18
|
### Patch Changes
|
|
@@ -4,6 +4,7 @@ export declare const BITCOIN_NATIVE_TOKEN = "btc";
|
|
|
4
4
|
export declare const BITCOIN_CHAIN = "bitcoin";
|
|
5
5
|
export declare const ETHEREUM_CHAIN = "ethereum";
|
|
6
6
|
export declare const BINANCE_CHAIN = "binance";
|
|
7
|
+
export declare const BASE_CHAIN = "base";
|
|
7
8
|
export declare const CARDANO_CHAIN = "cardano";
|
|
8
9
|
export declare const ERGO_CHAIN = "ergo";
|
|
9
10
|
export declare const DOGE_CHAIN = "doge";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"const.d.ts","sourceRoot":"","sources":["../../lib/getRosenData/const.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,oBAAoB,QAAQ,CAAC;AAC1C,eAAO,MAAM,iBAAiB,QAAQ,CAAC;AACvC,eAAO,MAAM,oBAAoB,QAAQ,CAAC;AAC1C,eAAO,MAAM,aAAa,YAAY,CAAC;AACvC,eAAO,MAAM,cAAc,aAAa,CAAC;AACzC,eAAO,MAAM,aAAa,YAAY,CAAC;AACvC,eAAO,MAAM,aAAa,YAAY,CAAC;AACvC,eAAO,MAAM,UAAU,SAAS,CAAC;AACjC,eAAO,MAAM,UAAU,SAAS,CAAC;AACjC,eAAO,MAAM,iBAAiB,SAAS,CAAC;AACxC,eAAO,MAAM,mBAAmB,kBAAkB,CAAC;AACnD,eAAO,MAAM,eAAe,cAAc,CAAC;AAC3C,eAAO,MAAM,sBAAsB,QAAQ,CAAC;AAC5C,eAAO,MAAM,UAAU,SAAS,CAAC;AACjC,eAAO,MAAM,iBAAiB,SAAS,CAAC;AACxC,eAAO,MAAM,gBAAgB,
|
|
1
|
+
{"version":3,"file":"const.d.ts","sourceRoot":"","sources":["../../lib/getRosenData/const.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,oBAAoB,QAAQ,CAAC;AAC1C,eAAO,MAAM,iBAAiB,QAAQ,CAAC;AACvC,eAAO,MAAM,oBAAoB,QAAQ,CAAC;AAC1C,eAAO,MAAM,aAAa,YAAY,CAAC;AACvC,eAAO,MAAM,cAAc,aAAa,CAAC;AACzC,eAAO,MAAM,aAAa,YAAY,CAAC;AACvC,eAAO,MAAM,UAAU,SAAS,CAAC;AACjC,eAAO,MAAM,aAAa,YAAY,CAAC;AACvC,eAAO,MAAM,UAAU,SAAS,CAAC;AACjC,eAAO,MAAM,UAAU,SAAS,CAAC;AACjC,eAAO,MAAM,iBAAiB,SAAS,CAAC;AACxC,eAAO,MAAM,mBAAmB,kBAAkB,CAAC;AACnD,eAAO,MAAM,eAAe,cAAc,CAAC;AAC3C,eAAO,MAAM,sBAAsB,QAAQ,CAAC;AAC5C,eAAO,MAAM,UAAU,SAAS,CAAC;AACjC,eAAO,MAAM,iBAAiB,SAAS,CAAC;AACxC,eAAO,MAAM,gBAAgB,UAW5B,CAAC"}
|
|
@@ -4,6 +4,7 @@ export const BITCOIN_NATIVE_TOKEN = 'btc';
|
|
|
4
4
|
export const BITCOIN_CHAIN = 'bitcoin';
|
|
5
5
|
export const ETHEREUM_CHAIN = 'ethereum';
|
|
6
6
|
export const BINANCE_CHAIN = 'binance';
|
|
7
|
+
export const BASE_CHAIN = 'base';
|
|
7
8
|
export const CARDANO_CHAIN = 'cardano';
|
|
8
9
|
export const ERGO_CHAIN = 'ergo';
|
|
9
10
|
export const DOGE_CHAIN = 'doge';
|
|
@@ -19,9 +20,10 @@ export const SUPPORTED_CHAINS = [
|
|
|
19
20
|
BITCOIN_CHAIN,
|
|
20
21
|
ETHEREUM_CHAIN,
|
|
21
22
|
BINANCE_CHAIN,
|
|
23
|
+
BASE_CHAIN,
|
|
22
24
|
DOGE_CHAIN,
|
|
23
25
|
BITCOIN_RUNES_CHAIN,
|
|
24
26
|
FIRO_CHAIN,
|
|
25
27
|
HANDSHAKE_CHAIN,
|
|
26
28
|
];
|
|
27
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
29
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9saWIvZ2V0Um9zZW5EYXRhL2NvbnN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE1BQU0sQ0FBQyxNQUFNLG9CQUFvQixHQUFHLEtBQUssQ0FBQztBQUMxQyxNQUFNLENBQUMsTUFBTSxpQkFBaUIsR0FBRyxLQUFLLENBQUM7QUFDdkMsTUFBTSxDQUFDLE1BQU0sb0JBQW9CLEdBQUcsS0FBSyxDQUFDO0FBQzFDLE1BQU0sQ0FBQyxNQUFNLGFBQWEsR0FBRyxTQUFTLENBQUM7QUFDdkMsTUFBTSxDQUFDLE1BQU0sY0FBYyxHQUFHLFVBQVUsQ0FBQztBQUN6QyxNQUFNLENBQUMsTUFBTSxhQUFhLEdBQUcsU0FBUyxDQUFDO0FBQ3ZDLE1BQU0sQ0FBQyxNQUFNLFVBQVUsR0FBRyxNQUFNLENBQUM7QUFDakMsTUFBTSxDQUFDLE1BQU0sYUFBYSxHQUFHLFNBQVMsQ0FBQztBQUN2QyxNQUFNLENBQUMsTUFBTSxVQUFVLEdBQUcsTUFBTSxDQUFDO0FBQ2pDLE1BQU0sQ0FBQyxNQUFNLFVBQVUsR0FBRyxNQUFNLENBQUM7QUFDakMsTUFBTSxDQUFDLE1BQU0saUJBQWlCLEdBQUcsTUFBTSxDQUFDO0FBQ3hDLE1BQU0sQ0FBQyxNQUFNLG1CQUFtQixHQUFHLGVBQWUsQ0FBQztBQUNuRCxNQUFNLENBQUMsTUFBTSxlQUFlLEdBQUcsV0FBVyxDQUFDO0FBQzNDLE1BQU0sQ0FBQyxNQUFNLHNCQUFzQixHQUFHLEtBQUssQ0FBQztBQUM1QyxNQUFNLENBQUMsTUFBTSxVQUFVLEdBQUcsTUFBTSxDQUFDO0FBQ2pDLE1BQU0sQ0FBQyxNQUFNLGlCQUFpQixHQUFHLE1BQU0sQ0FBQztBQUN4QyxNQUFNLENBQUMsTUFBTSxnQkFBZ0IsR0FBRztJQUM5QixVQUFVO0lBQ1YsYUFBYTtJQUNiLGFBQWE7SUFDYixjQUFjO0lBQ2QsYUFBYTtJQUNiLFVBQVU7SUFDVixVQUFVO0lBQ1YsbUJBQW1CO0lBQ25CLFVBQVU7SUFDVixlQUFlO0NBQ2hCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgY29uc3QgQ0FSREFOT19OQVRJVkVfVE9LRU4gPSAnYWRhJztcbmV4cG9ydCBjb25zdCBFUkdPX05BVElWRV9UT0tFTiA9ICdlcmcnO1xuZXhwb3J0IGNvbnN0IEJJVENPSU5fTkFUSVZFX1RPS0VOID0gJ2J0Yyc7XG5leHBvcnQgY29uc3QgQklUQ09JTl9DSEFJTiA9ICdiaXRjb2luJztcbmV4cG9ydCBjb25zdCBFVEhFUkVVTV9DSEFJTiA9ICdldGhlcmV1bSc7XG5leHBvcnQgY29uc3QgQklOQU5DRV9DSEFJTiA9ICdiaW5hbmNlJztcbmV4cG9ydCBjb25zdCBCQVNFX0NIQUlOID0gJ2Jhc2UnO1xuZXhwb3J0IGNvbnN0IENBUkRBTk9fQ0hBSU4gPSAnY2FyZGFubyc7XG5leHBvcnQgY29uc3QgRVJHT19DSEFJTiA9ICdlcmdvJztcbmV4cG9ydCBjb25zdCBET0dFX0NIQUlOID0gJ2RvZ2UnO1xuZXhwb3J0IGNvbnN0IERPR0VfTkFUSVZFX1RPS0VOID0gJ2RvZ2UnO1xuZXhwb3J0IGNvbnN0IEJJVENPSU5fUlVORVNfQ0hBSU4gPSAnYml0Y29pbi1ydW5lcyc7XG5leHBvcnQgY29uc3QgSEFORFNIQUtFX0NIQUlOID0gJ2hhbmRzaGFrZSc7XG5leHBvcnQgY29uc3QgSEFORFNIQUtFX05BVElWRV9UT0tFTiA9ICdobnMnO1xuZXhwb3J0IGNvbnN0IEZJUk9fQ0hBSU4gPSAnZmlybyc7XG5leHBvcnQgY29uc3QgRklST19OQVRJVkVfVE9LRU4gPSAnZmlybyc7XG5leHBvcnQgY29uc3QgU1VQUE9SVEVEX0NIQUlOUyA9IFtcbiAgRVJHT19DSEFJTixcbiAgQ0FSREFOT19DSEFJTixcbiAgQklUQ09JTl9DSEFJTixcbiAgRVRIRVJFVU1fQ0hBSU4sXG4gIEJJTkFOQ0VfQ0hBSU4sXG4gIEJBU0VfQ0hBSU4sXG4gIERPR0VfQ0hBSU4sXG4gIEJJVENPSU5fUlVORVNfQ0hBSU4sXG4gIEZJUk9fQ0hBSU4sXG4gIEhBTkRTSEFLRV9DSEFJTixcbl07XG4iXX0=
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../lib/getRosenData/firo/utils.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../lib/getRosenData/firo/utils.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAgFtD;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,GAAI,MAAM,MAAM,KAAG,MAQpD,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,aAAa,GACxB,iBAAiB,MAAM,KACtB,uBAEF,CAAC"}
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { address } from 'bitcoinjs-lib';
|
|
2
2
|
import { parseRosenData } from '../../utils';
|
|
3
|
+
const OP_RETURN = 0x6a;
|
|
4
|
+
const OP_PUSHDATA1 = 0x4c;
|
|
5
|
+
const OP_PUSHDATA2 = 0x4d;
|
|
6
|
+
const OP_PUSHDATA4 = 0x4e;
|
|
7
|
+
const MAX_OP_RETURN_DATA_BYTES = 80;
|
|
3
8
|
const firoNetwork = {
|
|
4
9
|
// Firo network parameters
|
|
5
10
|
messagePrefix: '\x19Firo Signed Message:\n',
|
|
@@ -12,6 +17,54 @@ const firoNetwork = {
|
|
|
12
17
|
scriptHash: 0x07,
|
|
13
18
|
wif: 0xd2,
|
|
14
19
|
};
|
|
20
|
+
/**
|
|
21
|
+
* Extracts Rosen OP_RETURN payload from a Firo scriptPubKey.
|
|
22
|
+
*
|
|
23
|
+
* Supports direct push and OP_PUSHDATA1/2/4 encodings while enforcing Rosen's
|
|
24
|
+
* 80-byte OP_RETURN payload limit.
|
|
25
|
+
*
|
|
26
|
+
* @param scriptPubKeyHex Firo scriptPubKey hex
|
|
27
|
+
* @returns OP_RETURN payload hex
|
|
28
|
+
*/
|
|
29
|
+
const parseOpReturnData = (scriptPubKeyHex) => {
|
|
30
|
+
if (scriptPubKeyHex.length % 2 !== 0)
|
|
31
|
+
throw Error(`script hex length is odd`);
|
|
32
|
+
const scriptLength = scriptPubKeyHex.length / 2;
|
|
33
|
+
let offset = 0;
|
|
34
|
+
const readBytes = (length) => {
|
|
35
|
+
if (offset + length > scriptLength)
|
|
36
|
+
throw Error(`script length is unexpected [${offset + length} > ${scriptLength}]`);
|
|
37
|
+
const result = scriptPubKeyHex.slice(offset * 2, (offset + length) * 2);
|
|
38
|
+
offset += length;
|
|
39
|
+
return result;
|
|
40
|
+
};
|
|
41
|
+
const opcode = parseInt(readBytes(1), 16);
|
|
42
|
+
if (opcode !== OP_RETURN)
|
|
43
|
+
throw Error(`script does not start with OP_RETURN opcode (6a)`);
|
|
44
|
+
const pushOpcode = parseInt(readBytes(1), 16);
|
|
45
|
+
let dataLength;
|
|
46
|
+
if (pushOpcode < OP_PUSHDATA1) {
|
|
47
|
+
dataLength = pushOpcode;
|
|
48
|
+
}
|
|
49
|
+
else if (pushOpcode === OP_PUSHDATA1) {
|
|
50
|
+
dataLength = parseInt(readBytes(1), 16);
|
|
51
|
+
}
|
|
52
|
+
else if (pushOpcode === OP_PUSHDATA2) {
|
|
53
|
+
dataLength = Buffer.from(readBytes(2), 'hex').readUInt16LE();
|
|
54
|
+
}
|
|
55
|
+
else if (pushOpcode === OP_PUSHDATA4) {
|
|
56
|
+
dataLength = Buffer.from(readBytes(4), 'hex').readUInt32LE();
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
throw Error(`script contains unsupported push opcode [${pushOpcode}]`);
|
|
60
|
+
}
|
|
61
|
+
if (dataLength > MAX_OP_RETURN_DATA_BYTES)
|
|
62
|
+
throw Error(`OP_RETURN data length exceeds Rosen limit [${dataLength} > ${MAX_OP_RETURN_DATA_BYTES}]`);
|
|
63
|
+
const expectedScriptLength = offset + dataLength;
|
|
64
|
+
if (Number.isNaN(dataLength) || expectedScriptLength !== scriptLength)
|
|
65
|
+
throw Error(`script length is unexpected [${expectedScriptLength} !== ${scriptLength}]`);
|
|
66
|
+
return readBytes(dataLength);
|
|
67
|
+
};
|
|
15
68
|
/**
|
|
16
69
|
* Converts a Firocoin address to its corresponding output script
|
|
17
70
|
* @param addr The Firocoin address to convert
|
|
@@ -30,14 +83,6 @@ export const addressToOutputScript = (addr) => {
|
|
|
30
83
|
* @param scriptPubKeyHex
|
|
31
84
|
*/
|
|
32
85
|
export const parseOpReturn = (scriptPubKeyHex) => {
|
|
33
|
-
|
|
34
|
-
if (scriptPubKeyHex.slice(0, 2) !== '6a')
|
|
35
|
-
throw Error(`script does not start with OP_RETURN opcode (6a)`);
|
|
36
|
-
// check script length (should not use more than one OP_RETURN)
|
|
37
|
-
const dataLength = scriptPubKeyHex.slice(2, 4);
|
|
38
|
-
if (parseInt(dataLength, 16) + 2 !== scriptPubKeyHex.length / 2)
|
|
39
|
-
throw Error(`script length is unexpected [${parseInt(dataLength, 16) + 3} !== ${scriptPubKeyHex.length / 2}]`);
|
|
40
|
-
const remainingData = scriptPubKeyHex.slice(4);
|
|
41
|
-
return parseRosenData(remainingData);
|
|
86
|
+
return parseRosenData(parseOpReturnData(scriptPubKeyHex));
|
|
42
87
|
};
|
|
43
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
88
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9saWIvZ2V0Um9zZW5EYXRhL2Zpcm8vdXRpbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUd4QyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBRTdDLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQztBQUN2QixNQUFNLFlBQVksR0FBRyxJQUFJLENBQUM7QUFDMUIsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDO0FBQzFCLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQztBQUMxQixNQUFNLHdCQUF3QixHQUFHLEVBQUUsQ0FBQztBQUVwQyxNQUFNLFdBQVcsR0FBRztJQUNsQiwwQkFBMEI7SUFDMUIsYUFBYSxFQUFFLDRCQUE0QjtJQUMzQyxNQUFNLEVBQUUsTUFBTTtJQUNkLEtBQUssRUFBRTtRQUNMLE1BQU0sRUFBRSxVQUFVO1FBQ2xCLE9BQU8sRUFBRSxVQUFVO0tBQ3BCO0lBQ0QsVUFBVSxFQUFFLElBQUksRUFBRSx3RUFBd0U7SUFDMUYsVUFBVSxFQUFFLElBQUk7SUFDaEIsR0FBRyxFQUFFLElBQUk7Q0FDVixDQUFDO0FBRUY7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFNLGlCQUFpQixHQUFHLENBQUMsZUFBdUIsRUFBVSxFQUFFO0lBQzVELElBQUksZUFBZSxDQUFDLE1BQU0sR0FBRyxDQUFDLEtBQUssQ0FBQztRQUFFLE1BQU0sS0FBSyxDQUFDLDBCQUEwQixDQUFDLENBQUM7SUFFOUUsTUFBTSxZQUFZLEdBQUcsZUFBZSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7SUFDaEQsSUFBSSxNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBRWYsTUFBTSxTQUFTLEdBQUcsQ0FBQyxNQUFjLEVBQUUsRUFBRTtRQUNuQyxJQUFJLE1BQU0sR0FBRyxNQUFNLEdBQUcsWUFBWTtZQUNoQyxNQUFNLEtBQUssQ0FDVCxnQ0FBZ0MsTUFBTSxHQUFHLE1BQU0sTUFBTSxZQUFZLEdBQUcsQ0FDckUsQ0FBQztRQUVKLE1BQU0sTUFBTSxHQUFHLGVBQWUsQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUN4RSxNQUFNLElBQUksTUFBTSxDQUFDO1FBQ2pCLE9BQU8sTUFBTSxDQUFDO0lBQ2hCLENBQUMsQ0FBQztJQUVGLE1BQU0sTUFBTSxHQUFHLFFBQVEsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDMUMsSUFBSSxNQUFNLEtBQUssU0FBUztRQUN0QixNQUFNLEtBQUssQ0FBQyxrREFBa0QsQ0FBQyxDQUFDO0lBRWxFLE1BQU0sVUFBVSxHQUFHLFFBQVEsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDOUMsSUFBSSxVQUFrQixDQUFDO0lBQ3ZCLElBQUksVUFBVSxHQUFHLFlBQVksRUFBRSxDQUFDO1FBQzlCLFVBQVUsR0FBRyxVQUFVLENBQUM7SUFDMUIsQ0FBQztTQUFNLElBQUksVUFBVSxLQUFLLFlBQVksRUFBRSxDQUFDO1FBQ3ZDLFVBQVUsR0FBRyxRQUFRLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQzFDLENBQUM7U0FBTSxJQUFJLFVBQVUsS0FBSyxZQUFZLEVBQUUsQ0FBQztRQUN2QyxVQUFVLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUMsWUFBWSxFQUFFLENBQUM7SUFDL0QsQ0FBQztTQUFNLElBQUksVUFBVSxLQUFLLFlBQVksRUFBRSxDQUFDO1FBQ3ZDLFVBQVUsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUMvRCxDQUFDO1NBQU0sQ0FBQztRQUNOLE1BQU0sS0FBSyxDQUFDLDRDQUE0QyxVQUFVLEdBQUcsQ0FBQyxDQUFDO0lBQ3pFLENBQUM7SUFFRCxJQUFJLFVBQVUsR0FBRyx3QkFBd0I7UUFDdkMsTUFBTSxLQUFLLENBQ1QsOENBQThDLFVBQVUsTUFBTSx3QkFBd0IsR0FBRyxDQUMxRixDQUFDO0lBRUosTUFBTSxvQkFBb0IsR0FBRyxNQUFNLEdBQUcsVUFBVSxDQUFDO0lBQ2pELElBQUksTUFBTSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsSUFBSSxvQkFBb0IsS0FBSyxZQUFZO1FBQ25FLE1BQU0sS0FBSyxDQUNULGdDQUFnQyxvQkFBb0IsUUFBUSxZQUFZLEdBQUcsQ0FDNUUsQ0FBQztJQUVKLE9BQU8sU0FBUyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0FBQy9CLENBQUMsQ0FBQztBQUVGOzs7O0dBSUc7QUFDSCxNQUFNLENBQUMsTUFBTSxxQkFBcUIsR0FBRyxDQUFDLElBQVksRUFBVSxFQUFFO0lBQzVELElBQUksQ0FBQztRQUNILE9BQU8sT0FBTyxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsV0FBVyxDQUFDLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ25FLENBQUM7SUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1FBQ1gsTUFBTSxJQUFJLEtBQUssQ0FDYixvREFBb0QsQ0FBQyx1SEFBdUgsQ0FDN0ssQ0FBQztJQUNKLENBQUM7QUFDSCxDQUFDLENBQUM7QUFFRjs7O0dBR0c7QUFDSCxNQUFNLENBQUMsTUFBTSxhQUFhLEdBQUcsQ0FDM0IsZUFBdUIsRUFDRSxFQUFFO0lBQzNCLE9BQU8sY0FBYyxDQUFDLGlCQUFpQixDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUM7QUFDNUQsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgYWRkcmVzcyB9IGZyb20gJ2JpdGNvaW5qcy1saWInO1xuXG5pbXBvcnQgeyBNaW5pbWFsT25DaGFpblJvc2VuRGF0YSB9IGZyb20gJy4uLy4uL3R5cGVzJztcbmltcG9ydCB7IHBhcnNlUm9zZW5EYXRhIH0gZnJvbSAnLi4vLi4vdXRpbHMnO1xuXG5jb25zdCBPUF9SRVRVUk4gPSAweDZhO1xuY29uc3QgT1BfUFVTSERBVEExID0gMHg0YztcbmNvbnN0IE9QX1BVU0hEQVRBMiA9IDB4NGQ7XG5jb25zdCBPUF9QVVNIREFUQTQgPSAweDRlO1xuY29uc3QgTUFYX09QX1JFVFVSTl9EQVRBX0JZVEVTID0gODA7XG5cbmNvbnN0IGZpcm9OZXR3b3JrID0ge1xuICAvLyBGaXJvIG5ldHdvcmsgcGFyYW1ldGVyc1xuICBtZXNzYWdlUHJlZml4OiAnXFx4MTlGaXJvIFNpZ25lZCBNZXNzYWdlOlxcbicsXG4gIGJlY2gzMjogJ2Zpcm8nLFxuICBiaXAzMjoge1xuICAgIHB1YmxpYzogMHgwNDg4YjIxZSxcbiAgICBwcml2YXRlOiAweDA0ODhhZGU0LFxuICB9LFxuICBwdWJLZXlIYXNoOiAweDUyLCAvLyBGaXJvIG1haW5uZXQgdXNlcyAweDUyIChhIGFkZHJlc3NlcyksIHRlc3RuZXQgdXNlcyAweDQxIChUIGFkZHJlc3NlcylcbiAgc2NyaXB0SGFzaDogMHgwNyxcbiAgd2lmOiAweGQyLFxufTtcblxuLyoqXG4gKiBFeHRyYWN0cyBSb3NlbiBPUF9SRVRVUk4gcGF5bG9hZCBmcm9tIGEgRmlybyBzY3JpcHRQdWJLZXkuXG4gKlxuICogU3VwcG9ydHMgZGlyZWN0IHB1c2ggYW5kIE9QX1BVU0hEQVRBMS8yLzQgZW5jb2RpbmdzIHdoaWxlIGVuZm9yY2luZyBSb3NlbidzXG4gKiA4MC1ieXRlIE9QX1JFVFVSTiBwYXlsb2FkIGxpbWl0LlxuICpcbiAqIEBwYXJhbSBzY3JpcHRQdWJLZXlIZXggRmlybyBzY3JpcHRQdWJLZXkgaGV4XG4gKiBAcmV0dXJucyBPUF9SRVRVUk4gcGF5bG9hZCBoZXhcbiAqL1xuY29uc3QgcGFyc2VPcFJldHVybkRhdGEgPSAoc2NyaXB0UHViS2V5SGV4OiBzdHJpbmcpOiBzdHJpbmcgPT4ge1xuICBpZiAoc2NyaXB0UHViS2V5SGV4Lmxlbmd0aCAlIDIgIT09IDApIHRocm93IEVycm9yKGBzY3JpcHQgaGV4IGxlbmd0aCBpcyBvZGRgKTtcblxuICBjb25zdCBzY3JpcHRMZW5ndGggPSBzY3JpcHRQdWJLZXlIZXgubGVuZ3RoIC8gMjtcbiAgbGV0IG9mZnNldCA9IDA7XG5cbiAgY29uc3QgcmVhZEJ5dGVzID0gKGxlbmd0aDogbnVtYmVyKSA9PiB7XG4gICAgaWYgKG9mZnNldCArIGxlbmd0aCA+IHNjcmlwdExlbmd0aClcbiAgICAgIHRocm93IEVycm9yKFxuICAgICAgICBgc2NyaXB0IGxlbmd0aCBpcyB1bmV4cGVjdGVkIFske29mZnNldCArIGxlbmd0aH0gPiAke3NjcmlwdExlbmd0aH1dYCxcbiAgICAgICk7XG5cbiAgICBjb25zdCByZXN1bHQgPSBzY3JpcHRQdWJLZXlIZXguc2xpY2Uob2Zmc2V0ICogMiwgKG9mZnNldCArIGxlbmd0aCkgKiAyKTtcbiAgICBvZmZzZXQgKz0gbGVuZ3RoO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH07XG5cbiAgY29uc3Qgb3Bjb2RlID0gcGFyc2VJbnQocmVhZEJ5dGVzKDEpLCAxNik7XG4gIGlmIChvcGNvZGUgIT09IE9QX1JFVFVSTilcbiAgICB0aHJvdyBFcnJvcihgc2NyaXB0IGRvZXMgbm90IHN0YXJ0IHdpdGggT1BfUkVUVVJOIG9wY29kZSAoNmEpYCk7XG5cbiAgY29uc3QgcHVzaE9wY29kZSA9IHBhcnNlSW50KHJlYWRCeXRlcygxKSwgMTYpO1xuICBsZXQgZGF0YUxlbmd0aDogbnVtYmVyO1xuICBpZiAocHVzaE9wY29kZSA8IE9QX1BVU0hEQVRBMSkge1xuICAgIGRhdGFMZW5ndGggPSBwdXNoT3Bjb2RlO1xuICB9IGVsc2UgaWYgKHB1c2hPcGNvZGUgPT09IE9QX1BVU0hEQVRBMSkge1xuICAgIGRhdGFMZW5ndGggPSBwYXJzZUludChyZWFkQnl0ZXMoMSksIDE2KTtcbiAgfSBlbHNlIGlmIChwdXNoT3Bjb2RlID09PSBPUF9QVVNIREFUQTIpIHtcbiAgICBkYXRhTGVuZ3RoID0gQnVmZmVyLmZyb20ocmVhZEJ5dGVzKDIpLCAnaGV4JykucmVhZFVJbnQxNkxFKCk7XG4gIH0gZWxzZSBpZiAocHVzaE9wY29kZSA9PT0gT1BfUFVTSERBVEE0KSB7XG4gICAgZGF0YUxlbmd0aCA9IEJ1ZmZlci5mcm9tKHJlYWRCeXRlcyg0KSwgJ2hleCcpLnJlYWRVSW50MzJMRSgpO1xuICB9IGVsc2Uge1xuICAgIHRocm93IEVycm9yKGBzY3JpcHQgY29udGFpbnMgdW5zdXBwb3J0ZWQgcHVzaCBvcGNvZGUgWyR7cHVzaE9wY29kZX1dYCk7XG4gIH1cblxuICBpZiAoZGF0YUxlbmd0aCA+IE1BWF9PUF9SRVRVUk5fREFUQV9CWVRFUylcbiAgICB0aHJvdyBFcnJvcihcbiAgICAgIGBPUF9SRVRVUk4gZGF0YSBsZW5ndGggZXhjZWVkcyBSb3NlbiBsaW1pdCBbJHtkYXRhTGVuZ3RofSA+ICR7TUFYX09QX1JFVFVSTl9EQVRBX0JZVEVTfV1gLFxuICAgICk7XG5cbiAgY29uc3QgZXhwZWN0ZWRTY3JpcHRMZW5ndGggPSBvZmZzZXQgKyBkYXRhTGVuZ3RoO1xuICBpZiAoTnVtYmVyLmlzTmFOKGRhdGFMZW5ndGgpIHx8IGV4cGVjdGVkU2NyaXB0TGVuZ3RoICE9PSBzY3JpcHRMZW5ndGgpXG4gICAgdGhyb3cgRXJyb3IoXG4gICAgICBgc2NyaXB0IGxlbmd0aCBpcyB1bmV4cGVjdGVkIFske2V4cGVjdGVkU2NyaXB0TGVuZ3RofSAhPT0gJHtzY3JpcHRMZW5ndGh9XWAsXG4gICAgKTtcblxuICByZXR1cm4gcmVhZEJ5dGVzKGRhdGFMZW5ndGgpO1xufTtcblxuLyoqXG4gKiBDb252ZXJ0cyBhIEZpcm9jb2luIGFkZHJlc3MgdG8gaXRzIGNvcnJlc3BvbmRpbmcgb3V0cHV0IHNjcmlwdFxuICogQHBhcmFtIGFkZHIgVGhlIEZpcm9jb2luIGFkZHJlc3MgdG8gY29udmVydFxuICogQHJldHVybnMgVGhlIG91dHB1dCBzY3JpcHQgYXMgYSBoZXggc3RyaW5nXG4gKi9cbmV4cG9ydCBjb25zdCBhZGRyZXNzVG9PdXRwdXRTY3JpcHQgPSAoYWRkcjogc3RyaW5nKTogc3RyaW5nID0+IHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gYWRkcmVzcy50b091dHB1dFNjcmlwdChhZGRyLCBmaXJvTmV0d29yaykudG9TdHJpbmcoJ2hleCcpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgYEZhaWxlZCB0byBjb252ZXJ0IEZpcm8gYWRkcmVzcyB0byBvdXRwdXQgc2NyaXB0OiAke2V9LiBPbmx5IHRyYW5zcGFyZW50IGFkZHJlc3NlcyAoUDJQS0gsIFAyU0gpIGFyZSBzdXBwb3J0ZWQuIFByaXZhY3kgYWRkcmVzc2VzIChSQVAsIFNwYXJrLCBMZWxhbnR1cykgYXJlIG5vdCBzdXBwb3J0ZWQuYCxcbiAgICApO1xuICB9XG59O1xuXG4vKipcbiAqIGV4dHJhY3RzIHJvc2VuIGRhdGEgZnJvbSBPUF9SRVRVUk4gYm94IHNjcmlwdCBwdWIga2V5XG4gKiBAcGFyYW0gc2NyaXB0UHViS2V5SGV4XG4gKi9cbmV4cG9ydCBjb25zdCBwYXJzZU9wUmV0dXJuID0gKFxuICBzY3JpcHRQdWJLZXlIZXg6IHN0cmluZyxcbik6IE1pbmltYWxPbkNoYWluUm9zZW5EYXRhID0+IHtcbiAgcmV0dXJuIHBhcnNlUm9zZW5EYXRhKHBhcnNlT3BSZXR1cm5EYXRhKHNjcmlwdFB1YktleUhleCkpO1xufTtcbiJdfQ==
|