@logixjs/sandbox 0.0.1 → 0.0.2
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/LICENSE +201 -0
- package/package.json +3 -1
- package/public/sandbox/chunks/chunk-2AUQRESB.js +1114 -0
- package/public/sandbox/chunks/chunk-2F72LQKW.js +194 -0
- package/public/sandbox/chunks/chunk-2PYDGDD3.js +4071 -0
- package/public/sandbox/chunks/chunk-2UGKSXDZ.js +16 -0
- package/public/sandbox/chunks/chunk-2XVE7F26.js +153 -0
- package/public/sandbox/chunks/chunk-3A7TFNZN.js +219 -0
- package/public/sandbox/chunks/chunk-3BHC6JAV.js +1070 -0
- package/public/sandbox/chunks/chunk-3U4CAKCX.js +61 -0
- package/public/sandbox/chunks/chunk-3VU3JLZO.js +272 -0
- package/public/sandbox/chunks/chunk-4CPONKWY.js +1170 -0
- package/public/sandbox/chunks/chunk-4GMUQTWH.js +850 -0
- package/public/sandbox/chunks/chunk-4KIYG5E4.js +749 -0
- package/public/sandbox/chunks/chunk-4MY35XR3.js +175 -0
- package/public/sandbox/chunks/chunk-5DNHJMHA.js +69 -0
- package/public/sandbox/chunks/chunk-5EC4S7X6.js +42 -0
- package/public/sandbox/chunks/chunk-5FB7QFSH.js +227 -0
- package/public/sandbox/chunks/chunk-5GEYCJW2.js +206 -0
- package/public/sandbox/chunks/chunk-5PT7Q5SS.js +373 -0
- package/public/sandbox/chunks/chunk-5WN5IGKA.js +166 -0
- package/public/sandbox/chunks/chunk-5XOBKSOT.js +213 -0
- package/public/sandbox/chunks/chunk-67RVISUC.js +313 -0
- package/public/sandbox/chunks/chunk-6ELJEKZS.js +12 -0
- package/public/sandbox/chunks/chunk-6FKWRVP4.js +85 -0
- package/public/sandbox/chunks/chunk-6JRP52YT.js +34 -0
- package/public/sandbox/chunks/chunk-6JYAC3G6.js +42 -0
- package/public/sandbox/chunks/chunk-6TUOP63Q.js +86 -0
- package/public/sandbox/chunks/{chunk-A6JFUNQQ.js → chunk-74C5VW7Z.js} +2 -2
- package/public/sandbox/chunks/chunk-75DQFC5M.js +16 -0
- package/public/sandbox/chunks/{chunk-UCFEP3BH.js → chunk-7GPAF2UK.js} +1 -1
- package/public/sandbox/chunks/chunk-7KQFTS2Y.js +135 -0
- package/public/sandbox/chunks/chunk-7POKWYE3.js +112 -0
- package/public/sandbox/chunks/chunk-7VUEF5F3.js +395 -0
- package/public/sandbox/chunks/chunk-7W5APZS2.js +77 -0
- package/public/sandbox/chunks/chunk-A6OFCXDQ.js +397 -0
- package/public/sandbox/chunks/chunk-A7HLOSO6.js +216 -0
- package/public/sandbox/chunks/chunk-AGF4RRCB.js +408 -0
- package/public/sandbox/chunks/chunk-ASJSJAAL.js +122 -0
- package/public/sandbox/chunks/chunk-ASVMK364.js +283 -0
- package/public/sandbox/chunks/chunk-AUDTI2BQ.js +895 -0
- package/public/sandbox/chunks/chunk-B2SZTA3M.js +16 -0
- package/public/sandbox/chunks/chunk-B6YS2UMV.js +372 -0
- package/public/sandbox/chunks/chunk-BCEO3MGD.js +244 -0
- package/public/sandbox/chunks/chunk-BCOO65D4.js +373 -0
- package/public/sandbox/chunks/chunk-BJOWSSEL.js +38 -0
- package/public/sandbox/chunks/chunk-BS2WBFW4.js +373 -0
- package/public/sandbox/chunks/chunk-BUVHG3NJ.js +439 -0
- package/public/sandbox/chunks/chunk-BVE33AN6.js +42 -0
- package/public/sandbox/chunks/chunk-BWTGJZVP.js +19 -0
- package/public/sandbox/chunks/chunk-BXD7GZC3.js +1025 -0
- package/public/sandbox/chunks/chunk-BZH4EUUD.js +164 -0
- package/public/sandbox/chunks/{chunk-HFV5GJPK.js → chunk-C2MYMMO4.js} +3 -3
- package/public/sandbox/chunks/chunk-CRE4NJJ6.js +271 -0
- package/public/sandbox/chunks/chunk-CVZPRIDB.js +706 -0
- package/public/sandbox/chunks/chunk-CWOXD5NG.js +991 -0
- package/public/sandbox/chunks/chunk-D6DOC3BJ.js +373 -0
- package/public/sandbox/chunks/chunk-DEPSGFSY.js +1698 -0
- package/public/sandbox/chunks/chunk-DM7C5NP5.js +819 -0
- package/public/sandbox/chunks/chunk-DN33LMOF.js +1112 -0
- package/public/sandbox/chunks/{chunk-S46P7MC6.js → chunk-DT7YIIWE.js} +2 -2
- package/public/sandbox/chunks/chunk-DVB5WRCI.js +260 -0
- package/public/sandbox/chunks/{chunk-TOHCFMQS.js → chunk-E3EVW7NR.js} +11 -18
- package/public/sandbox/chunks/chunk-E5BV567Q.js +417 -0
- package/public/sandbox/chunks/chunk-E7BIWMQQ.js +203 -0
- package/public/sandbox/chunks/chunk-EAKGPSOQ.js +83 -0
- package/public/sandbox/chunks/chunk-EGUYL2ER.js +75 -0
- package/public/sandbox/chunks/chunk-EP5GQYZ5.js +85 -0
- package/public/sandbox/chunks/chunk-ET6CJEHC.js +221 -0
- package/public/sandbox/chunks/chunk-EU67YZHZ.js +1070 -0
- package/public/sandbox/chunks/{chunk-PTSJJANP.js → chunk-EYNDQLSB.js} +1 -1
- package/public/sandbox/chunks/{chunk-CEGSWZ5S.js → chunk-EZTMVCJF.js} +1 -1
- package/public/sandbox/chunks/chunk-F5CLVIS6.js +907 -0
- package/public/sandbox/chunks/chunk-F743SKYD.js +85 -0
- package/public/sandbox/chunks/chunk-FEGFZ5OX.js +86 -0
- package/public/sandbox/chunks/chunk-FG5B7ZX3.js +373 -0
- package/public/sandbox/chunks/chunk-FKZPYMDG.js +373 -0
- package/public/sandbox/chunks/chunk-FNLXHWIU.js +220 -0
- package/public/sandbox/chunks/chunk-FQRUTYAD.js +1991 -0
- package/public/sandbox/chunks/{chunk-VLYP4WUS.js → chunk-FY5A73NK.js} +5 -5
- package/public/sandbox/chunks/chunk-G7FAOG3O.js +221 -0
- package/public/sandbox/chunks/chunk-GFXHUC7Y.js +73 -0
- package/public/sandbox/chunks/chunk-GIPXUIZQ.js +534 -0
- package/public/sandbox/chunks/chunk-GP37MEGJ.js +52 -0
- package/public/sandbox/chunks/chunk-GXL5QCMF.js +4511 -0
- package/public/sandbox/chunks/chunk-GZ2NSE6A.js +177 -0
- package/public/sandbox/chunks/chunk-GZATW4YD.js +69 -0
- package/public/sandbox/chunks/chunk-H4EBXROQ.js +166 -0
- package/public/sandbox/chunks/chunk-HETCPK6Z.js +153 -0
- package/public/sandbox/chunks/chunk-HGUFQ2QC.js +4431 -0
- package/public/sandbox/chunks/chunk-HGV3VNH3.js +255 -0
- package/public/sandbox/chunks/chunk-HIJ67QWR.js +5397 -0
- package/public/sandbox/chunks/chunk-IDHERBKW.js +1114 -0
- package/public/sandbox/chunks/chunk-IDTK4FIY.js +102 -0
- package/public/sandbox/chunks/chunk-ILFVY7H5.js +164 -0
- package/public/sandbox/chunks/chunk-ISGSRYGO.js +57 -0
- package/public/sandbox/chunks/chunk-J45VPU24.js +408 -0
- package/public/sandbox/chunks/chunk-JAUIM3O5.js +42 -0
- package/public/sandbox/chunks/chunk-JB7OQEM6.js +373 -0
- package/public/sandbox/chunks/chunk-JCKW6NHD.js +15 -0
- package/public/sandbox/chunks/chunk-JMA7GY7Z.js +221 -0
- package/public/sandbox/chunks/chunk-JY46J6IL.js +836 -0
- package/public/sandbox/chunks/{chunk-X72PZOFA.js → chunk-K2MQ66O7.js} +1 -1
- package/public/sandbox/chunks/chunk-KA7PZA6F.js +464 -0
- package/public/sandbox/chunks/chunk-KDEQTUID.js +102 -0
- package/public/sandbox/chunks/chunk-KDJR27JV.js +1696 -0
- package/public/sandbox/chunks/chunk-KFE3JO6N.js +77 -0
- package/public/sandbox/chunks/chunk-KLDSYWT5.js +536 -0
- package/public/sandbox/chunks/chunk-KQWWFYBF.js +203 -0
- package/public/sandbox/chunks/chunk-KTFZSXOW.js +6473 -0
- package/public/sandbox/chunks/chunk-KXVIC55U.js +108 -0
- package/public/sandbox/chunks/{chunk-HNEDTEGQ.js → chunk-L4PNO2H6.js} +1 -1
- package/public/sandbox/chunks/{chunk-WE4STGO2.js → chunk-L4ZNW5DI.js} +2 -2
- package/public/sandbox/chunks/chunk-LBUINGZ4.js +836 -0
- package/public/sandbox/chunks/chunk-LIYPPU6I.js +112 -0
- package/public/sandbox/chunks/chunk-LJHTOJXW.js +221 -0
- package/public/sandbox/chunks/{chunk-BWSNPKO5.js → chunk-LQL23SWJ.js} +2 -2
- package/public/sandbox/chunks/chunk-LTFCYZQ6.js +46 -0
- package/public/sandbox/chunks/chunk-LTWLVCKQ.js +166 -0
- package/public/sandbox/chunks/chunk-LWI7BXFN.js +395 -0
- package/public/sandbox/chunks/chunk-LYBBX6WM.js +225 -0
- package/public/sandbox/chunks/chunk-MXE7HIBM.js +474 -0
- package/public/sandbox/chunks/chunk-MYBDYNK4.js +6004 -0
- package/public/sandbox/chunks/chunk-NC2MIWZX.js +732 -0
- package/public/sandbox/chunks/chunk-NE447XAF.js +597 -0
- package/public/sandbox/chunks/chunk-NEAYV5C2.js +255 -0
- package/public/sandbox/chunks/chunk-NMGFJZ4I.js +26 -0
- package/public/sandbox/chunks/chunk-NWCJJZNQ.js +71 -0
- package/public/sandbox/chunks/chunk-O57OZBDR.js +214 -0
- package/public/sandbox/chunks/chunk-OJJT664Q.js +731 -0
- package/public/sandbox/chunks/chunk-OKTBUTCH.js +1175 -0
- package/public/sandbox/chunks/chunk-OQ4SYV5D.js +534 -0
- package/public/sandbox/chunks/chunk-OTVVIHJD.js +219 -0
- package/public/sandbox/chunks/chunk-OWTMSCF7.js +1052 -0
- package/public/sandbox/chunks/chunk-P5ZQNFC3.js +122 -0
- package/public/sandbox/chunks/chunk-PBPT2U2N.js +1698 -0
- package/public/sandbox/chunks/chunk-PHBJLCP3.js +836 -0
- package/public/sandbox/chunks/chunk-PHV4HYHB.js +397 -0
- package/public/sandbox/chunks/chunk-PIXQ6SOX.js +4071 -0
- package/public/sandbox/chunks/chunk-PKJL6YLK.js +73 -0
- package/public/sandbox/chunks/chunk-PKPOITIU.js +221 -0
- package/public/sandbox/chunks/{chunk-NQW73ACJ.js → chunk-PMXBOYQI.js} +1 -1
- package/public/sandbox/chunks/chunk-PQLZD7NR.js +836 -0
- package/public/sandbox/chunks/chunk-QEESVOZU.js +16 -0
- package/public/sandbox/chunks/chunk-QGIM3FQK.js +159 -0
- package/public/sandbox/chunks/chunk-QL5JNEDO.js +69 -0
- package/public/sandbox/chunks/chunk-QQOZ3RMH.js +867 -0
- package/public/sandbox/chunks/chunk-QUMEVT2F.js +194 -0
- package/public/sandbox/chunks/chunk-QVZBXYVY.js +102 -0
- package/public/sandbox/chunks/chunk-R5HQS6RB.js +135 -0
- package/public/sandbox/chunks/chunk-R75Q2CTT.js +900 -0
- package/public/sandbox/chunks/chunk-RBB6SHW2.js +253 -0
- package/public/sandbox/chunks/chunk-RDHNRWQP.js +383 -0
- package/public/sandbox/chunks/chunk-RIWOEI3T.js +1101 -0
- package/public/sandbox/chunks/chunk-RS5FFPUV.js +103 -0
- package/public/sandbox/chunks/chunk-RYSSJBGX.js +203 -0
- package/public/sandbox/chunks/chunk-S3KBAE5Z.js +1114 -0
- package/public/sandbox/chunks/chunk-S6ZZHV6G.js +244 -0
- package/public/sandbox/chunks/chunk-SFXJ24HY.js +499 -0
- package/public/sandbox/chunks/chunk-SH7TP5CJ.js +1109 -0
- package/public/sandbox/chunks/chunk-SI5OKFFY.js +317 -0
- package/public/sandbox/chunks/chunk-SIXNQNIR.js +86 -0
- package/public/sandbox/chunks/chunk-ST353BOX.js +42 -0
- package/public/sandbox/chunks/chunk-SYEHKMLP.js +1140 -0
- package/public/sandbox/chunks/chunk-SZ4KQUJU.js +69 -0
- package/public/sandbox/chunks/{chunk-5SOP6EKV.js → chunk-SZI65PSP.js} +5 -10
- package/public/sandbox/chunks/chunk-T7RLTSMX.js +78 -0
- package/public/sandbox/chunks/chunk-TJ2RLUTW.js +57 -0
- package/public/sandbox/chunks/chunk-TJB73XPN.js +4071 -0
- package/public/sandbox/chunks/chunk-TXJCYO56.js +4046 -0
- package/public/sandbox/chunks/chunk-U5J3LCYI.js +731 -0
- package/public/sandbox/chunks/chunk-UABFN3NH.js +208 -0
- package/public/sandbox/chunks/chunk-UBMUY7WO.js +13 -0
- package/public/sandbox/chunks/chunk-UC27CE32.js +69 -0
- package/public/sandbox/chunks/chunk-UJGVDFZN.js +147 -0
- package/public/sandbox/chunks/chunk-UNVLTK4N.js +122 -0
- package/public/sandbox/chunks/chunk-UQKQ6V3V.js +208 -0
- package/public/sandbox/chunks/chunk-UZZBHWIO.js +703 -0
- package/public/sandbox/chunks/chunk-VKZIJERL.js +1114 -0
- package/public/sandbox/chunks/chunk-VQQEAGID.js +372 -0
- package/public/sandbox/chunks/{chunk-3LX3KIQQ.js → chunk-W365QUZ5.js} +3 -5
- package/public/sandbox/chunks/chunk-WJY2LSWG.js +1052 -0
- package/public/sandbox/chunks/chunk-WNOBN3DX.js +391 -0
- package/public/sandbox/chunks/chunk-X2Z5VYG3.js +245 -0
- package/public/sandbox/chunks/chunk-X74KU74D.js +959 -0
- package/public/sandbox/chunks/chunk-XE7ULSGQ.js +46 -0
- package/public/sandbox/chunks/chunk-XRXUJZ3X.js +431 -0
- package/public/sandbox/chunks/chunk-XWHIN7CC.js +85 -0
- package/public/sandbox/chunks/chunk-Y2TVGGVL.js +527 -0
- package/public/sandbox/chunks/chunk-YMVMZA3U.js +1395 -0
- package/public/sandbox/chunks/chunk-YOBLFWDV.js +431 -0
- package/public/sandbox/chunks/chunk-YR2RFEZA.js +11 -0
- package/public/sandbox/chunks/chunk-YTD6A35P.js +836 -0
- package/public/sandbox/chunks/chunk-Z5L7EZXS.js +81 -0
- package/public/sandbox/chunks/chunk-Z65I5ET2.js +108 -0
- package/public/sandbox/chunks/chunk-Z6LV34RO.js +390 -0
- package/public/sandbox/chunks/chunk-ZAKUP6QG.js +1634 -0
- package/public/sandbox/chunks/chunk-ZHNYE2YH.js +731 -0
- package/public/sandbox/chunks/chunk-ZHQX3B3Y.js +867 -0
- package/public/sandbox/chunks/chunk-ZIXDFRHJ.js +731 -0
- package/public/sandbox/chunks/chunk-ZPZ2MZ4D.js +528 -0
- package/public/sandbox/chunks/chunk-ZQD6NZXB.js +373 -0
- package/public/sandbox/chunks/chunk-ZVVBP7ON.js +16 -0
- package/public/sandbox/chunks/chunk-ZWE3P6X2.js +11 -0
- package/public/sandbox/logix-core/Bound.js +14 -14
- package/public/sandbox/logix-core/Debug.js +12 -10
- package/public/sandbox/logix-core/EffectOp.js +3 -4
- package/public/sandbox/logix-core/Env.js +5 -2
- package/public/sandbox/logix-core/ExternalStore.js +239 -0
- package/public/sandbox/logix-core/Flow.js +7 -8
- package/public/sandbox/logix-core/Kernel.js +7 -4
- package/public/sandbox/logix-core/Link.js +33 -25
- package/public/sandbox/logix-core/Middleware.js +13 -11
- package/public/sandbox/logix-core/Module.js +93 -30
- package/public/sandbox/logix-core/ModuleTag.js +28 -25
- package/public/sandbox/logix-core/Observability.js +21 -19
- package/public/sandbox/logix-core/Process.js +27 -22
- package/public/sandbox/logix-core/ReadQuery.js +7 -11
- package/public/sandbox/logix-core/Reflection.js +173 -53
- package/public/sandbox/logix-core/Resource.js +6 -3
- package/public/sandbox/logix-core/Root.js +7 -3
- package/public/sandbox/logix-core/Runtime.js +54 -40
- package/public/sandbox/logix-core/ScopeRegistry.js +6 -3
- package/public/sandbox/logix-core/StateTrait.js +17 -14
- package/public/sandbox/logix-core/TraitLifecycle.js +8 -8
- package/public/sandbox/logix-core/Workflow.js +332 -0
- package/public/sandbox/logix-core.js +11133 -6622
- package/public/sandbox/logix-core.manifest.json +4 -2
- package/public/sandbox/worker.js +3 -3
- package/public/sandbox/chunks/chunk-4LRLOTMA.js +0 -1698
- package/public/sandbox/chunks/chunk-CDLXJHXY.js +0 -120
- package/public/sandbox/chunks/chunk-CZRI7MHA.js +0 -46
- package/public/sandbox/chunks/chunk-EJDFUZ4B.js +0 -408
- package/public/sandbox/chunks/chunk-IP63FME6.js +0 -282
- package/public/sandbox/chunks/chunk-JIXTOQXJ.js +0 -1103
- package/public/sandbox/chunks/chunk-MPUSOFJ3.js +0 -1928
- package/public/sandbox/chunks/chunk-ON2LY6HJ.js +0 -135
- package/public/sandbox/chunks/chunk-POIBXAH5.js +0 -995
- package/public/sandbox/chunks/chunk-PQ652ULI.js +0 -6359
- package/public/sandbox/chunks/chunk-RJQ4PG2F.js +0 -77
- package/public/sandbox/chunks/chunk-S4EXG3OS.js +0 -533
- package/public/sandbox/chunks/chunk-SUXDGXVE.js +0 -390
- package/public/sandbox/chunks/chunk-TOQ6SJ6O.js +0 -244
- package/public/sandbox/chunks/chunk-UKYAF3NL.js +0 -1036
- package/public/sandbox/chunks/chunk-UMVN3AWO.js +0 -395
- package/public/sandbox/chunks/chunk-WFV5PPWJ.js +0 -194
- package/public/sandbox/chunks/chunk-YF6IO732.js +0 -206
- package/public/sandbox/chunks/chunk-ZUBABAAO.js +0 -86
|
@@ -1,1928 +0,0 @@
|
|
|
1
|
-
// @logixjs/core subpath bundles for @logixjs/sandbox
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
ReplayLog,
|
|
5
|
-
getAtPath,
|
|
6
|
-
parseListItemFieldPath,
|
|
7
|
-
setAtPathMutating,
|
|
8
|
-
toListItemValuePath
|
|
9
|
-
} from "./chunk-HFV5GJPK.js";
|
|
10
|
-
import {
|
|
11
|
-
Snapshot,
|
|
12
|
-
internal,
|
|
13
|
-
keyHash
|
|
14
|
-
} from "./chunk-CEGSWZ5S.js";
|
|
15
|
-
import {
|
|
16
|
-
create
|
|
17
|
-
} from "./chunk-KE2H62D6.js";
|
|
18
|
-
import {
|
|
19
|
-
forceSourceRefresh,
|
|
20
|
-
inSyncTransactionFiber
|
|
21
|
-
} from "./chunk-WFV5PPWJ.js";
|
|
22
|
-
import {
|
|
23
|
-
compareFieldPath,
|
|
24
|
-
getFieldPathId,
|
|
25
|
-
makeFieldPathIdRegistry,
|
|
26
|
-
normalizeFieldPath
|
|
27
|
-
} from "./chunk-IP63FME6.js";
|
|
28
|
-
import {
|
|
29
|
-
getBoundInternals
|
|
30
|
-
} from "./chunk-UCFEP3BH.js";
|
|
31
|
-
import {
|
|
32
|
-
ReplayModeConfigTag,
|
|
33
|
-
isDevEnv
|
|
34
|
-
} from "./chunk-CZRI7MHA.js";
|
|
35
|
-
import {
|
|
36
|
-
record
|
|
37
|
-
} from "./chunk-UKYAF3NL.js";
|
|
38
|
-
import {
|
|
39
|
-
fnv1a32,
|
|
40
|
-
stableStringify
|
|
41
|
-
} from "./chunk-S46P7MC6.js";
|
|
42
|
-
import {
|
|
43
|
-
RunSessionTag,
|
|
44
|
-
make,
|
|
45
|
-
run
|
|
46
|
-
} from "./chunk-3LX3KIQQ.js";
|
|
47
|
-
import {
|
|
48
|
-
EffectOpMiddlewareTag
|
|
49
|
-
} from "./chunk-TOQ6SJ6O.js";
|
|
50
|
-
|
|
51
|
-
// ../logix-core/src/internal/state-trait/build.ts
|
|
52
|
-
import * as SchemaAST from "../effect/SchemaAST.js";
|
|
53
|
-
|
|
54
|
-
// ../logix-core/src/internal/state-trait/meta.ts
|
|
55
|
-
var uniqSortedStrings = (input) => {
|
|
56
|
-
const set = /* @__PURE__ */ new Set();
|
|
57
|
-
for (const item of input) {
|
|
58
|
-
const v = item.trim();
|
|
59
|
-
if (!v) continue;
|
|
60
|
-
set.add(v);
|
|
61
|
-
}
|
|
62
|
-
return Array.from(set).sort((a, b) => a.localeCompare(b));
|
|
63
|
-
};
|
|
64
|
-
var isPlainRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
65
|
-
var sanitizeJsonValue = (input, depth) => {
|
|
66
|
-
if (input === null) return null;
|
|
67
|
-
if (typeof input === "string") return input;
|
|
68
|
-
if (typeof input === "boolean") return input;
|
|
69
|
-
if (typeof input === "number") {
|
|
70
|
-
return Number.isFinite(input) ? input : void 0;
|
|
71
|
-
}
|
|
72
|
-
if (depth >= 6) return void 0;
|
|
73
|
-
if (Array.isArray(input)) {
|
|
74
|
-
const out = [];
|
|
75
|
-
for (const item of input) {
|
|
76
|
-
const v = sanitizeJsonValue(item, depth + 1);
|
|
77
|
-
if (v !== void 0) out.push(v);
|
|
78
|
-
}
|
|
79
|
-
return out;
|
|
80
|
-
}
|
|
81
|
-
if (isPlainRecord(input)) {
|
|
82
|
-
const keys = Object.keys(input).sort();
|
|
83
|
-
const out = {};
|
|
84
|
-
for (const key of keys) {
|
|
85
|
-
const v = sanitizeJsonValue(input[key], depth + 1);
|
|
86
|
-
if (v !== void 0) out[key] = v;
|
|
87
|
-
}
|
|
88
|
-
return out;
|
|
89
|
-
}
|
|
90
|
-
return void 0;
|
|
91
|
-
};
|
|
92
|
-
var sanitize = (input) => {
|
|
93
|
-
if (input === null || input === void 0) return void 0;
|
|
94
|
-
if (typeof input !== "object" || Array.isArray(input)) return void 0;
|
|
95
|
-
const record2 = input;
|
|
96
|
-
const out = {};
|
|
97
|
-
const pickString = (key) => {
|
|
98
|
-
const value = record2[key];
|
|
99
|
-
if (typeof value !== "string") return;
|
|
100
|
-
const trimmed = value.trim();
|
|
101
|
-
if (!trimmed) return;
|
|
102
|
-
out[key] = trimmed;
|
|
103
|
-
};
|
|
104
|
-
pickString("label");
|
|
105
|
-
pickString("description");
|
|
106
|
-
pickString("group");
|
|
107
|
-
pickString("docsUrl");
|
|
108
|
-
pickString("cacheGroup");
|
|
109
|
-
const canonical = record2.canonical;
|
|
110
|
-
if (typeof canonical === "boolean") {
|
|
111
|
-
out.canonical = canonical;
|
|
112
|
-
}
|
|
113
|
-
const tagsRaw = record2.tags;
|
|
114
|
-
if (typeof tagsRaw === "string") {
|
|
115
|
-
const tags = uniqSortedStrings([tagsRaw]);
|
|
116
|
-
if (tags.length > 0) out.tags = tags;
|
|
117
|
-
} else if (Array.isArray(tagsRaw)) {
|
|
118
|
-
const tags = uniqSortedStrings(tagsRaw.filter((x) => typeof x === "string"));
|
|
119
|
-
if (tags.length > 0) out.tags = tags;
|
|
120
|
-
}
|
|
121
|
-
const annotations = {};
|
|
122
|
-
const annotationKeys = Object.keys(record2).filter((k) => k.startsWith("x-")).sort((a, b) => a.localeCompare(b));
|
|
123
|
-
for (const key of annotationKeys) {
|
|
124
|
-
const v = sanitizeJsonValue(record2[key], 0);
|
|
125
|
-
if (v !== void 0) annotations[key] = v;
|
|
126
|
-
}
|
|
127
|
-
const annotationsRaw = record2.annotations;
|
|
128
|
-
if (isPlainRecord(annotationsRaw)) {
|
|
129
|
-
const keys = Object.keys(annotationsRaw).filter((k) => k.startsWith("x-")).sort((a, b) => a.localeCompare(b));
|
|
130
|
-
for (const key of keys) {
|
|
131
|
-
const v = sanitizeJsonValue(annotationsRaw[key], 0);
|
|
132
|
-
if (v !== void 0) annotations[key] = v;
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
if (Object.keys(annotations).length > 0) out.annotations = annotations;
|
|
136
|
-
return Object.keys(out).length > 0 ? out : void 0;
|
|
137
|
-
};
|
|
138
|
-
var stableStringify2 = (meta) => {
|
|
139
|
-
const out = {};
|
|
140
|
-
const keys = Object.keys(meta).sort();
|
|
141
|
-
for (const k of keys) {
|
|
142
|
-
out[k] = meta[k];
|
|
143
|
-
}
|
|
144
|
-
return JSON.stringify(out);
|
|
145
|
-
};
|
|
146
|
-
var equals = (a, b) => {
|
|
147
|
-
if (a === b) return true;
|
|
148
|
-
if (!a || !b) return false;
|
|
149
|
-
return stableStringify2(a) === stableStringify2(b);
|
|
150
|
-
};
|
|
151
|
-
var mergeCanonical = (current, incoming) => {
|
|
152
|
-
const existing = current.meta;
|
|
153
|
-
if (!existing) {
|
|
154
|
-
return {
|
|
155
|
-
meta: incoming.meta,
|
|
156
|
-
origin: incoming.origin,
|
|
157
|
-
conflicts: current.conflicts
|
|
158
|
-
};
|
|
159
|
-
}
|
|
160
|
-
if (equals(existing, incoming.meta)) {
|
|
161
|
-
return current;
|
|
162
|
-
}
|
|
163
|
-
const conflicts = [...current.conflicts ?? []];
|
|
164
|
-
const push = (conflict) => {
|
|
165
|
-
const exists = conflicts.some((c) => c.origin === conflict.origin && equals(c.meta, conflict.meta));
|
|
166
|
-
if (!exists) conflicts.push(conflict);
|
|
167
|
-
};
|
|
168
|
-
const existingCanonical = existing.canonical === true;
|
|
169
|
-
const incomingCanonical = incoming.meta.canonical === true;
|
|
170
|
-
if (!existingCanonical && incomingCanonical) {
|
|
171
|
-
push({
|
|
172
|
-
origin: current.origin ?? "unknown",
|
|
173
|
-
meta: existing
|
|
174
|
-
});
|
|
175
|
-
return {
|
|
176
|
-
meta: incoming.meta,
|
|
177
|
-
origin: incoming.origin,
|
|
178
|
-
conflicts
|
|
179
|
-
};
|
|
180
|
-
}
|
|
181
|
-
push({
|
|
182
|
-
origin: incoming.origin,
|
|
183
|
-
meta: incoming.meta
|
|
184
|
-
});
|
|
185
|
-
return {
|
|
186
|
-
meta: existing,
|
|
187
|
-
origin: current.origin ?? incoming.origin,
|
|
188
|
-
conflicts
|
|
189
|
-
};
|
|
190
|
-
};
|
|
191
|
-
|
|
192
|
-
// ../logix-core/src/internal/state-trait/model.ts
|
|
193
|
-
var normalizeSpec = (spec) => {
|
|
194
|
-
const entries = [];
|
|
195
|
-
const isNode = (value) => typeof value === "object" && value !== null && value._tag === "StateTraitNode";
|
|
196
|
-
const isList = (value) => typeof value === "object" && value !== null && value._tag === "StateTraitList";
|
|
197
|
-
const joinPath = (prefix, suffix) => {
|
|
198
|
-
if (!prefix) return suffix;
|
|
199
|
-
if (!suffix) return prefix;
|
|
200
|
-
return `${prefix}.${suffix}`;
|
|
201
|
-
};
|
|
202
|
-
const prefixDeps = (deps, prefix) => {
|
|
203
|
-
if (!deps || deps.length === 0) return [];
|
|
204
|
-
return deps.map((d) => prefix ? joinPath(prefix, d) : d);
|
|
205
|
-
};
|
|
206
|
-
const normalizeEntry = (entry, fieldPath, depPrefix) => {
|
|
207
|
-
if (entry.kind === "computed") {
|
|
208
|
-
const meta = entry.meta;
|
|
209
|
-
const rawDeps = meta.deps;
|
|
210
|
-
const deps = rawDeps !== void 0 ? prefixDeps(rawDeps, depPrefix) : void 0;
|
|
211
|
-
return {
|
|
212
|
-
...entry,
|
|
213
|
-
fieldPath,
|
|
214
|
-
meta: { ...meta, deps }
|
|
215
|
-
};
|
|
216
|
-
}
|
|
217
|
-
if (entry.kind === "source") {
|
|
218
|
-
const meta = entry.meta;
|
|
219
|
-
const rawDeps = meta.deps;
|
|
220
|
-
const deps = rawDeps !== void 0 ? prefixDeps(rawDeps, depPrefix) : void 0;
|
|
221
|
-
return {
|
|
222
|
-
...entry,
|
|
223
|
-
fieldPath,
|
|
224
|
-
meta: { ...meta, deps, _fieldPath: fieldPath }
|
|
225
|
-
};
|
|
226
|
-
}
|
|
227
|
-
if (entry.kind === "link") {
|
|
228
|
-
const meta = entry.meta;
|
|
229
|
-
const from = prefixDeps([meta.from], depPrefix)[0] ?? meta.from;
|
|
230
|
-
return {
|
|
231
|
-
...entry,
|
|
232
|
-
fieldPath,
|
|
233
|
-
meta: { ...meta, from }
|
|
234
|
-
};
|
|
235
|
-
}
|
|
236
|
-
return {
|
|
237
|
-
...entry,
|
|
238
|
-
fieldPath
|
|
239
|
-
};
|
|
240
|
-
};
|
|
241
|
-
const expandNode = (scopeId, joinPrefix, node, options) => {
|
|
242
|
-
const addEntry = (relativeTarget, raw) => {
|
|
243
|
-
const rel = raw.fieldPath ?? relativeTarget;
|
|
244
|
-
const fieldPath = joinPrefix ? joinPath(joinPrefix, String(rel)) : String(rel);
|
|
245
|
-
entries.push(normalizeEntry(raw, fieldPath, joinPrefix));
|
|
246
|
-
};
|
|
247
|
-
const expandMaybeRecord = (value) => {
|
|
248
|
-
if (!value) return;
|
|
249
|
-
if (typeof value.kind === "string") {
|
|
250
|
-
addEntry("", value);
|
|
251
|
-
return;
|
|
252
|
-
}
|
|
253
|
-
const record2 = value;
|
|
254
|
-
for (const key in record2) {
|
|
255
|
-
if (!Object.prototype.hasOwnProperty.call(record2, key)) continue;
|
|
256
|
-
const entry = record2[key];
|
|
257
|
-
if (!entry) continue;
|
|
258
|
-
addEntry(key, entry);
|
|
259
|
-
}
|
|
260
|
-
};
|
|
261
|
-
expandMaybeRecord(node.computed);
|
|
262
|
-
expandMaybeRecord(node.source);
|
|
263
|
-
expandMaybeRecord(node.link);
|
|
264
|
-
if (node.check) {
|
|
265
|
-
const rules = {};
|
|
266
|
-
const checkDepsPrefix = options?.checkDepsPrefix ?? (joinPrefix.endsWith("[]") ? joinPrefix : "");
|
|
267
|
-
const prefixCheckDeps = (deps) => {
|
|
268
|
-
if (!deps || deps.length === 0) return [];
|
|
269
|
-
return deps.map((d) => d === "" ? scopeId : checkDepsPrefix ? joinPath(checkDepsPrefix, d) : d);
|
|
270
|
-
};
|
|
271
|
-
for (const name of Object.keys(node.check)) {
|
|
272
|
-
const rule = node.check[name];
|
|
273
|
-
if (typeof rule === "function") {
|
|
274
|
-
rules[name] = rule;
|
|
275
|
-
continue;
|
|
276
|
-
}
|
|
277
|
-
if (rule && typeof rule === "object") {
|
|
278
|
-
const meta = sanitize(rule.meta);
|
|
279
|
-
rules[name] = {
|
|
280
|
-
...rule,
|
|
281
|
-
deps: prefixCheckDeps(rule.deps),
|
|
282
|
-
meta
|
|
283
|
-
};
|
|
284
|
-
continue;
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
entries.push({
|
|
288
|
-
fieldPath: scopeId,
|
|
289
|
-
kind: "check",
|
|
290
|
-
meta: {
|
|
291
|
-
rules,
|
|
292
|
-
writeback: { kind: "errors" }
|
|
293
|
-
}
|
|
294
|
-
});
|
|
295
|
-
}
|
|
296
|
-
};
|
|
297
|
-
for (const key in spec) {
|
|
298
|
-
if (!Object.prototype.hasOwnProperty.call(spec, key)) continue;
|
|
299
|
-
const raw = spec[key];
|
|
300
|
-
if (!raw) continue;
|
|
301
|
-
if (isList(raw)) {
|
|
302
|
-
const listPath = key;
|
|
303
|
-
if (raw.item) {
|
|
304
|
-
expandNode(`${listPath}[]`, `${listPath}[]`, raw.item);
|
|
305
|
-
}
|
|
306
|
-
if (raw.list) {
|
|
307
|
-
expandNode(listPath, listPath, raw.list, {
|
|
308
|
-
checkDepsPrefix: `${listPath}[]`
|
|
309
|
-
});
|
|
310
|
-
}
|
|
311
|
-
continue;
|
|
312
|
-
}
|
|
313
|
-
if (isNode(raw)) {
|
|
314
|
-
if (key === "$root") {
|
|
315
|
-
expandNode("$root", "", raw);
|
|
316
|
-
} else {
|
|
317
|
-
expandNode(key, key, raw);
|
|
318
|
-
}
|
|
319
|
-
continue;
|
|
320
|
-
}
|
|
321
|
-
const entry = raw;
|
|
322
|
-
const fieldPath = entry.fieldPath ?? key;
|
|
323
|
-
entries.push(normalizeEntry(entry, String(fieldPath), ""));
|
|
324
|
-
}
|
|
325
|
-
return entries;
|
|
326
|
-
};
|
|
327
|
-
var collectNodeMeta = (spec) => {
|
|
328
|
-
const out = /* @__PURE__ */ new Map();
|
|
329
|
-
const isNode = (value) => typeof value === "object" && value !== null && value._tag === "StateTraitNode";
|
|
330
|
-
const isList = (value) => typeof value === "object" && value !== null && value._tag === "StateTraitList";
|
|
331
|
-
const add = (scopeId, node) => {
|
|
332
|
-
const meta = sanitize(node.meta);
|
|
333
|
-
if (meta) out.set(scopeId, meta);
|
|
334
|
-
};
|
|
335
|
-
for (const key in spec) {
|
|
336
|
-
if (!Object.prototype.hasOwnProperty.call(spec, key)) continue;
|
|
337
|
-
const raw = spec[key];
|
|
338
|
-
if (!raw) continue;
|
|
339
|
-
if (isList(raw)) {
|
|
340
|
-
const listPath = key;
|
|
341
|
-
if (raw.item) add(`${listPath}[]`, raw.item);
|
|
342
|
-
if (raw.list) add(listPath, raw.list);
|
|
343
|
-
continue;
|
|
344
|
-
}
|
|
345
|
-
if (isNode(raw)) {
|
|
346
|
-
if (key === "$root") add("$root", raw);
|
|
347
|
-
else add(key, raw);
|
|
348
|
-
continue;
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
return out;
|
|
352
|
-
};
|
|
353
|
-
|
|
354
|
-
// ../logix-core/src/internal/state-trait/build.ts
|
|
355
|
-
var nowPerf = () => typeof globalThis.performance !== "undefined" && typeof globalThis.performance.now === "function" ? globalThis.performance.now() : Date.now();
|
|
356
|
-
var getConvergeWriterDeps = (entry) => {
|
|
357
|
-
if (entry.kind === "computed") {
|
|
358
|
-
return entry.meta?.deps ?? [];
|
|
359
|
-
}
|
|
360
|
-
return [entry.meta.from];
|
|
361
|
-
};
|
|
362
|
-
var computeConvergeTopoOrder = (writers) => {
|
|
363
|
-
const writerByPath = /* @__PURE__ */ new Map();
|
|
364
|
-
for (const entry of writers) {
|
|
365
|
-
const existing = writerByPath.get(entry.fieldPath);
|
|
366
|
-
if (existing) {
|
|
367
|
-
return {
|
|
368
|
-
order: [],
|
|
369
|
-
configError: {
|
|
370
|
-
code: "MULTIPLE_WRITERS",
|
|
371
|
-
message: `[StateTrait.converge] Multiple writers for field "${entry.fieldPath}" (${existing.kind} + ${entry.kind}).`,
|
|
372
|
-
fields: [entry.fieldPath]
|
|
373
|
-
}
|
|
374
|
-
};
|
|
375
|
-
}
|
|
376
|
-
writerByPath.set(entry.fieldPath, entry);
|
|
377
|
-
}
|
|
378
|
-
const nodes = /* @__PURE__ */ new Set();
|
|
379
|
-
for (const entry of writers) {
|
|
380
|
-
nodes.add(entry.fieldPath);
|
|
381
|
-
}
|
|
382
|
-
const indegree = /* @__PURE__ */ new Map();
|
|
383
|
-
const forward = /* @__PURE__ */ new Map();
|
|
384
|
-
for (const node of nodes) {
|
|
385
|
-
indegree.set(node, 0);
|
|
386
|
-
forward.set(node, []);
|
|
387
|
-
}
|
|
388
|
-
for (const entry of writers) {
|
|
389
|
-
const to = entry.fieldPath;
|
|
390
|
-
const deps = getConvergeWriterDeps(entry);
|
|
391
|
-
for (const dep of deps) {
|
|
392
|
-
if (!nodes.has(dep)) continue;
|
|
393
|
-
forward.get(dep).push(to);
|
|
394
|
-
indegree.set(to, (indegree.get(to) ?? 0) + 1);
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
const queue = [];
|
|
398
|
-
for (const [node, deg] of indegree.entries()) {
|
|
399
|
-
if (deg === 0) queue.push(node);
|
|
400
|
-
}
|
|
401
|
-
const order = [];
|
|
402
|
-
while (queue.length) {
|
|
403
|
-
const n = queue.shift();
|
|
404
|
-
order.push(n);
|
|
405
|
-
const outs = forward.get(n);
|
|
406
|
-
for (const to of outs) {
|
|
407
|
-
const next = (indegree.get(to) ?? 0) - 1;
|
|
408
|
-
indegree.set(to, next);
|
|
409
|
-
if (next === 0) queue.push(to);
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
if (order.length !== nodes.size) {
|
|
413
|
-
const remaining = Array.from(nodes).filter((n) => !order.includes(n));
|
|
414
|
-
return {
|
|
415
|
-
order: [],
|
|
416
|
-
configError: {
|
|
417
|
-
code: "CYCLE_DETECTED",
|
|
418
|
-
message: `[StateTrait.converge] Cycle detected in computed/link graph: ${remaining.join(", ")}`,
|
|
419
|
-
fields: remaining
|
|
420
|
-
}
|
|
421
|
-
};
|
|
422
|
-
}
|
|
423
|
-
return { order };
|
|
424
|
-
};
|
|
425
|
-
var collectSchemaFieldPaths = (schema) => {
|
|
426
|
-
const byKey = /* @__PURE__ */ new Map();
|
|
427
|
-
const add = (path) => {
|
|
428
|
-
const normalized = normalizeFieldPath(path);
|
|
429
|
-
if (!normalized) return;
|
|
430
|
-
byKey.set(JSON.stringify(normalized), normalized);
|
|
431
|
-
};
|
|
432
|
-
const visit = (ast, prefix, seen) => {
|
|
433
|
-
let current = ast;
|
|
434
|
-
while (true) {
|
|
435
|
-
if (SchemaAST.isSuspend(current)) {
|
|
436
|
-
if (seen.has(current)) return;
|
|
437
|
-
seen.add(current);
|
|
438
|
-
current = current.f();
|
|
439
|
-
continue;
|
|
440
|
-
}
|
|
441
|
-
if (SchemaAST.isRefinement(current)) {
|
|
442
|
-
current = current.from;
|
|
443
|
-
continue;
|
|
444
|
-
}
|
|
445
|
-
break;
|
|
446
|
-
}
|
|
447
|
-
if (SchemaAST.isTransformation(current)) {
|
|
448
|
-
visit(current.to, prefix, seen);
|
|
449
|
-
visit(current.from, prefix, seen);
|
|
450
|
-
return;
|
|
451
|
-
}
|
|
452
|
-
if (SchemaAST.isUnion(current)) {
|
|
453
|
-
for (const t of current.types) {
|
|
454
|
-
visit(t, prefix, seen);
|
|
455
|
-
}
|
|
456
|
-
return;
|
|
457
|
-
}
|
|
458
|
-
if (SchemaAST.isTupleType(current)) {
|
|
459
|
-
for (const e of current.elements) {
|
|
460
|
-
visit(e.type, prefix, seen);
|
|
461
|
-
}
|
|
462
|
-
for (const r of current.rest) {
|
|
463
|
-
visit(r.type, prefix, seen);
|
|
464
|
-
}
|
|
465
|
-
return;
|
|
466
|
-
}
|
|
467
|
-
if (SchemaAST.isTypeLiteral(current)) {
|
|
468
|
-
for (const ps of current.propertySignatures) {
|
|
469
|
-
const seg = String(ps.name);
|
|
470
|
-
if (!seg) continue;
|
|
471
|
-
const next = [...prefix, seg];
|
|
472
|
-
add(next);
|
|
473
|
-
visit(ps.type, next, seen);
|
|
474
|
-
}
|
|
475
|
-
return;
|
|
476
|
-
}
|
|
477
|
-
};
|
|
478
|
-
visit(schema.ast, [], /* @__PURE__ */ new Set());
|
|
479
|
-
return Array.from(byKey.values()).sort(compareFieldPath);
|
|
480
|
-
};
|
|
481
|
-
var buildConvergeIr = (stateSchema, entries) => {
|
|
482
|
-
const startedAt = nowPerf();
|
|
483
|
-
const generation = 0;
|
|
484
|
-
const writers = entries.filter((e) => e.kind === "computed" || e.kind === "link");
|
|
485
|
-
const writersKey = writers.map((entry) => `${entry.kind}:${entry.fieldPath}`).sort().join("|");
|
|
486
|
-
const depsKey = writers.map((entry) => {
|
|
487
|
-
const deps = getConvergeWriterDeps(entry).slice().sort().join(",");
|
|
488
|
-
const scheduling = entry.meta?.scheduling === "deferred" ? "d" : "i";
|
|
489
|
-
return `${entry.kind}:${entry.fieldPath}@${scheduling}=>${deps}`;
|
|
490
|
-
}).sort().join("|");
|
|
491
|
-
const writerByPath = /* @__PURE__ */ new Map();
|
|
492
|
-
for (const entry of writers) {
|
|
493
|
-
writerByPath.set(entry.fieldPath, entry);
|
|
494
|
-
}
|
|
495
|
-
const topo = writers.length > 0 ? computeConvergeTopoOrder(writers) : { order: [] };
|
|
496
|
-
const stepsById = topo.configError ? [] : topo.order.map((path) => writerByPath.get(path));
|
|
497
|
-
const fieldPathTable = /* @__PURE__ */ new Map();
|
|
498
|
-
const addPath = (path) => {
|
|
499
|
-
for (let i = 1; i <= path.length; i++) {
|
|
500
|
-
const prefix = path.slice(0, i);
|
|
501
|
-
const key = JSON.stringify(prefix);
|
|
502
|
-
if (!fieldPathTable.has(key)) fieldPathTable.set(key, prefix);
|
|
503
|
-
}
|
|
504
|
-
};
|
|
505
|
-
for (const schemaPath of collectSchemaFieldPaths(stateSchema)) {
|
|
506
|
-
addPath(schemaPath);
|
|
507
|
-
}
|
|
508
|
-
for (const entry of writers) {
|
|
509
|
-
const out = normalizeFieldPath(entry.fieldPath);
|
|
510
|
-
if (out) addPath(out);
|
|
511
|
-
for (const dep of getConvergeWriterDeps(entry)) {
|
|
512
|
-
const depPath = normalizeFieldPath(dep);
|
|
513
|
-
if (depPath) addPath(depPath);
|
|
514
|
-
}
|
|
515
|
-
}
|
|
516
|
-
const fieldPaths = Array.from(fieldPathTable.values()).sort(compareFieldPath);
|
|
517
|
-
const fieldPathIdRegistry = makeFieldPathIdRegistry(fieldPaths);
|
|
518
|
-
const fieldPathsKey = fnv1a32(stableStringify(fieldPaths));
|
|
519
|
-
const stepOutFieldPathIdByStepId = [];
|
|
520
|
-
const stepDepsFieldPathIdsByStepId = [];
|
|
521
|
-
const stepSchedulingByStepId = [];
|
|
522
|
-
for (const entry of stepsById) {
|
|
523
|
-
const out = normalizeFieldPath(entry.fieldPath);
|
|
524
|
-
const outId = out != null ? getFieldPathId(fieldPathIdRegistry, out) : void 0;
|
|
525
|
-
if (outId == null) {
|
|
526
|
-
throw new Error(`[StateTrait.build] Failed to map converge output fieldPath "${entry.fieldPath}" to FieldPathId.`);
|
|
527
|
-
}
|
|
528
|
-
const depIds = [];
|
|
529
|
-
for (const dep of getConvergeWriterDeps(entry)) {
|
|
530
|
-
const depPath = normalizeFieldPath(dep);
|
|
531
|
-
if (!depPath) continue;
|
|
532
|
-
const depId = getFieldPathId(fieldPathIdRegistry, depPath);
|
|
533
|
-
if (depId != null) depIds.push(depId);
|
|
534
|
-
}
|
|
535
|
-
stepOutFieldPathIdByStepId.push(outId);
|
|
536
|
-
stepDepsFieldPathIdsByStepId.push(depIds);
|
|
537
|
-
stepSchedulingByStepId.push(entry.meta?.scheduling === "deferred" ? "deferred" : "immediate");
|
|
538
|
-
}
|
|
539
|
-
const topoOrder = stepsById.map((_, i) => i);
|
|
540
|
-
const buildDurationMs = Math.max(0, nowPerf() - startedAt);
|
|
541
|
-
return {
|
|
542
|
-
generation,
|
|
543
|
-
writersKey,
|
|
544
|
-
depsKey,
|
|
545
|
-
fieldPathsKey,
|
|
546
|
-
fieldPaths,
|
|
547
|
-
fieldPathIdRegistry,
|
|
548
|
-
...topo.configError ? { configError: topo.configError } : null,
|
|
549
|
-
stepsById,
|
|
550
|
-
stepOutFieldPathIdByStepId,
|
|
551
|
-
stepDepsFieldPathIdsByStepId,
|
|
552
|
-
stepSchedulingByStepId,
|
|
553
|
-
topoOrder,
|
|
554
|
-
buildDurationMs
|
|
555
|
-
};
|
|
556
|
-
};
|
|
557
|
-
var toFieldTrait = (entry) => {
|
|
558
|
-
const deps = [];
|
|
559
|
-
if (entry.kind === "computed") {
|
|
560
|
-
const meta = entry.meta;
|
|
561
|
-
const list = meta.deps;
|
|
562
|
-
if (list) deps.push(...list);
|
|
563
|
-
} else if (entry.kind === "source") {
|
|
564
|
-
const meta = entry.meta;
|
|
565
|
-
const list = meta.deps;
|
|
566
|
-
if (list) deps.push(...list);
|
|
567
|
-
} else if (entry.kind === "link") {
|
|
568
|
-
deps.push(entry.meta.from);
|
|
569
|
-
} else if (entry.kind === "check") {
|
|
570
|
-
const meta = entry.meta;
|
|
571
|
-
const rules = meta?.rules ?? {};
|
|
572
|
-
for (const name of Object.keys(rules)) {
|
|
573
|
-
const rule = rules[name];
|
|
574
|
-
if (rule && typeof rule === "object") {
|
|
575
|
-
const list = rule.deps;
|
|
576
|
-
if (list) deps.push(...list);
|
|
577
|
-
}
|
|
578
|
-
}
|
|
579
|
-
}
|
|
580
|
-
return {
|
|
581
|
-
fieldId: entry.fieldPath,
|
|
582
|
-
kind: entry.kind,
|
|
583
|
-
// Keep meta identical to Entry.meta at runtime so install can reuse it directly.
|
|
584
|
-
meta: entry.meta,
|
|
585
|
-
deps
|
|
586
|
-
};
|
|
587
|
-
};
|
|
588
|
-
var buildGraph = (entries, nodeMetaByFieldPath) => {
|
|
589
|
-
const fieldMap = /* @__PURE__ */ new Map();
|
|
590
|
-
const nodes = [];
|
|
591
|
-
const edges = [];
|
|
592
|
-
const resourcesById = /* @__PURE__ */ new Map();
|
|
593
|
-
const planSteps = [];
|
|
594
|
-
const ensureField = (fieldPath) => {
|
|
595
|
-
let field = fieldMap.get(fieldPath);
|
|
596
|
-
if (!field) {
|
|
597
|
-
field = {
|
|
598
|
-
id: fieldPath,
|
|
599
|
-
path: fieldPath,
|
|
600
|
-
traits: []
|
|
601
|
-
};
|
|
602
|
-
fieldMap.set(fieldPath, field);
|
|
603
|
-
}
|
|
604
|
-
return field;
|
|
605
|
-
};
|
|
606
|
-
for (const entry of entries) {
|
|
607
|
-
const fieldPath = entry.fieldPath;
|
|
608
|
-
const field = ensureField(fieldPath);
|
|
609
|
-
const trait = toFieldTrait(entry);
|
|
610
|
-
field.traits.push(trait);
|
|
611
|
-
if (entry.kind === "computed") {
|
|
612
|
-
const stepId = `computed:${fieldPath}`;
|
|
613
|
-
planSteps.push({
|
|
614
|
-
id: stepId,
|
|
615
|
-
kind: "computed-update",
|
|
616
|
-
targetFieldPath: fieldPath
|
|
617
|
-
// Note: the current version does not statically analyze computed dependencies; sourceFieldPaths remains empty.
|
|
618
|
-
});
|
|
619
|
-
const deps = entry.meta.deps;
|
|
620
|
-
if (deps) {
|
|
621
|
-
for (const dep of deps) {
|
|
622
|
-
ensureField(dep);
|
|
623
|
-
edges.push({
|
|
624
|
-
id: `computed:${dep}->${fieldPath}`,
|
|
625
|
-
from: dep,
|
|
626
|
-
to: fieldPath,
|
|
627
|
-
kind: "computed"
|
|
628
|
-
});
|
|
629
|
-
}
|
|
630
|
-
}
|
|
631
|
-
} else if (entry.kind === "link") {
|
|
632
|
-
const from = entry.meta.from;
|
|
633
|
-
ensureField(from);
|
|
634
|
-
const edgeId = `link:${from}->${fieldPath}`;
|
|
635
|
-
edges.push({
|
|
636
|
-
id: edgeId,
|
|
637
|
-
from,
|
|
638
|
-
to: fieldPath,
|
|
639
|
-
kind: "link"
|
|
640
|
-
});
|
|
641
|
-
planSteps.push({
|
|
642
|
-
id: `link:${fieldPath}`,
|
|
643
|
-
kind: "link-propagate",
|
|
644
|
-
targetFieldPath: fieldPath,
|
|
645
|
-
sourceFieldPaths: [from],
|
|
646
|
-
debugInfo: {
|
|
647
|
-
graphEdgeId: edgeId
|
|
648
|
-
}
|
|
649
|
-
});
|
|
650
|
-
} else if (entry.kind === "source") {
|
|
651
|
-
const resourceId = entry.meta.resource;
|
|
652
|
-
const resourceMeta = sanitize(entry.meta.meta);
|
|
653
|
-
const existing = resourcesById.get(resourceId);
|
|
654
|
-
if (existing) {
|
|
655
|
-
const ownerFields = [...existing.ownerFields, fieldPath];
|
|
656
|
-
let meta = existing.meta;
|
|
657
|
-
let metaOrigin = existing.metaOrigin;
|
|
658
|
-
let metaConflicts = existing.metaConflicts;
|
|
659
|
-
if (resourceMeta) {
|
|
660
|
-
const merged = mergeCanonical(
|
|
661
|
-
{ meta, origin: metaOrigin, conflicts: metaConflicts },
|
|
662
|
-
{ origin: fieldPath, meta: resourceMeta }
|
|
663
|
-
);
|
|
664
|
-
meta = merged.meta;
|
|
665
|
-
metaOrigin = merged.origin;
|
|
666
|
-
metaConflicts = merged.conflicts;
|
|
667
|
-
}
|
|
668
|
-
resourcesById.set(resourceId, {
|
|
669
|
-
...existing,
|
|
670
|
-
ownerFields,
|
|
671
|
-
meta,
|
|
672
|
-
metaOrigin,
|
|
673
|
-
metaConflicts
|
|
674
|
-
});
|
|
675
|
-
} else {
|
|
676
|
-
resourcesById.set(resourceId, {
|
|
677
|
-
resourceId,
|
|
678
|
-
// Use a simple identifier string for now; may evolve into a structured form based on key rules.
|
|
679
|
-
keySelector: `StateTrait.source@${fieldPath}`,
|
|
680
|
-
ownerFields: [fieldPath],
|
|
681
|
-
meta: resourceMeta,
|
|
682
|
-
metaOrigin: resourceMeta ? fieldPath : void 0
|
|
683
|
-
});
|
|
684
|
-
}
|
|
685
|
-
planSteps.push({
|
|
686
|
-
id: `source:${fieldPath}`,
|
|
687
|
-
kind: "source-refresh",
|
|
688
|
-
targetFieldPath: fieldPath,
|
|
689
|
-
resourceId,
|
|
690
|
-
keySelectorId: `StateTrait.source@${fieldPath}`
|
|
691
|
-
});
|
|
692
|
-
const deps = entry.meta.deps;
|
|
693
|
-
if (deps) {
|
|
694
|
-
for (const dep of deps) {
|
|
695
|
-
ensureField(dep);
|
|
696
|
-
edges.push({
|
|
697
|
-
id: `source-dep:${dep}->${fieldPath}`,
|
|
698
|
-
from: dep,
|
|
699
|
-
to: fieldPath,
|
|
700
|
-
kind: "source-dep"
|
|
701
|
-
});
|
|
702
|
-
}
|
|
703
|
-
}
|
|
704
|
-
} else if (entry.kind === "check") {
|
|
705
|
-
planSteps.push({
|
|
706
|
-
id: `check:${fieldPath}`,
|
|
707
|
-
kind: "check-validate",
|
|
708
|
-
targetFieldPath: fieldPath
|
|
709
|
-
});
|
|
710
|
-
if (trait.deps.length > 0) {
|
|
711
|
-
for (const dep of trait.deps) {
|
|
712
|
-
ensureField(dep);
|
|
713
|
-
edges.push({
|
|
714
|
-
id: `check-dep:${dep}->${fieldPath}`,
|
|
715
|
-
from: dep,
|
|
716
|
-
to: fieldPath,
|
|
717
|
-
kind: "check-dep"
|
|
718
|
-
});
|
|
719
|
-
}
|
|
720
|
-
}
|
|
721
|
-
}
|
|
722
|
-
}
|
|
723
|
-
for (const field of fieldMap.values()) {
|
|
724
|
-
nodes.push({
|
|
725
|
-
id: field.id,
|
|
726
|
-
field,
|
|
727
|
-
traits: field.traits,
|
|
728
|
-
meta: nodeMetaByFieldPath.get(field.id)
|
|
729
|
-
});
|
|
730
|
-
}
|
|
731
|
-
const graph = {
|
|
732
|
-
_tag: "StateTraitGraph",
|
|
733
|
-
nodes,
|
|
734
|
-
edges,
|
|
735
|
-
resources: Array.from(resourcesById.values())
|
|
736
|
-
};
|
|
737
|
-
const plan = {
|
|
738
|
-
_tag: "StateTraitPlan",
|
|
739
|
-
steps: planSteps
|
|
740
|
-
};
|
|
741
|
-
return { graph, plan };
|
|
742
|
-
};
|
|
743
|
-
var assertNoLinkCycles = (edges) => {
|
|
744
|
-
const adjacency = /* @__PURE__ */ new Map();
|
|
745
|
-
for (const edge of edges) {
|
|
746
|
-
if (edge.kind !== "link") continue;
|
|
747
|
-
const list = adjacency.get(edge.from) ?? [];
|
|
748
|
-
list.push(edge.to);
|
|
749
|
-
adjacency.set(edge.from, list);
|
|
750
|
-
}
|
|
751
|
-
const visited = /* @__PURE__ */ new Set();
|
|
752
|
-
const stack = /* @__PURE__ */ new Set();
|
|
753
|
-
const dfs = (node) => {
|
|
754
|
-
if (stack.has(node)) {
|
|
755
|
-
throw new Error(
|
|
756
|
-
`[StateTrait.build] link cycle detected at field "${node}". Please check link traits for circular dependencies.`
|
|
757
|
-
);
|
|
758
|
-
}
|
|
759
|
-
if (visited.has(node)) return;
|
|
760
|
-
visited.add(node);
|
|
761
|
-
stack.add(node);
|
|
762
|
-
const nexts = adjacency.get(node);
|
|
763
|
-
if (nexts) {
|
|
764
|
-
for (const to of nexts) {
|
|
765
|
-
dfs(to);
|
|
766
|
-
}
|
|
767
|
-
}
|
|
768
|
-
stack.delete(node);
|
|
769
|
-
};
|
|
770
|
-
for (const node of adjacency.keys()) {
|
|
771
|
-
if (!visited.has(node)) {
|
|
772
|
-
dfs(node);
|
|
773
|
-
}
|
|
774
|
-
}
|
|
775
|
-
};
|
|
776
|
-
var collectSchemaPaths = (entries) => {
|
|
777
|
-
const byKey = /* @__PURE__ */ new Map();
|
|
778
|
-
const add = (ref) => {
|
|
779
|
-
if (!ref.path) return;
|
|
780
|
-
const k = `${ref.kind}|${ref.entryKind}|${ref.entryFieldPath}|${ref.ruleName ?? ""}|${ref.path}`;
|
|
781
|
-
byKey.set(k, ref);
|
|
782
|
-
};
|
|
783
|
-
const getCheckWritebackPath = (entry) => {
|
|
784
|
-
const wb = entry.meta?.writeback;
|
|
785
|
-
const p = wb && typeof wb === "object" ? wb.path : void 0;
|
|
786
|
-
const writebackPath = typeof p === "string" && p.startsWith("errors.") ? p : void 0;
|
|
787
|
-
if (writebackPath) return writebackPath;
|
|
788
|
-
const fieldPath = entry.fieldPath;
|
|
789
|
-
if (fieldPath.endsWith("[]")) {
|
|
790
|
-
return `errors.${fieldPath.slice(0, -2)}`;
|
|
791
|
-
}
|
|
792
|
-
return `errors.${fieldPath}`;
|
|
793
|
-
};
|
|
794
|
-
for (const entry of entries) {
|
|
795
|
-
add({
|
|
796
|
-
kind: "fieldPath",
|
|
797
|
-
entryKind: entry.kind,
|
|
798
|
-
entryFieldPath: entry.fieldPath,
|
|
799
|
-
path: entry.fieldPath
|
|
800
|
-
});
|
|
801
|
-
if (entry.kind === "computed" || entry.kind === "source") {
|
|
802
|
-
const deps = entry.meta?.deps ?? [];
|
|
803
|
-
for (const dep of deps) {
|
|
804
|
-
add({
|
|
805
|
-
kind: "dep",
|
|
806
|
-
entryKind: entry.kind,
|
|
807
|
-
entryFieldPath: entry.fieldPath,
|
|
808
|
-
path: dep
|
|
809
|
-
});
|
|
810
|
-
}
|
|
811
|
-
}
|
|
812
|
-
if (entry.kind === "link") {
|
|
813
|
-
add({
|
|
814
|
-
kind: "link_from",
|
|
815
|
-
entryKind: "link",
|
|
816
|
-
entryFieldPath: entry.fieldPath,
|
|
817
|
-
path: entry.meta.from
|
|
818
|
-
});
|
|
819
|
-
}
|
|
820
|
-
if (entry.kind === "check") {
|
|
821
|
-
add({
|
|
822
|
-
kind: "check_writeback",
|
|
823
|
-
entryKind: "check",
|
|
824
|
-
entryFieldPath: entry.fieldPath,
|
|
825
|
-
path: getCheckWritebackPath(entry)
|
|
826
|
-
});
|
|
827
|
-
const rules = entry.meta?.rules ?? {};
|
|
828
|
-
for (const name of Object.keys(rules)) {
|
|
829
|
-
const rule = rules[name];
|
|
830
|
-
if (!rule || typeof rule !== "object") continue;
|
|
831
|
-
const deps = rule.deps ?? [];
|
|
832
|
-
for (const dep of deps) {
|
|
833
|
-
add({
|
|
834
|
-
kind: "dep",
|
|
835
|
-
entryKind: "check",
|
|
836
|
-
entryFieldPath: entry.fieldPath,
|
|
837
|
-
ruleName: name,
|
|
838
|
-
path: dep
|
|
839
|
-
});
|
|
840
|
-
}
|
|
841
|
-
}
|
|
842
|
-
}
|
|
843
|
-
}
|
|
844
|
-
return Array.from(byKey.entries()).sort((a, b) => a[0].localeCompare(b[0])).map(([, v]) => v);
|
|
845
|
-
};
|
|
846
|
-
var build = (stateSchema, spec) => {
|
|
847
|
-
const entries = normalizeSpec(spec);
|
|
848
|
-
const nodeMetaByFieldPath = collectNodeMeta(spec);
|
|
849
|
-
for (const entry of entries) {
|
|
850
|
-
if (entry.kind === "computed") {
|
|
851
|
-
const deps = entry.meta.deps;
|
|
852
|
-
if (deps === void 0) {
|
|
853
|
-
throw new Error(
|
|
854
|
-
`[StateTrait.build] Missing explicit deps for computed "${entry.fieldPath}". Please use StateTrait.computed({ deps: [...], get: ... }).`
|
|
855
|
-
);
|
|
856
|
-
}
|
|
857
|
-
}
|
|
858
|
-
if (entry.kind === "source") {
|
|
859
|
-
const deps = entry.meta.deps;
|
|
860
|
-
if (deps === void 0) {
|
|
861
|
-
throw new Error(
|
|
862
|
-
`[StateTrait.build] Missing explicit deps for source "${entry.fieldPath}". Please provide meta.deps for StateTrait.source({ deps: [...], ... }).`
|
|
863
|
-
);
|
|
864
|
-
}
|
|
865
|
-
}
|
|
866
|
-
if (entry.kind === "check") {
|
|
867
|
-
const rules = entry.meta?.rules ?? {};
|
|
868
|
-
for (const name of Object.keys(rules)) {
|
|
869
|
-
const rule = rules[name];
|
|
870
|
-
if (typeof rule === "function" || !rule || typeof rule !== "object") {
|
|
871
|
-
throw new Error(
|
|
872
|
-
`[StateTrait.build] Missing explicit deps for check "${entry.fieldPath}" rule "${name}". Please use { deps: [...], validate: ... } form.`
|
|
873
|
-
);
|
|
874
|
-
}
|
|
875
|
-
if (rule.deps === void 0) {
|
|
876
|
-
throw new Error(
|
|
877
|
-
`[StateTrait.build] Missing explicit deps for check "${entry.fieldPath}" rule "${name}". Please provide deps: [...].`
|
|
878
|
-
);
|
|
879
|
-
}
|
|
880
|
-
}
|
|
881
|
-
}
|
|
882
|
-
}
|
|
883
|
-
const { graph, plan } = buildGraph(entries, nodeMetaByFieldPath);
|
|
884
|
-
assertNoLinkCycles(graph.edges);
|
|
885
|
-
return {
|
|
886
|
-
stateSchema,
|
|
887
|
-
spec,
|
|
888
|
-
entries,
|
|
889
|
-
graph,
|
|
890
|
-
plan,
|
|
891
|
-
convergeIr: buildConvergeIr(stateSchema, entries),
|
|
892
|
-
schemaPaths: collectSchemaPaths(entries)
|
|
893
|
-
};
|
|
894
|
-
};
|
|
895
|
-
|
|
896
|
-
// ../logix-core/src/internal/state-trait/source.ts
|
|
897
|
-
import { Effect, Fiber, FiberRef, Option } from "../effect.js";
|
|
898
|
-
|
|
899
|
-
// ../logix-core/src/internal/state-trait/deps-trace.ts
|
|
900
|
-
var isTraceableObject = (value) => {
|
|
901
|
-
if (!value || typeof value !== "object") return false;
|
|
902
|
-
if (Array.isArray(value)) return true;
|
|
903
|
-
if (value instanceof Date) return false;
|
|
904
|
-
if (value instanceof RegExp) return false;
|
|
905
|
-
if (value instanceof Error) return false;
|
|
906
|
-
if (value instanceof Map) return false;
|
|
907
|
-
if (value instanceof Set) return false;
|
|
908
|
-
if (value instanceof WeakMap) return false;
|
|
909
|
-
if (value instanceof WeakSet) return false;
|
|
910
|
-
return true;
|
|
911
|
-
};
|
|
912
|
-
var shouldIgnoreKey = (key) => key === "__proto__" || key === "prototype" || key === "constructor";
|
|
913
|
-
var normalizeReads = (reads) => {
|
|
914
|
-
const all = Array.from(reads).filter((p) => typeof p === "string" && p.length > 0);
|
|
915
|
-
all.sort();
|
|
916
|
-
const isPrefix = (prefix, full) => full !== prefix && full.startsWith(prefix + ".");
|
|
917
|
-
const pruned = [];
|
|
918
|
-
for (const p of all) {
|
|
919
|
-
let hasMoreSpecific = false;
|
|
920
|
-
for (const other of all) {
|
|
921
|
-
if (isPrefix(p, other)) {
|
|
922
|
-
hasMoreSpecific = true;
|
|
923
|
-
break;
|
|
924
|
-
}
|
|
925
|
-
}
|
|
926
|
-
if (!hasMoreSpecific) {
|
|
927
|
-
pruned.push(p);
|
|
928
|
-
}
|
|
929
|
-
}
|
|
930
|
-
pruned.sort();
|
|
931
|
-
return pruned;
|
|
932
|
-
};
|
|
933
|
-
var covers = (declared, read) => declared === read || read.startsWith(declared + ".");
|
|
934
|
-
var diffDeps = (declared, reads) => {
|
|
935
|
-
const declaredList = Array.from(new Set(declared)).filter((p) => typeof p === "string" && p.length > 0);
|
|
936
|
-
declaredList.sort();
|
|
937
|
-
const readList = Array.from(new Set(reads)).filter((p) => typeof p === "string" && p.length > 0);
|
|
938
|
-
readList.sort();
|
|
939
|
-
const missing = readList.filter((r) => declaredList.every((d) => !covers(d, r)));
|
|
940
|
-
const unused = declaredList.filter((d) => readList.every((r) => !covers(d, r)));
|
|
941
|
-
if (missing.length === 0 && unused.length === 0) return void 0;
|
|
942
|
-
return {
|
|
943
|
-
reads: readList,
|
|
944
|
-
declared: declaredList,
|
|
945
|
-
missing,
|
|
946
|
-
unused
|
|
947
|
-
};
|
|
948
|
-
};
|
|
949
|
-
var trace = (fn, state) => {
|
|
950
|
-
if (!isTraceableObject(state)) {
|
|
951
|
-
return { value: fn(state), reads: [] };
|
|
952
|
-
}
|
|
953
|
-
const reads = /* @__PURE__ */ new Set();
|
|
954
|
-
const proxyCache = /* @__PURE__ */ new WeakMap();
|
|
955
|
-
const proxyToTarget = /* @__PURE__ */ new WeakMap();
|
|
956
|
-
const wrap = (value2, path) => {
|
|
957
|
-
if (!isTraceableObject(value2)) return value2;
|
|
958
|
-
return getProxy(value2, path);
|
|
959
|
-
};
|
|
960
|
-
const unwrap = (value2) => {
|
|
961
|
-
if (value2 && (typeof value2 === "object" || typeof value2 === "function")) {
|
|
962
|
-
const target = proxyToTarget.get(value2);
|
|
963
|
-
if (target) return target;
|
|
964
|
-
}
|
|
965
|
-
return value2;
|
|
966
|
-
};
|
|
967
|
-
const getProxy = (target, basePath) => {
|
|
968
|
-
let byPath = proxyCache.get(target);
|
|
969
|
-
if (!byPath) {
|
|
970
|
-
byPath = /* @__PURE__ */ new Map();
|
|
971
|
-
proxyCache.set(target, byPath);
|
|
972
|
-
}
|
|
973
|
-
const cached = byPath.get(basePath);
|
|
974
|
-
if (cached) return cached;
|
|
975
|
-
const record2 = (path) => {
|
|
976
|
-
if (path) reads.add(path);
|
|
977
|
-
};
|
|
978
|
-
const proxy = new Proxy(target, {
|
|
979
|
-
get: (t, prop, receiver) => {
|
|
980
|
-
if (typeof prop === "symbol") {
|
|
981
|
-
return Reflect.get(t, prop, receiver);
|
|
982
|
-
}
|
|
983
|
-
const key = String(prop);
|
|
984
|
-
if (shouldIgnoreKey(key)) {
|
|
985
|
-
return Reflect.get(t, prop, receiver);
|
|
986
|
-
}
|
|
987
|
-
const nextPath = basePath ? `${basePath}.${key}` : key;
|
|
988
|
-
record2(nextPath);
|
|
989
|
-
const value2 = Reflect.get(t, prop, receiver);
|
|
990
|
-
return wrap(value2, nextPath);
|
|
991
|
-
},
|
|
992
|
-
has: (t, prop) => {
|
|
993
|
-
if (typeof prop === "symbol") return Reflect.has(t, prop);
|
|
994
|
-
const key = String(prop);
|
|
995
|
-
if (!shouldIgnoreKey(key)) {
|
|
996
|
-
const nextPath = basePath ? `${basePath}.${key}` : key;
|
|
997
|
-
record2(nextPath);
|
|
998
|
-
}
|
|
999
|
-
return Reflect.has(t, prop);
|
|
1000
|
-
},
|
|
1001
|
-
ownKeys: (t) => {
|
|
1002
|
-
if (basePath) record2(basePath);
|
|
1003
|
-
return Reflect.ownKeys(t);
|
|
1004
|
-
},
|
|
1005
|
-
getOwnPropertyDescriptor: (t, prop) => {
|
|
1006
|
-
if (typeof prop === "symbol") {
|
|
1007
|
-
return Reflect.getOwnPropertyDescriptor(t, prop);
|
|
1008
|
-
}
|
|
1009
|
-
const key = String(prop);
|
|
1010
|
-
if (!shouldIgnoreKey(key)) {
|
|
1011
|
-
const nextPath = basePath ? `${basePath}.${key}` : key;
|
|
1012
|
-
record2(nextPath);
|
|
1013
|
-
}
|
|
1014
|
-
return Reflect.getOwnPropertyDescriptor(t, prop);
|
|
1015
|
-
},
|
|
1016
|
-
set: () => {
|
|
1017
|
-
throw new Error(
|
|
1018
|
-
"[deps-trace] Attempted to mutate state during deps tracing (state is readonly in dev-mode diagnostics)."
|
|
1019
|
-
);
|
|
1020
|
-
},
|
|
1021
|
-
defineProperty: () => {
|
|
1022
|
-
throw new Error(
|
|
1023
|
-
"[deps-trace] Attempted to define property on state during deps tracing (state is readonly in dev-mode diagnostics)."
|
|
1024
|
-
);
|
|
1025
|
-
},
|
|
1026
|
-
deleteProperty: () => {
|
|
1027
|
-
throw new Error(
|
|
1028
|
-
"[deps-trace] Attempted to delete property on state during deps tracing (state is readonly in dev-mode diagnostics)."
|
|
1029
|
-
);
|
|
1030
|
-
}
|
|
1031
|
-
});
|
|
1032
|
-
byPath.set(basePath, proxy);
|
|
1033
|
-
proxyToTarget.set(proxy, target);
|
|
1034
|
-
return proxy;
|
|
1035
|
-
};
|
|
1036
|
-
const root = getProxy(state, "");
|
|
1037
|
-
const value = unwrap(fn(root));
|
|
1038
|
-
return {
|
|
1039
|
-
value,
|
|
1040
|
-
reads: normalizeReads(reads)
|
|
1041
|
-
};
|
|
1042
|
-
};
|
|
1043
|
-
|
|
1044
|
-
// ../logix-core/src/internal/state-trait/source.ts
|
|
1045
|
-
var onceInRunSession = (key) => Effect.serviceOption(RunSessionTag).pipe(
|
|
1046
|
-
Effect.map((maybe) => Option.isSome(maybe) ? maybe.value.local.once(key) : true)
|
|
1047
|
-
);
|
|
1048
|
-
var formatList = (items, limit = 10) => {
|
|
1049
|
-
if (items.length === 0) return "";
|
|
1050
|
-
if (items.length <= limit) return items.join(", ");
|
|
1051
|
-
return `${items.slice(0, limit).join(", ")}, \u2026(+${items.length - limit})`;
|
|
1052
|
-
};
|
|
1053
|
-
var emitDepsMismatch = (params) => Effect.gen(function* () {
|
|
1054
|
-
const key = `${params.instanceId ?? "unknown"}::${params.kind}::${params.fieldPath}`;
|
|
1055
|
-
const shouldEmit = yield* onceInRunSession(`deps_mismatch:${key}`);
|
|
1056
|
-
if (!shouldEmit) return;
|
|
1057
|
-
yield* record({
|
|
1058
|
-
type: "diagnostic",
|
|
1059
|
-
moduleId: params.moduleId,
|
|
1060
|
-
instanceId: params.instanceId,
|
|
1061
|
-
code: "state_trait::deps_mismatch",
|
|
1062
|
-
severity: "warning",
|
|
1063
|
-
message: `[deps] ${params.kind} "${params.fieldPath}" declared=[${formatList(params.diff.declared)}] reads=[${formatList(params.diff.reads)}] missing=[${formatList(params.diff.missing)}] unused=[${formatList(params.diff.unused)}]`,
|
|
1064
|
-
hint: 'deps is the single source of truth for dependencies: incremental scheduling / reverse closures / performance optimizations rely on deps only. Keep deps consistent with actual reads; if you really depend on the whole object, declare a coarser-grained dep (e.g. "profile") to cover sub-field reads.',
|
|
1065
|
-
kind: `deps_mismatch:${params.kind}`
|
|
1066
|
-
});
|
|
1067
|
-
});
|
|
1068
|
-
var getMiddlewareStack = () => Effect.serviceOption(EffectOpMiddlewareTag).pipe(
|
|
1069
|
-
Effect.map((maybe) => Option.isSome(maybe) ? maybe.value.stack : [])
|
|
1070
|
-
);
|
|
1071
|
-
var recordTraitPatch = (bound, path, reason, from, to, traitNodeId) => {
|
|
1072
|
-
const normalized = normalizeFieldPath(path) ?? [];
|
|
1073
|
-
try {
|
|
1074
|
-
const internals = getBoundInternals(bound);
|
|
1075
|
-
internals.txn.recordStatePatch(normalized, reason, from, to, traitNodeId);
|
|
1076
|
-
} catch {
|
|
1077
|
-
}
|
|
1078
|
-
};
|
|
1079
|
-
var recordReplayEvent = (bound, event) => {
|
|
1080
|
-
try {
|
|
1081
|
-
const internals = getBoundInternals(bound);
|
|
1082
|
-
internals.txn.recordReplayEvent(event);
|
|
1083
|
-
} catch {
|
|
1084
|
-
}
|
|
1085
|
-
};
|
|
1086
|
-
var getBoundScope = (bound) => {
|
|
1087
|
-
try {
|
|
1088
|
-
const internals = getBoundInternals(bound);
|
|
1089
|
-
return { moduleId: internals.moduleId, instanceId: internals.instanceId };
|
|
1090
|
-
} catch {
|
|
1091
|
-
return { moduleId: void 0, instanceId: void 0 };
|
|
1092
|
-
}
|
|
1093
|
-
};
|
|
1094
|
-
var setSnapshotInTxn = (bound, fieldPath, next, reason, stepId, traitNodeId) => Effect.gen(function* () {
|
|
1095
|
-
let wrote = false;
|
|
1096
|
-
yield* bound.state.mutate((draft) => {
|
|
1097
|
-
const prev = getAtPath(draft, fieldPath);
|
|
1098
|
-
if (Object.is(prev, next)) return;
|
|
1099
|
-
wrote = true;
|
|
1100
|
-
setAtPathMutating(draft, fieldPath, next);
|
|
1101
|
-
recordTraitPatch(bound, fieldPath, reason, prev, next, traitNodeId);
|
|
1102
|
-
});
|
|
1103
|
-
return wrote;
|
|
1104
|
-
});
|
|
1105
|
-
var writebackIfCurrentKeyHash = (bound, fieldPath, keyHash2, next, reason, stepId, traitNodeId, replayEvent) => Effect.gen(function* () {
|
|
1106
|
-
let wrote = false;
|
|
1107
|
-
yield* bound.state.mutate((draft) => {
|
|
1108
|
-
const current = getAtPath(draft, fieldPath);
|
|
1109
|
-
const currentKeyHash = current && typeof current === "object" ? current.keyHash : void 0;
|
|
1110
|
-
if (currentKeyHash !== keyHash2) return;
|
|
1111
|
-
const prev = current;
|
|
1112
|
-
if (Object.is(prev, next)) return;
|
|
1113
|
-
wrote = true;
|
|
1114
|
-
setAtPathMutating(draft, fieldPath, next);
|
|
1115
|
-
if (replayEvent) {
|
|
1116
|
-
recordReplayEvent(bound, replayEvent);
|
|
1117
|
-
}
|
|
1118
|
-
recordTraitPatch(bound, fieldPath, reason, prev, next, traitNodeId);
|
|
1119
|
-
});
|
|
1120
|
-
return wrote;
|
|
1121
|
-
});
|
|
1122
|
-
var syncIdleInTransaction = (program, ctx) => Effect.sync(() => {
|
|
1123
|
-
const draft = ctx.getDraft();
|
|
1124
|
-
const updates = [];
|
|
1125
|
-
for (const entry of program.entries) {
|
|
1126
|
-
if (entry.kind !== "source") continue;
|
|
1127
|
-
const fieldPath = entry.fieldPath;
|
|
1128
|
-
const listItem = parseListItemFieldPath(fieldPath);
|
|
1129
|
-
if (listItem) {
|
|
1130
|
-
const listValue = getAtPath(draft, listItem.listPath);
|
|
1131
|
-
const items = Array.isArray(listValue) ? listValue : [];
|
|
1132
|
-
for (let index = 0; index < items.length; index++) {
|
|
1133
|
-
const item = items[index];
|
|
1134
|
-
let key2;
|
|
1135
|
-
try {
|
|
1136
|
-
key2 = entry.meta.key(item);
|
|
1137
|
-
} catch {
|
|
1138
|
-
continue;
|
|
1139
|
-
}
|
|
1140
|
-
if (key2 !== void 0) continue;
|
|
1141
|
-
const concretePath = toListItemValuePath(listItem.listPath, index, listItem.itemPath);
|
|
1142
|
-
const prev2 = getAtPath(draft, concretePath);
|
|
1143
|
-
const prevStatus2 = prev2 && typeof prev2 === "object" ? prev2.status : void 0;
|
|
1144
|
-
if (prevStatus2 === "idle") {
|
|
1145
|
-
const data = prev2?.data;
|
|
1146
|
-
const error = prev2?.error;
|
|
1147
|
-
if (data === void 0 && error === void 0) {
|
|
1148
|
-
continue;
|
|
1149
|
-
}
|
|
1150
|
-
}
|
|
1151
|
-
updates.push({ fieldPath: concretePath, prev: prev2 });
|
|
1152
|
-
}
|
|
1153
|
-
continue;
|
|
1154
|
-
}
|
|
1155
|
-
let key;
|
|
1156
|
-
try {
|
|
1157
|
-
key = entry.meta.key(draft);
|
|
1158
|
-
} catch {
|
|
1159
|
-
continue;
|
|
1160
|
-
}
|
|
1161
|
-
if (key !== void 0) continue;
|
|
1162
|
-
const prev = getAtPath(draft, fieldPath);
|
|
1163
|
-
const prevStatus = prev && typeof prev === "object" ? prev.status : void 0;
|
|
1164
|
-
if (prevStatus === "idle") {
|
|
1165
|
-
const data = prev?.data;
|
|
1166
|
-
const error = prev?.error;
|
|
1167
|
-
if (data === void 0 && error === void 0) {
|
|
1168
|
-
continue;
|
|
1169
|
-
}
|
|
1170
|
-
}
|
|
1171
|
-
updates.push({ fieldPath, prev });
|
|
1172
|
-
}
|
|
1173
|
-
if (updates.length === 0) return;
|
|
1174
|
-
const reason = "source-refresh";
|
|
1175
|
-
const nextDraft = create(draft, (next) => {
|
|
1176
|
-
for (const u of updates) {
|
|
1177
|
-
setAtPathMutating(next, u.fieldPath, Snapshot.idle());
|
|
1178
|
-
}
|
|
1179
|
-
});
|
|
1180
|
-
ctx.setDraft(nextDraft);
|
|
1181
|
-
for (const u of updates) {
|
|
1182
|
-
const normalized = normalizeFieldPath(u.fieldPath) ?? [];
|
|
1183
|
-
ctx.recordPatch(normalized, reason, u.prev, Snapshot.idle(), `source:${u.fieldPath}:idle`);
|
|
1184
|
-
}
|
|
1185
|
-
});
|
|
1186
|
-
var installSourceRefresh = (bound, step, entry) => {
|
|
1187
|
-
if (!step.targetFieldPath) return Effect.void;
|
|
1188
|
-
const fieldPath = step.targetFieldPath;
|
|
1189
|
-
const resourceId = step.resourceId ?? entry.meta.resource;
|
|
1190
|
-
const listItem = parseListItemFieldPath(fieldPath);
|
|
1191
|
-
let internals;
|
|
1192
|
-
try {
|
|
1193
|
-
internals = getBoundInternals(bound);
|
|
1194
|
-
} catch {
|
|
1195
|
-
return Effect.void;
|
|
1196
|
-
}
|
|
1197
|
-
const register = internals.traits.registerSourceRefresh;
|
|
1198
|
-
const recordSnapshot = (replayMode, replayLog, input) => {
|
|
1199
|
-
if (!replayLog) return Effect.void;
|
|
1200
|
-
if (replayMode !== "live") return Effect.void;
|
|
1201
|
-
const event = input && typeof input === "object" && input._tag === "ResourceSnapshot" ? input : {
|
|
1202
|
-
_tag: "ResourceSnapshot",
|
|
1203
|
-
resourceId,
|
|
1204
|
-
fieldPath: input.fieldPath,
|
|
1205
|
-
keyHash: input.keyHash,
|
|
1206
|
-
concurrency: input.concurrency,
|
|
1207
|
-
phase: input.phase,
|
|
1208
|
-
snapshot: input.snapshot,
|
|
1209
|
-
timestamp: Date.now(),
|
|
1210
|
-
moduleId: input.moduleId,
|
|
1211
|
-
instanceId: input.instanceId
|
|
1212
|
-
};
|
|
1213
|
-
return replayLog.record(event);
|
|
1214
|
-
};
|
|
1215
|
-
if (listItem) {
|
|
1216
|
-
const store = internals.traits.rowIdStore;
|
|
1217
|
-
if (!store) {
|
|
1218
|
-
return Effect.void;
|
|
1219
|
-
}
|
|
1220
|
-
const listPath = listItem.listPath;
|
|
1221
|
-
const itemPath = listItem.itemPath;
|
|
1222
|
-
if (!itemPath) {
|
|
1223
|
-
return Effect.void;
|
|
1224
|
-
}
|
|
1225
|
-
const concurrency2 = entry.meta.concurrency;
|
|
1226
|
-
const mode2 = concurrency2 ?? "switch";
|
|
1227
|
-
const inFlight2 = /* @__PURE__ */ new Map();
|
|
1228
|
-
const trailing2 = /* @__PURE__ */ new Map();
|
|
1229
|
-
let gen2 = 0;
|
|
1230
|
-
store.onRemoved(listPath, (rowId) => {
|
|
1231
|
-
trailing2.delete(rowId);
|
|
1232
|
-
inFlight2.delete(rowId);
|
|
1233
|
-
});
|
|
1234
|
-
const setSnapshotForRowInTxn = (rowId, next, reason, stepId) => Effect.gen(function* () {
|
|
1235
|
-
let wrotePath;
|
|
1236
|
-
yield* bound.state.mutate((draft) => {
|
|
1237
|
-
const index = store.getIndex(listPath, rowId);
|
|
1238
|
-
if (index === void 0) return;
|
|
1239
|
-
const concretePath = toListItemValuePath(listPath, index, itemPath);
|
|
1240
|
-
const prev = getAtPath(draft, concretePath);
|
|
1241
|
-
if (Object.is(prev, next)) return;
|
|
1242
|
-
wrotePath = concretePath;
|
|
1243
|
-
setAtPathMutating(draft, concretePath, next);
|
|
1244
|
-
recordTraitPatch(bound, concretePath, reason, prev, next, step.debugInfo?.graphNodeId);
|
|
1245
|
-
});
|
|
1246
|
-
return wrotePath;
|
|
1247
|
-
});
|
|
1248
|
-
const writebackIfCurrentKeyHashForRow = (rowId, keyHash2, next, reason, stepId, phase) => Effect.gen(function* () {
|
|
1249
|
-
let wrotePath;
|
|
1250
|
-
yield* bound.state.mutate((draft) => {
|
|
1251
|
-
const index = store.getIndex(listPath, rowId);
|
|
1252
|
-
if (index === void 0) return;
|
|
1253
|
-
const concretePath = toListItemValuePath(listPath, index, itemPath);
|
|
1254
|
-
const current = getAtPath(draft, concretePath);
|
|
1255
|
-
const currentKeyHash = current && typeof current === "object" ? current.keyHash : void 0;
|
|
1256
|
-
if (currentKeyHash !== keyHash2) return;
|
|
1257
|
-
const prev = current;
|
|
1258
|
-
if (Object.is(prev, next)) return;
|
|
1259
|
-
wrotePath = concretePath;
|
|
1260
|
-
setAtPathMutating(draft, concretePath, next);
|
|
1261
|
-
if (phase) {
|
|
1262
|
-
const { moduleId, instanceId } = getBoundScope(bound);
|
|
1263
|
-
recordReplayEvent(bound, {
|
|
1264
|
-
_tag: "ResourceSnapshot",
|
|
1265
|
-
resourceId,
|
|
1266
|
-
fieldPath: concretePath,
|
|
1267
|
-
keyHash: keyHash2,
|
|
1268
|
-
concurrency: mode2,
|
|
1269
|
-
phase,
|
|
1270
|
-
snapshot: next,
|
|
1271
|
-
timestamp: Date.now(),
|
|
1272
|
-
moduleId,
|
|
1273
|
-
instanceId
|
|
1274
|
-
});
|
|
1275
|
-
}
|
|
1276
|
-
recordTraitPatch(bound, concretePath, reason, prev, next, step.debugInfo?.graphNodeId);
|
|
1277
|
-
});
|
|
1278
|
-
return wrotePath;
|
|
1279
|
-
});
|
|
1280
|
-
const startFetch2 = (rowId, key, keyHash2, replayMode, replayLog) => Effect.gen(function* () {
|
|
1281
|
-
const { moduleId, instanceId } = getBoundScope(bound);
|
|
1282
|
-
const indexForLog = store.getIndex(listPath, rowId);
|
|
1283
|
-
const logFieldPath = indexForLog === void 0 ? void 0 : toListItemValuePath(listPath, indexForLog, itemPath);
|
|
1284
|
-
let loadingSnapshot = Snapshot.loading({ keyHash: keyHash2 });
|
|
1285
|
-
if (replayMode === "replay" && replayLog && logFieldPath) {
|
|
1286
|
-
const replayLoading = yield* replayLog.consumeNextResourceSnapshot({
|
|
1287
|
-
resourceId,
|
|
1288
|
-
fieldPath: logFieldPath,
|
|
1289
|
-
keyHash: keyHash2,
|
|
1290
|
-
phase: "loading"
|
|
1291
|
-
});
|
|
1292
|
-
if (replayLoading) {
|
|
1293
|
-
loadingSnapshot = replayLoading.snapshot;
|
|
1294
|
-
}
|
|
1295
|
-
}
|
|
1296
|
-
const wroteLoadingPath = yield* setSnapshotForRowInTxn(
|
|
1297
|
-
rowId,
|
|
1298
|
-
loadingSnapshot,
|
|
1299
|
-
"source-refresh",
|
|
1300
|
-
`source:${fieldPath}:${rowId}:loading`
|
|
1301
|
-
);
|
|
1302
|
-
if (wroteLoadingPath) {
|
|
1303
|
-
const event = {
|
|
1304
|
-
_tag: "ResourceSnapshot",
|
|
1305
|
-
resourceId,
|
|
1306
|
-
fieldPath: wroteLoadingPath,
|
|
1307
|
-
keyHash: keyHash2,
|
|
1308
|
-
concurrency: mode2,
|
|
1309
|
-
phase: "loading",
|
|
1310
|
-
snapshot: loadingSnapshot,
|
|
1311
|
-
timestamp: Date.now(),
|
|
1312
|
-
moduleId,
|
|
1313
|
-
instanceId
|
|
1314
|
-
};
|
|
1315
|
-
recordReplayEvent(bound, event);
|
|
1316
|
-
yield* recordSnapshot(replayMode, replayLog, event);
|
|
1317
|
-
}
|
|
1318
|
-
const io = Effect.gen(function* () {
|
|
1319
|
-
if (replayMode === "replay" && replayLog) {
|
|
1320
|
-
yield* Effect.yieldNow();
|
|
1321
|
-
const consumePath = wroteLoadingPath ?? logFieldPath;
|
|
1322
|
-
if (!consumePath) return yield* Effect.void;
|
|
1323
|
-
const replayed = yield* replayLog.consumeNextResourceSnapshot({
|
|
1324
|
-
resourceId,
|
|
1325
|
-
fieldPath: consumePath,
|
|
1326
|
-
keyHash: keyHash2
|
|
1327
|
-
});
|
|
1328
|
-
if (!replayed) return yield* Effect.void;
|
|
1329
|
-
if (replayed.phase === "success") {
|
|
1330
|
-
yield* writebackIfCurrentKeyHashForRow(
|
|
1331
|
-
rowId,
|
|
1332
|
-
keyHash2,
|
|
1333
|
-
replayed.snapshot,
|
|
1334
|
-
"source-refresh",
|
|
1335
|
-
`source:${fieldPath}:${rowId}:success`,
|
|
1336
|
-
"success"
|
|
1337
|
-
);
|
|
1338
|
-
} else if (replayed.phase === "error") {
|
|
1339
|
-
yield* writebackIfCurrentKeyHashForRow(
|
|
1340
|
-
rowId,
|
|
1341
|
-
keyHash2,
|
|
1342
|
-
replayed.snapshot,
|
|
1343
|
-
"source-refresh",
|
|
1344
|
-
`source:${fieldPath}:${rowId}:error`,
|
|
1345
|
-
"error"
|
|
1346
|
-
);
|
|
1347
|
-
}
|
|
1348
|
-
return yield* Effect.void;
|
|
1349
|
-
}
|
|
1350
|
-
const stack = yield* getMiddlewareStack();
|
|
1351
|
-
const registryOpt = yield* Effect.serviceOption(internal.ResourceRegistryTag);
|
|
1352
|
-
const registry = Option.isSome(registryOpt) ? registryOpt.value : void 0;
|
|
1353
|
-
const spec = registry?.specs.get(resourceId);
|
|
1354
|
-
if (!spec) {
|
|
1355
|
-
return yield* Effect.void;
|
|
1356
|
-
}
|
|
1357
|
-
const loadEffect = spec.load(key);
|
|
1358
|
-
const meta = {
|
|
1359
|
-
moduleId,
|
|
1360
|
-
instanceId,
|
|
1361
|
-
fieldPath,
|
|
1362
|
-
resourceId,
|
|
1363
|
-
key,
|
|
1364
|
-
keyHash: keyHash2,
|
|
1365
|
-
rowId,
|
|
1366
|
-
traitNodeId: step.debugInfo?.graphNodeId,
|
|
1367
|
-
stepId: step.id
|
|
1368
|
-
};
|
|
1369
|
-
if (!(typeof meta.opSeq === "number" && Number.isFinite(meta.opSeq))) {
|
|
1370
|
-
const sessionOpt = yield* Effect.serviceOption(RunSessionTag);
|
|
1371
|
-
if (Option.isSome(sessionOpt)) {
|
|
1372
|
-
const seqKey = instanceId ?? "global";
|
|
1373
|
-
meta.opSeq = sessionOpt.value.local.nextSeq("opSeq", seqKey);
|
|
1374
|
-
}
|
|
1375
|
-
}
|
|
1376
|
-
const op = make({
|
|
1377
|
-
kind: "service",
|
|
1378
|
-
name: resourceId,
|
|
1379
|
-
effect: loadEffect,
|
|
1380
|
-
meta
|
|
1381
|
-
});
|
|
1382
|
-
const exit = yield* Effect.exit(run(op, stack));
|
|
1383
|
-
if (exit._tag === "Success") {
|
|
1384
|
-
const successSnapshot = Snapshot.success({ keyHash: keyHash2, data: exit.value });
|
|
1385
|
-
const wroteSuccessPath = yield* writebackIfCurrentKeyHashForRow(
|
|
1386
|
-
rowId,
|
|
1387
|
-
keyHash2,
|
|
1388
|
-
successSnapshot,
|
|
1389
|
-
"source-refresh",
|
|
1390
|
-
`source:${fieldPath}:${rowId}:success`,
|
|
1391
|
-
"success"
|
|
1392
|
-
);
|
|
1393
|
-
if (wroteSuccessPath) {
|
|
1394
|
-
yield* recordSnapshot(replayMode, replayLog, {
|
|
1395
|
-
_tag: "ResourceSnapshot",
|
|
1396
|
-
resourceId,
|
|
1397
|
-
fieldPath: wroteSuccessPath,
|
|
1398
|
-
keyHash: keyHash2,
|
|
1399
|
-
concurrency: mode2,
|
|
1400
|
-
phase: "success",
|
|
1401
|
-
snapshot: successSnapshot,
|
|
1402
|
-
timestamp: Date.now(),
|
|
1403
|
-
moduleId,
|
|
1404
|
-
instanceId
|
|
1405
|
-
});
|
|
1406
|
-
}
|
|
1407
|
-
} else {
|
|
1408
|
-
const errorSnapshot = Snapshot.error({ keyHash: keyHash2, error: exit.cause });
|
|
1409
|
-
const wroteErrorPath = yield* writebackIfCurrentKeyHashForRow(
|
|
1410
|
-
rowId,
|
|
1411
|
-
keyHash2,
|
|
1412
|
-
errorSnapshot,
|
|
1413
|
-
"source-refresh",
|
|
1414
|
-
`source:${fieldPath}:${rowId}:error`,
|
|
1415
|
-
"error"
|
|
1416
|
-
);
|
|
1417
|
-
if (wroteErrorPath) {
|
|
1418
|
-
yield* recordSnapshot(replayMode, replayLog, {
|
|
1419
|
-
_tag: "ResourceSnapshot",
|
|
1420
|
-
resourceId,
|
|
1421
|
-
fieldPath: wroteErrorPath,
|
|
1422
|
-
keyHash: keyHash2,
|
|
1423
|
-
concurrency: mode2,
|
|
1424
|
-
phase: "error",
|
|
1425
|
-
snapshot: errorSnapshot,
|
|
1426
|
-
timestamp: Date.now(),
|
|
1427
|
-
moduleId,
|
|
1428
|
-
instanceId
|
|
1429
|
-
});
|
|
1430
|
-
}
|
|
1431
|
-
}
|
|
1432
|
-
}).pipe(Effect.catchAllCause(() => Effect.void));
|
|
1433
|
-
const fiber = yield* Effect.forkScoped(Effect.locally(inSyncTransactionFiber, false)(io));
|
|
1434
|
-
const myGen = gen2 += 1;
|
|
1435
|
-
inFlight2.set(rowId, { gen: myGen, fiber, keyHash: keyHash2 });
|
|
1436
|
-
yield* Effect.forkScoped(
|
|
1437
|
-
Effect.locally(
|
|
1438
|
-
inSyncTransactionFiber,
|
|
1439
|
-
false
|
|
1440
|
-
)(
|
|
1441
|
-
Fiber.await(fiber).pipe(
|
|
1442
|
-
Effect.zipRight(
|
|
1443
|
-
Effect.sync(() => {
|
|
1444
|
-
const current = inFlight2.get(rowId);
|
|
1445
|
-
if (current && current.gen === myGen) {
|
|
1446
|
-
inFlight2.delete(rowId);
|
|
1447
|
-
}
|
|
1448
|
-
})
|
|
1449
|
-
),
|
|
1450
|
-
Effect.zipRight(
|
|
1451
|
-
mode2 === "exhaust-trailing" ? Effect.gen(function* () {
|
|
1452
|
-
const next = trailing2.get(rowId);
|
|
1453
|
-
trailing2.delete(rowId);
|
|
1454
|
-
if (next) {
|
|
1455
|
-
yield* startFetch2(rowId, next.key, next.keyHash, replayMode, replayLog);
|
|
1456
|
-
}
|
|
1457
|
-
}) : Effect.void
|
|
1458
|
-
),
|
|
1459
|
-
Effect.catchAllCause(() => Effect.void)
|
|
1460
|
-
)
|
|
1461
|
-
)
|
|
1462
|
-
);
|
|
1463
|
-
});
|
|
1464
|
-
register(
|
|
1465
|
-
fieldPath,
|
|
1466
|
-
(state) => Effect.gen(function* () {
|
|
1467
|
-
const { moduleId, instanceId } = getBoundScope(bound);
|
|
1468
|
-
const replayModeOpt = yield* Effect.serviceOption(ReplayModeConfigTag);
|
|
1469
|
-
const replayMode = Option.isSome(replayModeOpt) ? replayModeOpt.value.mode : "live";
|
|
1470
|
-
const replayLogOpt = yield* Effect.serviceOption(ReplayLog);
|
|
1471
|
-
const replayLog = Option.isSome(replayLogOpt) ? replayLogOpt.value : void 0;
|
|
1472
|
-
const force = yield* FiberRef.get(forceSourceRefresh);
|
|
1473
|
-
const listValue = getAtPath(state, listPath);
|
|
1474
|
-
const items = Array.isArray(listValue) ? listValue : [];
|
|
1475
|
-
const ids = store.ensureList(listPath, items);
|
|
1476
|
-
const traceKey = `${instanceId ?? "unknown"}::source::${fieldPath}`;
|
|
1477
|
-
if (isDevEnv() && (yield* onceInRunSession(`deps_trace_settled:${traceKey}`))) {
|
|
1478
|
-
try {
|
|
1479
|
-
const sample = items[0];
|
|
1480
|
-
if (sample !== void 0) {
|
|
1481
|
-
const traced = trace((s) => entry.meta.key(s), sample);
|
|
1482
|
-
const prefixedReads = traced.reads.map((r) => r ? `${listPath}[].${r}` : `${listPath}[]`);
|
|
1483
|
-
const diff = diffDeps(entry.meta.deps ?? [], prefixedReads);
|
|
1484
|
-
if (diff) {
|
|
1485
|
-
yield* emitDepsMismatch({
|
|
1486
|
-
moduleId,
|
|
1487
|
-
instanceId,
|
|
1488
|
-
kind: "source",
|
|
1489
|
-
fieldPath,
|
|
1490
|
-
diff
|
|
1491
|
-
});
|
|
1492
|
-
}
|
|
1493
|
-
}
|
|
1494
|
-
} catch {
|
|
1495
|
-
}
|
|
1496
|
-
}
|
|
1497
|
-
for (let index = 0; index < items.length; index++) {
|
|
1498
|
-
const rowId = ids[index];
|
|
1499
|
-
if (!rowId) continue;
|
|
1500
|
-
const concretePath = toListItemValuePath(listPath, index, itemPath);
|
|
1501
|
-
const prevSnapshot = getAtPath(state, concretePath);
|
|
1502
|
-
let key;
|
|
1503
|
-
try {
|
|
1504
|
-
key = entry.meta.key(items[index]);
|
|
1505
|
-
} catch {
|
|
1506
|
-
key = void 0;
|
|
1507
|
-
}
|
|
1508
|
-
const current = inFlight2.get(rowId);
|
|
1509
|
-
if (key === void 0) {
|
|
1510
|
-
trailing2.delete(rowId);
|
|
1511
|
-
inFlight2.delete(rowId);
|
|
1512
|
-
if (prevSnapshot && typeof prevSnapshot === "object" && prevSnapshot.status === "idle" && prevSnapshot.data === void 0 && prevSnapshot.error === void 0) {
|
|
1513
|
-
continue;
|
|
1514
|
-
}
|
|
1515
|
-
const idleSnapshot = Snapshot.idle();
|
|
1516
|
-
const wroteIdlePath = yield* setSnapshotForRowInTxn(
|
|
1517
|
-
rowId,
|
|
1518
|
-
idleSnapshot,
|
|
1519
|
-
"source-refresh",
|
|
1520
|
-
`source:${fieldPath}:${rowId}:idle`
|
|
1521
|
-
);
|
|
1522
|
-
if (wroteIdlePath) {
|
|
1523
|
-
const event = {
|
|
1524
|
-
_tag: "ResourceSnapshot",
|
|
1525
|
-
resourceId,
|
|
1526
|
-
fieldPath: wroteIdlePath,
|
|
1527
|
-
keyHash: void 0,
|
|
1528
|
-
concurrency: mode2,
|
|
1529
|
-
phase: "idle",
|
|
1530
|
-
snapshot: idleSnapshot,
|
|
1531
|
-
timestamp: Date.now(),
|
|
1532
|
-
moduleId,
|
|
1533
|
-
instanceId
|
|
1534
|
-
};
|
|
1535
|
-
recordReplayEvent(bound, event);
|
|
1536
|
-
yield* recordSnapshot(replayMode, replayLog, event);
|
|
1537
|
-
}
|
|
1538
|
-
continue;
|
|
1539
|
-
}
|
|
1540
|
-
const h = keyHash(key);
|
|
1541
|
-
if (!force && current && current.keyHash === h) {
|
|
1542
|
-
continue;
|
|
1543
|
-
}
|
|
1544
|
-
const prevKeyHash = prevSnapshot && typeof prevSnapshot === "object" ? prevSnapshot.keyHash : void 0;
|
|
1545
|
-
if (!force && !current && prevKeyHash === h) {
|
|
1546
|
-
continue;
|
|
1547
|
-
}
|
|
1548
|
-
if (mode2 === "exhaust-trailing" && current) {
|
|
1549
|
-
trailing2.set(rowId, { key, keyHash: h });
|
|
1550
|
-
const loadingSnapshot = Snapshot.loading({ keyHash: h });
|
|
1551
|
-
const wroteLoadingPath = yield* setSnapshotForRowInTxn(
|
|
1552
|
-
rowId,
|
|
1553
|
-
loadingSnapshot,
|
|
1554
|
-
"source-refresh",
|
|
1555
|
-
`source:${fieldPath}:${rowId}:loading`
|
|
1556
|
-
);
|
|
1557
|
-
if (wroteLoadingPath) {
|
|
1558
|
-
const event = {
|
|
1559
|
-
_tag: "ResourceSnapshot",
|
|
1560
|
-
resourceId,
|
|
1561
|
-
fieldPath: wroteLoadingPath,
|
|
1562
|
-
keyHash: h,
|
|
1563
|
-
concurrency: mode2,
|
|
1564
|
-
phase: "loading",
|
|
1565
|
-
snapshot: loadingSnapshot,
|
|
1566
|
-
timestamp: Date.now(),
|
|
1567
|
-
moduleId,
|
|
1568
|
-
instanceId
|
|
1569
|
-
};
|
|
1570
|
-
recordReplayEvent(bound, event);
|
|
1571
|
-
yield* recordSnapshot(replayMode, replayLog, event);
|
|
1572
|
-
}
|
|
1573
|
-
continue;
|
|
1574
|
-
}
|
|
1575
|
-
if (mode2 === "switch" && current) {
|
|
1576
|
-
trailing2.delete(rowId);
|
|
1577
|
-
inFlight2.delete(rowId);
|
|
1578
|
-
}
|
|
1579
|
-
yield* startFetch2(rowId, key, h, replayMode, replayLog);
|
|
1580
|
-
}
|
|
1581
|
-
})
|
|
1582
|
-
);
|
|
1583
|
-
return Effect.void;
|
|
1584
|
-
}
|
|
1585
|
-
let inFlight;
|
|
1586
|
-
let gen = 0;
|
|
1587
|
-
let trailing;
|
|
1588
|
-
const concurrency = entry.meta.concurrency;
|
|
1589
|
-
const mode = concurrency ?? "switch";
|
|
1590
|
-
const startFetch = (key, keyHash2, replayMode, replayLog) => Effect.gen(function* () {
|
|
1591
|
-
const { moduleId, instanceId } = getBoundScope(bound);
|
|
1592
|
-
let loadingSnapshot = Snapshot.loading({ keyHash: keyHash2 });
|
|
1593
|
-
if (replayMode === "replay" && replayLog) {
|
|
1594
|
-
const replayLoading = yield* replayLog.consumeNextResourceSnapshot({
|
|
1595
|
-
resourceId,
|
|
1596
|
-
fieldPath,
|
|
1597
|
-
keyHash: keyHash2,
|
|
1598
|
-
phase: "loading"
|
|
1599
|
-
});
|
|
1600
|
-
if (replayLoading) {
|
|
1601
|
-
loadingSnapshot = replayLoading.snapshot;
|
|
1602
|
-
}
|
|
1603
|
-
}
|
|
1604
|
-
const wroteLoading = yield* setSnapshotInTxn(
|
|
1605
|
-
bound,
|
|
1606
|
-
fieldPath,
|
|
1607
|
-
loadingSnapshot,
|
|
1608
|
-
"source-refresh",
|
|
1609
|
-
`source:${fieldPath}:loading`,
|
|
1610
|
-
step.debugInfo?.graphNodeId
|
|
1611
|
-
);
|
|
1612
|
-
if (wroteLoading) {
|
|
1613
|
-
const event = {
|
|
1614
|
-
_tag: "ResourceSnapshot",
|
|
1615
|
-
resourceId,
|
|
1616
|
-
fieldPath,
|
|
1617
|
-
keyHash: keyHash2,
|
|
1618
|
-
concurrency: mode,
|
|
1619
|
-
phase: "loading",
|
|
1620
|
-
snapshot: loadingSnapshot,
|
|
1621
|
-
timestamp: Date.now(),
|
|
1622
|
-
moduleId,
|
|
1623
|
-
instanceId
|
|
1624
|
-
};
|
|
1625
|
-
recordReplayEvent(bound, event);
|
|
1626
|
-
yield* recordSnapshot(replayMode, replayLog, event);
|
|
1627
|
-
}
|
|
1628
|
-
const io = Effect.gen(function* () {
|
|
1629
|
-
if (replayMode === "replay" && replayLog) {
|
|
1630
|
-
yield* Effect.yieldNow();
|
|
1631
|
-
const replayed = yield* replayLog.consumeNextResourceSnapshot({
|
|
1632
|
-
resourceId,
|
|
1633
|
-
fieldPath,
|
|
1634
|
-
keyHash: keyHash2
|
|
1635
|
-
});
|
|
1636
|
-
if (!replayed) return yield* Effect.void;
|
|
1637
|
-
if (replayed.phase === "success") {
|
|
1638
|
-
const event = {
|
|
1639
|
-
_tag: "ResourceSnapshot",
|
|
1640
|
-
resourceId,
|
|
1641
|
-
fieldPath,
|
|
1642
|
-
keyHash: keyHash2,
|
|
1643
|
-
concurrency: mode,
|
|
1644
|
-
phase: "success",
|
|
1645
|
-
snapshot: replayed.snapshot,
|
|
1646
|
-
timestamp: Date.now(),
|
|
1647
|
-
moduleId,
|
|
1648
|
-
instanceId
|
|
1649
|
-
};
|
|
1650
|
-
yield* writebackIfCurrentKeyHash(
|
|
1651
|
-
bound,
|
|
1652
|
-
fieldPath,
|
|
1653
|
-
keyHash2,
|
|
1654
|
-
replayed.snapshot,
|
|
1655
|
-
"source-refresh",
|
|
1656
|
-
`source:${fieldPath}:success`,
|
|
1657
|
-
step.debugInfo?.graphNodeId,
|
|
1658
|
-
event
|
|
1659
|
-
);
|
|
1660
|
-
} else if (replayed.phase === "error") {
|
|
1661
|
-
const event = {
|
|
1662
|
-
_tag: "ResourceSnapshot",
|
|
1663
|
-
resourceId,
|
|
1664
|
-
fieldPath,
|
|
1665
|
-
keyHash: keyHash2,
|
|
1666
|
-
concurrency: mode,
|
|
1667
|
-
phase: "error",
|
|
1668
|
-
snapshot: replayed.snapshot,
|
|
1669
|
-
timestamp: Date.now(),
|
|
1670
|
-
moduleId,
|
|
1671
|
-
instanceId
|
|
1672
|
-
};
|
|
1673
|
-
yield* writebackIfCurrentKeyHash(
|
|
1674
|
-
bound,
|
|
1675
|
-
fieldPath,
|
|
1676
|
-
keyHash2,
|
|
1677
|
-
replayed.snapshot,
|
|
1678
|
-
"source-refresh",
|
|
1679
|
-
`source:${fieldPath}:error`,
|
|
1680
|
-
step.debugInfo?.graphNodeId,
|
|
1681
|
-
event
|
|
1682
|
-
);
|
|
1683
|
-
}
|
|
1684
|
-
return yield* Effect.void;
|
|
1685
|
-
}
|
|
1686
|
-
const stack = yield* getMiddlewareStack();
|
|
1687
|
-
const registryOpt = yield* Effect.serviceOption(internal.ResourceRegistryTag);
|
|
1688
|
-
const registry = Option.isSome(registryOpt) ? registryOpt.value : void 0;
|
|
1689
|
-
const spec = registry?.specs.get(resourceId);
|
|
1690
|
-
if (!spec) {
|
|
1691
|
-
return yield* Effect.void;
|
|
1692
|
-
}
|
|
1693
|
-
const loadEffect = spec.load(key);
|
|
1694
|
-
const meta = {
|
|
1695
|
-
moduleId,
|
|
1696
|
-
instanceId,
|
|
1697
|
-
fieldPath,
|
|
1698
|
-
resourceId,
|
|
1699
|
-
key,
|
|
1700
|
-
keyHash: keyHash2,
|
|
1701
|
-
traitNodeId: step.debugInfo?.graphNodeId,
|
|
1702
|
-
stepId: step.id
|
|
1703
|
-
};
|
|
1704
|
-
if (!(typeof meta.opSeq === "number" && Number.isFinite(meta.opSeq))) {
|
|
1705
|
-
const sessionOpt = yield* Effect.serviceOption(RunSessionTag);
|
|
1706
|
-
if (Option.isSome(sessionOpt)) {
|
|
1707
|
-
const seqKey = instanceId ?? "global";
|
|
1708
|
-
meta.opSeq = sessionOpt.value.local.nextSeq("opSeq", seqKey);
|
|
1709
|
-
}
|
|
1710
|
-
}
|
|
1711
|
-
const op = make({
|
|
1712
|
-
kind: "trait-source",
|
|
1713
|
-
name: resourceId,
|
|
1714
|
-
effect: loadEffect,
|
|
1715
|
-
meta
|
|
1716
|
-
});
|
|
1717
|
-
const exit = yield* Effect.exit(run(op, stack));
|
|
1718
|
-
if (exit._tag === "Success") {
|
|
1719
|
-
const successSnapshot = Snapshot.success({ keyHash: keyHash2, data: exit.value });
|
|
1720
|
-
const event = {
|
|
1721
|
-
_tag: "ResourceSnapshot",
|
|
1722
|
-
resourceId,
|
|
1723
|
-
fieldPath,
|
|
1724
|
-
keyHash: keyHash2,
|
|
1725
|
-
concurrency: mode,
|
|
1726
|
-
phase: "success",
|
|
1727
|
-
snapshot: successSnapshot,
|
|
1728
|
-
timestamp: Date.now(),
|
|
1729
|
-
moduleId,
|
|
1730
|
-
instanceId
|
|
1731
|
-
};
|
|
1732
|
-
const wroteSuccess = yield* writebackIfCurrentKeyHash(
|
|
1733
|
-
bound,
|
|
1734
|
-
fieldPath,
|
|
1735
|
-
keyHash2,
|
|
1736
|
-
successSnapshot,
|
|
1737
|
-
"source-refresh",
|
|
1738
|
-
`source:${fieldPath}:success`,
|
|
1739
|
-
step.debugInfo?.graphNodeId,
|
|
1740
|
-
event
|
|
1741
|
-
);
|
|
1742
|
-
if (wroteSuccess) {
|
|
1743
|
-
yield* recordSnapshot(replayMode, replayLog, event);
|
|
1744
|
-
}
|
|
1745
|
-
} else {
|
|
1746
|
-
const errorSnapshot = Snapshot.error({ keyHash: keyHash2, error: exit.cause });
|
|
1747
|
-
const event = {
|
|
1748
|
-
_tag: "ResourceSnapshot",
|
|
1749
|
-
resourceId,
|
|
1750
|
-
fieldPath,
|
|
1751
|
-
keyHash: keyHash2,
|
|
1752
|
-
concurrency: mode,
|
|
1753
|
-
phase: "error",
|
|
1754
|
-
snapshot: errorSnapshot,
|
|
1755
|
-
timestamp: Date.now(),
|
|
1756
|
-
moduleId,
|
|
1757
|
-
instanceId
|
|
1758
|
-
};
|
|
1759
|
-
const wroteError = yield* writebackIfCurrentKeyHash(
|
|
1760
|
-
bound,
|
|
1761
|
-
fieldPath,
|
|
1762
|
-
keyHash2,
|
|
1763
|
-
errorSnapshot,
|
|
1764
|
-
"source-refresh",
|
|
1765
|
-
`source:${fieldPath}:error`,
|
|
1766
|
-
step.debugInfo?.graphNodeId,
|
|
1767
|
-
event
|
|
1768
|
-
);
|
|
1769
|
-
if (wroteError) {
|
|
1770
|
-
yield* recordSnapshot(replayMode, replayLog, event);
|
|
1771
|
-
}
|
|
1772
|
-
}
|
|
1773
|
-
}).pipe(Effect.catchAllCause(() => Effect.void));
|
|
1774
|
-
const fiber = yield* Effect.forkScoped(Effect.locally(inSyncTransactionFiber, false)(io));
|
|
1775
|
-
const myGen = gen += 1;
|
|
1776
|
-
inFlight = { gen: myGen, fiber, keyHash: keyHash2 };
|
|
1777
|
-
yield* Effect.forkScoped(
|
|
1778
|
-
Effect.locally(
|
|
1779
|
-
inSyncTransactionFiber,
|
|
1780
|
-
false
|
|
1781
|
-
)(
|
|
1782
|
-
Fiber.await(fiber).pipe(
|
|
1783
|
-
Effect.zipRight(
|
|
1784
|
-
Effect.sync(() => {
|
|
1785
|
-
if (inFlight && inFlight.gen === myGen) {
|
|
1786
|
-
inFlight = void 0;
|
|
1787
|
-
}
|
|
1788
|
-
})
|
|
1789
|
-
),
|
|
1790
|
-
Effect.zipRight(
|
|
1791
|
-
mode === "exhaust-trailing" ? Effect.gen(function* () {
|
|
1792
|
-
const next = trailing;
|
|
1793
|
-
trailing = void 0;
|
|
1794
|
-
if (next) {
|
|
1795
|
-
yield* startFetch(next.key, next.keyHash, replayMode, replayLog);
|
|
1796
|
-
}
|
|
1797
|
-
}) : Effect.void
|
|
1798
|
-
),
|
|
1799
|
-
Effect.catchAllCause(() => Effect.void)
|
|
1800
|
-
)
|
|
1801
|
-
)
|
|
1802
|
-
);
|
|
1803
|
-
});
|
|
1804
|
-
register(
|
|
1805
|
-
fieldPath,
|
|
1806
|
-
(state) => Effect.gen(function* () {
|
|
1807
|
-
const { moduleId, instanceId } = getBoundScope(bound);
|
|
1808
|
-
const replayModeOpt = yield* Effect.serviceOption(ReplayModeConfigTag);
|
|
1809
|
-
const replayMode = Option.isSome(replayModeOpt) ? replayModeOpt.value.mode : "live";
|
|
1810
|
-
const replayLogOpt = yield* Effect.serviceOption(ReplayLog);
|
|
1811
|
-
const replayLog = Option.isSome(replayLogOpt) ? replayLogOpt.value : void 0;
|
|
1812
|
-
const force = yield* FiberRef.get(forceSourceRefresh);
|
|
1813
|
-
let key;
|
|
1814
|
-
try {
|
|
1815
|
-
key = entry.meta.key(state);
|
|
1816
|
-
} catch {
|
|
1817
|
-
key = void 0;
|
|
1818
|
-
}
|
|
1819
|
-
const traceKey = `${instanceId ?? "unknown"}::source::${fieldPath}`;
|
|
1820
|
-
if (isDevEnv() && (yield* onceInRunSession(`deps_trace_settled:${traceKey}`))) {
|
|
1821
|
-
try {
|
|
1822
|
-
const traced = trace((s) => entry.meta.key(s), state);
|
|
1823
|
-
const diff = diffDeps(entry.meta.deps ?? [], traced.reads);
|
|
1824
|
-
if (diff) {
|
|
1825
|
-
yield* emitDepsMismatch({
|
|
1826
|
-
moduleId,
|
|
1827
|
-
instanceId,
|
|
1828
|
-
kind: "source",
|
|
1829
|
-
fieldPath,
|
|
1830
|
-
diff
|
|
1831
|
-
});
|
|
1832
|
-
}
|
|
1833
|
-
} catch {
|
|
1834
|
-
}
|
|
1835
|
-
}
|
|
1836
|
-
if (key === void 0) {
|
|
1837
|
-
if (inFlight) {
|
|
1838
|
-
yield* Fiber.interruptFork(inFlight.fiber);
|
|
1839
|
-
inFlight = void 0;
|
|
1840
|
-
}
|
|
1841
|
-
trailing = void 0;
|
|
1842
|
-
const idleSnapshot = Snapshot.idle();
|
|
1843
|
-
const wroteIdle = yield* setSnapshotInTxn(
|
|
1844
|
-
bound,
|
|
1845
|
-
fieldPath,
|
|
1846
|
-
idleSnapshot,
|
|
1847
|
-
"source-refresh",
|
|
1848
|
-
`source:${fieldPath}:idle`,
|
|
1849
|
-
step.debugInfo?.graphNodeId
|
|
1850
|
-
);
|
|
1851
|
-
if (wroteIdle) {
|
|
1852
|
-
const event = {
|
|
1853
|
-
_tag: "ResourceSnapshot",
|
|
1854
|
-
resourceId,
|
|
1855
|
-
fieldPath,
|
|
1856
|
-
keyHash: void 0,
|
|
1857
|
-
concurrency: mode,
|
|
1858
|
-
phase: "idle",
|
|
1859
|
-
snapshot: idleSnapshot,
|
|
1860
|
-
timestamp: Date.now(),
|
|
1861
|
-
moduleId,
|
|
1862
|
-
instanceId
|
|
1863
|
-
};
|
|
1864
|
-
recordReplayEvent(bound, event);
|
|
1865
|
-
yield* recordSnapshot(replayMode, replayLog, event);
|
|
1866
|
-
}
|
|
1867
|
-
return;
|
|
1868
|
-
}
|
|
1869
|
-
const h = keyHash(key);
|
|
1870
|
-
if (!force) {
|
|
1871
|
-
if (inFlight && inFlight.keyHash === h) {
|
|
1872
|
-
return;
|
|
1873
|
-
}
|
|
1874
|
-
const currentSnapshot = getAtPath(state, fieldPath);
|
|
1875
|
-
const currentKeyHash = currentSnapshot && typeof currentSnapshot === "object" ? currentSnapshot.keyHash : void 0;
|
|
1876
|
-
const currentStatus = currentSnapshot && typeof currentSnapshot === "object" ? currentSnapshot.status : void 0;
|
|
1877
|
-
if (currentStatus && currentStatus !== "idle" && currentKeyHash === h) {
|
|
1878
|
-
return;
|
|
1879
|
-
}
|
|
1880
|
-
}
|
|
1881
|
-
if (mode === "exhaust-trailing" && inFlight) {
|
|
1882
|
-
trailing = { key, keyHash: h };
|
|
1883
|
-
const loadingSnapshot = Snapshot.loading({ keyHash: h });
|
|
1884
|
-
const wroteLoading = yield* setSnapshotInTxn(
|
|
1885
|
-
bound,
|
|
1886
|
-
fieldPath,
|
|
1887
|
-
loadingSnapshot,
|
|
1888
|
-
"source-refresh",
|
|
1889
|
-
`source:${fieldPath}:loading`,
|
|
1890
|
-
step.debugInfo?.graphNodeId
|
|
1891
|
-
);
|
|
1892
|
-
if (wroteLoading) {
|
|
1893
|
-
const event = {
|
|
1894
|
-
_tag: "ResourceSnapshot",
|
|
1895
|
-
resourceId,
|
|
1896
|
-
fieldPath,
|
|
1897
|
-
keyHash: h,
|
|
1898
|
-
concurrency: mode,
|
|
1899
|
-
phase: "loading",
|
|
1900
|
-
snapshot: loadingSnapshot,
|
|
1901
|
-
timestamp: Date.now(),
|
|
1902
|
-
moduleId,
|
|
1903
|
-
instanceId
|
|
1904
|
-
};
|
|
1905
|
-
recordReplayEvent(bound, event);
|
|
1906
|
-
yield* recordSnapshot(replayMode, replayLog, event);
|
|
1907
|
-
}
|
|
1908
|
-
return;
|
|
1909
|
-
}
|
|
1910
|
-
if (mode === "switch" && inFlight) {
|
|
1911
|
-
yield* Fiber.interruptFork(inFlight.fiber);
|
|
1912
|
-
inFlight = void 0;
|
|
1913
|
-
trailing = void 0;
|
|
1914
|
-
}
|
|
1915
|
-
yield* startFetch(key, h, replayMode, replayLog);
|
|
1916
|
-
})
|
|
1917
|
-
);
|
|
1918
|
-
return Effect.void;
|
|
1919
|
-
};
|
|
1920
|
-
|
|
1921
|
-
export {
|
|
1922
|
-
diffDeps,
|
|
1923
|
-
trace,
|
|
1924
|
-
syncIdleInTransaction,
|
|
1925
|
-
installSourceRefresh,
|
|
1926
|
-
build
|
|
1927
|
-
};
|
|
1928
|
-
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vLi4vbG9naXgtY29yZS9zcmMvaW50ZXJuYWwvc3RhdGUtdHJhaXQvYnVpbGQudHMiLCAiLi4vLi4vLi4vLi4vbG9naXgtY29yZS9zcmMvaW50ZXJuYWwvc3RhdGUtdHJhaXQvbWV0YS50cyIsICIuLi8uLi8uLi8uLi9sb2dpeC1jb3JlL3NyYy9pbnRlcm5hbC9zdGF0ZS10cmFpdC9tb2RlbC50cyIsICIuLi8uLi8uLi8uLi9sb2dpeC1jb3JlL3NyYy9pbnRlcm5hbC9zdGF0ZS10cmFpdC9zb3VyY2UudHMiLCAiLi4vLi4vLi4vLi4vbG9naXgtY29yZS9zcmMvaW50ZXJuYWwvc3RhdGUtdHJhaXQvZGVwcy10cmFjZS50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiaW1wb3J0IHR5cGUgeyBTY2hlbWEgfSBmcm9tICdlZmZlY3QnXG5pbXBvcnQgKiBhcyBTY2hlbWFBU1QgZnJvbSAnZWZmZWN0L1NjaGVtYUFTVCdcbmltcG9ydCB7XG4gIHR5cGUgU3RhdGVUcmFpdFByb2dyYW0sXG4gIHR5cGUgU3RhdGVUcmFpdFNwZWMsXG4gIHR5cGUgU3RhdGVUcmFpdEVudHJ5LFxuICB0eXBlIFN0YXRlVHJhaXRHcmFwaCxcbiAgdHlwZSBTdGF0ZVRyYWl0R3JhcGhFZGdlLFxuICB0eXBlIFN0YXRlVHJhaXRHcmFwaE5vZGUsXG4gIHR5cGUgU3RhdGVUcmFpdEZpZWxkLFxuICB0eXBlIFN0YXRlVHJhaXRGaWVsZFRyYWl0LFxuICB0eXBlIFN0YXRlVHJhaXRQbGFuLFxuICB0eXBlIFN0YXRlVHJhaXRQbGFuU3RlcCxcbiAgdHlwZSBTdGF0ZVRyYWl0UmVzb3VyY2UsXG4gIHR5cGUgU3RhdGVUcmFpdFNjaGVtYVBhdGhSZWYsXG4gIGNvbGxlY3ROb2RlTWV0YSxcbiAgbm9ybWFsaXplU3BlYyxcbn0gZnJvbSAnLi9tb2RlbC5qcydcbmltcG9ydCAqIGFzIE1ldGEgZnJvbSAnLi9tZXRhLmpzJ1xuaW1wb3J0IHtcbiAgY29tcGFyZUZpZWxkUGF0aCxcbiAgZ2V0RmllbGRQYXRoSWQsXG4gIG1ha2VGaWVsZFBhdGhJZFJlZ2lzdHJ5LFxuICBub3JtYWxpemVGaWVsZFBhdGgsXG4gIHR5cGUgRmllbGRQYXRoLFxuICB0eXBlIEZpZWxkUGF0aElkLFxufSBmcm9tICcuLi9maWVsZC1wYXRoLmpzJ1xuaW1wb3J0IHsgZm52MWEzMiwgc3RhYmxlU3RyaW5naWZ5IH0gZnJvbSAnLi4vZGlnZXN0LmpzJ1xuaW1wb3J0IHR5cGUgeyBDb252ZXJnZVN0YXRpY0lyUmVnaXN0cnkgfSBmcm9tICcuL2NvbnZlcmdlLWlyLmpzJ1xuXG5jb25zdCBub3dQZXJmID0gKCk6IG51bWJlciA9PlxuICB0eXBlb2YgZ2xvYmFsVGhpcy5wZXJmb3JtYW5jZSAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIGdsb2JhbFRoaXMucGVyZm9ybWFuY2Uubm93ID09PSAnZnVuY3Rpb24nXG4gICAgPyBnbG9iYWxUaGlzLnBlcmZvcm1hbmNlLm5vdygpXG4gICAgOiBEYXRlLm5vdygpXG5cbnR5cGUgQ29udmVyZ2VXcml0ZXIgPSBFeHRyYWN0PFN0YXRlVHJhaXRFbnRyeTxhbnksIHN0cmluZz4sIHsgcmVhZG9ubHkga2luZDogJ2NvbXB1dGVkJyB8ICdsaW5rJyB9PlxuXG5jb25zdCBnZXRDb252ZXJnZVdyaXRlckRlcHMgPSAoZW50cnk6IENvbnZlcmdlV3JpdGVyKTogUmVhZG9ubHlBcnJheTxzdHJpbmc+ID0+IHtcbiAgaWYgKGVudHJ5LmtpbmQgPT09ICdjb21wdXRlZCcpIHtcbiAgICByZXR1cm4gKChlbnRyeS5tZXRhIGFzIGFueSk/LmRlcHMgPz8gW10pIGFzIFJlYWRvbmx5QXJyYXk8c3RyaW5nPlxuICB9XG4gIHJldHVybiBbZW50cnkubWV0YS5mcm9tIGFzIHN0cmluZ11cbn1cblxuY29uc3QgY29tcHV0ZUNvbnZlcmdlVG9wb09yZGVyID0gKFxuICB3cml0ZXJzOiBSZWFkb25seUFycmF5PENvbnZlcmdlV3JpdGVyPixcbik6IHsgcmVhZG9ubHkgb3JkZXI6IFJlYWRvbmx5QXJyYXk8c3RyaW5nPjsgcmVhZG9ubHkgY29uZmlnRXJyb3I/OiBDb252ZXJnZVN0YXRpY0lyUmVnaXN0cnlbJ2NvbmZpZ0Vycm9yJ10gfSA9PiB7XG4gIGNvbnN0IHdyaXRlckJ5UGF0aCA9IG5ldyBNYXA8c3RyaW5nLCBDb252ZXJnZVdyaXRlcj4oKVxuICBmb3IgKGNvbnN0IGVudHJ5IG9mIHdyaXRlcnMpIHtcbiAgICBjb25zdCBleGlzdGluZyA9IHdyaXRlckJ5UGF0aC5nZXQoZW50cnkuZmllbGRQYXRoKVxuICAgIGlmIChleGlzdGluZykge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgb3JkZXI6IFtdLFxuICAgICAgICBjb25maWdFcnJvcjoge1xuICAgICAgICAgIGNvZGU6ICdNVUxUSVBMRV9XUklURVJTJyxcbiAgICAgICAgICBtZXNzYWdlOiBgW1N0YXRlVHJhaXQuY29udmVyZ2VdIE11bHRpcGxlIHdyaXRlcnMgZm9yIGZpZWxkIFwiJHtlbnRyeS5maWVsZFBhdGh9XCIgKCR7ZXhpc3Rpbmcua2luZH0gKyAke2VudHJ5LmtpbmR9KS5gLFxuICAgICAgICAgIGZpZWxkczogW2VudHJ5LmZpZWxkUGF0aF0sXG4gICAgICAgIH0sXG4gICAgICB9XG4gICAgfVxuICAgIHdyaXRlckJ5UGF0aC5zZXQoZW50cnkuZmllbGRQYXRoLCBlbnRyeSlcbiAgfVxuXG4gIGNvbnN0IG5vZGVzID0gbmV3IFNldDxzdHJpbmc+KClcbiAgZm9yIChjb25zdCBlbnRyeSBvZiB3cml0ZXJzKSB7XG4gICAgbm9kZXMuYWRkKGVudHJ5LmZpZWxkUGF0aClcbiAgfVxuXG4gIGNvbnN0IGluZGVncmVlID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKVxuICBjb25zdCBmb3J3YXJkID0gbmV3IE1hcDxzdHJpbmcsIEFycmF5PHN0cmluZz4+KClcblxuICBmb3IgKGNvbnN0IG5vZGUgb2Ygbm9kZXMpIHtcbiAgICBpbmRlZ3JlZS5zZXQobm9kZSwgMClcbiAgICBmb3J3YXJkLnNldChub2RlLCBbXSlcbiAgfVxuXG4gIGZvciAoY29uc3QgZW50cnkgb2Ygd3JpdGVycykge1xuICAgIGNvbnN0IHRvID0gZW50cnkuZmllbGRQYXRoXG4gICAgY29uc3QgZGVwcyA9IGdldENvbnZlcmdlV3JpdGVyRGVwcyhlbnRyeSlcbiAgICBmb3IgKGNvbnN0IGRlcCBvZiBkZXBzKSB7XG4gICAgICBpZiAoIW5vZGVzLmhhcyhkZXApKSBjb250aW51ZVxuICAgICAgZm9yd2FyZC5nZXQoZGVwKSEucHVzaCh0bylcbiAgICAgIGluZGVncmVlLnNldCh0bywgKGluZGVncmVlLmdldCh0bykgPz8gMCkgKyAxKVxuICAgIH1cbiAgfVxuXG4gIGNvbnN0IHF1ZXVlOiBBcnJheTxzdHJpbmc+ID0gW11cbiAgZm9yIChjb25zdCBbbm9kZSwgZGVnXSBvZiBpbmRlZ3JlZS5lbnRyaWVzKCkpIHtcbiAgICBpZiAoZGVnID09PSAwKSBxdWV1ZS5wdXNoKG5vZGUpXG4gIH1cblxuICBjb25zdCBvcmRlcjogQXJyYXk8c3RyaW5nPiA9IFtdXG4gIHdoaWxlIChxdWV1ZS5sZW5ndGgpIHtcbiAgICBjb25zdCBuID0gcXVldWUuc2hpZnQoKSFcbiAgICBvcmRlci5wdXNoKG4pXG4gICAgY29uc3Qgb3V0cyA9IGZvcndhcmQuZ2V0KG4pIVxuICAgIGZvciAoY29uc3QgdG8gb2Ygb3V0cykge1xuICAgICAgY29uc3QgbmV4dCA9IChpbmRlZ3JlZS5nZXQodG8pID8/IDApIC0gMVxuICAgICAgaW5kZWdyZWUuc2V0KHRvLCBuZXh0KVxuICAgICAgaWYgKG5leHQgPT09IDApIHF1ZXVlLnB1c2godG8pXG4gICAgfVxuICB9XG5cbiAgaWYgKG9yZGVyLmxlbmd0aCAhPT0gbm9kZXMuc2l6ZSkge1xuICAgIGNvbnN0IHJlbWFpbmluZyA9IEFycmF5LmZyb20obm9kZXMpLmZpbHRlcigobikgPT4gIW9yZGVyLmluY2x1ZGVzKG4pKVxuICAgIHJldHVybiB7XG4gICAgICBvcmRlcjogW10sXG4gICAgICBjb25maWdFcnJvcjoge1xuICAgICAgICBjb2RlOiAnQ1lDTEVfREVURUNURUQnLFxuICAgICAgICBtZXNzYWdlOiBgW1N0YXRlVHJhaXQuY29udmVyZ2VdIEN5Y2xlIGRldGVjdGVkIGluIGNvbXB1dGVkL2xpbmsgZ3JhcGg6ICR7cmVtYWluaW5nLmpvaW4oJywgJyl9YCxcbiAgICAgICAgZmllbGRzOiByZW1haW5pbmcsXG4gICAgICB9LFxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7IG9yZGVyIH1cbn1cblxuY29uc3QgY29sbGVjdFNjaGVtYUZpZWxkUGF0aHMgPSAoc2NoZW1hOiBTY2hlbWEuU2NoZW1hPGFueSwgYW55Pik6IFJlYWRvbmx5QXJyYXk8RmllbGRQYXRoPiA9PiB7XG4gIGNvbnN0IGJ5S2V5ID0gbmV3IE1hcDxzdHJpbmcsIEZpZWxkUGF0aD4oKVxuXG4gIGNvbnN0IGFkZCA9IChwYXRoOiBGaWVsZFBhdGgpOiB2b2lkID0+IHtcbiAgICBjb25zdCBub3JtYWxpemVkID0gbm9ybWFsaXplRmllbGRQYXRoKHBhdGgpXG4gICAgaWYgKCFub3JtYWxpemVkKSByZXR1cm5cbiAgICBieUtleS5zZXQoSlNPTi5zdHJpbmdpZnkobm9ybWFsaXplZCksIG5vcm1hbGl6ZWQpXG4gIH1cblxuICBjb25zdCB2aXNpdCA9IChhc3Q6IFNjaGVtYUFTVC5BU1QsIHByZWZpeDogUmVhZG9ubHlBcnJheTxzdHJpbmc+LCBzZWVuOiBTZXQ8U2NoZW1hQVNULkFTVD4pOiB2b2lkID0+IHtcbiAgICBsZXQgY3VycmVudDogU2NoZW1hQVNULkFTVCA9IGFzdFxuXG4gICAgLy8gVW53cmFwIFN1c3BlbmQvUmVmaW5lbWVudCAocmVjdXJzaXZlIHNjaGVtYSAvIGJyYW5kZWQgc2NoZW1hKS5cbiAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgaWYgKFNjaGVtYUFTVC5pc1N1c3BlbmQoY3VycmVudCkpIHtcbiAgICAgICAgaWYgKHNlZW4uaGFzKGN1cnJlbnQpKSByZXR1cm5cbiAgICAgICAgc2Vlbi5hZGQoY3VycmVudClcbiAgICAgICAgY3VycmVudCA9IGN1cnJlbnQuZigpXG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG4gICAgICBpZiAoU2NoZW1hQVNULmlzUmVmaW5lbWVudChjdXJyZW50KSkge1xuICAgICAgICBjdXJyZW50ID0gY3VycmVudC5mcm9tXG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG4gICAgICBicmVha1xuICAgIH1cblxuICAgIGlmIChTY2hlbWFBU1QuaXNUcmFuc2Zvcm1hdGlvbihjdXJyZW50KSkge1xuICAgICAgdmlzaXQoY3VycmVudC50bywgcHJlZml4LCBzZWVuKVxuICAgICAgdmlzaXQoY3VycmVudC5mcm9tLCBwcmVmaXgsIHNlZW4pXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBpZiAoU2NoZW1hQVNULmlzVW5pb24oY3VycmVudCkpIHtcbiAgICAgIGZvciAoY29uc3QgdCBvZiBjdXJyZW50LnR5cGVzKSB7XG4gICAgICAgIHZpc2l0KHQsIHByZWZpeCwgc2VlbilcbiAgICAgIH1cbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIC8vIEFycmF5IC8gVHVwbGU6IGluZGljZXMgZG8gbm90IGVudGVyIHRoZSBGaWVsZFBhdGhJZCBzcGFjZTsgcmVjdXJzZSBpbnRvIGVsZW1lbnQgdHlwZXMgdG8gc3VwcG9ydCBgaXRlbXNbMF0ubmFtZSAtPiBpdGVtcy5uYW1lYC5cbiAgICBpZiAoU2NoZW1hQVNULmlzVHVwbGVUeXBlKGN1cnJlbnQpKSB7XG4gICAgICBmb3IgKGNvbnN0IGUgb2YgY3VycmVudC5lbGVtZW50cykge1xuICAgICAgICB2aXNpdChlLnR5cGUsIHByZWZpeCwgc2VlbilcbiAgICAgIH1cbiAgICAgIGZvciAoY29uc3QgciBvZiBjdXJyZW50LnJlc3QpIHtcbiAgICAgICAgdmlzaXQoci50eXBlLCBwcmVmaXgsIHNlZW4pXG4gICAgICB9XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBpZiAoU2NoZW1hQVNULmlzVHlwZUxpdGVyYWwoY3VycmVudCkpIHtcbiAgICAgIGZvciAoY29uc3QgcHMgb2YgY3VycmVudC5wcm9wZXJ0eVNpZ25hdHVyZXMpIHtcbiAgICAgICAgY29uc3Qgc2VnID0gU3RyaW5nKHBzLm5hbWUpXG4gICAgICAgIGlmICghc2VnKSBjb250aW51ZVxuICAgICAgICBjb25zdCBuZXh0ID0gWy4uLnByZWZpeCwgc2VnXVxuICAgICAgICBhZGQobmV4dClcbiAgICAgICAgdmlzaXQocHMudHlwZSwgbmV4dCwgc2VlbilcbiAgICAgIH1cbiAgICAgIC8vIEluZGV4IHNpZ25hdHVyZSAoUmVjb3JkPHN0cmluZywgVD4pIGNhbid0IGJlIGVudW1lcmF0ZWQgc3RhdGljYWxseTogYXZvaWQgZ2VuZXJhdGluZyBtaXNhbGlnbmVkIGR5bmFtaWMga2V5IHBhdGhzLlxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgLy8gQW55IC8gVW5rbm93biAvIE9iamVjdCAvIERlY2xhcmF0aW9uIChvcGVuIHR5cGVzKTogY2Fubm90IGVudW1lcmF0ZSBuZXN0ZWQgcGF0aHM7IHN0b3AgY29uc2VydmF0aXZlbHkuXG4gIH1cblxuICB2aXNpdChzY2hlbWEuYXN0IGFzIHVua25vd24gYXMgU2NoZW1hQVNULkFTVCwgW10sIG5ldyBTZXQoKSlcbiAgcmV0dXJuIEFycmF5LmZyb20oYnlLZXkudmFsdWVzKCkpLnNvcnQoY29tcGFyZUZpZWxkUGF0aClcbn1cblxuY29uc3QgYnVpbGRDb252ZXJnZUlyID0gKFxuICBzdGF0ZVNjaGVtYTogU2NoZW1hLlNjaGVtYTxhbnksIGFueT4sXG4gIGVudHJpZXM6IFJlYWRvbmx5QXJyYXk8U3RhdGVUcmFpdEVudHJ5PGFueSwgc3RyaW5nPj4sXG4pOiBDb252ZXJnZVN0YXRpY0lyUmVnaXN0cnkgPT4ge1xuICBjb25zdCBzdGFydGVkQXQgPSBub3dQZXJmKClcbiAgY29uc3QgZ2VuZXJhdGlvbiA9IDBcblxuICBjb25zdCB3cml0ZXJzID0gZW50cmllcy5maWx0ZXIoKGUpOiBlIGlzIENvbnZlcmdlV3JpdGVyID0+IGUua2luZCA9PT0gJ2NvbXB1dGVkJyB8fCBlLmtpbmQgPT09ICdsaW5rJylcblxuICBjb25zdCB3cml0ZXJzS2V5ID0gd3JpdGVyc1xuICAgIC5tYXAoKGVudHJ5KSA9PiBgJHtlbnRyeS5raW5kfToke2VudHJ5LmZpZWxkUGF0aH1gKVxuICAgIC5zb3J0KClcbiAgICAuam9pbignfCcpXG5cbiAgY29uc3QgZGVwc0tleSA9IHdyaXRlcnNcbiAgICAubWFwKChlbnRyeSkgPT4ge1xuICAgICAgY29uc3QgZGVwcyA9IGdldENvbnZlcmdlV3JpdGVyRGVwcyhlbnRyeSkuc2xpY2UoKS5zb3J0KCkuam9pbignLCcpXG4gICAgICBjb25zdCBzY2hlZHVsaW5nID0gKGVudHJ5Lm1ldGEgYXMgYW55KT8uc2NoZWR1bGluZyA9PT0gJ2RlZmVycmVkJyA/ICdkJyA6ICdpJ1xuICAgICAgcmV0dXJuIGAke2VudHJ5LmtpbmR9OiR7ZW50cnkuZmllbGRQYXRofUAke3NjaGVkdWxpbmd9PT4ke2RlcHN9YFxuICAgIH0pXG4gICAgLnNvcnQoKVxuICAgIC5qb2luKCd8JylcblxuICBjb25zdCB3cml0ZXJCeVBhdGggPSBuZXcgTWFwPHN0cmluZywgQ29udmVyZ2VXcml0ZXI+KClcbiAgZm9yIChjb25zdCBlbnRyeSBvZiB3cml0ZXJzKSB7XG4gICAgd3JpdGVyQnlQYXRoLnNldChlbnRyeS5maWVsZFBhdGgsIGVudHJ5KVxuICB9XG5cbiAgY29uc3QgdG9wbyA9IHdyaXRlcnMubGVuZ3RoID4gMCA/IGNvbXB1dGVDb252ZXJnZVRvcG9PcmRlcih3cml0ZXJzKSA6IHsgb3JkZXI6IFtdIGFzIFJlYWRvbmx5QXJyYXk8c3RyaW5nPiB9XG4gIGNvbnN0IHN0ZXBzQnlJZDogQXJyYXk8Q29udmVyZ2VXcml0ZXI+ID0gdG9wby5jb25maWdFcnJvciA/IFtdIDogdG9wby5vcmRlci5tYXAoKHBhdGgpID0+IHdyaXRlckJ5UGF0aC5nZXQocGF0aCkhKVxuXG4gIGNvbnN0IGZpZWxkUGF0aFRhYmxlID0gbmV3IE1hcDxzdHJpbmcsIEZpZWxkUGF0aD4oKVxuICBjb25zdCBhZGRQYXRoID0gKHBhdGg6IEZpZWxkUGF0aCk6IHZvaWQgPT4ge1xuICAgIGZvciAobGV0IGkgPSAxOyBpIDw9IHBhdGgubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IHByZWZpeCA9IHBhdGguc2xpY2UoMCwgaSlcbiAgICAgIGNvbnN0IGtleSA9IEpTT04uc3RyaW5naWZ5KHByZWZpeClcbiAgICAgIGlmICghZmllbGRQYXRoVGFibGUuaGFzKGtleSkpIGZpZWxkUGF0aFRhYmxlLnNldChrZXksIHByZWZpeClcbiAgICB9XG4gIH1cblxuICAvLyAwNjU6IEZpZWxkUGF0aElkIHNlbWFudGljcyBtdXN0IGNvdmVyIGFsbCBlbnVtZXJhYmxlIGZpZWxkIHBhdGhzIG9mIHN0YXRlU2NoZW1hOyBvdGhlcndpc2UgcmVkdWNlciBwYXRjaFBhdGhzIGNhbid0IG1hcCBhbmQgd2lsbCBmYWxsIGJhY2sgdG8gZGlydHlBbGwuXG4gIGZvciAoY29uc3Qgc2NoZW1hUGF0aCBvZiBjb2xsZWN0U2NoZW1hRmllbGRQYXRocyhzdGF0ZVNjaGVtYSkpIHtcbiAgICBhZGRQYXRoKHNjaGVtYVBhdGgpXG4gIH1cblxuICBmb3IgKGNvbnN0IGVudHJ5IG9mIHdyaXRlcnMpIHtcbiAgICBjb25zdCBvdXQgPSBub3JtYWxpemVGaWVsZFBhdGgoZW50cnkuZmllbGRQYXRoKVxuICAgIGlmIChvdXQpIGFkZFBhdGgob3V0KVxuICAgIGZvciAoY29uc3QgZGVwIG9mIGdldENvbnZlcmdlV3JpdGVyRGVwcyhlbnRyeSkpIHtcbiAgICAgIGNvbnN0IGRlcFBhdGggPSBub3JtYWxpemVGaWVsZFBhdGgoZGVwKVxuICAgICAgaWYgKGRlcFBhdGgpIGFkZFBhdGgoZGVwUGF0aClcbiAgICB9XG4gIH1cblxuICBjb25zdCBmaWVsZFBhdGhzID0gQXJyYXkuZnJvbShmaWVsZFBhdGhUYWJsZS52YWx1ZXMoKSkuc29ydChjb21wYXJlRmllbGRQYXRoKVxuICBjb25zdCBmaWVsZFBhdGhJZFJlZ2lzdHJ5ID0gbWFrZUZpZWxkUGF0aElkUmVnaXN0cnkoZmllbGRQYXRocylcbiAgY29uc3QgZmllbGRQYXRoc0tleSA9IGZudjFhMzIoc3RhYmxlU3RyaW5naWZ5KGZpZWxkUGF0aHMpKVxuXG4gIGNvbnN0IHN0ZXBPdXRGaWVsZFBhdGhJZEJ5U3RlcElkOiBBcnJheTxGaWVsZFBhdGhJZD4gPSBbXVxuICBjb25zdCBzdGVwRGVwc0ZpZWxkUGF0aElkc0J5U3RlcElkOiBBcnJheTxSZWFkb25seUFycmF5PEZpZWxkUGF0aElkPj4gPSBbXVxuICBjb25zdCBzdGVwU2NoZWR1bGluZ0J5U3RlcElkOiBBcnJheTwnaW1tZWRpYXRlJyB8ICdkZWZlcnJlZCc+ID0gW11cblxuICBmb3IgKGNvbnN0IGVudHJ5IG9mIHN0ZXBzQnlJZCkge1xuICAgIGNvbnN0IG91dCA9IG5vcm1hbGl6ZUZpZWxkUGF0aChlbnRyeS5maWVsZFBhdGgpXG4gICAgY29uc3Qgb3V0SWQgPSBvdXQgIT0gbnVsbCA/IGdldEZpZWxkUGF0aElkKGZpZWxkUGF0aElkUmVnaXN0cnksIG91dCkgOiB1bmRlZmluZWRcbiAgICBpZiAob3V0SWQgPT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBbU3RhdGVUcmFpdC5idWlsZF0gRmFpbGVkIHRvIG1hcCBjb252ZXJnZSBvdXRwdXQgZmllbGRQYXRoIFwiJHtlbnRyeS5maWVsZFBhdGh9XCIgdG8gRmllbGRQYXRoSWQuYClcbiAgICB9XG5cbiAgICBjb25zdCBkZXBJZHM6IEFycmF5PEZpZWxkUGF0aElkPiA9IFtdXG4gICAgZm9yIChjb25zdCBkZXAgb2YgZ2V0Q29udmVyZ2VXcml0ZXJEZXBzKGVudHJ5KSkge1xuICAgICAgY29uc3QgZGVwUGF0aCA9IG5vcm1hbGl6ZUZpZWxkUGF0aChkZXApXG4gICAgICBpZiAoIWRlcFBhdGgpIGNvbnRpbnVlXG4gICAgICBjb25zdCBkZXBJZCA9IGdldEZpZWxkUGF0aElkKGZpZWxkUGF0aElkUmVnaXN0cnksIGRlcFBhdGgpXG4gICAgICBpZiAoZGVwSWQgIT0gbnVsbCkgZGVwSWRzLnB1c2goZGVwSWQpXG4gICAgfVxuXG4gICAgc3RlcE91dEZpZWxkUGF0aElkQnlTdGVwSWQucHVzaChvdXRJZClcbiAgICBzdGVwRGVwc0ZpZWxkUGF0aElkc0J5U3RlcElkLnB1c2goZGVwSWRzKVxuICAgIHN0ZXBTY2hlZHVsaW5nQnlTdGVwSWQucHVzaCgoZW50cnkubWV0YSBhcyBhbnkpPy5zY2hlZHVsaW5nID09PSAnZGVmZXJyZWQnID8gJ2RlZmVycmVkJyA6ICdpbW1lZGlhdGUnKVxuICB9XG5cbiAgY29uc3QgdG9wb09yZGVyID0gc3RlcHNCeUlkLm1hcCgoXywgaSkgPT4gaSlcbiAgY29uc3QgYnVpbGREdXJhdGlvbk1zID0gTWF0aC5tYXgoMCwgbm93UGVyZigpIC0gc3RhcnRlZEF0KVxuXG4gIHJldHVybiB7XG4gICAgZ2VuZXJhdGlvbixcbiAgICB3cml0ZXJzS2V5LFxuICAgIGRlcHNLZXksXG4gICAgZmllbGRQYXRoc0tleSxcbiAgICBmaWVsZFBhdGhzLFxuICAgIGZpZWxkUGF0aElkUmVnaXN0cnksXG4gICAgLi4uKHRvcG8uY29uZmlnRXJyb3IgPyB7IGNvbmZpZ0Vycm9yOiB0b3BvLmNvbmZpZ0Vycm9yIH0gOiBudWxsKSxcbiAgICBzdGVwc0J5SWQsXG4gICAgc3RlcE91dEZpZWxkUGF0aElkQnlTdGVwSWQsXG4gICAgc3RlcERlcHNGaWVsZFBhdGhJZHNCeVN0ZXBJZCxcbiAgICBzdGVwU2NoZWR1bGluZ0J5U3RlcElkLFxuICAgIHRvcG9PcmRlcixcbiAgICBidWlsZER1cmF0aW9uTXMsXG4gIH1cbn1cblxuLyoqXG4gKiBCdWlsZHMgYSBub3JtYWxpemVkIEZpZWxkVHJhaXQgZnJvbSBhIFN0YXRlVHJhaXRFbnRyeS5cbiAqXG4gKiAtIEN1cnJlbnRseSB1c2VzIGV4cGxpY2l0IGRlcHMgZm9yIGNvbXB1dGVkL3NvdXJjZSBhbmQgbGluayBlZGdlczsgZGVlcGVyIGRlcGVuZGVuY3kgYW5hbHlzaXMgaXMgaW50ZW50aW9uYWxseSBub3QgcGVyZm9ybWVkLlxuICogLSBJZiB3ZSBldm9sdmUgZXhwbGljaXQgZGVwZW5kZW5jeSBkZWNsYXJhdGlvbnMgZnVydGhlciwgZXh0ZW5kIGhlcmUuXG4gKi9cbmNvbnN0IHRvRmllbGRUcmFpdCA9IChlbnRyeTogU3RhdGVUcmFpdEVudHJ5PGFueSwgc3RyaW5nPik6IFN0YXRlVHJhaXRGaWVsZFRyYWl0ID0+IHtcbiAgY29uc3QgZGVwczogQXJyYXk8c3RyaW5nPiA9IFtdXG5cbiAgaWYgKGVudHJ5LmtpbmQgPT09ICdjb21wdXRlZCcpIHtcbiAgICBjb25zdCBtZXRhID0gZW50cnkubWV0YSBhcyBhbnlcbiAgICBjb25zdCBsaXN0ID0gbWV0YS5kZXBzIGFzIFJlYWRvbmx5QXJyYXk8c3RyaW5nPiB8IHVuZGVmaW5lZFxuICAgIGlmIChsaXN0KSBkZXBzLnB1c2goLi4ubGlzdClcbiAgfSBlbHNlIGlmIChlbnRyeS5raW5kID09PSAnc291cmNlJykge1xuICAgIGNvbnN0IG1ldGEgPSBlbnRyeS5tZXRhIGFzIGFueVxuICAgIGNvbnN0IGxpc3QgPSBtZXRhLmRlcHMgYXMgUmVhZG9ubHlBcnJheTxzdHJpbmc+IHwgdW5kZWZpbmVkXG4gICAgaWYgKGxpc3QpIGRlcHMucHVzaCguLi5saXN0KVxuICB9IGVsc2UgaWYgKGVudHJ5LmtpbmQgPT09ICdsaW5rJykge1xuICAgIGRlcHMucHVzaChlbnRyeS5tZXRhLmZyb20gYXMgc3RyaW5nKVxuICB9IGVsc2UgaWYgKGVudHJ5LmtpbmQgPT09ICdjaGVjaycpIHtcbiAgICBjb25zdCBtZXRhID0gZW50cnkubWV0YSBhcyBhbnlcbiAgICBjb25zdCBydWxlcyA9IChtZXRhPy5ydWxlcyA/PyB7fSkgYXMgUmVjb3JkPHN0cmluZywgYW55PlxuICAgIGZvciAoY29uc3QgbmFtZSBvZiBPYmplY3Qua2V5cyhydWxlcykpIHtcbiAgICAgIGNvbnN0IHJ1bGUgPSBydWxlc1tuYW1lXVxuICAgICAgaWYgKHJ1bGUgJiYgdHlwZW9mIHJ1bGUgPT09ICdvYmplY3QnKSB7XG4gICAgICAgIGNvbnN0IGxpc3QgPSBydWxlLmRlcHMgYXMgUmVhZG9ubHlBcnJheTxzdHJpbmc+IHwgdW5kZWZpbmVkXG4gICAgICAgIGlmIChsaXN0KSBkZXBzLnB1c2goLi4ubGlzdClcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4ge1xuICAgIGZpZWxkSWQ6IGVudHJ5LmZpZWxkUGF0aCxcbiAgICBraW5kOiBlbnRyeS5raW5kLFxuICAgIC8vIEtlZXAgbWV0YSBpZGVudGljYWwgdG8gRW50cnkubWV0YSBhdCBydW50aW1lIHNvIGluc3RhbGwgY2FuIHJldXNlIGl0IGRpcmVjdGx5LlxuICAgIG1ldGE6IGVudHJ5Lm1ldGEgYXMgYW55LFxuICAgIGRlcHMsXG4gIH1cbn1cblxuLyoqXG4gKiBCdWlsZHMgRmllbGQgLyBOb2RlIC8gRWRnZSAvIFJlc291cmNlIHNldHMgZnJvbSBub3JtYWxpemVkIGVudHJpZXMuXG4gKi9cbmNvbnN0IGJ1aWxkR3JhcGggPSAoXG4gIGVudHJpZXM6IFJlYWRvbmx5QXJyYXk8U3RhdGVUcmFpdEVudHJ5PGFueSwgc3RyaW5nPj4sXG4gIG5vZGVNZXRhQnlGaWVsZFBhdGg6IFJlYWRvbmx5TWFwPHN0cmluZywgTWV0YS5UcmFpdE1ldGE+LFxuKToge1xuICByZWFkb25seSBncmFwaDogU3RhdGVUcmFpdEdyYXBoXG4gIHJlYWRvbmx5IHBsYW46IFN0YXRlVHJhaXRQbGFuXG59ID0+IHtcbiAgY29uc3QgZmllbGRNYXAgPSBuZXcgTWFwPHN0cmluZywgU3RhdGVUcmFpdEZpZWxkPigpXG4gIGNvbnN0IG5vZGVzOiBBcnJheTxTdGF0ZVRyYWl0R3JhcGhOb2RlPiA9IFtdXG4gIGNvbnN0IGVkZ2VzOiBBcnJheTxTdGF0ZVRyYWl0R3JhcGhFZGdlPiA9IFtdXG4gIGNvbnN0IHJlc291cmNlc0J5SWQgPSBuZXcgTWFwPHN0cmluZywgU3RhdGVUcmFpdFJlc291cmNlPigpXG4gIGNvbnN0IHBsYW5TdGVwczogQXJyYXk8U3RhdGVUcmFpdFBsYW5TdGVwPiA9IFtdXG5cbiAgY29uc3QgZW5zdXJlRmllbGQgPSAoZmllbGRQYXRoOiBzdHJpbmcpOiBTdGF0ZVRyYWl0RmllbGQgPT4ge1xuICAgIGxldCBmaWVsZCA9IGZpZWxkTWFwLmdldChmaWVsZFBhdGgpXG4gICAgaWYgKCFmaWVsZCkge1xuICAgICAgZmllbGQgPSB7XG4gICAgICAgIGlkOiBmaWVsZFBhdGgsXG4gICAgICAgIHBhdGg6IGZpZWxkUGF0aCxcbiAgICAgICAgdHJhaXRzOiBbXSxcbiAgICAgIH1cbiAgICAgIGZpZWxkTWFwLnNldChmaWVsZFBhdGgsIGZpZWxkKVxuICAgIH1cbiAgICByZXR1cm4gZmllbGRcbiAgfVxuXG4gIGZvciAoY29uc3QgZW50cnkgb2YgZW50cmllcykge1xuICAgIGNvbnN0IGZpZWxkUGF0aCA9IGVudHJ5LmZpZWxkUGF0aFxuICAgIGNvbnN0IGZpZWxkID0gZW5zdXJlRmllbGQoZmllbGRQYXRoKVxuICAgIGNvbnN0IHRyYWl0ID0gdG9GaWVsZFRyYWl0KGVudHJ5KVxuXG4gICAgOyhmaWVsZC50cmFpdHMgYXMgQXJyYXk8U3RhdGVUcmFpdEZpZWxkVHJhaXQ+KS5wdXNoKHRyYWl0KVxuXG4gICAgLy8gQnVpbGQgR3JhcGggZWRnZXMgYW5kIFBsYW4gc3RlcHMgYnkga2luZC5cbiAgICBpZiAoZW50cnkua2luZCA9PT0gJ2NvbXB1dGVkJykge1xuICAgICAgY29uc3Qgc3RlcElkID0gYGNvbXB1dGVkOiR7ZmllbGRQYXRofWBcbiAgICAgIHBsYW5TdGVwcy5wdXNoKHtcbiAgICAgICAgaWQ6IHN0ZXBJZCxcbiAgICAgICAga2luZDogJ2NvbXB1dGVkLXVwZGF0ZScsXG4gICAgICAgIHRhcmdldEZpZWxkUGF0aDogZmllbGRQYXRoLFxuICAgICAgICAvLyBOb3RlOiB0aGUgY3VycmVudCB2ZXJzaW9uIGRvZXMgbm90IHN0YXRpY2FsbHkgYW5hbHl6ZSBjb21wdXRlZCBkZXBlbmRlbmNpZXM7IHNvdXJjZUZpZWxkUGF0aHMgcmVtYWlucyBlbXB0eS5cbiAgICAgIH0pXG4gICAgICAvLyBJZiBkZXBzIGlzIGV4cGxpY2l0bHkgZGVjbGFyZWQsIGFkZCBHcmFwaCBlZGdlcyAoZm9yIGRpYWdub3N0aWNzIC8gcmV2ZXJzZS1jbG9zdXJlIGNvbXB1dGF0aW9uKS5cbiAgICAgIGNvbnN0IGRlcHMgPSAoZW50cnkubWV0YSBhcyBhbnkpLmRlcHMgYXMgUmVhZG9ubHlBcnJheTxzdHJpbmc+IHwgdW5kZWZpbmVkXG4gICAgICBpZiAoZGVwcykge1xuICAgICAgICBmb3IgKGNvbnN0IGRlcCBvZiBkZXBzKSB7XG4gICAgICAgICAgZW5zdXJlRmllbGQoZGVwKVxuICAgICAgICAgIGVkZ2VzLnB1c2goe1xuICAgICAgICAgICAgaWQ6IGBjb21wdXRlZDoke2RlcH0tPiR7ZmllbGRQYXRofWAsXG4gICAgICAgICAgICBmcm9tOiBkZXAsXG4gICAgICAgICAgICB0bzogZmllbGRQYXRoLFxuICAgICAgICAgICAga2luZDogJ2NvbXB1dGVkJyxcbiAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChlbnRyeS5raW5kID09PSAnbGluaycpIHtcbiAgICAgIGNvbnN0IGZyb20gPSBlbnRyeS5tZXRhLmZyb20gYXMgc3RyaW5nXG4gICAgICBlbnN1cmVGaWVsZChmcm9tKVxuXG4gICAgICBjb25zdCBlZGdlSWQgPSBgbGluazoke2Zyb219LT4ke2ZpZWxkUGF0aH1gXG4gICAgICBlZGdlcy5wdXNoKHtcbiAgICAgICAgaWQ6IGVkZ2VJZCxcbiAgICAgICAgZnJvbSxcbiAgICAgICAgdG86IGZpZWxkUGF0aCxcbiAgICAgICAga2luZDogJ2xpbmsnLFxuICAgICAgfSlcblxuICAgICAgcGxhblN0ZXBzLnB1c2goe1xuICAgICAgICBpZDogYGxpbms6JHtmaWVsZFBhdGh9YCxcbiAgICAgICAga2luZDogJ2xpbmstcHJvcGFnYXRlJyxcbiAgICAgICAgdGFyZ2V0RmllbGRQYXRoOiBmaWVsZFBhdGgsXG4gICAgICAgIHNvdXJjZUZpZWxkUGF0aHM6IFtmcm9tXSxcbiAgICAgICAgZGVidWdJbmZvOiB7XG4gICAgICAgICAgZ3JhcGhFZGdlSWQ6IGVkZ2VJZCxcbiAgICAgICAgfSxcbiAgICAgIH0pXG4gICAgfSBlbHNlIGlmIChlbnRyeS5raW5kID09PSAnc291cmNlJykge1xuICAgICAgY29uc3QgcmVzb3VyY2VJZCA9IGVudHJ5Lm1ldGEucmVzb3VyY2VcbiAgICAgIGNvbnN0IHJlc291cmNlTWV0YSA9IE1ldGEuc2FuaXRpemUoKGVudHJ5Lm1ldGEgYXMgYW55KS5tZXRhKVxuXG4gICAgICBjb25zdCBleGlzdGluZyA9IHJlc291cmNlc0J5SWQuZ2V0KHJlc291cmNlSWQpXG4gICAgICBpZiAoZXhpc3RpbmcpIHtcbiAgICAgICAgY29uc3Qgb3duZXJGaWVsZHMgPSBbLi4uZXhpc3Rpbmcub3duZXJGaWVsZHMsIGZpZWxkUGF0aF1cbiAgICAgICAgbGV0IG1ldGEgPSBleGlzdGluZy5tZXRhXG4gICAgICAgIGxldCBtZXRhT3JpZ2luID0gZXhpc3RpbmcubWV0YU9yaWdpblxuICAgICAgICBsZXQgbWV0YUNvbmZsaWN0cyA9IGV4aXN0aW5nLm1ldGFDb25mbGljdHNcblxuICAgICAgICBpZiAocmVzb3VyY2VNZXRhKSB7XG4gICAgICAgICAgY29uc3QgbWVyZ2VkID0gTWV0YS5tZXJnZUNhbm9uaWNhbChcbiAgICAgICAgICAgIHsgbWV0YSwgb3JpZ2luOiBtZXRhT3JpZ2luLCBjb25mbGljdHM6IG1ldGFDb25mbGljdHMgfSxcbiAgICAgICAgICAgIHsgb3JpZ2luOiBmaWVsZFBhdGgsIG1ldGE6IHJlc291cmNlTWV0YSB9LFxuICAgICAgICAgIClcbiAgICAgICAgICBtZXRhID0gbWVyZ2VkLm1ldGFcbiAgICAgICAgICBtZXRhT3JpZ2luID0gbWVyZ2VkLm9yaWdpblxuICAgICAgICAgIG1ldGFDb25mbGljdHMgPSBtZXJnZWQuY29uZmxpY3RzXG4gICAgICAgIH1cblxuICAgICAgICByZXNvdXJjZXNCeUlkLnNldChyZXNvdXJjZUlkLCB7XG4gICAgICAgICAgLi4uZXhpc3RpbmcsXG4gICAgICAgICAgb3duZXJGaWVsZHMsXG4gICAgICAgICAgbWV0YSxcbiAgICAgICAgICBtZXRhT3JpZ2luLFxuICAgICAgICAgIG1ldGFDb25mbGljdHMsXG4gICAgICAgIH0pXG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXNvdXJjZXNCeUlkLnNldChyZXNvdXJjZUlkLCB7XG4gICAgICAgICAgcmVzb3VyY2VJZCxcbiAgICAgICAgICAvLyBVc2UgYSBzaW1wbGUgaWRlbnRpZmllciBzdHJpbmcgZm9yIG5vdzsgbWF5IGV2b2x2ZSBpbnRvIGEgc3RydWN0dXJlZCBmb3JtIGJhc2VkIG9uIGtleSBydWxlcy5cbiAgICAgICAgICBrZXlTZWxlY3RvcjogYFN0YXRlVHJhaXQuc291cmNlQCR7ZmllbGRQYXRofWAsXG4gICAgICAgICAgb3duZXJGaWVsZHM6IFtmaWVsZFBhdGhdLFxuICAgICAgICAgIG1ldGE6IHJlc291cmNlTWV0YSxcbiAgICAgICAgICBtZXRhT3JpZ2luOiByZXNvdXJjZU1ldGEgPyBmaWVsZFBhdGggOiB1bmRlZmluZWQsXG4gICAgICAgIH0pXG4gICAgICB9XG5cbiAgICAgIHBsYW5TdGVwcy5wdXNoKHtcbiAgICAgICAgaWQ6IGBzb3VyY2U6JHtmaWVsZFBhdGh9YCxcbiAgICAgICAga2luZDogJ3NvdXJjZS1yZWZyZXNoJyxcbiAgICAgICAgdGFyZ2V0RmllbGRQYXRoOiBmaWVsZFBhdGgsXG4gICAgICAgIHJlc291cmNlSWQsXG4gICAgICAgIGtleVNlbGVjdG9ySWQ6IGBTdGF0ZVRyYWl0LnNvdXJjZUAke2ZpZWxkUGF0aH1gLFxuICAgICAgfSlcblxuICAgICAgY29uc3QgZGVwcyA9IChlbnRyeS5tZXRhIGFzIGFueSkuZGVwcyBhcyBSZWFkb25seUFycmF5PHN0cmluZz4gfCB1bmRlZmluZWRcbiAgICAgIGlmIChkZXBzKSB7XG4gICAgICAgIGZvciAoY29uc3QgZGVwIG9mIGRlcHMpIHtcbiAgICAgICAgICBlbnN1cmVGaWVsZChkZXApXG4gICAgICAgICAgZWRnZXMucHVzaCh7XG4gICAgICAgICAgICBpZDogYHNvdXJjZS1kZXA6JHtkZXB9LT4ke2ZpZWxkUGF0aH1gLFxuICAgICAgICAgICAgZnJvbTogZGVwLFxuICAgICAgICAgICAgdG86IGZpZWxkUGF0aCxcbiAgICAgICAgICAgIGtpbmQ6ICdzb3VyY2UtZGVwJyxcbiAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChlbnRyeS5raW5kID09PSAnY2hlY2snKSB7XG4gICAgICBwbGFuU3RlcHMucHVzaCh7XG4gICAgICAgIGlkOiBgY2hlY2s6JHtmaWVsZFBhdGh9YCxcbiAgICAgICAga2luZDogJ2NoZWNrLXZhbGlkYXRlJyxcbiAgICAgICAgdGFyZ2V0RmllbGRQYXRoOiBmaWVsZFBhdGgsXG4gICAgICB9KVxuXG4gICAgICAvLyBJZiB0aGUgcnVsZSBleHBsaWNpdGx5IGRlY2xhcmVzIGRlcHMsIGFkZCBHcmFwaCBlZGdlcyAoZm9yIFJldmVyc2VDbG9zdXJlIHNjb3BlZCB2YWxpZGF0ZSkuXG4gICAgICBpZiAodHJhaXQuZGVwcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGZvciAoY29uc3QgZGVwIG9mIHRyYWl0LmRlcHMpIHtcbiAgICAgICAgICBlbnN1cmVGaWVsZChkZXApXG4gICAgICAgICAgZWRnZXMucHVzaCh7XG4gICAgICAgICAgICBpZDogYGNoZWNrLWRlcDoke2RlcH0tPiR7ZmllbGRQYXRofWAsXG4gICAgICAgICAgICBmcm9tOiBkZXAsXG4gICAgICAgICAgICB0bzogZmllbGRQYXRoLFxuICAgICAgICAgICAga2luZDogJ2NoZWNrLWRlcCcsXG4gICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGZvciAoY29uc3QgZmllbGQgb2YgZmllbGRNYXAudmFsdWVzKCkpIHtcbiAgICBub2Rlcy5wdXNoKHtcbiAgICAgIGlkOiBmaWVsZC5pZCxcbiAgICAgIGZpZWxkLFxuICAgICAgdHJhaXRzOiBmaWVsZC50cmFpdHMsXG4gICAgICBtZXRhOiBub2RlTWV0YUJ5RmllbGRQYXRoLmdldChmaWVsZC5pZCksXG4gICAgfSlcbiAgfVxuXG4gIGNvbnN0IGdyYXBoOiBTdGF0ZVRyYWl0R3JhcGggPSB7XG4gICAgX3RhZzogJ1N0YXRlVHJhaXRHcmFwaCcsXG4gICAgbm9kZXMsXG4gICAgZWRnZXMsXG4gICAgcmVzb3VyY2VzOiBBcnJheS5mcm9tKHJlc291cmNlc0J5SWQudmFsdWVzKCkpLFxuICB9XG5cbiAgY29uc3QgcGxhbjogU3RhdGVUcmFpdFBsYW4gPSB7XG4gICAgX3RhZzogJ1N0YXRlVHJhaXRQbGFuJyxcbiAgICBzdGVwczogcGxhblN0ZXBzLFxuICB9XG5cbiAgcmV0dXJuIHsgZ3JhcGgsIHBsYW4gfVxufVxuXG4vKipcbiAqIFBlcmZvcm1zIGEgc2ltcGxlIGN5Y2xlIGRldGVjdGlvbiBmb3IgbGluayBlZGdlcy5cbiAqXG4gKiAtIE9ubHkgY29uc2lkZXJzIGVkZ2VzIHdpdGgga2luZCA9ICdsaW5rJzsgY29tcHV0ZWQvc291cmNlIGRvIG5vdCBwYXJ0aWNpcGF0ZSBpbiB0aGUgZmlyc3QgdmVyc2lvbi5cbiAqIC0gT24gY3ljbGUgZGV0ZWN0aW9uLCB0aHJvd3MgYW4gZXJyb3Igd2l0aCBwYXRoIGNvbnRleHQgdG8gYXZvaWQgaW5maW5pdGUgdXBkYXRlcyBhdCBydW50aW1lLlxuICovXG5jb25zdCBhc3NlcnROb0xpbmtDeWNsZXMgPSAoZWRnZXM6IFJlYWRvbmx5QXJyYXk8U3RhdGVUcmFpdEdyYXBoRWRnZT4pOiB2b2lkID0+IHtcbiAgY29uc3QgYWRqYWNlbmN5ID0gbmV3IE1hcDxzdHJpbmcsIHN0cmluZ1tdPigpXG5cbiAgZm9yIChjb25zdCBlZGdlIG9mIGVkZ2VzKSB7XG4gICAgaWYgKGVkZ2Uua2luZCAhPT0gJ2xpbmsnKSBjb250aW51ZVxuICAgIGNvbnN0IGxpc3QgPSBhZGphY2VuY3kuZ2V0KGVkZ2UuZnJvbSkgPz8gW11cbiAgICBsaXN0LnB1c2goZWRnZS50bylcbiAgICBhZGphY2VuY3kuc2V0KGVkZ2UuZnJvbSwgbGlzdClcbiAgfVxuXG4gIGNvbnN0IHZpc2l0ZWQgPSBuZXcgU2V0PHN0cmluZz4oKVxuICBjb25zdCBzdGFjayA9IG5ldyBTZXQ8c3RyaW5nPigpXG5cbiAgY29uc3QgZGZzID0gKG5vZGU6IHN0cmluZyk6IHZvaWQgPT4ge1xuICAgIGlmIChzdGFjay5oYXMobm9kZSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYFtTdGF0ZVRyYWl0LmJ1aWxkXSBsaW5rIGN5Y2xlIGRldGVjdGVkIGF0IGZpZWxkIFwiJHtub2RlfVwiLiBgICtcbiAgICAgICAgICAnUGxlYXNlIGNoZWNrIGxpbmsgdHJhaXRzIGZvciBjaXJjdWxhciBkZXBlbmRlbmNpZXMuJyxcbiAgICAgIClcbiAgICB9XG4gICAgaWYgKHZpc2l0ZWQuaGFzKG5vZGUpKSByZXR1cm5cbiAgICB2aXNpdGVkLmFkZChub2RlKVxuICAgIHN0YWNrLmFkZChub2RlKVxuXG4gICAgY29uc3QgbmV4dHMgPSBhZGphY2VuY3kuZ2V0KG5vZGUpXG4gICAgaWYgKG5leHRzKSB7XG4gICAgICBmb3IgKGNvbnN0IHRvIG9mIG5leHRzKSB7XG4gICAgICAgIGRmcyh0bylcbiAgICAgIH1cbiAgICB9XG5cbiAgICBzdGFjay5kZWxldGUobm9kZSlcbiAgfVxuXG4gIGZvciAoY29uc3Qgbm9kZSBvZiBhZGphY2VuY3kua2V5cygpKSB7XG4gICAgaWYgKCF2aXNpdGVkLmhhcyhub2RlKSkge1xuICAgICAgZGZzKG5vZGUpXG4gICAgfVxuICB9XG59XG5cbmNvbnN0IGNvbGxlY3RTY2hlbWFQYXRocyA9IChcbiAgZW50cmllczogUmVhZG9ubHlBcnJheTxTdGF0ZVRyYWl0RW50cnk8YW55LCBzdHJpbmc+Pixcbik6IFJlYWRvbmx5QXJyYXk8U3RhdGVUcmFpdFNjaGVtYVBhdGhSZWY+ID0+IHtcbiAgY29uc3QgYnlLZXkgPSBuZXcgTWFwPHN0cmluZywgU3RhdGVUcmFpdFNjaGVtYVBhdGhSZWY+KClcblxuICBjb25zdCBhZGQgPSAocmVmOiBTdGF0ZVRyYWl0U2NoZW1hUGF0aFJlZik6IHZvaWQgPT4ge1xuICAgIGlmICghcmVmLnBhdGgpIHJldHVyblxuICAgIGNvbnN0IGsgPSBgJHtyZWYua2luZH18JHtyZWYuZW50cnlLaW5kfXwke3JlZi5lbnRyeUZpZWxkUGF0aH18JHtyZWYucnVsZU5hbWUgPz8gJyd9fCR7cmVmLnBhdGh9YFxuICAgIGJ5S2V5LnNldChrLCByZWYpXG4gIH1cblxuICBjb25zdCBnZXRDaGVja1dyaXRlYmFja1BhdGggPSAoZW50cnk6IEV4dHJhY3Q8U3RhdGVUcmFpdEVudHJ5PGFueSwgc3RyaW5nPiwgeyByZWFkb25seSBraW5kOiAnY2hlY2snIH0+KTogc3RyaW5nID0+IHtcbiAgICBjb25zdCB3YiA9IChlbnRyeS5tZXRhIGFzIGFueSk/LndyaXRlYmFja1xuICAgIGNvbnN0IHAgPSB3YiAmJiB0eXBlb2Ygd2IgPT09ICdvYmplY3QnID8gKHdiIGFzIGFueSkucGF0aCA6IHVuZGVmaW5lZFxuICAgIGNvbnN0IHdyaXRlYmFja1BhdGggPSB0eXBlb2YgcCA9PT0gJ3N0cmluZycgJiYgcC5zdGFydHNXaXRoKCdlcnJvcnMuJykgPyBwIDogdW5kZWZpbmVkXG5cbiAgICBpZiAod3JpdGViYWNrUGF0aCkgcmV0dXJuIHdyaXRlYmFja1BhdGhcblxuICAgIGNvbnN0IGZpZWxkUGF0aCA9IGVudHJ5LmZpZWxkUGF0aFxuICAgIGlmIChmaWVsZFBhdGguZW5kc1dpdGgoJ1tdJykpIHtcbiAgICAgIHJldHVybiBgZXJyb3JzLiR7ZmllbGRQYXRoLnNsaWNlKDAsIC0yKX1gXG4gICAgfVxuICAgIHJldHVybiBgZXJyb3JzLiR7ZmllbGRQYXRofWBcbiAgfVxuXG4gIGZvciAoY29uc3QgZW50cnkgb2YgZW50cmllcykge1xuICAgIGFkZCh7XG4gICAgICBraW5kOiAnZmllbGRQYXRoJyxcbiAgICAgIGVudHJ5S2luZDogZW50cnkua2luZCxcbiAgICAgIGVudHJ5RmllbGRQYXRoOiBlbnRyeS5maWVsZFBhdGgsXG4gICAgICBwYXRoOiBlbnRyeS5maWVsZFBhdGgsXG4gICAgfSlcblxuICAgIGlmIChlbnRyeS5raW5kID09PSAnY29tcHV0ZWQnIHx8IGVudHJ5LmtpbmQgPT09ICdzb3VyY2UnKSB7XG4gICAgICBjb25zdCBkZXBzID0gKChlbnRyeS5tZXRhIGFzIGFueSk/LmRlcHMgPz8gW10pIGFzIFJlYWRvbmx5QXJyYXk8c3RyaW5nPlxuICAgICAgZm9yIChjb25zdCBkZXAgb2YgZGVwcykge1xuICAgICAgICBhZGQoe1xuICAgICAgICAgIGtpbmQ6ICdkZXAnLFxuICAgICAgICAgIGVudHJ5S2luZDogZW50cnkua2luZCxcbiAgICAgICAgICBlbnRyeUZpZWxkUGF0aDogZW50cnkuZmllbGRQYXRoLFxuICAgICAgICAgIHBhdGg6IGRlcCxcbiAgICAgICAgfSlcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoZW50cnkua2luZCA9PT0gJ2xpbmsnKSB7XG4gICAgICBhZGQoe1xuICAgICAgICBraW5kOiAnbGlua19mcm9tJyxcbiAgICAgICAgZW50cnlLaW5kOiAnbGluaycsXG4gICAgICAgIGVudHJ5RmllbGRQYXRoOiBlbnRyeS5maWVsZFBhdGgsXG4gICAgICAgIHBhdGg6IGVudHJ5Lm1ldGEuZnJvbSBhcyBzdHJpbmcsXG4gICAgICB9KVxuICAgIH1cblxuICAgIGlmIChlbnRyeS5raW5kID09PSAnY2hlY2snKSB7XG4gICAgICBhZGQoe1xuICAgICAgICBraW5kOiAnY2hlY2tfd3JpdGViYWNrJyxcbiAgICAgICAgZW50cnlLaW5kOiAnY2hlY2snLFxuICAgICAgICBlbnRyeUZpZWxkUGF0aDogZW50cnkuZmllbGRQYXRoLFxuICAgICAgICBwYXRoOiBnZXRDaGVja1dyaXRlYmFja1BhdGgoZW50cnkpLFxuICAgICAgfSlcblxuICAgICAgY29uc3QgcnVsZXMgPSAoKGVudHJ5Lm1ldGEgYXMgYW55KT8ucnVsZXMgPz8ge30pIGFzIFJlY29yZDxzdHJpbmcsIGFueT5cbiAgICAgIGZvciAoY29uc3QgbmFtZSBvZiBPYmplY3Qua2V5cyhydWxlcykpIHtcbiAgICAgICAgY29uc3QgcnVsZSA9IHJ1bGVzW25hbWVdXG4gICAgICAgIGlmICghcnVsZSB8fCB0eXBlb2YgcnVsZSAhPT0gJ29iamVjdCcpIGNvbnRpbnVlXG4gICAgICAgIGNvbnN0IGRlcHMgPSAocnVsZS5kZXBzID8/IFtdKSBhcyBSZWFkb25seUFycmF5PHN0cmluZz5cbiAgICAgICAgZm9yIChjb25zdCBkZXAgb2YgZGVwcykge1xuICAgICAgICAgIGFkZCh7XG4gICAgICAgICAgICBraW5kOiAnZGVwJyxcbiAgICAgICAgICAgIGVudHJ5S2luZDogJ2NoZWNrJyxcbiAgICAgICAgICAgIGVudHJ5RmllbGRQYXRoOiBlbnRyeS5maWVsZFBhdGgsXG4gICAgICAgICAgICBydWxlTmFtZTogbmFtZSxcbiAgICAgICAgICAgIHBhdGg6IGRlcCxcbiAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIEFycmF5LmZyb20oYnlLZXkuZW50cmllcygpKVxuICAgIC5zb3J0KChhLCBiKSA9PiBhWzBdLmxvY2FsZUNvbXBhcmUoYlswXSkpXG4gICAgLm1hcCgoWywgdl0pID0+IHYpXG59XG5cbi8qKlxuICogQnVpbGRzIGEgU3RhdGVUcmFpdFByb2dyYW0gZnJvbSB0aGUgZ2l2ZW4gc3RhdGVTY2hlbWEgYW5kIHRyYWl0IHNwZWMuXG4gKlxuICogLSBQdXJlIGZ1bmN0aW9uOiBkb2VzIG5vdCBkZXBlbmQgb24gZXh0ZXJuYWwgRW52IC8gZ2xvYmFsIHN0YXRlLlxuICogLSBDdXJyZW50IGltcGxlbWVudGF0aW9uIGZvY3VzZXMgb246XG4gKiAgIC0gTm9ybWFsaXppbmcgU3BlYyBpbnRvIGVudHJpZXMuXG4gKiAgIC0gQnVpbGRpbmcgYSBsaWdodHdlaWdodCBHcmFwaCAvIFBsYW4gZnJvbSBlbnRyaWVzLlxuICogICAtIFJ1bm5pbmcgYmFzaWMgY3ljbGUgZGV0ZWN0aW9uIGZvciBsaW5rIGVkZ2VzLlxuICpcbiAqIElmIHdlIGxhdGVyIG5lZWQgZmluZXItZ3JhaW5lZCBkZXBlbmRlbmN5IGFuYWx5c2lzIChlLmcuIHN0YXRpYyBhbmFseXNpcyBmb3IgY29tcHV0ZWQva2V5KSxcbiAqIGV2b2x2ZSBpdCBpbnNpZGUgdGhpcyBtb2R1bGUgd2l0aG91dCBjaGFuZ2luZyB0aGUgcHVibGljIEFQSSBzdXJmYWNlLlxuICovXG5leHBvcnQgY29uc3QgYnVpbGQgPSA8UyBleHRlbmRzIG9iamVjdD4oXG4gIHN0YXRlU2NoZW1hOiBTY2hlbWEuU2NoZW1hPFMsIGFueT4sXG4gIHNwZWM6IFN0YXRlVHJhaXRTcGVjPFM+LFxuKTogU3RhdGVUcmFpdFByb2dyYW08Uz4gPT4ge1xuICBjb25zdCBlbnRyaWVzID0gbm9ybWFsaXplU3BlYyhzcGVjKSBhcyBSZWFkb25seUFycmF5PFN0YXRlVHJhaXRFbnRyeTxTLCBzdHJpbmc+PlxuICBjb25zdCBub2RlTWV0YUJ5RmllbGRQYXRoID0gY29sbGVjdE5vZGVNZXRhKHNwZWMpXG5cbiAgLy8gUGhhc2UgNCAoVVMyKTogcmVxdWlyZSBleHBsaWNpdCBkZXBzIChHcmFwaC9kaWFnbm9zdGljcy9yZXBsYXkgdHJlYXQgZGVwcyBhcyB0aGUgc2luZ2xlIGRlcGVuZGVuY3kgc291cmNlIG9mIHRydXRoKS5cbiAgZm9yIChjb25zdCBlbnRyeSBvZiBlbnRyaWVzKSB7XG4gICAgaWYgKGVudHJ5LmtpbmQgPT09ICdjb21wdXRlZCcpIHtcbiAgICAgIGNvbnN0IGRlcHMgPSAoZW50cnkubWV0YSBhcyBhbnkpLmRlcHMgYXMgUmVhZG9ubHlBcnJheTxzdHJpbmc+IHwgdW5kZWZpbmVkXG4gICAgICBpZiAoZGVwcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBgW1N0YXRlVHJhaXQuYnVpbGRdIE1pc3NpbmcgZXhwbGljaXQgZGVwcyBmb3IgY29tcHV0ZWQgXCIke2VudHJ5LmZpZWxkUGF0aH1cIi4gYCArXG4gICAgICAgICAgICAnUGxlYXNlIHVzZSBTdGF0ZVRyYWl0LmNvbXB1dGVkKHsgZGVwczogWy4uLl0sIGdldDogLi4uIH0pLicsXG4gICAgICAgIClcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGVudHJ5LmtpbmQgPT09ICdzb3VyY2UnKSB7XG4gICAgICBjb25zdCBkZXBzID0gKGVudHJ5Lm1ldGEgYXMgYW55KS5kZXBzIGFzIFJlYWRvbmx5QXJyYXk8c3RyaW5nPiB8IHVuZGVmaW5lZFxuICAgICAgaWYgKGRlcHMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgYFtTdGF0ZVRyYWl0LmJ1aWxkXSBNaXNzaW5nIGV4cGxpY2l0IGRlcHMgZm9yIHNvdXJjZSBcIiR7ZW50cnkuZmllbGRQYXRofVwiLiBgICtcbiAgICAgICAgICAgICdQbGVhc2UgcHJvdmlkZSBtZXRhLmRlcHMgZm9yIFN0YXRlVHJhaXQuc291cmNlKHsgZGVwczogWy4uLl0sIC4uLiB9KS4nLFxuICAgICAgICApXG4gICAgICB9XG4gICAgfVxuICAgIGlmIChlbnRyeS5raW5kID09PSAnY2hlY2snKSB7XG4gICAgICBjb25zdCBydWxlcyA9ICgoZW50cnkubWV0YSBhcyBhbnkpPy5ydWxlcyA/PyB7fSkgYXMgUmVjb3JkPHN0cmluZywgYW55PlxuICAgICAgZm9yIChjb25zdCBuYW1lIG9mIE9iamVjdC5rZXlzKHJ1bGVzKSkge1xuICAgICAgICBjb25zdCBydWxlID0gcnVsZXNbbmFtZV1cbiAgICAgICAgaWYgKHR5cGVvZiBydWxlID09PSAnZnVuY3Rpb24nIHx8ICFydWxlIHx8IHR5cGVvZiBydWxlICE9PSAnb2JqZWN0Jykge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgIGBbU3RhdGVUcmFpdC5idWlsZF0gTWlzc2luZyBleHBsaWNpdCBkZXBzIGZvciBjaGVjayBcIiR7ZW50cnkuZmllbGRQYXRofVwiIHJ1bGUgXCIke25hbWV9XCIuIGAgK1xuICAgICAgICAgICAgICAnUGxlYXNlIHVzZSB7IGRlcHM6IFsuLi5dLCB2YWxpZGF0ZTogLi4uIH0gZm9ybS4nLFxuICAgICAgICAgIClcbiAgICAgICAgfVxuICAgICAgICBpZiAoKHJ1bGUgYXMgYW55KS5kZXBzID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICBgW1N0YXRlVHJhaXQuYnVpbGRdIE1pc3NpbmcgZXhwbGljaXQgZGVwcyBmb3IgY2hlY2sgXCIke2VudHJ5LmZpZWxkUGF0aH1cIiBydWxlIFwiJHtuYW1lfVwiLiBgICtcbiAgICAgICAgICAgICAgJ1BsZWFzZSBwcm92aWRlIGRlcHM6IFsuLi5dLicsXG4gICAgICAgICAgKVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgY29uc3QgeyBncmFwaCwgcGxhbiB9ID0gYnVpbGRHcmFwaChlbnRyaWVzLCBub2RlTWV0YUJ5RmllbGRQYXRoKVxuXG4gIC8vIFJ1biBhIGN5Y2xlIGNoZWNrIGZvciBsaW5rIGVkZ2VzIHRvIGF2b2lkIG9idmlvdXMgY29uZmlndXJhdGlvbiBlcnJvcnMuXG4gIGFzc2VydE5vTGlua0N5Y2xlcyhncmFwaC5lZGdlcylcblxuICByZXR1cm4ge1xuICAgIHN0YXRlU2NoZW1hLFxuICAgIHNwZWMsXG4gICAgZW50cmllczogZW50cmllcyBhcyBSZWFkb25seUFycmF5PFN0YXRlVHJhaXRFbnRyeTxhbnksIHN0cmluZz4+LFxuICAgIGdyYXBoLFxuICAgIHBsYW4sXG4gICAgY29udmVyZ2VJcjogYnVpbGRDb252ZXJnZUlyKHN0YXRlU2NoZW1hIGFzIGFueSwgZW50cmllcyBhcyBSZWFkb25seUFycmF5PFN0YXRlVHJhaXRFbnRyeTxhbnksIHN0cmluZz4+KSxcbiAgICBzY2hlbWFQYXRoczogY29sbGVjdFNjaGVtYVBhdGhzKGVudHJpZXMgYXMgUmVhZG9ubHlBcnJheTxTdGF0ZVRyYWl0RW50cnk8YW55LCBzdHJpbmc+PiksXG4gIH1cbn1cbiIsICJleHBvcnQgdHlwZSBUcmFpdE1ldGEgPSBSZWFkb25seTx7XG4gIHJlYWRvbmx5IGxhYmVsPzogc3RyaW5nXG4gIHJlYWRvbmx5IGRlc2NyaXB0aW9uPzogc3RyaW5nXG4gIHJlYWRvbmx5IHRhZ3M/OiBSZWFkb25seUFycmF5PHN0cmluZz5cbiAgcmVhZG9ubHkgZ3JvdXA/OiBzdHJpbmdcbiAgcmVhZG9ubHkgZG9jc1VybD86IHN0cmluZ1xuICByZWFkb25seSBjYWNoZUdyb3VwPzogc3RyaW5nXG4gIC8qKlxuICAgKiBFeHRlbnNpb24gYW5ub3RhdGlvbnM6IG9ubHkgYWNjZXB0cyBgeC0qYCBrZXlzIChhbmNob3JzIGZvciBjYXBhYmlsaXRpZXMgbGlrZSBQaGFudG9tIFNvdXJjZSAvIERyaWZ0IERldGVjdGlvbikuXG4gICAqXG4gICAqIENvbnN0cmFpbnRzOlxuICAgKiAtIE11c3QgYmUgc2VyaWFsaXphYmxlIChKU09OIHZhbHVlcykuXG4gICAqIC0gTXVzdCBiZSBzbGltIChrZWVwIG9ubHkgYSBmZXcga2V5IGhpbnRzOyBkb24ndCBzdHVmZiBsYXJnZSBvYmplY3RzKS5cbiAgICovXG4gIHJlYWRvbmx5IGFubm90YXRpb25zPzogUmVhZG9ubHk8UmVjb3JkPHN0cmluZywgSnNvblZhbHVlPj5cbiAgLyoqXG4gICAqIFNlbWFudGljIGhpbnQ6IHdoZW4gdGhlIHNhbWUgZW50aXR5IChlLmcuIHRoZSBzYW1lIHJlc291cmNlSWQpIGhhcyBtdWx0aXBsZSBpbmNvbnNpc3RlbnQgbWV0YSBkZWNsYXJhdGlvbnMsXG4gICAqIHRoZSBvbmUgd2l0aCBjYW5vbmljYWw9dHJ1ZSBiZWNvbWVzIHRoZSBcImRpc3BsYXkgY2Fub25pY2FsXCIsIGFuZCBvdGhlcnMgYXJlIHJlY29yZGVkIGFzIGNvbmZsaWN0cy5cbiAgICovXG4gIHJlYWRvbmx5IGNhbm9uaWNhbD86IGJvb2xlYW5cbn0+XG5cbmV4cG9ydCB0eXBlIFRyYWl0TWV0YUNvbmZsaWN0ID0gUmVhZG9ubHk8e1xuICByZWFkb25seSBvcmlnaW46IHN0cmluZ1xuICByZWFkb25seSBtZXRhOiBUcmFpdE1ldGFcbn0+XG5cbmV4cG9ydCB0eXBlIEpzb25QcmltaXRpdmUgPSBzdHJpbmcgfCBudW1iZXIgfCBib29sZWFuIHwgbnVsbFxuZXhwb3J0IHR5cGUgSnNvblZhbHVlID0gSnNvblByaW1pdGl2ZSB8IFJlYWRvbmx5QXJyYXk8SnNvblZhbHVlPiB8IHsgcmVhZG9ubHkgW2tleTogc3RyaW5nXTogSnNvblZhbHVlIH1cblxuY29uc3QgdW5pcVNvcnRlZFN0cmluZ3MgPSAoaW5wdXQ6IFJlYWRvbmx5QXJyYXk8c3RyaW5nPik6IFJlYWRvbmx5QXJyYXk8c3RyaW5nPiA9PiB7XG4gIGNvbnN0IHNldCA9IG5ldyBTZXQ8c3RyaW5nPigpXG4gIGZvciAoY29uc3QgaXRlbSBvZiBpbnB1dCkge1xuICAgIGNvbnN0IHYgPSBpdGVtLnRyaW0oKVxuICAgIGlmICghdikgY29udGludWVcbiAgICBzZXQuYWRkKHYpXG4gIH1cbiAgcmV0dXJuIEFycmF5LmZyb20oc2V0KS5zb3J0KChhLCBiKSA9PiBhLmxvY2FsZUNvbXBhcmUoYikpXG59XG5cbmNvbnN0IGlzUGxhaW5SZWNvcmQgPSAodmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9PlxuICB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmIHZhbHVlICE9PSBudWxsICYmICFBcnJheS5pc0FycmF5KHZhbHVlKVxuXG5jb25zdCBzYW5pdGl6ZUpzb25WYWx1ZSA9IChpbnB1dDogdW5rbm93biwgZGVwdGg6IG51bWJlcik6IEpzb25WYWx1ZSB8IHVuZGVmaW5lZCA9PiB7XG4gIGlmIChpbnB1dCA9PT0gbnVsbCkgcmV0dXJuIG51bGxcblxuICBpZiAodHlwZW9mIGlucHV0ID09PSAnc3RyaW5nJykgcmV0dXJuIGlucHV0XG4gIGlmICh0eXBlb2YgaW5wdXQgPT09ICdib29sZWFuJykgcmV0dXJuIGlucHV0XG4gIGlmICh0eXBlb2YgaW5wdXQgPT09ICdudW1iZXInKSB7XG4gICAgcmV0dXJuIE51bWJlci5pc0Zpbml0ZShpbnB1dCkgPyBpbnB1dCA6IHVuZGVmaW5lZFxuICB9XG5cbiAgaWYgKGRlcHRoID49IDYpIHJldHVybiB1bmRlZmluZWRcblxuICBpZiAoQXJyYXkuaXNBcnJheShpbnB1dCkpIHtcbiAgICBjb25zdCBvdXQ6IEFycmF5PEpzb25WYWx1ZT4gPSBbXVxuICAgIGZvciAoY29uc3QgaXRlbSBvZiBpbnB1dCkge1xuICAgICAgY29uc3QgdiA9IHNhbml0aXplSnNvblZhbHVlKGl0ZW0sIGRlcHRoICsgMSlcbiAgICAgIGlmICh2ICE9PSB1bmRlZmluZWQpIG91dC5wdXNoKHYpXG4gICAgfVxuICAgIHJldHVybiBvdXRcbiAgfVxuXG4gIGlmIChpc1BsYWluUmVjb3JkKGlucHV0KSkge1xuICAgIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyhpbnB1dCkuc29ydCgpXG4gICAgY29uc3Qgb3V0OiBSZWNvcmQ8c3RyaW5nLCBKc29uVmFsdWU+ID0ge31cbiAgICBmb3IgKGNvbnN0IGtleSBvZiBrZXlzKSB7XG4gICAgICBjb25zdCB2ID0gc2FuaXRpemVKc29uVmFsdWUoaW5wdXRba2V5XSwgZGVwdGggKyAxKVxuICAgICAgaWYgKHYgIT09IHVuZGVmaW5lZCkgb3V0W2tleV0gPSB2XG4gICAgfVxuICAgIHJldHVybiBvdXRcbiAgfVxuXG4gIHJldHVybiB1bmRlZmluZWRcbn1cblxuZXhwb3J0IGNvbnN0IHNhbml0aXplID0gKGlucHV0OiB1bmtub3duKTogVHJhaXRNZXRhIHwgdW5kZWZpbmVkID0+IHtcbiAgaWYgKGlucHV0ID09PSBudWxsIHx8IGlucHV0ID09PSB1bmRlZmluZWQpIHJldHVybiB1bmRlZmluZWRcbiAgaWYgKHR5cGVvZiBpbnB1dCAhPT0gJ29iamVjdCcgfHwgQXJyYXkuaXNBcnJheShpbnB1dCkpIHJldHVybiB1bmRlZmluZWRcblxuICBjb25zdCByZWNvcmQgPSBpbnB1dCBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPlxuICBjb25zdCBvdXQ6IFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0ge31cblxuICBjb25zdCBwaWNrU3RyaW5nID0gKGtleToga2V5b2YgVHJhaXRNZXRhKTogdm9pZCA9PiB7XG4gICAgY29uc3QgdmFsdWUgPSByZWNvcmRba2V5IGFzIHN0cmluZ11cbiAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAnc3RyaW5nJykgcmV0dXJuXG4gICAgY29uc3QgdHJpbW1lZCA9IHZhbHVlLnRyaW0oKVxuICAgIGlmICghdHJpbW1lZCkgcmV0dXJuXG4gICAgb3V0W2tleV0gPSB0cmltbWVkXG4gIH1cblxuICBwaWNrU3RyaW5nKCdsYWJlbCcpXG4gIHBpY2tTdHJpbmcoJ2Rlc2NyaXB0aW9uJylcbiAgcGlja1N0cmluZygnZ3JvdXAnKVxuICBwaWNrU3RyaW5nKCdkb2NzVXJsJylcbiAgcGlja1N0cmluZygnY2FjaGVHcm91cCcpXG5cbiAgY29uc3QgY2Fub25pY2FsID0gcmVjb3JkLmNhbm9uaWNhbFxuICBpZiAodHlwZW9mIGNhbm9uaWNhbCA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgb3V0LmNhbm9uaWNhbCA9IGNhbm9uaWNhbFxuICB9XG5cbiAgY29uc3QgdGFnc1JhdyA9IHJlY29yZC50YWdzXG4gIGlmICh0eXBlb2YgdGFnc1JhdyA9PT0gJ3N0cmluZycpIHtcbiAgICBjb25zdCB0YWdzID0gdW5pcVNvcnRlZFN0cmluZ3MoW3RhZ3NSYXddKVxuICAgIGlmICh0YWdzLmxlbmd0aCA+IDApIG91dC50YWdzID0gdGFnc1xuICB9IGVsc2UgaWYgKEFycmF5LmlzQXJyYXkodGFnc1JhdykpIHtcbiAgICBjb25zdCB0YWdzID0gdW5pcVNvcnRlZFN0cmluZ3ModGFnc1Jhdy5maWx0ZXIoKHgpOiB4IGlzIHN0cmluZyA9PiB0eXBlb2YgeCA9PT0gJ3N0cmluZycpKVxuICAgIGlmICh0YWdzLmxlbmd0aCA+IDApIG91dC50YWdzID0gdGFnc1xuICB9XG5cbiAgY29uc3QgYW5ub3RhdGlvbnM6IFJlY29yZDxzdHJpbmcsIEpzb25WYWx1ZT4gPSB7fVxuXG4gIC8vIGxlZ2FjeTogYWxsb3cgcGFzc2luZyBgeC0qYCBrZXlzIGF0IHRoZSB0b3AtbGV2ZWwgKHVudHlwZWQgaW5wdXQpLCB0aGVuIG5vcm1hbGl6ZSBpbnRvIGBhbm5vdGF0aW9uc2AuXG4gIGNvbnN0IGFubm90YXRpb25LZXlzID0gT2JqZWN0LmtleXMocmVjb3JkKVxuICAgIC5maWx0ZXIoKGspID0+IGsuc3RhcnRzV2l0aCgneC0nKSlcbiAgICAuc29ydCgoYSwgYikgPT4gYS5sb2NhbGVDb21wYXJlKGIpKVxuICBmb3IgKGNvbnN0IGtleSBvZiBhbm5vdGF0aW9uS2V5cykge1xuICAgIGNvbnN0IHYgPSBzYW5pdGl6ZUpzb25WYWx1ZShyZWNvcmRba2V5XSwgMClcbiAgICBpZiAodiAhPT0gdW5kZWZpbmVkKSBhbm5vdGF0aW9uc1trZXldID0gdlxuICB9XG5cbiAgLy8gcHJlZmVycmVkOiB0eXBlZCBgYW5ub3RhdGlvbnNgIGZpZWxkIChvbmx5IGFjY2VwdHMgYHgtKmAga2V5cykuXG4gIGNvbnN0IGFubm90YXRpb25zUmF3ID0gcmVjb3JkLmFubm90YXRpb25zXG4gIGlmIChpc1BsYWluUmVjb3JkKGFubm90YXRpb25zUmF3KSkge1xuICAgIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyhhbm5vdGF0aW9uc1JhdylcbiAgICAgIC5maWx0ZXIoKGspID0+IGsuc3RhcnRzV2l0aCgneC0nKSlcbiAgICAgIC5zb3J0KChhLCBiKSA9PiBhLmxvY2FsZUNvbXBhcmUoYikpXG4gICAgZm9yIChjb25zdCBrZXkgb2Yga2V5cykge1xuICAgICAgY29uc3QgdiA9IHNhbml0aXplSnNvblZhbHVlKGFubm90YXRpb25zUmF3W2tleV0sIDApXG4gICAgICBpZiAodiAhPT0gdW5kZWZpbmVkKSBhbm5vdGF0aW9uc1trZXldID0gdlxuICAgIH1cbiAgfVxuXG4gIGlmIChPYmplY3Qua2V5cyhhbm5vdGF0aW9ucykubGVuZ3RoID4gMCkgb3V0LmFubm90YXRpb25zID0gYW5ub3RhdGlvbnNcblxuICByZXR1cm4gT2JqZWN0LmtleXMob3V0KS5sZW5ndGggPiAwID8gKG91dCBhcyBUcmFpdE1ldGEpIDogdW5kZWZpbmVkXG59XG5cbmNvbnN0IHN0YWJsZVN0cmluZ2lmeSA9IChtZXRhOiBUcmFpdE1ldGEpOiBzdHJpbmcgPT4ge1xuICBjb25zdCBvdXQ6IFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0ge31cbiAgY29uc3Qga2V5cyA9IE9iamVjdC5rZXlzKG1ldGEpLnNvcnQoKVxuICBmb3IgKGNvbnN0IGsgb2Yga2V5cykge1xuICAgIG91dFtrXSA9IChtZXRhIGFzIGFueSlba11cbiAgfVxuICByZXR1cm4gSlNPTi5zdHJpbmdpZnkob3V0KVxufVxuXG5leHBvcnQgY29uc3QgZXF1YWxzID0gKGE6IFRyYWl0TWV0YSB8IHVuZGVmaW5lZCwgYjogVHJhaXRNZXRhIHwgdW5kZWZpbmVkKTogYm9vbGVhbiA9PiB7XG4gIGlmIChhID09PSBiKSByZXR1cm4gdHJ1ZVxuICBpZiAoIWEgfHwgIWIpIHJldHVybiBmYWxzZVxuICByZXR1cm4gc3RhYmxlU3RyaW5naWZ5KGEpID09PSBzdGFibGVTdHJpbmdpZnkoYilcbn1cblxuZXhwb3J0IHR5cGUgQ2Fub25pY2FsTWVyZ2VJbnB1dCA9IFJlYWRvbmx5PHtcbiAgcmVhZG9ubHkgbWV0YT86IFRyYWl0TWV0YVxuICByZWFkb25seSBvcmlnaW4/OiBzdHJpbmdcbiAgcmVhZG9ubHkgY29uZmxpY3RzPzogUmVhZG9ubHlBcnJheTxUcmFpdE1ldGFDb25mbGljdD5cbn0+XG5cbmV4cG9ydCB0eXBlIENhbm9uaWNhbE1lcmdlUmVzdWx0ID0gUmVhZG9ubHk8e1xuICByZWFkb25seSBtZXRhPzogVHJhaXRNZXRhXG4gIHJlYWRvbmx5IG9yaWdpbj86IHN0cmluZ1xuICByZWFkb25seSBjb25mbGljdHM/OiBSZWFkb25seUFycmF5PFRyYWl0TWV0YUNvbmZsaWN0PlxufT5cblxuZXhwb3J0IGNvbnN0IG1lcmdlQ2Fub25pY2FsID0gKFxuICBjdXJyZW50OiBDYW5vbmljYWxNZXJnZUlucHV0LFxuICBpbmNvbWluZzogUmVhZG9ubHk8eyByZWFkb25seSBvcmlnaW46IHN0cmluZzsgcmVhZG9ubHkgbWV0YTogVHJhaXRNZXRhIH0+LFxuKTogQ2Fub25pY2FsTWVyZ2VSZXN1bHQgPT4ge1xuICBjb25zdCBleGlzdGluZyA9IGN1cnJlbnQubWV0YVxuICBpZiAoIWV4aXN0aW5nKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIG1ldGE6IGluY29taW5nLm1ldGEsXG4gICAgICBvcmlnaW46IGluY29taW5nLm9yaWdpbixcbiAgICAgIGNvbmZsaWN0czogY3VycmVudC5jb25mbGljdHMsXG4gICAgfVxuICB9XG5cbiAgaWYgKGVxdWFscyhleGlzdGluZywgaW5jb21pbmcubWV0YSkpIHtcbiAgICByZXR1cm4gY3VycmVudFxuICB9XG5cbiAgY29uc3QgY29uZmxpY3RzOiBBcnJheTxUcmFpdE1ldGFDb25mbGljdD4gPSBbLi4uKChjdXJyZW50LmNvbmZsaWN0cyA/PyBbXSkgYXMgUmVhZG9ubHlBcnJheTxUcmFpdE1ldGFDb25mbGljdD4pXVxuXG4gIGNvbnN0IHB1c2ggPSAoY29uZmxpY3Q6IFRyYWl0TWV0YUNvbmZsaWN0KTogdm9pZCA9PiB7XG4gICAgY29uc3QgZXhpc3RzID0gY29uZmxpY3RzLnNvbWUoKGMpID0+IGMub3JpZ2luID09PSBjb25mbGljdC5vcmlnaW4gJiYgZXF1YWxzKGMubWV0YSwgY29uZmxpY3QubWV0YSkpXG4gICAgaWYgKCFleGlzdHMpIGNvbmZsaWN0cy5wdXNoKGNvbmZsaWN0KVxuICB9XG5cbiAgY29uc3QgZXhpc3RpbmdDYW5vbmljYWwgPSBleGlzdGluZy5jYW5vbmljYWwgPT09IHRydWVcbiAgY29uc3QgaW5jb21pbmdDYW5vbmljYWwgPSBpbmNvbWluZy5tZXRhLmNhbm9uaWNhbCA9PT0gdHJ1ZVxuXG4gIGlmICghZXhpc3RpbmdDYW5vbmljYWwgJiYgaW5jb21pbmdDYW5vbmljYWwpIHtcbiAgICBwdXNoKHtcbiAgICAgIG9yaWdpbjogY3VycmVudC5vcmlnaW4gPz8gJ3Vua25vd24nLFxuICAgICAgbWV0YTogZXhpc3RpbmcsXG4gICAgfSlcbiAgICByZXR1cm4ge1xuICAgICAgbWV0YTogaW5jb21pbmcubWV0YSxcbiAgICAgIG9yaWdpbjogaW5jb21pbmcub3JpZ2luLFxuICAgICAgY29uZmxpY3RzLFxuICAgIH1cbiAgfVxuXG4gIHB1c2goe1xuICAgIG9yaWdpbjogaW5jb21pbmcub3JpZ2luLFxuICAgIG1ldGE6IGluY29taW5nLm1ldGEsXG4gIH0pXG5cbiAgcmV0dXJuIHtcbiAgICBtZXRhOiBleGlzdGluZyxcbiAgICBvcmlnaW46IGN1cnJlbnQub3JpZ2luID8/IGluY29taW5nLm9yaWdpbixcbiAgICBjb25mbGljdHMsXG4gIH1cbn1cbiIsICJpbXBvcnQgdHlwZSB7IFNjaGVtYSB9IGZyb20gJ2VmZmVjdCdcbmltcG9ydCB0eXBlIHsgU3RhdGVBdFBhdGgsIFN0YXRlRmllbGRQYXRoIH0gZnJvbSAnLi9maWVsZC1wYXRoLmpzJ1xuaW1wb3J0IHR5cGUgeyBEaXJ0eUFsbFJlYXNvbiB9IGZyb20gJy4uL2ZpZWxkLXBhdGguanMnXG5pbXBvcnQgKiBhcyBNZXRhIGZyb20gJy4vbWV0YS5qcydcbmltcG9ydCB0eXBlIHsgQ29udmVyZ2VTdGF0aWNJclJlZ2lzdHJ5IH0gZnJvbSAnLi9jb252ZXJnZS1pci5qcydcbmltcG9ydCB0eXBlIHsgQ29udmVyZ2VFeGVjSXIgfSBmcm9tICcuL2NvbnZlcmdlLWV4ZWMtaXIuanMnXG5cbi8vIFN0YXRlVHJhaXQgY29yZSBtb2RlbC5cbi8vIEtlZXAgdGhlIGZpZWxkIHNlbWFudGljcyBhbGlnbmVkIHdpdGggZGF0YS1tb2RlbC5tZCAvIHJlZmVyZW5jZXMvc3RhdGUtdHJhaXQtY29yZS5tZC5cblxuLyoqXG4gKiBTdGF0ZVRyYWl0U3BlYzxTPlx1RkYxQVxuICogLSBUaGUgc3RhbmRhcmQgc2hhcGUgZm9yIHRoZSBgdHJhaXRzYCBzbG90IGluIGEgTW9kdWxlIGJsdWVwcmludC5cbiAqIC0gS2V5cyBhcmUgY29uc3RyYWluZWQgYnkgU3RhdGVGaWVsZFBhdGg8Uz47IHZhbHVlcyBhcmUgZGVjbGFyYXRpb25zIGZvciB0aGUgY29ycmVzcG9uZGluZyBzY29wZSAoRW50cnkgLyBOb2RlIC8gTGlzdCkuXG4gKi9cbmV4cG9ydCB0eXBlIFN0YXRlVHJhaXRTcGVjPFM+ID0gUyBleHRlbmRzIG9iamVjdFxuICA/IHtcbiAgICAgIFtQYXRoIGluIFN0YXRlRmllbGRQYXRoPFM+IHwgJyRyb290J10/OiBTdGF0ZVRyYWl0U3BlY1ZhbHVlPFMsIFBhdGg+XG4gICAgfVxuICA6IG5ldmVyXG5cbmV4cG9ydCB0eXBlIFN0YXRlVHJhaXRLaW5kID0gJ2NvbXB1dGVkJyB8ICdzb3VyY2UnIHwgJ2xpbmsnIHwgJ2NoZWNrJ1xuXG4vKipcbiAqIFRyYWl0Q29udmVyZ2VTY2hlZHVsaW5nXHVGRjFBXG4gKiAtIFNjaGVkdWxpbmcgc2VtYW50aWNzIGZvciBjb252ZXJnZS9kaXJ0eS1jaGVjayAoMDQzKTogZGVjaWRlcyB3aGV0aGVyIGEgc3RlcCBtdXN0IGNvbnZlcmdlIHdpdGhpbiBlYWNoIHRyYW5zYWN0aW9uIHdpbmRvdy5cbiAqIC0gRGVmYXVsdCBgaW1tZWRpYXRlYCAoa2VlcHMgbGVnYWN5IGJlaGF2aW9yKTsgYGRlZmVycmVkYCB0YWtlcyBlZmZlY3Qgb25seSB3aXRoIGV4cGxpY2l0IGRlY2xhcmF0aW9uICsgdGltZS1zbGljaW5nIGVuYWJsZWQuXG4gKi9cbmV4cG9ydCB0eXBlIFRyYWl0Q29udmVyZ2VTY2hlZHVsaW5nID0gJ2ltbWVkaWF0ZScgfCAnZGVmZXJyZWQnXG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29tcHV0ZWRNZXRhPFMsIFA+IHtcbiAgLyoqXG4gICAqIEV4cGxpY2l0IGRlcGVuZGVuY3kgZmllbGQgcGF0aHMgKHJlcXVpcmVkKTpcbiAgICpcbiAgICogLSBkZXBzIGlzIHRoZSBzaW5nbGUgc291cmNlIG9mIHRydXRoIGZvciBkZXBlbmRlbmNpZXM6IEdyYXBoL1JldmVyc2VDbG9zdXJlL2luY3JlbWVudGFsIHNjaGVkdWxpbmcvcGVyZiBvcHRpbWl6YXRpb25zIHJlbHkgb24gZGVwcyBvbmx5LlxuICAgKiAtIEluIHRoZSBEU0wsIGBTdGF0ZVRyYWl0LmNvbXB1dGVkKHsgZGVwcywgZ2V0IH0pYCB1c2VzIGRlcHMtYXMtYXJnczsgaXQgZG9lcyBub3QgZXhwb3NlIGAoc3RhdGUpID0+IC4uLmAuXG4gICAqIC0gRHVyaW5nIGJ1aWxkLCBgZ2V0KC4uLmRlcHNWYWx1ZXMpYCBpcyBsb3dlcmVkIGludG8gYGRlcml2ZShzdGF0ZSlgIGZvciBydW50aW1lIGV4ZWN1dGlvbiwgYnV0IHRoZSBkZXBlbmRlbmN5IHJlYWQtc2V0IHJlbWFpbnMgZGVwcy1iYXNlZC5cbiAgICogLSBJbiBkZXYtbW9kZSwgaWYgYWN0dWFsIHJlYWRzIGluIGBkZXJpdmUoc3RhdGUpYCBkaXNhZ3JlZSB3aXRoIGRlcHMsIGEgYGRlcHNfbWlzbWF0Y2hgIGRpYWdub3N0aWMgd2FybmluZyBpcyBlbWl0dGVkLlxuICAgKlxuICAgKiAtIEZvciByb290IHNjb3BlOiBkZXBzIGFyZSBTdGF0ZUZpZWxkUGF0aDxTdGF0ZT4uXG4gICAqIC0gRm9yIGxpc3QuaXRlbSBzY29wZTogZGVwcyBhcmUgU3RhdGVGaWVsZFBhdGg8SXRlbT4gKHJlbGF0aXZlIHBhdGhzOyBidWlsZCB3aWxsIHByZWZpeCB0aGVtKS5cbiAgICovXG4gIHJlYWRvbmx5IGRlcHM6IFJlYWRvbmx5QXJyYXk8U3RhdGVGaWVsZFBhdGg8Uz4+XG4gIHJlYWRvbmx5IGRlcml2ZTogKHN0YXRlOiBSZWFkb25seTxTPikgPT4gU3RhdGVBdFBhdGg8UywgUD5cbiAgLyoqXG4gICAqIE9wdGlvbmFsOiBlcXVhbGl0eSBwcmVkaWNhdGUgKHVzZWQgdG8gc2tpcCBuby1vcCB3cml0ZWJhY2tzKS5cbiAgICovXG4gIHJlYWRvbmx5IGVxdWFscz86IChwcmV2OiBTdGF0ZUF0UGF0aDxTLCBQPiwgbmV4dDogU3RhdGVBdFBhdGg8UywgUD4pID0+IGJvb2xlYW5cbiAgLyoqXG4gICAqIENvbnZlcmdlIHNjaGVkdWxpbmcgKDA0Myk6IGRlZmF1bHRzIHRvIGltbWVkaWF0ZS5cbiAgICovXG4gIHJlYWRvbmx5IHNjaGVkdWxpbmc/OiBUcmFpdENvbnZlcmdlU2NoZWR1bGluZ1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFNvdXJjZU1ldGE8UywgUD4ge1xuICByZWFkb25seSBkZXBzOiBSZWFkb25seUFycmF5PFN0YXRlRmllbGRQYXRoPFM+PlxuICAvKipcbiAgICogTG9naWNhbCByZXNvdXJjZSBpZGVudGlmaWVyIChlLmcuIFwidXNlci9wcm9maWxlXCIpLlxuICAgKlxuICAgKiAtIEluIHRoZSBTdGF0ZVRyYWl0LnNvdXJjZSBEU0wsIGByZXNvdXJjZWAgaXMgc3RvcmVkIGhlcmUgZHVyaW5nIGJ1aWxkLlxuICAgKiAtIGRhdGEtbW9kZWwubWQgY2FsbHMgaXQgcmVzb3VyY2VJZDsgd2Uga2VlcCB0aGUgRFNMIG5hbWluZyBoZXJlIHRvIGF2b2lkIGNvbmZ1c2lvbi5cbiAgICovXG4gIHJlYWRvbmx5IHJlc291cmNlOiBzdHJpbmdcbiAgLyoqXG4gICAqIFJ1bGUgZm9yIGNvbXB1dGluZyB0aGUga2V5IHJlcXVpcmVkIHRvIGFjY2VzcyB0aGUgcmVzb3VyY2UuXG4gICAqXG4gICAqIC0gZGVwcyBpcyB0aGUgc2luZ2xlIHNvdXJjZSBvZiB0cnV0aCBmb3IgZGVwZW5kZW5jaWVzOiBHcmFwaC9SZXZlcnNlQ2xvc3VyZS9pbmNyZW1lbnRhbCBzY2hlZHVsaW5nL3BlcmYgb3B0aW1pemF0aW9ucyByZWx5IG9uIGRlcHMgb25seS5cbiAgICogLSBJbiB0aGUgRFNMLCBgU3RhdGVUcmFpdC5zb3VyY2UoeyBkZXBzLCBrZXkgfSlgIHVzZXMgZGVwcy1hcy1hcmdzOyBpdCBkb2VzIG5vdCBleHBvc2UgYChzdGF0ZSkgPT4gLi4uYC5cbiAgICogLSBEdXJpbmcgYnVpbGQsIGBrZXkoLi4uZGVwc1ZhbHVlcylgIGlzIGxvd2VyZWQgaW50byBga2V5KHN0YXRlKWAgZm9yIHJ1bnRpbWUgZXhlY3V0aW9uLCBidXQgdGhlIGRlcGVuZGVuY3kgcmVhZC1zZXQgcmVtYWlucyBkZXBzLWJhc2VkLlxuICAgKlxuICAgKiAtIFJldHVybmluZyB1bmRlZmluZWQgbWVhbnMgdGhlIHJlc291cmNlIGlzIGluYWN0aXZlIHVuZGVyIHRoZSBjdXJyZW50IHN0YXRlIChzaG91bGQgYmUgcmVjeWNsZWQgdG8gaWRsZSkuXG4gICAqL1xuICByZWFkb25seSBrZXk6IChzdGF0ZTogUmVhZG9ubHk8Uz4pID0+IHVua25vd25cbiAgcmVhZG9ubHkgdHJpZ2dlcnM/OiBSZWFkb25seUFycmF5PCdvbk1vdW50JyB8ICdvbktleUNoYW5nZScgfCAnbWFudWFsJz5cbiAgcmVhZG9ubHkgZGVib3VuY2VNcz86IG51bWJlclxuICByZWFkb25seSBjb25jdXJyZW5jeT86ICdzd2l0Y2gnIHwgJ2V4aGF1c3QtdHJhaWxpbmcnXG4gIC8qKlxuICAgKiBTZXJpYWxpemFibGUgbWV0YWRhdGEgZm9yIGRldnRvb2xzL2RvY3MgKHdoaXRlbGlzdGVkIGZpZWxkcykuXG4gICAqL1xuICByZWFkb25seSBtZXRhPzogTWV0YS5UcmFpdE1ldGFcbiAgLyoqXG4gICAqIFJlc2VydmVkOiBidWlsZCBtYXkgcG9wdWxhdGUgdGhlIGZpZWxkIHBhdGggdGhpcyB0cmFpdCBpcyBhdHRhY2hlZCB0bywgZm9yIGVhc2llciBkZWJ1Z2dpbmcuXG4gICAqL1xuICByZWFkb25seSBfZmllbGRQYXRoPzogUFxufVxuXG5leHBvcnQgaW50ZXJmYWNlIExpbmtNZXRhPFM+IHtcbiAgLyoqXG4gICAqIFNvdXJjZSBmaWVsZCBwYXRoIChhbHNvIGNvbnN0cmFpbmVkIGJ5IFN0YXRlRmllbGRQYXRoPFM+KS5cbiAgICovXG4gIHJlYWRvbmx5IGZyb206IFN0YXRlRmllbGRQYXRoPFM+XG4gIC8qKlxuICAgKiBDb252ZXJnZSBzY2hlZHVsaW5nICgwNDMpOiBkZWZhdWx0cyB0byBpbW1lZGlhdGUuXG4gICAqL1xuICByZWFkb25seSBzY2hlZHVsaW5nPzogVHJhaXRDb252ZXJnZVNjaGVkdWxpbmdcbn1cblxuZXhwb3J0IHR5cGUgQ2hlY2tSdWxlPElucHV0ID0gdW5rbm93biwgQ3R4ID0gdW5rbm93bj4gPSB7XG4gIHJlYWRvbmx5IGRlcHM6IFJlYWRvbmx5QXJyYXk8c3RyaW5nPlxuICAvKipcbiAgICogdmFsaWRhdGVPblx1RkYxQVxuICAgKiAtIEFmZmVjdHMgb25seSBhdXRvIHZhbGlkYXRpb24gcGhhc2VzIChvbkNoYW5nZS9vbkJsdXIpOyBzdWJtaXQvbWFudWFsIGFsd2F5cyBydW4uXG4gICAqIC0gRW1wdHkgYXJyYXkgZGlzYWJsZXMgYXV0byB2YWxpZGF0aW9uIChvbmx5IHN1Ym1pdC9tYW51YWwgcnVuKS5cbiAgICovXG4gIHJlYWRvbmx5IHZhbGlkYXRlT24/OiBSZWFkb25seUFycmF5PCdvbkNoYW5nZScgfCAnb25CbHVyJz5cbiAgcmVhZG9ubHkgdmFsaWRhdGU6IChpbnB1dDogSW5wdXQsIGN0eDogQ3R4KSA9PiB1bmtub3duXG4gIHJlYWRvbmx5IG1ldGE/OiBNZXRhLlRyYWl0TWV0YVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIENoZWNrTWV0YTxJbnB1dCA9IHVua25vd24sIEN0eCA9IHVua25vd24+IHtcbiAgLyoqXG4gICAqIE5hbWVkIHJ1bGUgc2V0ICh1c2VkIGZvciBkZXRlcm1pbmlzdGljIG1lcmdlIGFuZCBkaWFnbm9zdGljcyBkaXNwbGF5KS5cbiAgICovXG4gIHJlYWRvbmx5IHJ1bGVzOiBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCBDaGVja1J1bGU8SW5wdXQsIEN0eD4+PlxuICAvKipcbiAgICogRXJyb3ItdHJlZSB3cml0ZWJhY2sgKFBoYXNlIDI6IHN0cnVjdHVyZSBvbmx5OyBjb25jcmV0ZSB3cml0ZWJhY2sgc2VtYW50aWNzIGxhbmQgaW4gbGF0ZXIgcGhhc2VzKS5cbiAgICovXG4gIHJlYWRvbmx5IHdyaXRlYmFjaz86IHtcbiAgICByZWFkb25seSBraW5kOiAnZXJyb3JzJ1xuICAgIHJlYWRvbmx5IHBhdGg/OiBzdHJpbmdcbiAgfVxufVxuXG4vKipcbiAqIFN0YXRlVHJhaXRFbnRyeTxTLCBQPlx1RkYxQVxuICogLSBBIHNpbmdsZSBUcmFpdCBjb25maWd1cmF0aW9uIGF0dGFjaGVkIHRvIGEgZmllbGQgcGF0aCBQLlxuICogLSBraW5kIGFuZCBtZXRhIGFsd2F5cyBjb21lIHRvZ2V0aGVyIGFuZCBhcmUgdXNlZCB0byBkaXNwYXRjaCBiZWhhdmlvciBkdXJpbmcgYnVpbGQvaW5zdGFsbC5cbiAqL1xuZXhwb3J0IHR5cGUgU3RhdGVUcmFpdEVudHJ5PFMgPSB1bmtub3duLCBQIGV4dGVuZHMgc3RyaW5nID0gU3RhdGVGaWVsZFBhdGg8Uz4+ID1cbiAgfCB7XG4gICAgICByZWFkb25seSBmaWVsZFBhdGg6IFBcbiAgICAgIHJlYWRvbmx5IGtpbmQ6ICdjb21wdXRlZCdcbiAgICAgIHJlYWRvbmx5IG1ldGE6IENvbXB1dGVkTWV0YTxTLCBQPlxuICAgIH1cbiAgfCB7XG4gICAgICByZWFkb25seSBmaWVsZFBhdGg6IFBcbiAgICAgIHJlYWRvbmx5IGtpbmQ6ICdzb3VyY2UnXG4gICAgICByZWFkb25seSBtZXRhOiBTb3VyY2VNZXRhPFMsIFA+XG4gICAgfVxuICB8IHtcbiAgICAgIHJlYWRvbmx5IGZpZWxkUGF0aDogUFxuICAgICAgcmVhZG9ubHkga2luZDogJ2xpbmsnXG4gICAgICByZWFkb25seSBtZXRhOiBMaW5rTWV0YTxTPlxuICAgIH1cbiAgfCB7XG4gICAgICByZWFkb25seSBmaWVsZFBhdGg6IFBcbiAgICAgIHJlYWRvbmx5IGtpbmQ6ICdjaGVjaydcbiAgICAgIHJlYWRvbmx5IG1ldGE6IENoZWNrTWV0YTx1bmtub3duLCB1bmtub3duPlxuICAgIH1cblxuZXhwb3J0IGludGVyZmFjZSBTdGF0ZVRyYWl0Tm9kZTxJbnB1dCA9IHVua25vd24sIEN0eCA9IHVua25vd24+IHtcbiAgcmVhZG9ubHkgX3RhZzogJ1N0YXRlVHJhaXROb2RlJ1xuICByZWFkb25seSBjb21wdXRlZD86IFN0YXRlVHJhaXRFbnRyeTxJbnB1dCwgYW55PiB8IFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIFN0YXRlVHJhaXRFbnRyeTxJbnB1dCwgYW55Pj4+XG4gIHJlYWRvbmx5IHNvdXJjZT86IFN0YXRlVHJhaXRFbnRyeTxJbnB1dCwgYW55PiB8IFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIFN0YXRlVHJhaXRFbnRyeTxJbnB1dCwgYW55Pj4+XG4gIHJlYWRvbmx5IGxpbms/OiBTdGF0ZVRyYWl0RW50cnk8SW5wdXQsIGFueT4gfCBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCBTdGF0ZVRyYWl0RW50cnk8SW5wdXQsIGFueT4+PlxuICByZWFkb25seSBjaGVjaz86IFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIENoZWNrUnVsZTxJbnB1dCwgQ3R4Pj4+XG4gIHJlYWRvbmx5IG1ldGE/OiBNZXRhLlRyYWl0TWV0YVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIFN0YXRlVHJhaXRMaXN0PEl0ZW0gPSB1bmtub3duPiB7XG4gIHJlYWRvbmx5IF90YWc6ICdTdGF0ZVRyYWl0TGlzdCdcbiAgcmVhZG9ubHkgaXRlbT86IFN0YXRlVHJhaXROb2RlPEl0ZW0sIGFueT5cbiAgcmVhZG9ubHkgbGlzdD86IFN0YXRlVHJhaXROb2RlPFJlYWRvbmx5QXJyYXk8SXRlbT4sIGFueT5cbiAgcmVhZG9ubHkgaWRlbnRpdHlIaW50Pzoge1xuICAgIHJlYWRvbmx5IHRyYWNrQnk/OiBzdHJpbmdcbiAgfVxufVxuXG5leHBvcnQgdHlwZSBTdGF0ZVRyYWl0U3BlY1ZhbHVlPFMsIFAgZXh0ZW5kcyBzdHJpbmc+ID1cbiAgfCBTdGF0ZVRyYWl0RW50cnk8UywgUD5cbiAgfCBTdGF0ZVRyYWl0Tm9kZTxhbnksIGFueT5cbiAgfCBTdGF0ZVRyYWl0TGlzdDxhbnk+XG5cbi8qKlxuICogU3RhdGVUcmFpdEZpZWxkXHVGRjFBXG4gKiAtIFJlcHJlc2VudHMgYSBmaWVsZCBub2RlIGluIFN0YXRlICh3aGV0aGVyIG9yIG5vdCB0cmFpdHMgYXJlIGF0dGFjaGVkKS5cbiAqIC0gTm9ybWFsaXplZCBmcm9tIFN0YXRlVHJhaXRTcGVjIGR1cmluZyBidWlsZC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTdGF0ZVRyYWl0RmllbGQge1xuICByZWFkb25seSBpZDogc3RyaW5nXG4gIHJlYWRvbmx5IHBhdGg6IHN0cmluZ1xuICByZWFkb25seSBkaXNwbGF5TmFtZT86IHN0cmluZ1xuICByZWFkb25seSB2YWx1ZVR5cGU/OiBzdHJpbmdcbiAgcmVhZG9ubHkgdHJhaXRzOiBSZWFkb25seUFycmF5PFN0YXRlVHJhaXRGaWVsZFRyYWl0PlxufVxuXG4vKipcbiAqIFN0YXRlVHJhaXRGaWVsZFRyYWl0XHVGRjFBXG4gKiAtIEEgc3RydWN0dXJlZCBkZXNjcmlwdGlvbiBvZiBhIGZpZWxkIHRyYWl0IChjb21wdXRlZCAvIHNvdXJjZSAvIGxpbmspLlxuICogLSBtZXRhIG1hdGNoZXMgU3RhdGVUcmFpdEVudHJ5Lm1ldGE7IGRlcHMgaXMgdGhlIHNldCBvZiBmaWVsZCBwYXRocyB0aGlzIHRyYWl0IGRlcGVuZHMgb24uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU3RhdGVUcmFpdEZpZWxkVHJhaXQge1xuICByZWFkb25seSBmaWVsZElkOiBzdHJpbmdcbiAgcmVhZG9ubHkga2luZDogU3RhdGVUcmFpdEtpbmRcbiAgcmVhZG9ubHkgbWV0YTpcbiAgICB8IENvbXB1dGVkTWV0YTx1bmtub3duLCBzdHJpbmc+XG4gICAgfCBTb3VyY2VNZXRhPHVua25vd24sIHN0cmluZz5cbiAgICB8IExpbmtNZXRhPHVua25vd24+XG4gICAgfCBDaGVja01ldGE8dW5rbm93biwgdW5rbm93bj5cbiAgcmVhZG9ubHkgZGVwczogUmVhZG9ubHlBcnJheTxzdHJpbmc+XG59XG5cbi8qKlxuICogU3RhdGVUcmFpdFJlc291cmNlXHVGRjFBXG4gKiAtIERlc2NyaWJlcyB0aGUgbG9naWNhbCByZXNvdXJjZSBtZXRhZGF0YSB0aGF0IGEgc291cmNlIHRyYWl0IGRlcGVuZHMgb24uXG4gKiAtIENvbmNyZXRlIFJlc291cmNlU3BlYyBpbXBsZW1lbnRhdGlvbiBsaXZlcyBpbiB0aGUgUmVzb3VyY2UgbmFtZXNwYWNlOyB0aGlzIGtlZXBzIG9ubHkgdHJhaXQtcGVyc3BlY3RpdmUgZGVwZW5kZW5jeSBpbmZvLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFN0YXRlVHJhaXRSZXNvdXJjZSB7XG4gIHJlYWRvbmx5IHJlc291cmNlSWQ6IHN0cmluZ1xuICByZWFkb25seSBrZXlTZWxlY3Rvcjogc3RyaW5nXG4gIHJlYWRvbmx5IGtleUV4YW1wbGU/OiB1bmtub3duXG4gIHJlYWRvbmx5IG93bmVyRmllbGRzOiBSZWFkb25seUFycmF5PHN0cmluZz5cbiAgcmVhZG9ubHkgbWV0YT86IE1ldGEuVHJhaXRNZXRhXG4gIHJlYWRvbmx5IG1ldGFPcmlnaW4/OiBzdHJpbmdcbiAgcmVhZG9ubHkgbWV0YUNvbmZsaWN0cz86IFJlYWRvbmx5QXJyYXk8TWV0YS5UcmFpdE1ldGFDb25mbGljdD5cbn1cblxuLyoqXG4gKiBHcmFwaCBOb2RlIC8gRWRnZVx1RkYxQVxuICogLSBOb2RlcyB0eXBpY2FsbHkgY29ycmVzcG9uZCB0byBmaWVsZHMuXG4gKiAtIEVkZ2VzIHJlcHJlc2VudCBkZXBlbmRlbmNpZXMgYmV0d2VlbiBmaWVsZHMsIG9yIGJldHdlZW4gZmllbGRzIGFuZCByZXNvdXJjZXMuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU3RhdGVUcmFpdEdyYXBoTm9kZSB7XG4gIHJlYWRvbmx5IGlkOiBzdHJpbmdcbiAgcmVhZG9ubHkgZmllbGQ6IFN0YXRlVHJhaXRGaWVsZFxuICByZWFkb25seSB0cmFpdHM6IFJlYWRvbmx5QXJyYXk8U3RhdGVUcmFpdEZpZWxkVHJhaXQ+XG4gIHJlYWRvbmx5IG1ldGE/OiBNZXRhLlRyYWl0TWV0YVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIFN0YXRlVHJhaXRHcmFwaEVkZ2Uge1xuICByZWFkb25seSBpZDogc3RyaW5nXG4gIHJlYWRvbmx5IGZyb206IHN0cmluZ1xuICByZWFkb25seSB0bzogc3RyaW5nXG4gIHJlYWRvbmx5IGtpbmQ6ICdjb21wdXRlZCcgfCAnbGluaycgfCAnc291cmNlLWRlcCcgfCAnY2hlY2stZGVwJ1xufVxuXG4vKipcbiAqIFN0YXRlVHJhaXRHcmFwaFx1RkYxQVxuICogLSBTdHJ1Y3R1cmFsIHZpZXcgb2YgdGhlIFN0YXRlVHJhaXQgZW5naW5lOiBhIGdyYXBoIG9mIG5vZGVzIGFuZCBkZXBlbmRlbmN5IGVkZ2VzLlxuICogLSBVc2VkIGJ5IERldnRvb2xzIC8gU3R1ZGlvIC8gUnVudGltZSBmb3Igc3RydWN0dXJhbCBhbmFseXNpcyBhbmQgdmlzdWFsaXphdGlvbi5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTdGF0ZVRyYWl0R3JhcGgge1xuICByZWFkb25seSBfdGFnOiAnU3RhdGVUcmFpdEdyYXBoJ1xuICByZWFkb25seSBub2RlczogUmVhZG9ubHlBcnJheTxTdGF0ZVRyYWl0R3JhcGhOb2RlPlxuICByZWFkb25seSBlZGdlczogUmVhZG9ubHlBcnJheTxTdGF0ZVRyYWl0R3JhcGhFZGdlPlxuICByZWFkb25seSByZXNvdXJjZXM6IFJlYWRvbmx5QXJyYXk8U3RhdGVUcmFpdFJlc291cmNlPlxuICByZWFkb25seSBtZXRhPzoge1xuICAgIHJlYWRvbmx5IG1vZHVsZUlkPzogc3RyaW5nXG4gICAgcmVhZG9ubHkgdmVyc2lvbj86IHN0cmluZ1xuICB9XG59XG5cbi8qKlxuICogU3RhdGVUcmFpdFBsYW5TdGVwXHVGRjFBXG4gKiAtIFRoZSBzbWFsbGVzdCBpbnN0cnVjdGlvbiB1bml0IHVzZWQgYnkgU3RhdGVUcmFpdC5pbnN0YWxsIC8gUnVudGltZSBleGVjdXRpb24uXG4gKiAtIERlcml2ZWQgZnJvbSB0aGUgZ3JhcGg7IHVzZWQgYXQgcnVudGltZSB0byBpbnN0YWxsIHdhdGNoZXJzIG9yIHRyaWdnZXIgZXh0ZXJuYWwgY2FsbHMuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU3RhdGVUcmFpdFBsYW5TdGVwIHtcbiAgcmVhZG9ubHkgaWQ6IHN0cmluZ1xuICByZWFkb25seSBraW5kOiAnY29tcHV0ZWQtdXBkYXRlJyB8ICdsaW5rLXByb3BhZ2F0ZScgfCAnc291cmNlLXJlZnJlc2gnIHwgJ2NoZWNrLXZhbGlkYXRlJ1xuICByZWFkb25seSB0YXJnZXRGaWVsZFBhdGg/OiBzdHJpbmdcbiAgcmVhZG9ubHkgc291cmNlRmllbGRQYXRocz86IFJlYWRvbmx5QXJyYXk8c3RyaW5nPlxuICByZWFkb25seSByZXNvdXJjZUlkPzogc3RyaW5nXG4gIHJlYWRvbmx5IGtleVNlbGVjdG9ySWQ/OiBzdHJpbmdcbiAgcmVhZG9ubHkgZGVidWdJbmZvPzoge1xuICAgIHJlYWRvbmx5IGdyYXBoTm9kZUlkPzogc3RyaW5nXG4gICAgcmVhZG9ubHkgZ3JhcGhFZGdlSWQ/OiBzdHJpbmdcbiAgfVxufVxuXG4vKipcbiAqIFN0YXRlVHJhaXRQbGFuXHVGRjFBXG4gKiAtIEV4ZWN1dGlvbiBwbGFuIHN1bW1hcml6aW5nIGFsbCB0cmFpdCBiZWhhdmlvcnMgZm9yIGEgbW9kdWxlLlxuICogLSBpbnN0YWxsIG1vdW50cyBiZWhhdmlvcnMgb250byBCb3VuZCBBUEkgLyBFZmZlY3RPcCBwaXBlbGluZXMgYWNjb3JkaW5nIHRvIHRoZSBwbGFuLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFN0YXRlVHJhaXRQbGFuIHtcbiAgcmVhZG9ubHkgX3RhZzogJ1N0YXRlVHJhaXRQbGFuJ1xuICByZWFkb25seSBtb2R1bGVJZD86IHN0cmluZ1xuICByZWFkb25seSBzdGVwczogUmVhZG9ubHlBcnJheTxTdGF0ZVRyYWl0UGxhblN0ZXA+XG4gIHJlYWRvbmx5IG1ldGE/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPlxufVxuXG5leHBvcnQgdHlwZSBTdGF0ZVRyYWl0U2NoZW1hUGF0aEtpbmQgPSAnZmllbGRQYXRoJyB8ICdkZXAnIHwgJ2xpbmtfZnJvbScgfCAnY2hlY2tfd3JpdGViYWNrJ1xuXG5leHBvcnQgaW50ZXJmYWNlIFN0YXRlVHJhaXRTY2hlbWFQYXRoUmVmIHtcbiAgcmVhZG9ubHkga2luZDogU3RhdGVUcmFpdFNjaGVtYVBhdGhLaW5kXG4gIHJlYWRvbmx5IGVudHJ5S2luZDogU3RhdGVUcmFpdEtpbmRcbiAgcmVhZG9ubHkgZW50cnlGaWVsZFBhdGg6IHN0cmluZ1xuICByZWFkb25seSBwYXRoOiBzdHJpbmdcbiAgcmVhZG9ubHkgcnVsZU5hbWU/OiBzdHJpbmdcbn1cblxuLyoqXG4gKiBTdGF0ZVRyYWl0UHJvZ3JhbTxTPlx1RkYxQVxuICogLSBQcm9ncmFtIG91dHB1dCBvZiB0aGUgU3RhdGVUcmFpdCBlbmdpbmU7IHRoZSB1bmlmaWVkIGVudHJ5cG9pbnQgZm9yIFJ1bnRpbWUgLyBEZXZ0b29scy5cbiAqIC0gc3RhdGVTY2hlbWEgYW5kIHNwZWMgcHJlc2VydmUgb3JpZ2luYWwgaW5wdXRzOyBncmFwaC9wbGFuIGFyZSBpbnRlcm5hbCBJUi5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTdGF0ZVRyYWl0UHJvZ3JhbTxTPiB7XG4gIHJlYWRvbmx5IHN0YXRlU2NoZW1hOiBTY2hlbWEuU2NoZW1hPFMsIGFueT5cbiAgcmVhZG9ubHkgc3BlYzogU3RhdGVUcmFpdFNwZWM8Uz5cbiAgLyoqXG4gICAqIFByb2dyYW0uZW50cmllc1x1RkYxQVxuICAgKiAtIE1pbmltYWwgcnVsZSBzZXQgbm9ybWFsaXplZCBmcm9tIHNwZWMgKGluY2x1ZGluZyBub2RlL2xpc3QvJHJvb3QpIGR1cmluZyBidWlsZC5cbiAgICogLSBQaGFzZSAyIGZvY3VzZXMgb24gYSByZWFkYWJsZS9kaWFnbm9zYWJsZSBzdHJ1Y3R1cmU7IGxhdGVyIHBoYXNlcyBhZGQgZXhlY3V0aW9uIGFuZCBjb252ZXJnZSBzZW1hbnRpY3MuXG4gICAqL1xuICByZWFkb25seSBlbnRyaWVzOiBSZWFkb25seUFycmF5PFN0YXRlVHJhaXRFbnRyeTxhbnksIHN0cmluZz4+XG4gIHJlYWRvbmx5IGdyYXBoOiBTdGF0ZVRyYWl0R3JhcGhcbiAgcmVhZG9ubHkgcGxhbjogU3RhdGVUcmFpdFBsYW5cbiAgcmVhZG9ubHkgY29udmVyZ2VJcj86IENvbnZlcmdlU3RhdGljSXJSZWdpc3RyeVxuICByZWFkb25seSBjb252ZXJnZUV4ZWNJcj86IENvbnZlcmdlRXhlY0lyXG4gIC8qKlxuICAgKiBzY2hlbWFQYXRoc1x1RkYxQVxuICAgKiAtIFBhdGggcmVmZXJlbmNlcyB0aGF0IG11c3QgZXhpc3QgaW4gc3RhdGVTY2hlbWEsIGNvbGxlY3RlZCBmcm9tIGVudHJpZXMgZHVyaW5nIGJ1aWxkOyBkZXYtb25seSBkaWFnbm9zdGljcyAoZS5nLiBzY2hlbWFfbWlzbWF0Y2gpLlxuICAgKiAtIFdoZW4gZGlhZ25vc3RpY3M9b2ZmLCB2YWxpZGF0aW9uIGNhbiBiZSBza2lwcGVkIGVudGlyZWx5IHRvIGtlZXAgbmVhci16ZXJvIGNvc3QuXG4gICAqL1xuICByZWFkb25seSBzY2hlbWFQYXRocz86IFJlYWRvbmx5QXJyYXk8U3RhdGVUcmFpdFNjaGVtYVBhdGhSZWY+XG59XG5cbi8qKlxuICogQnVpbGQgYSBub3JtYWxpemVkIGVudHJ5IGxpc3QgZnJvbSBTdGF0ZVRyYWl0U3BlYy5cbiAqXG4gKiAtIFBoYXNlIDI6IHN1cHBvcnRzIHN0cnVjdHVyYWwgZXhwYW5zaW9uIG9mIG5vZGUvbGlzdC8kcm9vdCBhbmQgZmlsbHMvcHJlZml4ZXMgZmllbGRQYXRoL2RlcHMgd2hlbiBuZWNlc3NhcnkuXG4gKiAtIExhdGVyIHBoYXNlcyBtYXkgZXh0ZW5kIHZhbGlkYXRpb24gaGVyZSAoZS5nLiBkZXRlY3RpbmcgZHVwbGljYXRlcywgb3ZlcnJpZGUgcnVsZXMsIGV0Yy4pLlxuICovXG5leHBvcnQgY29uc3Qgbm9ybWFsaXplU3BlYyA9IDxTPihzcGVjOiBTdGF0ZVRyYWl0U3BlYzxTPik6IFJlYWRvbmx5QXJyYXk8U3RhdGVUcmFpdEVudHJ5PGFueSwgc3RyaW5nPj4gPT4ge1xuICBjb25zdCBlbnRyaWVzOiBBcnJheTxTdGF0ZVRyYWl0RW50cnk8YW55LCBzdHJpbmc+PiA9IFtdXG5cbiAgY29uc3QgaXNOb2RlID0gKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgU3RhdGVUcmFpdE5vZGU8YW55LCBhbnk+ID0+XG4gICAgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiB2YWx1ZSAhPT0gbnVsbCAmJiAodmFsdWUgYXMgYW55KS5fdGFnID09PSAnU3RhdGVUcmFpdE5vZGUnXG5cbiAgY29uc3QgaXNMaXN0ID0gKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgU3RhdGVUcmFpdExpc3Q8YW55PiA9PlxuICAgIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgdmFsdWUgIT09IG51bGwgJiYgKHZhbHVlIGFzIGFueSkuX3RhZyA9PT0gJ1N0YXRlVHJhaXRMaXN0J1xuXG4gIGNvbnN0IGpvaW5QYXRoID0gKHByZWZpeDogc3RyaW5nLCBzdWZmaXg6IHN0cmluZyk6IHN0cmluZyA9PiB7XG4gICAgaWYgKCFwcmVmaXgpIHJldHVybiBzdWZmaXhcbiAgICBpZiAoIXN1ZmZpeCkgcmV0dXJuIHByZWZpeFxuICAgIHJldHVybiBgJHtwcmVmaXh9LiR7c3VmZml4fWBcbiAgfVxuXG4gIGNvbnN0IHByZWZpeERlcHMgPSAoZGVwczogUmVhZG9ubHlBcnJheTxzdHJpbmc+IHwgdW5kZWZpbmVkLCBwcmVmaXg6IHN0cmluZyk6IFJlYWRvbmx5QXJyYXk8c3RyaW5nPiA9PiB7XG4gICAgaWYgKCFkZXBzIHx8IGRlcHMubGVuZ3RoID09PSAwKSByZXR1cm4gW11cbiAgICByZXR1cm4gZGVwcy5tYXAoKGQpID0+IChwcmVmaXggPyBqb2luUGF0aChwcmVmaXgsIGQpIDogZCkpXG4gIH1cblxuICBjb25zdCBub3JtYWxpemVFbnRyeSA9IChcbiAgICBlbnRyeTogU3RhdGVUcmFpdEVudHJ5PGFueSwgc3RyaW5nPixcbiAgICBmaWVsZFBhdGg6IHN0cmluZyxcbiAgICBkZXBQcmVmaXg6IHN0cmluZyxcbiAgKTogU3RhdGVUcmFpdEVudHJ5PGFueSwgc3RyaW5nPiA9PiB7XG4gICAgaWYgKGVudHJ5LmtpbmQgPT09ICdjb21wdXRlZCcpIHtcbiAgICAgIGNvbnN0IG1ldGEgPSBlbnRyeS5tZXRhIGFzIGFueVxuICAgICAgY29uc3QgcmF3RGVwcyA9IG1ldGEuZGVwcyBhcyBSZWFkb25seUFycmF5PHN0cmluZz4gfCB1bmRlZmluZWRcbiAgICAgIGNvbnN0IGRlcHMgPSByYXdEZXBzICE9PSB1bmRlZmluZWQgPyBwcmVmaXhEZXBzKHJhd0RlcHMsIGRlcFByZWZpeCkgOiB1bmRlZmluZWRcbiAgICAgIHJldHVybiB7XG4gICAgICAgIC4uLihlbnRyeSBhcyBhbnkpLFxuICAgICAgICBmaWVsZFBhdGgsXG4gICAgICAgIG1ldGE6IHsgLi4ubWV0YSwgZGVwcyB9LFxuICAgICAgfVxuICAgIH1cbiAgICBpZiAoZW50cnkua2luZCA9PT0gJ3NvdXJjZScpIHtcbiAgICAgIGNvbnN0IG1ldGEgPSBlbnRyeS5tZXRhIGFzIGFueVxuICAgICAgY29uc3QgcmF3RGVwcyA9IG1ldGEuZGVwcyBhcyBSZWFkb25seUFycmF5PHN0cmluZz4gfCB1bmRlZmluZWRcbiAgICAgIGNvbnN0IGRlcHMgPSByYXdEZXBzICE9PSB1bmRlZmluZWQgPyBwcmVmaXhEZXBzKHJhd0RlcHMsIGRlcFByZWZpeCkgOiB1bmRlZmluZWRcbiAgICAgIHJldHVybiB7XG4gICAgICAgIC4uLihlbnRyeSBhcyBhbnkpLFxuICAgICAgICBmaWVsZFBhdGgsXG4gICAgICAgIG1ldGE6IHsgLi4ubWV0YSwgZGVwcywgX2ZpZWxkUGF0aDogZmllbGRQYXRoIH0sXG4gICAgICB9XG4gICAgfVxuICAgIGlmIChlbnRyeS5raW5kID09PSAnbGluaycpIHtcbiAgICAgIGNvbnN0IG1ldGEgPSBlbnRyeS5tZXRhIGFzIGFueVxuICAgICAgY29uc3QgZnJvbSA9IHByZWZpeERlcHMoW21ldGEuZnJvbSBhcyBzdHJpbmddLCBkZXBQcmVmaXgpWzBdID8/IG1ldGEuZnJvbVxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4uKGVudHJ5IGFzIGFueSksXG4gICAgICAgIGZpZWxkUGF0aCxcbiAgICAgICAgbWV0YTogeyAuLi5tZXRhLCBmcm9tIH0sXG4gICAgICB9XG4gICAgfVxuICAgIC8vIGNoZWNrOiBQaGFzZSAyIGFkanVzdHMgZmllbGRQYXRoIG9ubHk7IGRlcHMgYXJlIHN0aWxsIGNvbGxlY3RlZCBmcm9tIG1ldGEucnVsZXMgZHVyaW5nIGJ1aWxkLlxuICAgIHJldHVybiB7XG4gICAgICAuLi4oZW50cnkgYXMgYW55KSxcbiAgICAgIGZpZWxkUGF0aCxcbiAgICB9XG4gIH1cblxuICBjb25zdCBleHBhbmROb2RlID0gKFxuICAgIHNjb3BlSWQ6IHN0cmluZyxcbiAgICBqb2luUHJlZml4OiBzdHJpbmcsXG4gICAgbm9kZTogU3RhdGVUcmFpdE5vZGU8YW55LCBhbnk+LFxuICAgIG9wdGlvbnM/OiB7XG4gICAgICAvKipcbiAgICAgICAqIFByZWZpeCBmb3IgY2hlY2sgZGVwczogZGVmYXVsdCBzZW1hbnRpY3MgZm9yIGxpc3Qtc2NvcGUgY2hlY2tzIChkZXBzIGFyZSByZWxhdGl2ZSB0byBhIHJvdyBpdGVtIHJhdGhlciB0aGFuIHRoZSBsaXN0IHJvb3QpLlxuICAgICAgICpcbiAgICAgICAqIC0gaXRlbSBzY29wZTogZGVwc1ByZWZpeCA9IGAke2xpc3RQYXRofVtdYCAobWF0Y2hlcyBqb2luUHJlZml4KS5cbiAgICAgICAqIC0gbGlzdCBzY29wZTogZmllbGRQYXRoID0gYCR7bGlzdFBhdGh9YCwgYnV0IGRlcHNQcmVmaXggc2hvdWxkIGJlIGAke2xpc3RQYXRofVtdYC5cbiAgICAgICAqL1xuICAgICAgcmVhZG9ubHkgY2hlY2tEZXBzUHJlZml4Pzogc3RyaW5nXG4gICAgfSxcbiAgKTogdm9pZCA9PiB7XG4gICAgY29uc3QgYWRkRW50cnkgPSAocmVsYXRpdmVUYXJnZXQ6IHN0cmluZywgcmF3OiBTdGF0ZVRyYWl0RW50cnk8YW55LCBzdHJpbmc+KTogdm9pZCA9PiB7XG4gICAgICBjb25zdCByZWwgPSAocmF3IGFzIGFueSkuZmllbGRQYXRoID8/IHJlbGF0aXZlVGFyZ2V0XG4gICAgICBjb25zdCBmaWVsZFBhdGggPSBqb2luUHJlZml4ID8gam9pblBhdGgoam9pblByZWZpeCwgU3RyaW5nKHJlbCkpIDogU3RyaW5nKHJlbClcbiAgICAgIGVudHJpZXMucHVzaChub3JtYWxpemVFbnRyeShyYXcsIGZpZWxkUGF0aCwgam9pblByZWZpeCkpXG4gICAgfVxuXG4gICAgY29uc3QgZXhwYW5kTWF5YmVSZWNvcmQgPSAoXG4gICAgICB2YWx1ZTogU3RhdGVUcmFpdEVudHJ5PGFueSwgYW55PiB8IFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIFN0YXRlVHJhaXRFbnRyeTxhbnksIGFueT4+PiB8IHVuZGVmaW5lZCxcbiAgICApOiB2b2lkID0+IHtcbiAgICAgIGlmICghdmFsdWUpIHJldHVyblxuICAgICAgaWYgKHR5cGVvZiAodmFsdWUgYXMgYW55KS5raW5kID09PSAnc3RyaW5nJykge1xuICAgICAgICBhZGRFbnRyeSgnJywgdmFsdWUgYXMgYW55KVxuICAgICAgICByZXR1cm5cbiAgICAgIH1cbiAgICAgIGNvbnN0IHJlY29yZCA9IHZhbHVlIGFzIFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIFN0YXRlVHJhaXRFbnRyeTxhbnksIGFueT4+PlxuICAgICAgZm9yIChjb25zdCBrZXkgaW4gcmVjb3JkKSB7XG4gICAgICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHJlY29yZCwga2V5KSkgY29udGludWVcbiAgICAgICAgY29uc3QgZW50cnkgPSByZWNvcmRba2V5XVxuICAgICAgICBpZiAoIWVudHJ5KSBjb250aW51ZVxuICAgICAgICBhZGRFbnRyeShrZXksIGVudHJ5IGFzIGFueSlcbiAgICAgIH1cbiAgICB9XG5cbiAgICBleHBhbmRNYXliZVJlY29yZChub2RlLmNvbXB1dGVkKVxuICAgIGV4cGFuZE1heWJlUmVjb3JkKG5vZGUuc291cmNlKVxuICAgIGV4cGFuZE1heWJlUmVjb3JkKG5vZGUubGluaylcblxuICAgIGlmIChub2RlLmNoZWNrKSB7XG4gICAgICBjb25zdCBydWxlczogUmVjb3JkPHN0cmluZywgQ2hlY2tSdWxlPGFueSwgYW55Pj4gPSB7fVxuICAgICAgY29uc3QgY2hlY2tEZXBzUHJlZml4ID0gb3B0aW9ucz8uY2hlY2tEZXBzUHJlZml4ID8/IChqb2luUHJlZml4LmVuZHNXaXRoKCdbXScpID8gam9pblByZWZpeCA6ICcnKVxuXG4gICAgICBjb25zdCBwcmVmaXhDaGVja0RlcHMgPSAoZGVwczogUmVhZG9ubHlBcnJheTxzdHJpbmc+IHwgdW5kZWZpbmVkKTogUmVhZG9ubHlBcnJheTxzdHJpbmc+ID0+IHtcbiAgICAgICAgaWYgKCFkZXBzIHx8IGRlcHMubGVuZ3RoID09PSAwKSByZXR1cm4gW11cbiAgICAgICAgcmV0dXJuIGRlcHMubWFwKChkKSA9PiAoZCA9PT0gJycgPyBzY29wZUlkIDogY2hlY2tEZXBzUHJlZml4ID8gam9pblBhdGgoY2hlY2tEZXBzUHJlZml4LCBkKSA6IGQpKVxuICAgICAgfVxuICAgICAgZm9yIChjb25zdCBuYW1lIG9mIE9iamVjdC5rZXlzKG5vZGUuY2hlY2spKSB7XG4gICAgICAgIGNvbnN0IHJ1bGUgPSAobm9kZS5jaGVjayBhcyBhbnkpW25hbWVdIGFzIENoZWNrUnVsZTxhbnksIGFueT5cbiAgICAgICAgaWYgKHR5cGVvZiBydWxlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgcnVsZXNbbmFtZV0gPSBydWxlXG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfVxuICAgICAgICBpZiAocnVsZSAmJiB0eXBlb2YgcnVsZSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICBjb25zdCBtZXRhID0gTWV0YS5zYW5pdGl6ZSgocnVsZSBhcyBhbnkpLm1ldGEpXG4gICAgICAgICAgcnVsZXNbbmFtZV0gPSB7XG4gICAgICAgICAgICAuLi5ydWxlLFxuICAgICAgICAgICAgZGVwczogcHJlZml4Q2hlY2tEZXBzKHJ1bGUuZGVwcyksXG4gICAgICAgICAgICBtZXRhLFxuICAgICAgICAgIH1cbiAgICAgICAgICBjb250aW51ZVxuICAgICAgICB9XG4gICAgICAgIC8vIEludmFsaWQgaW5wdXQ6IGlnbm9yZSAobGF0ZXIgcGhhc2VzIG1heSBwcm9tb3RlIHRoaXMgaW50byBhIGJ1aWxkLXRpbWUgY29uZmlnIGVycm9yKS5cbiAgICAgIH1cblxuICAgICAgZW50cmllcy5wdXNoKHtcbiAgICAgICAgZmllbGRQYXRoOiBzY29wZUlkLFxuICAgICAgICBraW5kOiAnY2hlY2snLFxuICAgICAgICBtZXRhOiB7XG4gICAgICAgICAgcnVsZXMsXG4gICAgICAgICAgd3JpdGViYWNrOiB7IGtpbmQ6ICdlcnJvcnMnIH0sXG4gICAgICAgIH0sXG4gICAgICB9IGFzIFN0YXRlVHJhaXRFbnRyeTxhbnksIGFueT4pXG4gICAgfVxuICB9XG5cbiAgZm9yIChjb25zdCBrZXkgaW4gc3BlYykge1xuICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNwZWMsIGtleSkpIGNvbnRpbnVlXG4gICAgY29uc3QgcmF3ID0gc3BlY1trZXkgYXMga2V5b2YgdHlwZW9mIHNwZWNdIGFzIFN0YXRlVHJhaXRTcGVjVmFsdWU8UywgYW55PiB8IHVuZGVmaW5lZFxuICAgIGlmICghcmF3KSBjb250aW51ZVxuXG4gICAgaWYgKGlzTGlzdChyYXcpKSB7XG4gICAgICBjb25zdCBsaXN0UGF0aCA9IGtleVxuICAgICAgaWYgKHJhdy5pdGVtKSB7XG4gICAgICAgIGV4cGFuZE5vZGUoYCR7bGlzdFBhdGh9W11gLCBgJHtsaXN0UGF0aH1bXWAsIHJhdy5pdGVtKVxuICAgICAgfVxuICAgICAgaWYgKHJhdy5saXN0KSB7XG4gICAgICAgIGV4cGFuZE5vZGUobGlzdFBhdGgsIGxpc3RQYXRoLCByYXcubGlzdCwge1xuICAgICAgICAgIGNoZWNrRGVwc1ByZWZpeDogYCR7bGlzdFBhdGh9W11gLFxuICAgICAgICB9KVxuICAgICAgfVxuICAgICAgY29udGludWVcbiAgICB9XG5cbiAgICBpZiAoaXNOb2RlKHJhdykpIHtcbiAgICAgIGlmIChrZXkgPT09ICckcm9vdCcpIHtcbiAgICAgICAgZXhwYW5kTm9kZSgnJHJvb3QnLCAnJywgcmF3KVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZXhwYW5kTm9kZShrZXksIGtleSwgcmF3KVxuICAgICAgfVxuICAgICAgY29udGludWVcbiAgICB9XG5cbiAgICBjb25zdCBlbnRyeSA9IHJhdyBhcyBhbnkgYXMgU3RhdGVUcmFpdEVudHJ5PGFueSwgc3RyaW5nPlxuICAgIGNvbnN0IGZpZWxkUGF0aCA9IChlbnRyeSBhcyBhbnkpLmZpZWxkUGF0aCA/PyBrZXlcbiAgICBlbnRyaWVzLnB1c2gobm9ybWFsaXplRW50cnkoZW50cnksIFN0cmluZyhmaWVsZFBhdGgpLCAnJykpXG4gIH1cblxuICByZXR1cm4gZW50cmllc1xufVxuXG4vKipcbiAqIGNvbGxlY3ROb2RlTWV0YVx1RkYxQVxuICogLSBFeHRyYWN0IFN0YXRlVHJhaXROb2RlLm1ldGEgKHdoaXRlbGlzdGVkIGZpZWxkcykgZnJvbSBTdGF0ZVRyYWl0U3BlYyBmb3IgZGV2dG9vbHMgc3RydWN0dXJhbCBkaXNwbGF5LlxuICogLSBtZXRhIGlzIGZvciBkaWFnbm9zdGljcy9kaXNwbGF5IG9ubHkgYW5kIGRvZXMgbm90IHBhcnRpY2lwYXRlIGluIHJ1bnRpbWUgc2VtYW50aWNzLlxuICovXG5leHBvcnQgY29uc3QgY29sbGVjdE5vZGVNZXRhID0gPFM+KHNwZWM6IFN0YXRlVHJhaXRTcGVjPFM+KTogUmVhZG9ubHlNYXA8c3RyaW5nLCBNZXRhLlRyYWl0TWV0YT4gPT4ge1xuICBjb25zdCBvdXQgPSBuZXcgTWFwPHN0cmluZywgTWV0YS5UcmFpdE1ldGE+KClcblxuICBjb25zdCBpc05vZGUgPSAodmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBTdGF0ZVRyYWl0Tm9kZTxhbnksIGFueT4gPT5cbiAgICB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmIHZhbHVlICE9PSBudWxsICYmICh2YWx1ZSBhcyBhbnkpLl90YWcgPT09ICdTdGF0ZVRyYWl0Tm9kZSdcblxuICBjb25zdCBpc0xpc3QgPSAodmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBTdGF0ZVRyYWl0TGlzdDxhbnk+ID0+XG4gICAgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiB2YWx1ZSAhPT0gbnVsbCAmJiAodmFsdWUgYXMgYW55KS5fdGFnID09PSAnU3RhdGVUcmFpdExpc3QnXG5cbiAgY29uc3QgYWRkID0gKHNjb3BlSWQ6IHN0cmluZywgbm9kZTogU3RhdGVUcmFpdE5vZGU8YW55LCBhbnk+KTogdm9pZCA9PiB7XG4gICAgY29uc3QgbWV0YSA9IE1ldGEuc2FuaXRpemUobm9kZS5tZXRhKVxuICAgIGlmIChtZXRhKSBvdXQuc2V0KHNjb3BlSWQsIG1ldGEpXG4gIH1cblxuICBmb3IgKGNvbnN0IGtleSBpbiBzcGVjKSB7XG4gICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoc3BlYywga2V5KSkgY29udGludWVcbiAgICBjb25zdCByYXcgPSBzcGVjW2tleSBhcyBrZXlvZiB0eXBlb2Ygc3BlY10gYXMgU3RhdGVUcmFpdFNwZWNWYWx1ZTxTLCBhbnk+IHwgdW5kZWZpbmVkXG4gICAgaWYgKCFyYXcpIGNvbnRpbnVlXG5cbiAgICBpZiAoaXNMaXN0KHJhdykpIHtcbiAgICAgIGNvbnN0IGxpc3RQYXRoID0ga2V5XG4gICAgICBpZiAocmF3Lml0ZW0pIGFkZChgJHtsaXN0UGF0aH1bXWAsIHJhdy5pdGVtKVxuICAgICAgaWYgKHJhdy5saXN0KSBhZGQobGlzdFBhdGgsIHJhdy5saXN0KVxuICAgICAgY29udGludWVcbiAgICB9XG5cbiAgICBpZiAoaXNOb2RlKHJhdykpIHtcbiAgICAgIGlmIChrZXkgPT09ICckcm9vdCcpIGFkZCgnJHJvb3QnLCByYXcpXG4gICAgICBlbHNlIGFkZChrZXksIHJhdylcbiAgICAgIGNvbnRpbnVlXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG91dFxufVxuXG4vLyAtLS0tIENvbnZlcmdlICgwMTMpIGV2aWRlbmNlIG1vZGVsIC0tLS1cblxuZXhwb3J0IHR5cGUgVHJhaXRDb252ZXJnZVJlcXVlc3RlZE1vZGUgPSAnYXV0bycgfCAnZnVsbCcgfCAnZGlydHknXG5leHBvcnQgdHlwZSBUcmFpdENvbnZlcmdlRXhlY3V0ZWRNb2RlID0gJ2Z1bGwnIHwgJ2RpcnR5J1xuZXhwb3J0IHR5cGUgVHJhaXRDb252ZXJnZU91dGNvbWUgPSAnQ29udmVyZ2VkJyB8ICdOb29wJyB8ICdEZWdyYWRlZCdcblxuZXhwb3J0IHR5cGUgVHJhaXRDb252ZXJnZUNvbmZpZ1Njb3BlID0gJ3Byb3ZpZGVyJyB8ICdydW50aW1lX21vZHVsZScgfCAncnVudGltZV9kZWZhdWx0JyB8ICdidWlsdGluJ1xuXG5leHBvcnQgdHlwZSBUcmFpdENvbnZlcmdlUmVhc29uID1cbiAgfCAnY29sZF9zdGFydCdcbiAgfCAnY2FjaGVfaGl0J1xuICB8ICdjYWNoZV9taXNzJ1xuICB8ICdidWRnZXRfY3V0b2ZmJ1xuICB8ICduZWFyX2Z1bGwnXG4gIHwgJ3Vua25vd25fd3JpdGUnXG4gIHwgJ2RpcnR5X2FsbCdcbiAgfCAnZ2VuZXJhdGlvbl9idW1wZWQnXG4gIHwgJ2xvd19oaXRfcmF0ZV9wcm90ZWN0aW9uJ1xuICB8ICdtb2R1bGVfb3ZlcnJpZGUnXG4gIHwgJ3RpbWVfc2xpY2luZ19pbW1lZGlhdGUnXG4gIHwgJ3RpbWVfc2xpY2luZ19kZWZlcnJlZCdcblxuZXhwb3J0IGludGVyZmFjZSBUcmFpdENvbnZlcmdlU3RlcFN0YXRzIHtcbiAgcmVhZG9ubHkgdG90YWxTdGVwczogbnVtYmVyXG4gIHJlYWRvbmx5IGV4ZWN1dGVkU3RlcHM6IG51bWJlclxuICByZWFkb25seSBza2lwcGVkU3RlcHM6IG51bWJlclxuICByZWFkb25seSBjaGFuZ2VkU3RlcHM6IG51bWJlclxuICByZWFkb25seSBhZmZlY3RlZFN0ZXBzPzogbnVtYmVyXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVHJhaXRDb252ZXJnZURpcnR5U3VtbWFyeSB7XG4gIHJlYWRvbmx5IGRpcnR5QWxsOiBib29sZWFuXG4gIHJlYWRvbmx5IHJlYXNvbj86IERpcnR5QWxsUmVhc29uXG4gIHJlYWRvbmx5IHJvb3RDb3VudD86IG51bWJlclxuICByZWFkb25seSByb290SWRzPzogUmVhZG9ubHlBcnJheTxudW1iZXI+XG4gIHJlYWRvbmx5IHJvb3RJZHNUcnVuY2F0ZWQ/OiBib29sZWFuXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVHJhaXRDb252ZXJnZVBsYW5DYWNoZUV2aWRlbmNlIHtcbiAgcmVhZG9ubHkgY2FwYWNpdHk6IG51bWJlclxuICByZWFkb25seSBzaXplOiBudW1iZXJcbiAgcmVhZG9ubHkgaGl0czogbnVtYmVyXG4gIHJlYWRvbmx5IG1pc3NlczogbnVtYmVyXG4gIHJlYWRvbmx5IGV2aWN0czogbnVtYmVyXG4gIHJlYWRvbmx5IGhpdDogYm9vbGVhblxuICByZWFkb25seSBrZXlTaXplPzogbnVtYmVyXG4gIHJlYWRvbmx5IG1pc3NSZWFzb24/OiAnY29sZF9zdGFydCcgfCAnZ2VuZXJhdGlvbl9idW1wZWQnIHwgJ25vdF9jYWNoZWQnIHwgJ3Vua25vd24nXG4gIHJlYWRvbmx5IGRpc2FibGVkPzogYm9vbGVhblxuICByZWFkb25seSBkaXNhYmxlUmVhc29uPzogJ2xvd19oaXRfcmF0ZScgfCAnZ2VuZXJhdGlvbl90aHJhc2gnIHwgJ21hbnVhbF9vdmVycmlkZScgfCAndW5rbm93bidcbn1cblxuZXhwb3J0IHR5cGUgVHJhaXRDb252ZXJnZUdlbmVyYXRpb25CdW1wUmVhc29uID1cbiAgfCAnd3JpdGVyc19jaGFuZ2VkJ1xuICB8ICdkZXBzX2NoYW5nZWQnXG4gIHwgJ2xvZ2ljX2luc3RhbGxlZCdcbiAgfCAnbG9naWNfdW5pbnN0YWxsZWQnXG4gIHwgJ2ltcG9ydHNfY2hhbmdlZCdcbiAgfCAndW5rbm93bidcblxuZXhwb3J0IGludGVyZmFjZSBUcmFpdENvbnZlcmdlR2VuZXJhdGlvbkV2aWRlbmNlIHtcbiAgcmVhZG9ubHkgZ2VuZXJhdGlvbjogbnVtYmVyXG4gIHJlYWRvbmx5IGdlbmVyYXRpb25CdW1wQ291bnQ/OiBudW1iZXJcbiAgcmVhZG9ubHkgbGFzdEJ1bXBSZWFzb24/OiBUcmFpdENvbnZlcmdlR2VuZXJhdGlvbkJ1bXBSZWFzb25cbn1cblxuZXhwb3J0IGludGVyZmFjZSBUcmFpdENvbnZlcmdlU3RhdGljSXJFdmlkZW5jZSB7XG4gIHJlYWRvbmx5IGZpZWxkUGF0aENvdW50OiBudW1iZXJcbiAgcmVhZG9ubHkgc3RlcENvdW50OiBudW1iZXJcbiAgcmVhZG9ubHkgYnVpbGREdXJhdGlvbk1zPzogbnVtYmVyXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVHJhaXRDb252ZXJnZUhvdHNwb3Qge1xuICByZWFkb25seSBraW5kPzogc3RyaW5nXG4gIHJlYWRvbmx5IHN0ZXBJZDogbnVtYmVyXG4gIHJlYWRvbmx5IG91dEZpZWxkUGF0aElkPzogbnVtYmVyXG4gIHJlYWRvbmx5IGR1cmF0aW9uTXM6IG51bWJlclxuICByZWFkb25seSBjaGFuZ2VkOiBib29sZWFuXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVHJhaXRDb252ZXJnZVRpbWVTbGljaW5nU3VtbWFyeSB7XG4gIHJlYWRvbmx5IHNjb3BlOiAnYWxsJyB8ICdpbW1lZGlhdGUnIHwgJ2RlZmVycmVkJ1xuICByZWFkb25seSBpbW1lZGlhdGVTdGVwQ291bnQ6IG51bWJlclxuICByZWFkb25seSBkZWZlcnJlZFN0ZXBDb3VudDogbnVtYmVyXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVHJhaXRDb252ZXJnZURpYWdub3N0aWNzU2FtcGxpbmdTdW1tYXJ5IHtcbiAgLyoqXG4gICAqIERldGVybWluaXN0aWMgc2FtcGxpbmc6IHVzZSBzdGFibGUgdHhuU2VxIGFzIGFuIGFuY2hvciBhbmQgc2FtcGxlIGV2ZXJ5IE4gdHJhbnNhY3Rpb25zLlxuICAgKiAtIHNhbXBsZWQ9dHJ1ZSBtZWFucyB0aGlzIGludm9jYXRpb24gY2FwdHVyZWQgcGVyLXN0ZXAgdGltaW5ncyBhbmQgcHJvZHVjZWQgaG90c3BvdHMuXG4gICAqL1xuICByZWFkb25seSBzdHJhdGVneTogJ3R4blNlcV9pbnRlcnZhbCdcbiAgcmVhZG9ubHkgc2FtcGxlRXZlcnlOOiBudW1iZXJcbiAgcmVhZG9ubHkgdG9wSzogbnVtYmVyXG4gIHJlYWRvbmx5IHNhbXBsZWQ6IGJvb2xlYW5cbn1cblxuZXhwb3J0IGludGVyZmFjZSBUcmFpdENvbnZlcmdlRGVjaXNpb25TdW1tYXJ5IHtcbiAgcmVhZG9ubHkgcmVxdWVzdGVkTW9kZTogVHJhaXRDb252ZXJnZVJlcXVlc3RlZE1vZGVcbiAgcmVhZG9ubHkgZXhlY3V0ZWRNb2RlOiBUcmFpdENvbnZlcmdlRXhlY3V0ZWRNb2RlXG4gIHJlYWRvbmx5IG91dGNvbWU6IFRyYWl0Q29udmVyZ2VPdXRjb21lXG4gIHJlYWRvbmx5IGNvbmZpZ1Njb3BlOiBUcmFpdENvbnZlcmdlQ29uZmlnU2NvcGVcbiAgcmVhZG9ubHkgc3RhdGljSXJEaWdlc3Q6IHN0cmluZ1xuICByZWFkb25seSBleGVjdXRpb25CdWRnZXRNczogbnVtYmVyXG4gIHJlYWRvbmx5IGV4ZWN1dGlvbkR1cmF0aW9uTXM6IG51bWJlclxuICByZWFkb25seSBkZWNpc2lvbkJ1ZGdldE1zPzogbnVtYmVyXG4gIHJlYWRvbmx5IGRlY2lzaW9uRHVyYXRpb25Ncz86IG51bWJlclxuICByZWFkb25seSByZWFzb25zOiBSZWFkb25seUFycmF5PFRyYWl0Q29udmVyZ2VSZWFzb24+XG4gIHJlYWRvbmx5IHN0ZXBTdGF0czogVHJhaXRDb252ZXJnZVN0ZXBTdGF0c1xuICByZWFkb25seSBkaXJ0eT86IFRyYWl0Q29udmVyZ2VEaXJ0eVN1bW1hcnlcbiAgcmVhZG9ubHkgY2FjaGU/OiBUcmFpdENvbnZlcmdlUGxhbkNhY2hlRXZpZGVuY2VcbiAgcmVhZG9ubHkgZ2VuZXJhdGlvbj86IFRyYWl0Q29udmVyZ2VHZW5lcmF0aW9uRXZpZGVuY2VcbiAgcmVhZG9ubHkgc3RhdGljSXI/OiBUcmFpdENvbnZlcmdlU3RhdGljSXJFdmlkZW5jZVxuICByZWFkb25seSB0aW1lU2xpY2luZz86IFRyYWl0Q29udmVyZ2VUaW1lU2xpY2luZ1N1bW1hcnlcbiAgcmVhZG9ubHkgdGhyZXNob2xkcz86IHsgcmVhZG9ubHkgZmxvb3JSYXRpbz86IG51bWJlciB9XG4gIHJlYWRvbmx5IGRpYWdub3N0aWNzU2FtcGxpbmc/OiBUcmFpdENvbnZlcmdlRGlhZ25vc3RpY3NTYW1wbGluZ1N1bW1hcnlcbiAgcmVhZG9ubHkgdG9wMz86IFJlYWRvbmx5QXJyYXk8VHJhaXRDb252ZXJnZUhvdHNwb3Q+XG59XG4iLCAiaW1wb3J0IHsgRWZmZWN0LCBGaWJlciwgRmliZXJSZWYsIE9wdGlvbiB9IGZyb20gJ2VmZmVjdCdcbmltcG9ydCB7IGNyZWF0ZSB9IGZyb20gJ211dGF0aXZlJ1xuaW1wb3J0ICogYXMgRWZmZWN0T3AgZnJvbSAnLi4vZWZmZWN0LW9wLmpzJ1xuaW1wb3J0IHsgU25hcHNob3QsIGludGVybmFsIGFzIFJlc291cmNlSW50ZXJuYWwsIGtleUhhc2ggYXMgaGFzaEtleSB9IGZyb20gJy4uL3Jlc291cmNlLmpzJ1xuaW1wb3J0ICogYXMgRWZmZWN0T3BDb3JlIGZyb20gJy4uL3J1bnRpbWUvY29yZS9FZmZlY3RPcENvcmUuanMnXG5pbXBvcnQgKiBhcyBEZWJ1ZyBmcm9tICcuLi9ydW50aW1lL2NvcmUvRGVidWdTaW5rLmpzJ1xuaW1wb3J0ICogYXMgVGFza1J1bm5lciBmcm9tICcuLi9ydW50aW1lL2NvcmUvVGFza1J1bm5lci5qcydcbmltcG9ydCB7IGlzRGV2RW52LCBSZXBsYXlNb2RlQ29uZmlnVGFnIH0gZnJvbSAnLi4vcnVudGltZS9jb3JlL2Vudi5qcydcbmltcG9ydCAqIGFzIFJlcGxheUxvZyBmcm9tICcuLi9ydW50aW1lL2NvcmUvUmVwbGF5TG9nLmpzJ1xuaW1wb3J0IHR5cGUgeyBQYXRjaFJlYXNvbiB9IGZyb20gJy4uL3J1bnRpbWUvY29yZS9TdGF0ZVRyYW5zYWN0aW9uLmpzJ1xuaW1wb3J0IHR5cGUgeyBGaWVsZFBhdGgsIEZpZWxkUGF0aElkIH0gZnJvbSAnLi4vZmllbGQtcGF0aC5qcydcbmltcG9ydCB7IG5vcm1hbGl6ZUZpZWxkUGF0aCB9IGZyb20gJy4uL2ZpZWxkLXBhdGguanMnXG5pbXBvcnQgdHlwZSB7IEJvdW5kQXBpIH0gZnJvbSAnLi4vcnVudGltZS9jb3JlL21vZHVsZS5qcydcbmltcG9ydCB7IGdldEJvdW5kSW50ZXJuYWxzIH0gZnJvbSAnLi4vcnVudGltZS9jb3JlL3J1bnRpbWVJbnRlcm5hbHNBY2Nlc3Nvci5qcydcbmltcG9ydCB7IFJ1blNlc3Npb25UYWcgfSBmcm9tICcuLi9vYnNlcnZhYmlsaXR5L3J1blNlc3Npb24uanMnXG5pbXBvcnQgKiBhcyBEZXBzVHJhY2UgZnJvbSAnLi9kZXBzLXRyYWNlLmpzJ1xuaW1wb3J0ICogYXMgUm93SWQgZnJvbSAnLi9yb3dpZC5qcydcbmltcG9ydCB0eXBlIHsgU3RhdGVUcmFpdEVudHJ5LCBTdGF0ZVRyYWl0UGxhblN0ZXAsIFN0YXRlVHJhaXRQcm9ncmFtIH0gZnJvbSAnLi9tb2RlbC5qcydcblxuZXhwb3J0IGludGVyZmFjZSBTb3VyY2VTeW5jQ29udGV4dDxTPiB7XG4gIHJlYWRvbmx5IG1vZHVsZUlkPzogc3RyaW5nXG4gIHJlYWRvbmx5IGluc3RhbmNlSWQ/OiBzdHJpbmdcbiAgcmVhZG9ubHkgZ2V0RHJhZnQ6ICgpID0+IFNcbiAgcmVhZG9ubHkgc2V0RHJhZnQ6IChuZXh0OiBTKSA9PiB2b2lkXG4gIHJlYWRvbmx5IHJlY29yZFBhdGNoOiAoXG4gICAgcGF0aDogc3RyaW5nIHwgRmllbGRQYXRoIHwgRmllbGRQYXRoSWQgfCB1bmRlZmluZWQsXG4gICAgcmVhc29uOiBQYXRjaFJlYXNvbixcbiAgICBmcm9tPzogdW5rbm93bixcbiAgICB0bz86IHVua25vd24sXG4gICAgdHJhaXROb2RlSWQ/OiBzdHJpbmcsXG4gICAgc3RlcElkPzogbnVtYmVyLFxuICApID0+IHZvaWRcbn1cblxuY29uc3Qgb25jZUluUnVuU2Vzc2lvbiA9IChrZXk6IHN0cmluZyk6IEVmZmVjdC5FZmZlY3Q8Ym9vbGVhbiwgbmV2ZXIsIGFueT4gPT5cbiAgRWZmZWN0LnNlcnZpY2VPcHRpb24oUnVuU2Vzc2lvblRhZykucGlwZShcbiAgICBFZmZlY3QubWFwKChtYXliZSkgPT4gKE9wdGlvbi5pc1NvbWUobWF5YmUpID8gbWF5YmUudmFsdWUubG9jYWwub25jZShrZXkpIDogdHJ1ZSkpLFxuICApXG5cbmNvbnN0IGZvcm1hdExpc3QgPSAoaXRlbXM6IFJlYWRvbmx5QXJyYXk8c3RyaW5nPiwgbGltaXQgPSAxMCk6IHN0cmluZyA9PiB7XG4gIGlmIChpdGVtcy5sZW5ndGggPT09IDApIHJldHVybiAnJ1xuICBpZiAoaXRlbXMubGVuZ3RoIDw9IGxpbWl0KSByZXR1cm4gaXRlbXMuam9pbignLCAnKVxuICByZXR1cm4gYCR7aXRlbXMuc2xpY2UoMCwgbGltaXQpLmpvaW4oJywgJyl9LCBcdTIwMjYoKyR7aXRlbXMubGVuZ3RoIC0gbGltaXR9KWBcbn1cblxuY29uc3QgZW1pdERlcHNNaXNtYXRjaCA9IChwYXJhbXM6IHtcbiAgcmVhZG9ubHkgbW9kdWxlSWQ/OiBzdHJpbmdcbiAgcmVhZG9ubHkgaW5zdGFuY2VJZD86IHN0cmluZ1xuICByZWFkb25seSBraW5kOiAnY29tcHV0ZWQnIHwgJ3NvdXJjZSdcbiAgcmVhZG9ubHkgZmllbGRQYXRoOiBzdHJpbmdcbiAgcmVhZG9ubHkgZGlmZjogRGVwc1RyYWNlLkRlcHNEaWZmXG59KTogRWZmZWN0LkVmZmVjdDx2b2lkLCBuZXZlciwgYW55PiA9PlxuICBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG4gICAgY29uc3Qga2V5ID0gYCR7cGFyYW1zLmluc3RhbmNlSWQgPz8gJ3Vua25vd24nfTo6JHtwYXJhbXMua2luZH06OiR7cGFyYW1zLmZpZWxkUGF0aH1gXG4gICAgY29uc3Qgc2hvdWxkRW1pdCA9IHlpZWxkKiBvbmNlSW5SdW5TZXNzaW9uKGBkZXBzX21pc21hdGNoOiR7a2V5fWApXG4gICAgaWYgKCFzaG91bGRFbWl0KSByZXR1cm5cblxuICAgIHlpZWxkKiBEZWJ1Zy5yZWNvcmQoe1xuICAgICAgdHlwZTogJ2RpYWdub3N0aWMnLFxuICAgICAgbW9kdWxlSWQ6IHBhcmFtcy5tb2R1bGVJZCxcbiAgICAgIGluc3RhbmNlSWQ6IHBhcmFtcy5pbnN0YW5jZUlkLFxuICAgICAgY29kZTogJ3N0YXRlX3RyYWl0OjpkZXBzX21pc21hdGNoJyxcbiAgICAgIHNldmVyaXR5OiAnd2FybmluZycsXG4gICAgICBtZXNzYWdlOlxuICAgICAgICBgW2RlcHNdICR7cGFyYW1zLmtpbmR9IFwiJHtwYXJhbXMuZmllbGRQYXRofVwiIGRlY2xhcmVkPVske2Zvcm1hdExpc3QocGFyYW1zLmRpZmYuZGVjbGFyZWQpfV0gYCArXG4gICAgICAgIGByZWFkcz1bJHtmb3JtYXRMaXN0KHBhcmFtcy5kaWZmLnJlYWRzKX1dIG1pc3Npbmc9WyR7Zm9ybWF0TGlzdChwYXJhbXMuZGlmZi5taXNzaW5nKX1dIGAgK1xuICAgICAgICBgdW51c2VkPVske2Zvcm1hdExpc3QocGFyYW1zLmRpZmYudW51c2VkKX1dYCxcbiAgICAgIGhpbnQ6XG4gICAgICAgICdkZXBzIGlzIHRoZSBzaW5nbGUgc291cmNlIG9mIHRydXRoIGZvciBkZXBlbmRlbmNpZXM6IGluY3JlbWVudGFsIHNjaGVkdWxpbmcgLyByZXZlcnNlIGNsb3N1cmVzIC8gcGVyZm9ybWFuY2Ugb3B0aW1pemF0aW9ucyByZWx5IG9uIGRlcHMgb25seS4gJyArXG4gICAgICAgICdLZWVwIGRlcHMgY29uc2lzdGVudCB3aXRoIGFjdHVhbCByZWFkczsgaWYgeW91IHJlYWxseSBkZXBlbmQgb24gdGhlIHdob2xlIG9iamVjdCwgZGVjbGFyZSBhIGNvYXJzZXItZ3JhaW5lZCBkZXAgKGUuZy4gXCJwcm9maWxlXCIpIHRvIGNvdmVyIHN1Yi1maWVsZCByZWFkcy4nLFxuICAgICAga2luZDogYGRlcHNfbWlzbWF0Y2g6JHtwYXJhbXMua2luZH1gLFxuICAgIH0pXG4gIH0pXG5cbmNvbnN0IGdldE1pZGRsZXdhcmVTdGFjayA9ICgpOiBFZmZlY3QuRWZmZWN0PEVmZmVjdE9wLk1pZGRsZXdhcmVTdGFjaywgbmV2ZXIsIGFueT4gPT5cbiAgRWZmZWN0LnNlcnZpY2VPcHRpb24oRWZmZWN0T3BDb3JlLkVmZmVjdE9wTWlkZGxld2FyZVRhZykucGlwZShcbiAgICBFZmZlY3QubWFwKChtYXliZSkgPT4gKE9wdGlvbi5pc1NvbWUobWF5YmUpID8gbWF5YmUudmFsdWUuc3RhY2sgOiBbXSkpLFxuICApXG5cbmNvbnN0IHJlY29yZFRyYWl0UGF0Y2ggPSAoXG4gIGJvdW5kOiBCb3VuZEFwaTxhbnksIGFueT4sXG4gIHBhdGg6IHN0cmluZyxcbiAgcmVhc29uOiBQYXRjaFJlYXNvbixcbiAgZnJvbT86IHVua25vd24sXG4gIHRvPzogdW5rbm93bixcbiAgdHJhaXROb2RlSWQ/OiBzdHJpbmcsXG4pOiB2b2lkID0+IHtcbiAgY29uc3Qgbm9ybWFsaXplZCA9IG5vcm1hbGl6ZUZpZWxkUGF0aChwYXRoKSA/PyBbXVxuICB0cnkge1xuICAgIGNvbnN0IGludGVybmFscyA9IGdldEJvdW5kSW50ZXJuYWxzKGJvdW5kIGFzIGFueSlcbiAgICBpbnRlcm5hbHMudHhuLnJlY29yZFN0YXRlUGF0Y2gobm9ybWFsaXplZCwgcmVhc29uLCBmcm9tLCB0bywgdHJhaXROb2RlSWQpXG4gIH0gY2F0Y2gge1xuICAgIC8vIG5vLW9wIGZvciBsZWdhY3kvbW9ja2VkIGJvdW5kXG4gIH1cbn1cblxuY29uc3QgcmVjb3JkUmVwbGF5RXZlbnQgPSAoYm91bmQ6IEJvdW5kQXBpPGFueSwgYW55PiwgZXZlbnQ6IFJlcGxheUxvZy5SZXBsYXlMb2dFdmVudCk6IHZvaWQgPT4ge1xuICB0cnkge1xuICAgIGNvbnN0IGludGVybmFscyA9IGdldEJvdW5kSW50ZXJuYWxzKGJvdW5kIGFzIGFueSlcbiAgICBpbnRlcm5hbHMudHhuLnJlY29yZFJlcGxheUV2ZW50KGV2ZW50KVxuICB9IGNhdGNoIHtcbiAgICAvLyBuby1vcCBmb3IgbGVnYWN5L21vY2tlZCBib3VuZFxuICB9XG59XG5cbmNvbnN0IGdldEJvdW5kU2NvcGUgPSAoYm91bmQ6IEJvdW5kQXBpPGFueSwgYW55Pik6IHsgcmVhZG9ubHkgbW9kdWxlSWQ/OiBzdHJpbmc7IHJlYWRvbmx5IGluc3RhbmNlSWQ/OiBzdHJpbmcgfSA9PiB7XG4gIHRyeSB7XG4gICAgY29uc3QgaW50ZXJuYWxzID0gZ2V0Qm91bmRJbnRlcm5hbHMoYm91bmQgYXMgYW55KVxuICAgIHJldHVybiB7IG1vZHVsZUlkOiBpbnRlcm5hbHMubW9kdWxlSWQsIGluc3RhbmNlSWQ6IGludGVybmFscy5pbnN0YW5jZUlkIH1cbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIHsgbW9kdWxlSWQ6IHVuZGVmaW5lZCwgaW5zdGFuY2VJZDogdW5kZWZpbmVkIH1cbiAgfVxufVxuXG5jb25zdCBzZXRTbmFwc2hvdEluVHhuID0gKFxuICBib3VuZDogQm91bmRBcGk8YW55LCBhbnk+LFxuICBmaWVsZFBhdGg6IHN0cmluZyxcbiAgbmV4dDogdW5rbm93bixcbiAgcmVhc29uOiBQYXRjaFJlYXNvbixcbiAgc3RlcElkOiBzdHJpbmcsXG4gIHRyYWl0Tm9kZUlkPzogc3RyaW5nLFxuKTogRWZmZWN0LkVmZmVjdDxib29sZWFuLCBuZXZlciwgYW55PiA9PlxuICBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG4gICAgbGV0IHdyb3RlID0gZmFsc2VcbiAgICB5aWVsZCogYm91bmQuc3RhdGUubXV0YXRlKChkcmFmdCkgPT4ge1xuICAgICAgY29uc3QgcHJldiA9IFJvd0lkLmdldEF0UGF0aChkcmFmdCwgZmllbGRQYXRoKVxuICAgICAgaWYgKE9iamVjdC5pcyhwcmV2LCBuZXh0KSkgcmV0dXJuXG4gICAgICB3cm90ZSA9IHRydWVcbiAgICAgIFJvd0lkLnNldEF0UGF0aE11dGF0aW5nKGRyYWZ0LCBmaWVsZFBhdGgsIG5leHQpXG4gICAgICByZWNvcmRUcmFpdFBhdGNoKGJvdW5kLCBmaWVsZFBhdGgsIHJlYXNvbiwgcHJldiwgbmV4dCwgdHJhaXROb2RlSWQpXG4gICAgfSlcbiAgICByZXR1cm4gd3JvdGVcbiAgfSlcblxuY29uc3Qgd3JpdGViYWNrSWZDdXJyZW50S2V5SGFzaCA9IChcbiAgYm91bmQ6IEJvdW5kQXBpPGFueSwgYW55PixcbiAgZmllbGRQYXRoOiBzdHJpbmcsXG4gIGtleUhhc2g6IHN0cmluZyxcbiAgbmV4dDogdW5rbm93bixcbiAgcmVhc29uOiBQYXRjaFJlYXNvbixcbiAgc3RlcElkOiBzdHJpbmcsXG4gIHRyYWl0Tm9kZUlkPzogc3RyaW5nLFxuICByZXBsYXlFdmVudD86IFJlcGxheUxvZy5SZXBsYXlMb2dFdmVudCxcbik6IEVmZmVjdC5FZmZlY3Q8Ym9vbGVhbiwgbmV2ZXIsIGFueT4gPT5cbiAgRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgIGxldCB3cm90ZSA9IGZhbHNlXG4gICAgeWllbGQqIGJvdW5kLnN0YXRlLm11dGF0ZSgoZHJhZnQpID0+IHtcbiAgICAgIGNvbnN0IGN1cnJlbnQgPSBSb3dJZC5nZXRBdFBhdGgoZHJhZnQsIGZpZWxkUGF0aClcbiAgICAgIGNvbnN0IGN1cnJlbnRLZXlIYXNoID0gY3VycmVudCAmJiB0eXBlb2YgY3VycmVudCA9PT0gJ29iamVjdCcgPyAoY3VycmVudCBhcyBhbnkpLmtleUhhc2ggOiB1bmRlZmluZWRcbiAgICAgIGlmIChjdXJyZW50S2V5SGFzaCAhPT0ga2V5SGFzaCkgcmV0dXJuXG5cbiAgICAgIGNvbnN0IHByZXYgPSBjdXJyZW50XG4gICAgICBpZiAoT2JqZWN0LmlzKHByZXYsIG5leHQpKSByZXR1cm5cblxuICAgICAgd3JvdGUgPSB0cnVlXG4gICAgICBSb3dJZC5zZXRBdFBhdGhNdXRhdGluZyhkcmFmdCwgZmllbGRQYXRoLCBuZXh0KVxuICAgICAgaWYgKHJlcGxheUV2ZW50KSB7XG4gICAgICAgIHJlY29yZFJlcGxheUV2ZW50KGJvdW5kLCByZXBsYXlFdmVudClcbiAgICAgIH1cbiAgICAgIHJlY29yZFRyYWl0UGF0Y2goYm91bmQsIGZpZWxkUGF0aCwgcmVhc29uLCBwcmV2LCBuZXh0LCB0cmFpdE5vZGVJZClcbiAgICB9KVxuICAgIHJldHVybiB3cm90ZVxuICB9KVxuXG4vKipcbiAqIHN5bmNJZGxlSW5UcmFuc2FjdGlvblx1RkYxQVxuICogLSBTeW5jaHJvbm91c2x5IGV2YWx1YXRlIGFsbCBzb3VyY2Uua2V5KHN0YXRlKSB3aXRoaW4gdGhlIHRyYW5zYWN0aW9uIHdpbmRvdy5cbiAqIC0gSWYgYSBrZXkgYmVjb21lcyBlbXB0eSAodW5kZWZpbmVkKSwgc3luY2hyb25vdXNseSByZXNldCB0aGUgZmllbGQgdG8gYW4gaWRsZSBzbmFwc2hvdCAoYXZvaWQgdGVhcmluZykuXG4gKi9cbmV4cG9ydCBjb25zdCBzeW5jSWRsZUluVHJhbnNhY3Rpb24gPSA8UyBleHRlbmRzIG9iamVjdD4oXG4gIHByb2dyYW06IFN0YXRlVHJhaXRQcm9ncmFtPFM+LFxuICBjdHg6IFNvdXJjZVN5bmNDb250ZXh0PFM+LFxuKTogRWZmZWN0LkVmZmVjdDx2b2lkPiA9PlxuICBFZmZlY3Quc3luYygoKSA9PiB7XG4gICAgY29uc3QgZHJhZnQgPSBjdHguZ2V0RHJhZnQoKSBhcyBhbnlcbiAgICBjb25zdCB1cGRhdGVzOiBBcnJheTx7IHJlYWRvbmx5IGZpZWxkUGF0aDogc3RyaW5nOyByZWFkb25seSBwcmV2OiB1bmtub3duIH0+ID0gW11cblxuICAgIGZvciAoY29uc3QgZW50cnkgb2YgcHJvZ3JhbS5lbnRyaWVzKSB7XG4gICAgICBpZiAoZW50cnkua2luZCAhPT0gJ3NvdXJjZScpIGNvbnRpbnVlXG4gICAgICBjb25zdCBmaWVsZFBhdGggPSBlbnRyeS5maWVsZFBhdGhcbiAgICAgIGNvbnN0IGxpc3RJdGVtID0gUm93SWQucGFyc2VMaXN0SXRlbUZpZWxkUGF0aChmaWVsZFBhdGgpXG5cbiAgICAgIGlmIChsaXN0SXRlbSkge1xuICAgICAgICAvLyBsaXN0Lml0ZW0gc2NvcGU6IGV2YWx1YXRlIGtleSBwZXIgcm93IGJ5IGluZGV4LCBhbmQgc3luY2hyb25vdXNseSB3cml0ZSBiYWNrIGlkbGUgZm9yIGluYWN0aXZlIHJvd3MuXG4gICAgICAgIGNvbnN0IGxpc3RWYWx1ZSA9IFJvd0lkLmdldEF0UGF0aChkcmFmdCwgbGlzdEl0ZW0ubGlzdFBhdGgpXG4gICAgICAgIGNvbnN0IGl0ZW1zOiBSZWFkb25seUFycmF5PHVua25vd24+ID0gQXJyYXkuaXNBcnJheShsaXN0VmFsdWUpID8gbGlzdFZhbHVlIDogW11cblxuICAgICAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgaXRlbXMubGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICAgICAgY29uc3QgaXRlbSA9IGl0ZW1zW2luZGV4XVxuXG4gICAgICAgICAgbGV0IGtleTogdW5rbm93blxuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBrZXkgPSAoZW50cnkubWV0YSBhcyBhbnkpLmtleShpdGVtKVxuICAgICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgICAgY29udGludWVcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoa2V5ICE9PSB1bmRlZmluZWQpIGNvbnRpbnVlXG5cbiAgICAgICAgICBjb25zdCBjb25jcmV0ZVBhdGggPSBSb3dJZC50b0xpc3RJdGVtVmFsdWVQYXRoKGxpc3RJdGVtLmxpc3RQYXRoLCBpbmRleCwgbGlzdEl0ZW0uaXRlbVBhdGgpXG4gICAgICAgICAgY29uc3QgcHJldiA9IFJvd0lkLmdldEF0UGF0aChkcmFmdCwgY29uY3JldGVQYXRoKVxuICAgICAgICAgIGNvbnN0IHByZXZTdGF0dXMgPSBwcmV2ICYmIHR5cGVvZiBwcmV2ID09PSAnb2JqZWN0JyA/IChwcmV2IGFzIGFueSkuc3RhdHVzIDogdW5kZWZpbmVkXG4gICAgICAgICAgaWYgKHByZXZTdGF0dXMgPT09ICdpZGxlJykge1xuICAgICAgICAgICAgY29uc3QgZGF0YSA9IChwcmV2IGFzIGFueSk/LmRhdGFcbiAgICAgICAgICAgIGNvbnN0IGVycm9yID0gKHByZXYgYXMgYW55KT8uZXJyb3JcbiAgICAgICAgICAgIGlmIChkYXRhID09PSB1bmRlZmluZWQgJiYgZXJyb3IgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICBjb250aW51ZVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIHVwZGF0ZXMucHVzaCh7IGZpZWxkUGF0aDogY29uY3JldGVQYXRoLCBwcmV2IH0pXG4gICAgICAgIH1cblxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICBsZXQga2V5OiB1bmtub3duXG4gICAgICB0cnkge1xuICAgICAgICBrZXkgPSAoZW50cnkubWV0YSBhcyBhbnkpLmtleShkcmFmdClcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICBpZiAoa2V5ICE9PSB1bmRlZmluZWQpIGNvbnRpbnVlXG5cbiAgICAgIGNvbnN0IHByZXYgPSBSb3dJZC5nZXRBdFBhdGgoZHJhZnQsIGZpZWxkUGF0aClcbiAgICAgIGNvbnN0IHByZXZTdGF0dXMgPSBwcmV2ICYmIHR5cGVvZiBwcmV2ID09PSAnb2JqZWN0JyA/IChwcmV2IGFzIGFueSkuc3RhdHVzIDogdW5kZWZpbmVkXG4gICAgICBpZiAocHJldlN0YXR1cyA9PT0gJ2lkbGUnKSB7XG4gICAgICAgIC8vIFN0aWxsIGVuc3VyZSBkYXRhL2Vycm9yIGFyZSBjbGVhcmVkLlxuICAgICAgICBjb25zdCBkYXRhID0gKHByZXYgYXMgYW55KT8uZGF0YVxuICAgICAgICBjb25zdCBlcnJvciA9IChwcmV2IGFzIGFueSk/LmVycm9yXG4gICAgICAgIGlmIChkYXRhID09PSB1bmRlZmluZWQgJiYgZXJyb3IgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgdXBkYXRlcy5wdXNoKHsgZmllbGRQYXRoLCBwcmV2IH0pXG4gICAgfVxuXG4gICAgaWYgKHVwZGF0ZXMubGVuZ3RoID09PSAwKSByZXR1cm5cblxuICAgIGNvbnN0IHJlYXNvbjogUGF0Y2hSZWFzb24gPSAnc291cmNlLXJlZnJlc2gnXG5cbiAgICBjb25zdCBuZXh0RHJhZnQgPSBjcmVhdGUoZHJhZnQsIChuZXh0KSA9PiB7XG4gICAgICBmb3IgKGNvbnN0IHUgb2YgdXBkYXRlcykge1xuICAgICAgICBSb3dJZC5zZXRBdFBhdGhNdXRhdGluZyhuZXh0LCB1LmZpZWxkUGF0aCwgU25hcHNob3QuaWRsZSgpKVxuICAgICAgfVxuICAgIH0pXG5cbiAgICBjdHguc2V0RHJhZnQobmV4dERyYWZ0IGFzIFMpXG5cbiAgICBmb3IgKGNvbnN0IHUgb2YgdXBkYXRlcykge1xuICAgICAgY29uc3Qgbm9ybWFsaXplZCA9IG5vcm1hbGl6ZUZpZWxkUGF0aCh1LmZpZWxkUGF0aCkgPz8gW11cbiAgICAgIGN0eC5yZWNvcmRQYXRjaChub3JtYWxpemVkLCByZWFzb24sIHUucHJldiwgU25hcHNob3QuaWRsZSgpLCBgc291cmNlOiR7dS5maWVsZFBhdGh9OmlkbGVgKVxuICAgIH1cbiAgfSlcblxuLyoqXG4gKiBpbnN0YWxsU291cmNlUmVmcmVzaFx1RkYxQVxuICogLSBSZWdpc3RlciB0aGUgcmVmcmVzaCBpbXBsZW1lbnRhdGlvbiBmb3IgYSBzaW5nbGUgc291cmNlIGZpZWxkIChSZXNvdXJjZVNuYXBzaG90ICsga2V5SGFzaCBnYXRlICsgY29uY3VycmVuY3kpLlxuICovXG5leHBvcnQgY29uc3QgaW5zdGFsbFNvdXJjZVJlZnJlc2ggPSA8Uz4oXG4gIGJvdW5kOiBCb3VuZEFwaTxhbnksIGFueT4sXG4gIHN0ZXA6IFN0YXRlVHJhaXRQbGFuU3RlcCxcbiAgZW50cnk6IEV4dHJhY3Q8U3RhdGVUcmFpdEVudHJ5PFMsIHN0cmluZz4sIHsgcmVhZG9ubHkga2luZDogJ3NvdXJjZScgfT4sXG4pOiBFZmZlY3QuRWZmZWN0PHZvaWQsIG5ldmVyLCBhbnk+ID0+IHtcbiAgaWYgKCFzdGVwLnRhcmdldEZpZWxkUGF0aCkgcmV0dXJuIEVmZmVjdC52b2lkXG5cbiAgY29uc3QgZmllbGRQYXRoID0gc3RlcC50YXJnZXRGaWVsZFBhdGhcbiAgY29uc3QgcmVzb3VyY2VJZCA9IHN0ZXAucmVzb3VyY2VJZCA/PyBlbnRyeS5tZXRhLnJlc291cmNlXG4gIGNvbnN0IGxpc3RJdGVtID0gUm93SWQucGFyc2VMaXN0SXRlbUZpZWxkUGF0aChmaWVsZFBhdGgpXG5cbiAgbGV0IGludGVybmFsczogUmV0dXJuVHlwZTx0eXBlb2YgZ2V0Qm91bmRJbnRlcm5hbHM+IHwgdW5kZWZpbmVkXG4gIHRyeSB7XG4gICAgaW50ZXJuYWxzID0gZ2V0Qm91bmRJbnRlcm5hbHMoYm91bmQgYXMgYW55KVxuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gRWZmZWN0LnZvaWRcbiAgfVxuXG4gIGNvbnN0IHJlZ2lzdGVyID0gaW50ZXJuYWxzLnRyYWl0cy5yZWdpc3RlclNvdXJjZVJlZnJlc2hcblxuICBjb25zdCByZWNvcmRTbmFwc2hvdCA9IChcbiAgICByZXBsYXlNb2RlOiAnbGl2ZScgfCAncmVwbGF5JyxcbiAgICByZXBsYXlMb2c6IFJlcGxheUxvZy5SZXBsYXlMb2dTZXJ2aWNlIHwgdW5kZWZpbmVkLFxuICAgIGlucHV0OlxuICAgICAgfCBSZXBsYXlMb2cuUmVwbGF5TG9nRXZlbnRcbiAgICAgIHwge1xuICAgICAgICAgIHJlYWRvbmx5IG1vZHVsZUlkPzogc3RyaW5nXG4gICAgICAgICAgcmVhZG9ubHkgaW5zdGFuY2VJZD86IHN0cmluZ1xuICAgICAgICAgIHJlYWRvbmx5IGZpZWxkUGF0aDogc3RyaW5nXG4gICAgICAgICAgcmVhZG9ubHkga2V5SGFzaD86IHN0cmluZ1xuICAgICAgICAgIHJlYWRvbmx5IGNvbmN1cnJlbmN5Pzogc3RyaW5nXG4gICAgICAgICAgcmVhZG9ubHkgcGhhc2U6IFJlcGxheUxvZy5SZXNvdXJjZVNuYXBzaG90UGhhc2VcbiAgICAgICAgICByZWFkb25seSBzbmFwc2hvdDogdW5rbm93blxuICAgICAgICB9LFxuICApOiBFZmZlY3QuRWZmZWN0PHZvaWQsIG5ldmVyLCBhbnk+ID0+IHtcbiAgICBpZiAoIXJlcGxheUxvZykgcmV0dXJuIEVmZmVjdC52b2lkXG4gICAgaWYgKHJlcGxheU1vZGUgIT09ICdsaXZlJykgcmV0dXJuIEVmZmVjdC52b2lkXG4gICAgY29uc3QgZXZlbnQ6IFJlcGxheUxvZy5SZXBsYXlMb2dFdmVudCA9XG4gICAgICBpbnB1dCAmJiB0eXBlb2YgaW5wdXQgPT09ICdvYmplY3QnICYmIChpbnB1dCBhcyBhbnkpLl90YWcgPT09ICdSZXNvdXJjZVNuYXBzaG90J1xuICAgICAgICA/IChpbnB1dCBhcyBSZXBsYXlMb2cuUmVwbGF5TG9nRXZlbnQpXG4gICAgICAgIDoge1xuICAgICAgICAgICAgX3RhZzogJ1Jlc291cmNlU25hcHNob3QnLFxuICAgICAgICAgICAgcmVzb3VyY2VJZCxcbiAgICAgICAgICAgIGZpZWxkUGF0aDogKGlucHV0IGFzIGFueSkuZmllbGRQYXRoLFxuICAgICAgICAgICAga2V5SGFzaDogKGlucHV0IGFzIGFueSkua2V5SGFzaCxcbiAgICAgICAgICAgIGNvbmN1cnJlbmN5OiAoaW5wdXQgYXMgYW55KS5jb25jdXJyZW5jeSxcbiAgICAgICAgICAgIHBoYXNlOiAoaW5wdXQgYXMgYW55KS5waGFzZSxcbiAgICAgICAgICAgIHNuYXBzaG90OiAoaW5wdXQgYXMgYW55KS5zbmFwc2hvdCxcbiAgICAgICAgICAgIHRpbWVzdGFtcDogRGF0ZS5ub3coKSxcbiAgICAgICAgICAgIG1vZHVsZUlkOiAoaW5wdXQgYXMgYW55KS5tb2R1bGVJZCxcbiAgICAgICAgICAgIGluc3RhbmNlSWQ6IChpbnB1dCBhcyBhbnkpLmluc3RhbmNlSWQsXG4gICAgICAgICAgfVxuICAgIHJldHVybiByZXBsYXlMb2cucmVjb3JkKGV2ZW50KVxuICB9XG5cbiAgLy8gbGlzdC5pdGVtIHNjb3BlOiBpbi1mbGlnaHQgZ2F0aW5nIGJ5IFJvd0lEIChhdm9pZCB3cml0aW5nIHRvIHRoZSB3cm9uZyByb3cgdW5kZXIgaW5zZXJ0L3JlbW92ZS9yZW9yZGVyKS5cbiAgaWYgKGxpc3RJdGVtKSB7XG4gICAgY29uc3Qgc3RvcmUgPSBpbnRlcm5hbHMudHJhaXRzLnJvd0lkU3RvcmUgYXMgUm93SWQuUm93SWRTdG9yZSB8IHVuZGVmaW5lZFxuICAgIGlmICghc3RvcmUpIHtcbiAgICAgIHJldHVybiBFZmZlY3Qudm9pZFxuICAgIH1cblxuICAgIGNvbnN0IGxpc3RQYXRoID0gbGlzdEl0ZW0ubGlzdFBhdGhcbiAgICBjb25zdCBpdGVtUGF0aCA9IGxpc3RJdGVtLml0ZW1QYXRoXG4gICAgaWYgKCFpdGVtUGF0aCkge1xuICAgICAgLy8gTmV2ZXIgd3JpdGUgdGhlIHNuYXBzaG90IGJhY2sgdG8gdGhlIHdob2xlIGl0ZW0gKGl0IHdvdWxkIG92ZXJ3cml0ZSBidXNpbmVzcyB2YWx1ZXMpLlxuICAgICAgcmV0dXJuIEVmZmVjdC52b2lkXG4gICAgfVxuXG4gICAgY29uc3QgY29uY3VycmVuY3kgPSAoZW50cnkubWV0YSBhcyBhbnkpLmNvbmN1cnJlbmN5IGFzICdzd2l0Y2gnIHwgJ2V4aGF1c3QtdHJhaWxpbmcnIHwgdW5kZWZpbmVkXG4gICAgY29uc3QgbW9kZSA9IGNvbmN1cnJlbmN5ID8/ICdzd2l0Y2gnXG5cbiAgICBjb25zdCBpbkZsaWdodCA9IG5ldyBNYXA8XG4gICAgICBSb3dJZC5Sb3dJZCxcbiAgICAgIHtcbiAgICAgICAgcmVhZG9ubHkgZ2VuOiBudW1iZXJcbiAgICAgICAgcmVhZG9ubHkgZmliZXI6IEZpYmVyLlJ1bnRpbWVGaWJlcjx2b2lkLCBuZXZlcj5cbiAgICAgICAgcmVhZG9ubHkga2V5SGFzaDogc3RyaW5nXG4gICAgICB9XG4gICAgPigpXG4gICAgY29uc3QgdHJhaWxpbmcgPSBuZXcgTWFwPFJvd0lkLlJvd0lkLCB7IHJlYWRvbmx5IGtleTogdW5rbm93bjsgcmVhZG9ubHkga2V5SGFzaDogc3RyaW5nIH0+KClcbiAgICBsZXQgZ2VuID0gMFxuXG4gICAgLy8gV2hlbiBhIHJvdyBpcyByZW1vdmVkOiBjbGVhciB0cmFpbGluZy9pbkZsaWdodCByZWZlcmVuY2VzIHRvIGF2b2lkIHdyb25nIGF0dHJpYnV0aW9uIG9yIG1lbW9yeSBsZWFrcy5cbiAgICBzdG9yZS5vblJlbW92ZWQobGlzdFBhdGgsIChyb3dJZCkgPT4ge1xuICAgICAgdHJhaWxpbmcuZGVsZXRlKHJvd0lkKVxuICAgICAgaW5GbGlnaHQuZGVsZXRlKHJvd0lkKVxuICAgIH0pXG5cbiAgICBjb25zdCBzZXRTbmFwc2hvdEZvclJvd0luVHhuID0gKFxuICAgICAgcm93SWQ6IFJvd0lkLlJvd0lkLFxuICAgICAgbmV4dDogdW5rbm93bixcbiAgICAgIHJlYXNvbjogUGF0Y2hSZWFzb24sXG4gICAgICBzdGVwSWQ6IHN0cmluZyxcbiAgICApOiBFZmZlY3QuRWZmZWN0PHN0cmluZyB8IHVuZGVmaW5lZCwgbmV2ZXIsIGFueT4gPT5cbiAgICAgIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICAgICAgbGV0IHdyb3RlUGF0aDogc3RyaW5nIHwgdW5kZWZpbmVkXG4gICAgICAgIHlpZWxkKiBib3VuZC5zdGF0ZS5tdXRhdGUoKGRyYWZ0KSA9PiB7XG4gICAgICAgICAgY29uc3QgaW5kZXggPSBzdG9yZS5nZXRJbmRleChsaXN0UGF0aCwgcm93SWQpXG4gICAgICAgICAgaWYgKGluZGV4ID09PSB1bmRlZmluZWQpIHJldHVyblxuICAgICAgICAgIGNvbnN0IGNvbmNyZXRlUGF0aCA9IFJvd0lkLnRvTGlzdEl0ZW1WYWx1ZVBhdGgobGlzdFBhdGgsIGluZGV4LCBpdGVtUGF0aClcbiAgICAgICAgICBjb25zdCBwcmV2ID0gUm93SWQuZ2V0QXRQYXRoKGRyYWZ0LCBjb25jcmV0ZVBhdGgpXG4gICAgICAgICAgaWYgKE9iamVjdC5pcyhwcmV2LCBuZXh0KSkgcmV0dXJuXG4gICAgICAgICAgd3JvdGVQYXRoID0gY29uY3JldGVQYXRoXG4gICAgICAgICAgUm93SWQuc2V0QXRQYXRoTXV0YXRpbmcoZHJhZnQsIGNvbmNyZXRlUGF0aCwgbmV4dClcbiAgICAgICAgICByZWNvcmRUcmFpdFBhdGNoKGJvdW5kLCBjb25jcmV0ZVBhdGgsIHJlYXNvbiwgcHJldiwgbmV4dCwgc3RlcC5kZWJ1Z0luZm8/LmdyYXBoTm9kZUlkKVxuICAgICAgICB9KVxuICAgICAgICByZXR1cm4gd3JvdGVQYXRoXG4gICAgICB9KVxuXG4gICAgY29uc3Qgd3JpdGViYWNrSWZDdXJyZW50S2V5SGFzaEZvclJvdyA9IChcbiAgICAgIHJvd0lkOiBSb3dJZC5Sb3dJZCxcbiAgICAgIGtleUhhc2g6IHN0cmluZyxcbiAgICAgIG5leHQ6IHVua25vd24sXG4gICAgICByZWFzb246IFBhdGNoUmVhc29uLFxuICAgICAgc3RlcElkOiBzdHJpbmcsXG4gICAgICBwaGFzZT86IFJlcGxheUxvZy5SZXNvdXJjZVNuYXBzaG90UGhhc2UsXG4gICAgKTogRWZmZWN0LkVmZmVjdDxzdHJpbmcgfCB1bmRlZmluZWQsIG5ldmVyLCBhbnk+ID0+XG4gICAgICBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgIGxldCB3cm90ZVBhdGg6IHN0cmluZyB8IHVuZGVmaW5lZFxuICAgICAgICB5aWVsZCogYm91bmQuc3RhdGUubXV0YXRlKChkcmFmdCkgPT4ge1xuICAgICAgICAgIGNvbnN0IGluZGV4ID0gc3RvcmUuZ2V0SW5kZXgobGlzdFBhdGgsIHJvd0lkKVxuICAgICAgICAgIGlmIChpbmRleCA9PT0gdW5kZWZpbmVkKSByZXR1cm5cbiAgICAgICAgICBjb25zdCBjb25jcmV0ZVBhdGggPSBSb3dJZC50b0xpc3RJdGVtVmFsdWVQYXRoKGxpc3RQYXRoLCBpbmRleCwgaXRlbVBhdGgpXG5cbiAgICAgICAgICBjb25zdCBjdXJyZW50ID0gUm93SWQuZ2V0QXRQYXRoKGRyYWZ0LCBjb25jcmV0ZVBhdGgpXG4gICAgICAgICAgY29uc3QgY3VycmVudEtleUhhc2ggPSBjdXJyZW50ICYmIHR5cGVvZiBjdXJyZW50ID09PSAnb2JqZWN0JyA/IChjdXJyZW50IGFzIGFueSkua2V5SGFzaCA6IHVuZGVmaW5lZFxuICAgICAgICAgIGlmIChjdXJyZW50S2V5SGFzaCAhPT0ga2V5SGFzaCkgcmV0dXJuXG5cbiAgICAgICAgICBjb25zdCBwcmV2ID0gY3VycmVudFxuICAgICAgICAgIGlmIChPYmplY3QuaXMocHJldiwgbmV4dCkpIHJldHVyblxuXG4gICAgICAgICAgd3JvdGVQYXRoID0gY29uY3JldGVQYXRoXG4gICAgICAgICAgUm93SWQuc2V0QXRQYXRoTXV0YXRpbmcoZHJhZnQsIGNvbmNyZXRlUGF0aCwgbmV4dClcbiAgICAgICAgICBpZiAocGhhc2UpIHtcbiAgICAgICAgICAgIGNvbnN0IHsgbW9kdWxlSWQsIGluc3RhbmNlSWQgfSA9IGdldEJvdW5kU2NvcGUoYm91bmQpXG4gICAgICAgICAgICByZWNvcmRSZXBsYXlFdmVudChib3VuZCwge1xuICAgICAgICAgICAgICBfdGFnOiAnUmVzb3VyY2VTbmFwc2hvdCcsXG4gICAgICAgICAgICAgIHJlc291cmNlSWQsXG4gICAgICAgICAgICAgIGZpZWxkUGF0aDogY29uY3JldGVQYXRoLFxuICAgICAgICAgICAgICBrZXlIYXNoLFxuICAgICAgICAgICAgICBjb25jdXJyZW5jeTogbW9kZSxcbiAgICAgICAgICAgICAgcGhhc2UsXG4gICAgICAgICAgICAgIHNuYXBzaG90OiBuZXh0LFxuICAgICAgICAgICAgICB0aW1lc3RhbXA6IERhdGUubm93KCksXG4gICAgICAgICAgICAgIG1vZHVsZUlkLFxuICAgICAgICAgICAgICBpbnN0YW5jZUlkLFxuICAgICAgICAgICAgfSlcbiAgICAgICAgICB9XG4gICAgICAgICAgcmVjb3JkVHJhaXRQYXRjaChib3VuZCwgY29uY3JldGVQYXRoLCByZWFzb24sIHByZXYsIG5leHQsIHN0ZXAuZGVidWdJbmZvPy5ncmFwaE5vZGVJZClcbiAgICAgICAgfSlcbiAgICAgICAgcmV0dXJuIHdyb3RlUGF0aFxuICAgICAgfSlcblxuICAgIGNvbnN0IHN0YXJ0RmV0Y2ggPSAoXG4gICAgICByb3dJZDogUm93SWQuUm93SWQsXG4gICAgICBrZXk6IHVua25vd24sXG4gICAgICBrZXlIYXNoOiBzdHJpbmcsXG4gICAgICByZXBsYXlNb2RlOiAnbGl2ZScgfCAncmVwbGF5JyxcbiAgICAgIHJlcGxheUxvZzogUmVwbGF5TG9nLlJlcGxheUxvZ1NlcnZpY2UgfCB1bmRlZmluZWQsXG4gICAgKTogRWZmZWN0LkVmZmVjdDx2b2lkLCBuZXZlciwgYW55PiA9PlxuICAgICAgRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgICAgICBjb25zdCB7IG1vZHVsZUlkLCBpbnN0YW5jZUlkIH0gPSBnZXRCb3VuZFNjb3BlKGJvdW5kKVxuXG4gICAgICAgIGNvbnN0IGluZGV4Rm9yTG9nID0gc3RvcmUuZ2V0SW5kZXgobGlzdFBhdGgsIHJvd0lkKVxuICAgICAgICBjb25zdCBsb2dGaWVsZFBhdGggPVxuICAgICAgICAgIGluZGV4Rm9yTG9nID09PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiBSb3dJZC50b0xpc3RJdGVtVmFsdWVQYXRoKGxpc3RQYXRoLCBpbmRleEZvckxvZywgaXRlbVBhdGgpXG5cbiAgICAgICAgbGV0IGxvYWRpbmdTbmFwc2hvdDogdW5rbm93biA9IFNuYXBzaG90LmxvYWRpbmcoeyBrZXlIYXNoIH0pXG4gICAgICAgIGlmIChyZXBsYXlNb2RlID09PSAncmVwbGF5JyAmJiByZXBsYXlMb2cgJiYgbG9nRmllbGRQYXRoKSB7XG4gICAgICAgICAgY29uc3QgcmVwbGF5TG9hZGluZyA9IHlpZWxkKiByZXBsYXlMb2cuY29uc3VtZU5leHRSZXNvdXJjZVNuYXBzaG90KHtcbiAgICAgICAgICAgIHJlc291cmNlSWQsXG4gICAgICAgICAgICBmaWVsZFBhdGg6IGxvZ0ZpZWxkUGF0aCxcbiAgICAgICAgICAgIGtleUhhc2gsXG4gICAgICAgICAgICBwaGFzZTogJ2xvYWRpbmcnLFxuICAgICAgICAgIH0pXG4gICAgICAgICAgaWYgKHJlcGxheUxvYWRpbmcpIHtcbiAgICAgICAgICAgIGxvYWRpbmdTbmFwc2hvdCA9IHJlcGxheUxvYWRpbmcuc25hcHNob3RcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgd3JvdGVMb2FkaW5nUGF0aCA9IHlpZWxkKiBzZXRTbmFwc2hvdEZvclJvd0luVHhuKFxuICAgICAgICAgIHJvd0lkLFxuICAgICAgICAgIGxvYWRpbmdTbmFwc2hvdCxcbiAgICAgICAgICAnc291cmNlLXJlZnJlc2gnLFxuICAgICAgICAgIGBzb3VyY2U6JHtmaWVsZFBhdGh9OiR7cm93SWR9OmxvYWRpbmdgLFxuICAgICAgICApXG4gICAgICAgIGlmICh3cm90ZUxvYWRpbmdQYXRoKSB7XG4gICAgICAgICAgY29uc3QgZXZlbnQ6IFJlcGxheUxvZy5SZXBsYXlMb2dFdmVudCA9IHtcbiAgICAgICAgICAgIF90YWc6ICdSZXNvdXJjZVNuYXBzaG90JyxcbiAgICAgICAgICAgIHJlc291cmNlSWQsXG4gICAgICAgICAgICBmaWVsZFBhdGg6IHdyb3RlTG9hZGluZ1BhdGgsXG4gICAgICAgICAgICBrZXlIYXNoLFxuICAgICAgICAgICAgY29uY3VycmVuY3k6IG1vZGUsXG4gICAgICAgICAgICBwaGFzZTogJ2xvYWRpbmcnLFxuICAgICAgICAgICAgc25hcHNob3Q6IGxvYWRpbmdTbmFwc2hvdCxcbiAgICAgICAgICAgIHRpbWVzdGFtcDogRGF0ZS5ub3coKSxcbiAgICAgICAgICAgIG1vZHVsZUlkLFxuICAgICAgICAgICAgaW5zdGFuY2VJZCxcbiAgICAgICAgICB9XG4gICAgICAgICAgcmVjb3JkUmVwbGF5RXZlbnQoYm91bmQsIGV2ZW50KVxuICAgICAgICAgIHlpZWxkKiByZWNvcmRTbmFwc2hvdChyZXBsYXlNb2RlLCByZXBsYXlMb2csIGV2ZW50KVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgaW8gPSBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgaWYgKHJlcGxheU1vZGUgPT09ICdyZXBsYXknICYmIHJlcGxheUxvZykge1xuICAgICAgICAgICAgLy8gTGV0IGxvYWRpbmcgY29tbWl0IGJlY29tZSB2aXNpYmxlIGZpcnN0LCB0aGVuIHJlcGxheSB0aGUgc2V0dGxlZCBwaGFzZSAocHJlc2VydmUgdGhlIGFzeW5jLXJlc291cmNlIHRpbWVsaW5lIHNoYXBlKS5cbiAgICAgICAgICAgIHlpZWxkKiBFZmZlY3QueWllbGROb3coKVxuICAgICAgICAgICAgY29uc3QgY29uc3VtZVBhdGggPSB3cm90ZUxvYWRpbmdQYXRoID8/IGxvZ0ZpZWxkUGF0aFxuICAgICAgICAgICAgaWYgKCFjb25zdW1lUGF0aCkgcmV0dXJuIHlpZWxkKiBFZmZlY3Qudm9pZFxuXG4gICAgICAgICAgICBjb25zdCByZXBsYXllZCA9IHlpZWxkKiByZXBsYXlMb2cuY29uc3VtZU5leHRSZXNvdXJjZVNuYXBzaG90KHtcbiAgICAgICAgICAgICAgcmVzb3VyY2VJZCxcbiAgICAgICAgICAgICAgZmllbGRQYXRoOiBjb25zdW1lUGF0aCxcbiAgICAgICAgICAgICAga2V5SGFzaCxcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICBpZiAoIXJlcGxheWVkKSByZXR1cm4geWllbGQqIEVmZmVjdC52b2lkXG5cbiAgICAgICAgICAgIGlmIChyZXBsYXllZC5waGFzZSA9PT0gJ3N1Y2Nlc3MnKSB7XG4gICAgICAgICAgICAgIHlpZWxkKiB3cml0ZWJhY2tJZkN1cnJlbnRLZXlIYXNoRm9yUm93KFxuICAgICAgICAgICAgICAgIHJvd0lkLFxuICAgICAgICAgICAgICAgIGtleUhhc2gsXG4gICAgICAgICAgICAgICAgcmVwbGF5ZWQuc25hcHNob3QsXG4gICAgICAgICAgICAgICAgJ3NvdXJjZS1yZWZyZXNoJyxcbiAgICAgICAgICAgICAgICBgc291cmNlOiR7ZmllbGRQYXRofToke3Jvd0lkfTpzdWNjZXNzYCxcbiAgICAgICAgICAgICAgICAnc3VjY2VzcycsXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgIH0gZWxzZSBpZiAocmVwbGF5ZWQucGhhc2UgPT09ICdlcnJvcicpIHtcbiAgICAgICAgICAgICAgeWllbGQqIHdyaXRlYmFja0lmQ3VycmVudEtleUhhc2hGb3JSb3coXG4gICAgICAgICAgICAgICAgcm93SWQsXG4gICAgICAgICAgICAgICAga2V5SGFzaCxcbiAgICAgICAgICAgICAgICByZXBsYXllZC5zbmFwc2hvdCxcbiAgICAgICAgICAgICAgICAnc291cmNlLXJlZnJlc2gnLFxuICAgICAgICAgICAgICAgIGBzb3VyY2U6JHtmaWVsZFBhdGh9OiR7cm93SWR9OmVycm9yYCxcbiAgICAgICAgICAgICAgICAnZXJyb3InLFxuICAgICAgICAgICAgICApXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiB5aWVsZCogRWZmZWN0LnZvaWRcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBzdGFjayA9IHlpZWxkKiBnZXRNaWRkbGV3YXJlU3RhY2soKVxuXG4gICAgICAgICAgY29uc3QgcmVnaXN0cnlPcHQgPSB5aWVsZCogRWZmZWN0LnNlcnZpY2VPcHRpb24oUmVzb3VyY2VJbnRlcm5hbC5SZXNvdXJjZVJlZ2lzdHJ5VGFnKVxuICAgICAgICAgIGNvbnN0IHJlZ2lzdHJ5ID0gT3B0aW9uLmlzU29tZShyZWdpc3RyeU9wdCkgPyByZWdpc3RyeU9wdC52YWx1ZSA6IHVuZGVmaW5lZFxuICAgICAgICAgIGNvbnN0IHNwZWMgPSByZWdpc3RyeT8uc3BlY3MuZ2V0KHJlc291cmNlSWQpXG5cbiAgICAgICAgICBpZiAoIXNwZWMpIHtcbiAgICAgICAgICAgIHJldHVybiB5aWVsZCogRWZmZWN0LnZvaWRcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBsb2FkRWZmZWN0ID0gKHNwZWMubG9hZCBhcyBhbnkpKGtleSkgYXMgRWZmZWN0LkVmZmVjdDxhbnksIGFueSwgYW55PlxuXG4gICAgICAgICAgY29uc3QgbWV0YTogYW55ID0ge1xuICAgICAgICAgICAgbW9kdWxlSWQsXG4gICAgICAgICAgICBpbnN0YW5jZUlkLFxuICAgICAgICAgICAgZmllbGRQYXRoLFxuICAgICAgICAgICAgcmVzb3VyY2VJZCxcbiAgICAgICAgICAgIGtleSxcbiAgICAgICAgICAgIGtleUhhc2gsXG4gICAgICAgICAgICByb3dJZCxcbiAgICAgICAgICAgIHRyYWl0Tm9kZUlkOiBzdGVwLmRlYnVnSW5mbz8uZ3JhcGhOb2RlSWQsXG4gICAgICAgICAgICBzdGVwSWQ6IHN0ZXAuaWQsXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKCEodHlwZW9mIG1ldGEub3BTZXEgPT09ICdudW1iZXInICYmIE51bWJlci5pc0Zpbml0ZShtZXRhLm9wU2VxKSkpIHtcbiAgICAgICAgICAgIGNvbnN0IHNlc3Npb25PcHQgPSB5aWVsZCogRWZmZWN0LnNlcnZpY2VPcHRpb24oUnVuU2Vzc2lvblRhZylcbiAgICAgICAgICAgIGlmIChPcHRpb24uaXNTb21lKHNlc3Npb25PcHQpKSB7XG4gICAgICAgICAgICAgIGNvbnN0IHNlcUtleSA9IGluc3RhbmNlSWQgPz8gJ2dsb2JhbCdcbiAgICAgICAgICAgICAgbWV0YS5vcFNlcSA9IHNlc3Npb25PcHQudmFsdWUubG9jYWwubmV4dFNlcSgnb3BTZXEnLCBzZXFLZXkpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3Qgb3AgPSBFZmZlY3RPcC5tYWtlPGFueSwgYW55LCBhbnk+KHtcbiAgICAgICAgICAgIGtpbmQ6ICdzZXJ2aWNlJyxcbiAgICAgICAgICAgIG5hbWU6IHJlc291cmNlSWQsXG4gICAgICAgICAgICBlZmZlY3Q6IGxvYWRFZmZlY3QsXG4gICAgICAgICAgICBtZXRhLFxuICAgICAgICAgIH0pXG5cbiAgICAgICAgICBjb25zdCBleGl0ID0geWllbGQqIEVmZmVjdC5leGl0KEVmZmVjdE9wLnJ1bihvcCwgc3RhY2spKVxuXG4gICAgICAgICAgaWYgKGV4aXQuX3RhZyA9PT0gJ1N1Y2Nlc3MnKSB7XG4gICAgICAgICAgICBjb25zdCBzdWNjZXNzU25hcHNob3QgPSBTbmFwc2hvdC5zdWNjZXNzKHsga2V5SGFzaCwgZGF0YTogZXhpdC52YWx1ZSB9KVxuICAgICAgICAgICAgY29uc3Qgd3JvdGVTdWNjZXNzUGF0aCA9IHlpZWxkKiB3cml0ZWJhY2tJZkN1cnJlbnRLZXlIYXNoRm9yUm93KFxuICAgICAgICAgICAgICByb3dJZCxcbiAgICAgICAgICAgICAga2V5SGFzaCxcbiAgICAgICAgICAgICAgc3VjY2Vzc1NuYXBzaG90LFxuICAgICAgICAgICAgICAnc291cmNlLXJlZnJlc2gnLFxuICAgICAgICAgICAgICBgc291cmNlOiR7ZmllbGRQYXRofToke3Jvd0lkfTpzdWNjZXNzYCxcbiAgICAgICAgICAgICAgJ3N1Y2Nlc3MnLFxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgaWYgKHdyb3RlU3VjY2Vzc1BhdGgpIHtcbiAgICAgICAgICAgICAgeWllbGQqIHJlY29yZFNuYXBzaG90KHJlcGxheU1vZGUsIHJlcGxheUxvZywge1xuICAgICAgICAgICAgICAgIF90YWc6ICdSZXNvdXJjZVNuYXBzaG90JyxcbiAgICAgICAgICAgICAgICByZXNvdXJjZUlkLFxuICAgICAgICAgICAgICAgIGZpZWxkUGF0aDogd3JvdGVTdWNjZXNzUGF0aCxcbiAgICAgICAgICAgICAgICBrZXlIYXNoLFxuICAgICAgICAgICAgICAgIGNvbmN1cnJlbmN5OiBtb2RlLFxuICAgICAgICAgICAgICAgIHBoYXNlOiAnc3VjY2VzcycsXG4gICAgICAgICAgICAgICAgc25hcHNob3Q6IHN1Y2Nlc3NTbmFwc2hvdCxcbiAgICAgICAgICAgICAgICB0aW1lc3RhbXA6IERhdGUubm93KCksXG4gICAgICAgICAgICAgICAgbW9kdWxlSWQsXG4gICAgICAgICAgICAgICAgaW5zdGFuY2VJZCxcbiAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgZXJyb3JTbmFwc2hvdCA9IFNuYXBzaG90LmVycm9yKHsga2V5SGFzaCwgZXJyb3I6IGV4aXQuY2F1c2UgfSlcbiAgICAgICAgICAgIGNvbnN0IHdyb3RlRXJyb3JQYXRoID0geWllbGQqIHdyaXRlYmFja0lmQ3VycmVudEtleUhhc2hGb3JSb3coXG4gICAgICAgICAgICAgIHJvd0lkLFxuICAgICAgICAgICAgICBrZXlIYXNoLFxuICAgICAgICAgICAgICBlcnJvclNuYXBzaG90LFxuICAgICAgICAgICAgICAnc291cmNlLXJlZnJlc2gnLFxuICAgICAgICAgICAgICBgc291cmNlOiR7ZmllbGRQYXRofToke3Jvd0lkfTplcnJvcmAsXG4gICAgICAgICAgICAgICdlcnJvcicsXG4gICAgICAgICAgICApXG4gICAgICAgICAgICBpZiAod3JvdGVFcnJvclBhdGgpIHtcbiAgICAgICAgICAgICAgeWllbGQqIHJlY29yZFNuYXBzaG90KHJlcGxheU1vZGUsIHJlcGxheUxvZywge1xuICAgICAgICAgICAgICAgIF90YWc6ICdSZXNvdXJjZVNuYXBzaG90JyxcbiAgICAgICAgICAgICAgICByZXNvdXJjZUlkLFxuICAgICAgICAgICAgICAgIGZpZWxkUGF0aDogd3JvdGVFcnJvclBhdGgsXG4gICAgICAgICAgICAgICAga2V5SGFzaCxcbiAgICAgICAgICAgICAgICBjb25jdXJyZW5jeTogbW9kZSxcbiAgICAgICAgICAgICAgICBwaGFzZTogJ2Vycm9yJyxcbiAgICAgICAgICAgICAgICBzbmFwc2hvdDogZXJyb3JTbmFwc2hvdCxcbiAgICAgICAgICAgICAgICB0aW1lc3RhbXA6IERhdGUubm93KCksXG4gICAgICAgICAgICAgICAgbW9kdWxlSWQsXG4gICAgICAgICAgICAgICAgaW5zdGFuY2VJZCxcbiAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0pLnBpcGUoRWZmZWN0LmNhdGNoQWxsQ2F1c2UoKCkgPT4gRWZmZWN0LnZvaWQpKVxuXG4gICAgICAgIC8vIGxpc3QuaXRlbTogSU8gZmliZXJzIG11c3QgZGV0YWNoIGZyb20gdGhlIHN5bmMtdHJhbnNhY3Rpb24gRmliZXJSZWY7IG90aGVyd2lzZSB0aGV5J2QgYmUgbWlzY2xhc3NpZmllZCBhcyBcImluIHR4biB3aW5kb3dcIlxuICAgICAgICAvLyBhbmQgYmxvY2sgc3Vic2VxdWVudCB3cml0ZWJhY2sgZW50cnlwb2ludHMuXG4gICAgICAgIGNvbnN0IGZpYmVyID0geWllbGQqIEVmZmVjdC5mb3JrU2NvcGVkKEVmZmVjdC5sb2NhbGx5KFRhc2tSdW5uZXIuaW5TeW5jVHJhbnNhY3Rpb25GaWJlciwgZmFsc2UpKGlvKSlcbiAgICAgICAgY29uc3QgbXlHZW4gPSAoZ2VuICs9IDEpXG4gICAgICAgIGluRmxpZ2h0LnNldChyb3dJZCwgeyBnZW46IG15R2VuLCBmaWJlciwga2V5SGFzaCB9KVxuXG4gICAgICAgIHlpZWxkKiBFZmZlY3QuZm9ya1Njb3BlZChcbiAgICAgICAgICBFZmZlY3QubG9jYWxseShcbiAgICAgICAgICAgIFRhc2tSdW5uZXIuaW5TeW5jVHJhbnNhY3Rpb25GaWJlcixcbiAgICAgICAgICAgIGZhbHNlLFxuICAgICAgICAgICkoXG4gICAgICAgICAgICBGaWJlci5hd2FpdChmaWJlcikucGlwZShcbiAgICAgICAgICAgICAgRWZmZWN0LnppcFJpZ2h0KFxuICAgICAgICAgICAgICAgIEVmZmVjdC5zeW5jKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IGN1cnJlbnQgPSBpbkZsaWdodC5nZXQocm93SWQpXG4gICAgICAgICAgICAgICAgICBpZiAoY3VycmVudCAmJiBjdXJyZW50LmdlbiA9PT0gbXlHZW4pIHtcbiAgICAgICAgICAgICAgICAgICAgaW5GbGlnaHQuZGVsZXRlKHJvd0lkKVxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICBFZmZlY3QuemlwUmlnaHQoXG4gICAgICAgICAgICAgICAgbW9kZSA9PT0gJ2V4aGF1c3QtdHJhaWxpbmcnXG4gICAgICAgICAgICAgICAgICA/IEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICBjb25zdCBuZXh0ID0gdHJhaWxpbmcuZ2V0KHJvd0lkKVxuICAgICAgICAgICAgICAgICAgICAgIHRyYWlsaW5nLmRlbGV0ZShyb3dJZClcbiAgICAgICAgICAgICAgICAgICAgICBpZiAobmV4dCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgeWllbGQqIHN0YXJ0RmV0Y2gocm93SWQsIG5leHQua2V5LCBuZXh0LmtleUhhc2gsIHJlcGxheU1vZGUsIHJlcGxheUxvZylcbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICA6IEVmZmVjdC52b2lkLFxuICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICBFZmZlY3QuY2F0Y2hBbGxDYXVzZSgoKSA9PiBFZmZlY3Qudm9pZCksXG4gICAgICAgICAgICApLFxuICAgICAgICAgICksXG4gICAgICAgIClcbiAgICAgIH0pXG5cbiAgICByZWdpc3RlcihmaWVsZFBhdGgsIChzdGF0ZTogYW55KSA9PlxuICAgICAgRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgICAgICBjb25zdCB7IG1vZHVsZUlkLCBpbnN0YW5jZUlkIH0gPSBnZXRCb3VuZFNjb3BlKGJvdW5kKVxuICAgICAgICBjb25zdCByZXBsYXlNb2RlT3B0ID0geWllbGQqIEVmZmVjdC5zZXJ2aWNlT3B0aW9uKFJlcGxheU1vZGVDb25maWdUYWcpXG4gICAgICAgIGNvbnN0IHJlcGxheU1vZGUgPSBPcHRpb24uaXNTb21lKHJlcGxheU1vZGVPcHQpID8gcmVwbGF5TW9kZU9wdC52YWx1ZS5tb2RlIDogJ2xpdmUnXG4gICAgICAgIGNvbnN0IHJlcGxheUxvZ09wdCA9IHlpZWxkKiBFZmZlY3Quc2VydmljZU9wdGlvbihSZXBsYXlMb2cuUmVwbGF5TG9nKVxuICAgICAgICBjb25zdCByZXBsYXlMb2cgPSBPcHRpb24uaXNTb21lKHJlcGxheUxvZ09wdCkgPyByZXBsYXlMb2dPcHQudmFsdWUgOiB1bmRlZmluZWRcbiAgICAgICAgY29uc3QgZm9yY2UgPSB5aWVsZCogRmliZXJSZWYuZ2V0KFRhc2tSdW5uZXIuZm9yY2VTb3VyY2VSZWZyZXNoKVxuXG4gICAgICAgIGNvbnN0IGxpc3RWYWx1ZSA9IFJvd0lkLmdldEF0UGF0aChzdGF0ZSwgbGlzdFBhdGgpXG4gICAgICAgIGNvbnN0IGl0ZW1zOiBSZWFkb25seUFycmF5PHVua25vd24+ID0gQXJyYXkuaXNBcnJheShsaXN0VmFsdWUpID8gbGlzdFZhbHVlIDogW11cbiAgICAgICAgY29uc3QgaWRzID0gc3RvcmUuZW5zdXJlTGlzdChsaXN0UGF0aCwgaXRlbXMpXG5cbiAgICAgICAgLy8gZGV2LW1vZGU6IHRyYWNlIGRlcHMgb25jZSBmb3IgdGhlIGZpcnN0IHJvdyAoZGlhZ25vc3RpY3Mgb25seTsgZG9lcyBub3QgYWZmZWN0IGV4ZWN1dGlvbiBzZW1hbnRpY3MpLlxuICAgICAgICBjb25zdCB0cmFjZUtleSA9IGAke2luc3RhbmNlSWQgPz8gJ3Vua25vd24nfTo6c291cmNlOjoke2ZpZWxkUGF0aH1gXG4gICAgICAgIGlmIChpc0RldkVudigpICYmICh5aWVsZCogb25jZUluUnVuU2Vzc2lvbihgZGVwc190cmFjZV9zZXR0bGVkOiR7dHJhY2VLZXl9YCkpKSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IHNhbXBsZSA9IGl0ZW1zWzBdXG4gICAgICAgICAgICBpZiAoc2FtcGxlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgY29uc3QgdHJhY2VkID0gRGVwc1RyYWNlLnRyYWNlKChzKSA9PiAoZW50cnkubWV0YSBhcyBhbnkpLmtleShzKSwgc2FtcGxlIGFzIGFueSlcbiAgICAgICAgICAgICAgY29uc3QgcHJlZml4ZWRSZWFkcyA9IHRyYWNlZC5yZWFkcy5tYXAoKHIpID0+IChyID8gYCR7bGlzdFBhdGh9W10uJHtyfWAgOiBgJHtsaXN0UGF0aH1bXWApKVxuICAgICAgICAgICAgICBjb25zdCBkaWZmID0gRGVwc1RyYWNlLmRpZmZEZXBzKCgoZW50cnkubWV0YSBhcyBhbnkpLmRlcHMgPz8gW10pIGFzIFJlYWRvbmx5QXJyYXk8c3RyaW5nPiwgcHJlZml4ZWRSZWFkcylcbiAgICAgICAgICAgICAgaWYgKGRpZmYpIHtcbiAgICAgICAgICAgICAgICB5aWVsZCogZW1pdERlcHNNaXNtYXRjaCh7XG4gICAgICAgICAgICAgICAgICBtb2R1bGVJZCxcbiAgICAgICAgICAgICAgICAgIGluc3RhbmNlSWQsXG4gICAgICAgICAgICAgICAgICBraW5kOiAnc291cmNlJyxcbiAgICAgICAgICAgICAgICAgIGZpZWxkUGF0aCxcbiAgICAgICAgICAgICAgICAgIGRpZmYsXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgICAgLy8gdHJhY2luZyBmYWlsdXJlIHNob3VsZCBuZXZlciBicmVhayByZWZyZXNoIGZsb3dcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgaXRlbXMubGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICAgICAgY29uc3Qgcm93SWQgPSBpZHNbaW5kZXhdXG4gICAgICAgICAgaWYgKCFyb3dJZCkgY29udGludWVcblxuICAgICAgICAgIGNvbnN0IGNvbmNyZXRlUGF0aCA9IFJvd0lkLnRvTGlzdEl0ZW1WYWx1ZVBhdGgobGlzdFBhdGgsIGluZGV4LCBpdGVtUGF0aClcbiAgICAgICAgICBjb25zdCBwcmV2U25hcHNob3QgPSBSb3dJZC5nZXRBdFBhdGgoc3RhdGUsIGNvbmNyZXRlUGF0aCkgYXMgYW55XG5cbiAgICAgICAgICBsZXQga2V5OiB1bmtub3duXG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGtleSA9IChlbnRyeS5tZXRhIGFzIGFueSkua2V5KGl0ZW1zW2luZGV4XSlcbiAgICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgIGtleSA9IHVuZGVmaW5lZFxuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IGN1cnJlbnQgPSBpbkZsaWdodC5nZXQocm93SWQpXG5cbiAgICAgICAgICBpZiAoa2V5ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRyYWlsaW5nLmRlbGV0ZShyb3dJZClcbiAgICAgICAgICAgIGluRmxpZ2h0LmRlbGV0ZShyb3dJZClcblxuICAgICAgICAgICAgLy8gSWYgaXQncyBhbHJlYWR5IGNsZWFuIGlkbGUsIGF2b2lkIHJlZHVuZGFudCB3cml0ZWJhY2sgKHByZXZlbnRzIG1lYW5pbmdsZXNzIHBhdGNoZXMgYW5kIFVJIGppdHRlcikuXG4gICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgIHByZXZTbmFwc2hvdCAmJlxuICAgICAgICAgICAgICB0eXBlb2YgcHJldlNuYXBzaG90ID09PSAnb2JqZWN0JyAmJlxuICAgICAgICAgICAgICBwcmV2U25hcHNob3Quc3RhdHVzID09PSAnaWRsZScgJiZcbiAgICAgICAgICAgICAgcHJldlNuYXBzaG90LmRhdGEgPT09IHVuZGVmaW5lZCAmJlxuICAgICAgICAgICAgICBwcmV2U25hcHNob3QuZXJyb3IgPT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGlkbGVTbmFwc2hvdCA9IFNuYXBzaG90LmlkbGUoKVxuICAgICAgICAgICAgY29uc3Qgd3JvdGVJZGxlUGF0aCA9IHlpZWxkKiBzZXRTbmFwc2hvdEZvclJvd0luVHhuKFxuICAgICAgICAgICAgICByb3dJZCxcbiAgICAgICAgICAgICAgaWRsZVNuYXBzaG90LFxuICAgICAgICAgICAgICAnc291cmNlLXJlZnJlc2gnLFxuICAgICAgICAgICAgICBgc291cmNlOiR7ZmllbGRQYXRofToke3Jvd0lkfTppZGxlYCxcbiAgICAgICAgICAgIClcbiAgICAgICAgICAgIGlmICh3cm90ZUlkbGVQYXRoKSB7XG4gICAgICAgICAgICAgIGNvbnN0IGV2ZW50OiBSZXBsYXlMb2cuUmVwbGF5TG9nRXZlbnQgPSB7XG4gICAgICAgICAgICAgICAgX3RhZzogJ1Jlc291cmNlU25hcHNob3QnLFxuICAgICAgICAgICAgICAgIHJlc291cmNlSWQsXG4gICAgICAgICAgICAgICAgZmllbGRQYXRoOiB3cm90ZUlkbGVQYXRoLFxuICAgICAgICAgICAgICAgIGtleUhhc2g6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICBjb25jdXJyZW5jeTogbW9kZSxcbiAgICAgICAgICAgICAgICBwaGFzZTogJ2lkbGUnLFxuICAgICAgICAgICAgICAgIHNuYXBzaG90OiBpZGxlU25hcHNob3QsXG4gICAgICAgICAgICAgICAgdGltZXN0YW1wOiBEYXRlLm5vdygpLFxuICAgICAgICAgICAgICAgIG1vZHVsZUlkLFxuICAgICAgICAgICAgICAgIGluc3RhbmNlSWQsXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgcmVjb3JkUmVwbGF5RXZlbnQoYm91bmQsIGV2ZW50KVxuICAgICAgICAgICAgICB5aWVsZCogcmVjb3JkU25hcHNob3QocmVwbGF5TW9kZSwgcmVwbGF5TG9nLCBldmVudClcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgaCA9IGhhc2hLZXkoa2V5KVxuXG4gICAgICAgICAgLy8ga2V5SGFzaCB1bmNoYW5nZWQ6IGF2b2lkIHJlZHVuZGFudCByZWZyZXNoIHdoaWxlIGtlZXBpbmcgaW4tZmxpZ2h0LlxuICAgICAgICAgIGlmICghZm9yY2UgJiYgY3VycmVudCAmJiBjdXJyZW50LmtleUhhc2ggPT09IGgpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gTm90IGluLWZsaWdodDogaWYgc25hcHNob3Qua2V5SGFzaCBhbHJlYWR5IG1hdGNoZXMsIHRyZWF0IGl0IGFzIGFscmVhZHkgdXAtdG8tZGF0ZSAoYXZvaWQgZnVsbCByZWZyZXNoIGFuZCByb3cgaml0dGVyKS5cbiAgICAgICAgICBjb25zdCBwcmV2S2V5SGFzaCA9XG4gICAgICAgICAgICBwcmV2U25hcHNob3QgJiYgdHlwZW9mIHByZXZTbmFwc2hvdCA9PT0gJ29iamVjdCcgPyAocHJldlNuYXBzaG90IGFzIGFueSkua2V5SGFzaCA6IHVuZGVmaW5lZFxuICAgICAgICAgIGlmICghZm9yY2UgJiYgIWN1cnJlbnQgJiYgcHJldktleUhhc2ggPT09IGgpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKG1vZGUgPT09ICdleGhhdXN0LXRyYWlsaW5nJyAmJiBjdXJyZW50KSB7XG4gICAgICAgICAgICB0cmFpbGluZy5zZXQocm93SWQsIHsga2V5LCBrZXlIYXNoOiBoIH0pXG4gICAgICAgICAgICBjb25zdCBsb2FkaW5nU25hcHNob3QgPSBTbmFwc2hvdC5sb2FkaW5nKHsga2V5SGFzaDogaCB9KVxuICAgICAgICAgICAgY29uc3Qgd3JvdGVMb2FkaW5nUGF0aCA9IHlpZWxkKiBzZXRTbmFwc2hvdEZvclJvd0luVHhuKFxuICAgICAgICAgICAgICByb3dJZCxcbiAgICAgICAgICAgICAgbG9hZGluZ1NuYXBzaG90LFxuICAgICAgICAgICAgICAnc291cmNlLXJlZnJlc2gnLFxuICAgICAgICAgICAgICBgc291cmNlOiR7ZmllbGRQYXRofToke3Jvd0lkfTpsb2FkaW5nYCxcbiAgICAgICAgICAgIClcbiAgICAgICAgICAgIGlmICh3cm90ZUxvYWRpbmdQYXRoKSB7XG4gICAgICAgICAgICAgIGNvbnN0IGV2ZW50OiBSZXBsYXlMb2cuUmVwbGF5TG9nRXZlbnQgPSB7XG4gICAgICAgICAgICAgICAgX3RhZzogJ1Jlc291cmNlU25hcHNob3QnLFxuICAgICAgICAgICAgICAgIHJlc291cmNlSWQsXG4gICAgICAgICAgICAgICAgZmllbGRQYXRoOiB3cm90ZUxvYWRpbmdQYXRoLFxuICAgICAgICAgICAgICAgIGtleUhhc2g6IGgsXG4gICAgICAgICAgICAgICAgY29uY3VycmVuY3k6IG1vZGUsXG4gICAgICAgICAgICAgICAgcGhhc2U6ICdsb2FkaW5nJyxcbiAgICAgICAgICAgICAgICBzbmFwc2hvdDogbG9hZGluZ1NuYXBzaG90LFxuICAgICAgICAgICAgICAgIHRpbWVzdGFtcDogRGF0ZS5ub3coKSxcbiAgICAgICAgICAgICAgICBtb2R1bGVJZCxcbiAgICAgICAgICAgICAgICBpbnN0YW5jZUlkLFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJlY29yZFJlcGxheUV2ZW50KGJvdW5kLCBldmVudClcbiAgICAgICAgICAgICAgeWllbGQqIHJlY29yZFNuYXBzaG90KHJlcGxheU1vZGUsIHJlcGxheUxvZywgZXZlbnQpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb250aW51ZVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChtb2RlID09PSAnc3dpdGNoJyAmJiBjdXJyZW50KSB7XG4gICAgICAgICAgICAvLyBEbyBub3QgcmVseSBvbiBjYW5jZWxsYXRpb24gY29ycmVjdG5lc3M6IHN0YWxlIHdyaXRlYmFja3MgYXJlIGRyb3BwZWQgYnkgdGhlIGtleUhhc2ggZ2F0ZS5cbiAgICAgICAgICAgIHRyYWlsaW5nLmRlbGV0ZShyb3dJZClcbiAgICAgICAgICAgIGluRmxpZ2h0LmRlbGV0ZShyb3dJZClcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB5aWVsZCogc3RhcnRGZXRjaChyb3dJZCwga2V5LCBoLCByZXBsYXlNb2RlLCByZXBsYXlMb2cpXG4gICAgICAgIH1cbiAgICAgIH0pLFxuICAgIClcblxuICAgIHJldHVybiBFZmZlY3Qudm9pZFxuICB9XG5cbiAgLy8gaW4tZmxpZ2h0IHN0YXRlIChwZXIgZmllbGQpXG4gIGxldCBpbkZsaWdodDpcbiAgICB8IHtcbiAgICAgICAgcmVhZG9ubHkgZ2VuOiBudW1iZXJcbiAgICAgICAgcmVhZG9ubHkgZmliZXI6IEZpYmVyLlJ1bnRpbWVGaWJlcjx2b2lkLCBuZXZlcj5cbiAgICAgICAgcmVhZG9ubHkga2V5SGFzaDogc3RyaW5nXG4gICAgICB9XG4gICAgfCB1bmRlZmluZWRcbiAgbGV0IGdlbiA9IDBcbiAgbGV0IHRyYWlsaW5nOiB7IHJlYWRvbmx5IGtleTogdW5rbm93bjsgcmVhZG9ubHkga2V5SGFzaDogc3RyaW5nIH0gfCB1bmRlZmluZWRcblxuICBjb25zdCBjb25jdXJyZW5jeSA9IChlbnRyeS5tZXRhIGFzIGFueSkuY29uY3VycmVuY3kgYXMgJ3N3aXRjaCcgfCAnZXhoYXVzdC10cmFpbGluZycgfCB1bmRlZmluZWRcbiAgY29uc3QgbW9kZSA9IGNvbmN1cnJlbmN5ID8/ICdzd2l0Y2gnXG5cbiAgY29uc3Qgc3RhcnRGZXRjaCA9IChcbiAgICBrZXk6IHVua25vd24sXG4gICAga2V5SGFzaDogc3RyaW5nLFxuICAgIHJlcGxheU1vZGU6ICdsaXZlJyB8ICdyZXBsYXknLFxuICAgIHJlcGxheUxvZzogUmVwbGF5TG9nLlJlcGxheUxvZ1NlcnZpY2UgfCB1bmRlZmluZWQsXG4gICk6IEVmZmVjdC5FZmZlY3Q8dm9pZCwgbmV2ZXIsIGFueT4gPT5cbiAgICBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG4gICAgICBjb25zdCB7IG1vZHVsZUlkLCBpbnN0YW5jZUlkIH0gPSBnZXRCb3VuZFNjb3BlKGJvdW5kKVxuXG4gICAgICAvLyAxKSBwZW5kaW5nOiBzeW5jaHJvbm91c2x5IHdyaXRlIGEgbG9hZGluZyBzbmFwc2hvdCAod2l0aGluIHRoZSBjdXJyZW50IHRyYW5zYWN0aW9uIHdpbmRvdykuXG4gICAgICBsZXQgbG9hZGluZ1NuYXBzaG90OiB1bmtub3duID0gU25hcHNob3QubG9hZGluZyh7IGtleUhhc2ggfSlcbiAgICAgIGlmIChyZXBsYXlNb2RlID09PSAncmVwbGF5JyAmJiByZXBsYXlMb2cpIHtcbiAgICAgICAgY29uc3QgcmVwbGF5TG9hZGluZyA9IHlpZWxkKiByZXBsYXlMb2cuY29uc3VtZU5leHRSZXNvdXJjZVNuYXBzaG90KHtcbiAgICAgICAgICByZXNvdXJjZUlkLFxuICAgICAgICAgIGZpZWxkUGF0aCxcbiAgICAgICAgICBrZXlIYXNoLFxuICAgICAgICAgIHBoYXNlOiAnbG9hZGluZycsXG4gICAgICAgIH0pXG4gICAgICAgIGlmIChyZXBsYXlMb2FkaW5nKSB7XG4gICAgICAgICAgbG9hZGluZ1NuYXBzaG90ID0gcmVwbGF5TG9hZGluZy5zbmFwc2hvdFxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBjb25zdCB3cm90ZUxvYWRpbmcgPSB5aWVsZCogc2V0U25hcHNob3RJblR4bihcbiAgICAgICAgYm91bmQsXG4gICAgICAgIGZpZWxkUGF0aCxcbiAgICAgICAgbG9hZGluZ1NuYXBzaG90LFxuICAgICAgICAnc291cmNlLXJlZnJlc2gnLFxuICAgICAgICBgc291cmNlOiR7ZmllbGRQYXRofTpsb2FkaW5nYCxcbiAgICAgICAgc3RlcC5kZWJ1Z0luZm8/LmdyYXBoTm9kZUlkLFxuICAgICAgKVxuICAgICAgaWYgKHdyb3RlTG9hZGluZykge1xuICAgICAgICBjb25zdCBldmVudDogUmVwbGF5TG9nLlJlcGxheUxvZ0V2ZW50ID0ge1xuICAgICAgICAgIF90YWc6ICdSZXNvdXJjZVNuYXBzaG90JyxcbiAgICAgICAgICByZXNvdXJjZUlkLFxuICAgICAgICAgIGZpZWxkUGF0aCxcbiAgICAgICAgICBrZXlIYXNoLFxuICAgICAgICAgIGNvbmN1cnJlbmN5OiBtb2RlLFxuICAgICAgICAgIHBoYXNlOiAnbG9hZGluZycsXG4gICAgICAgICAgc25hcHNob3Q6IGxvYWRpbmdTbmFwc2hvdCxcbiAgICAgICAgICB0aW1lc3RhbXA6IERhdGUubm93KCksXG4gICAgICAgICAgbW9kdWxlSWQsXG4gICAgICAgICAgaW5zdGFuY2VJZCxcbiAgICAgICAgfVxuICAgICAgICByZWNvcmRSZXBsYXlFdmVudChib3VuZCwgZXZlbnQpXG4gICAgICAgIHlpZWxkKiByZWNvcmRTbmFwc2hvdChyZXBsYXlNb2RlLCByZXBsYXlMb2csIGV2ZW50KVxuICAgICAgfVxuXG4gICAgICAvLyAyKSBJTzogcnVuIGluIGEgYmFja2dyb3VuZCBmaWJlciAoYXZvaWQgYmxvY2tpbmcgdGhlIGN1cnJlbnQgdHJhbnNhY3Rpb24pLlxuICAgICAgY29uc3QgaW8gPSBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgIGlmIChyZXBsYXlNb2RlID09PSAncmVwbGF5JyAmJiByZXBsYXlMb2cpIHtcbiAgICAgICAgICAvLyBMZXQgbG9hZGluZyBjb21taXQgYmVjb21lIHZpc2libGUgZmlyc3QsIHRoZW4gcmVwbGF5IHRoZSBzZXR0bGVkIHBoYXNlIChwcmVzZXJ2ZSB0aGUgYXN5bmMtcmVzb3VyY2UgdGltZWxpbmUgc2hhcGUpLlxuICAgICAgICAgIHlpZWxkKiBFZmZlY3QueWllbGROb3coKVxuICAgICAgICAgIGNvbnN0IHJlcGxheWVkID0geWllbGQqIHJlcGxheUxvZy5jb25zdW1lTmV4dFJlc291cmNlU25hcHNob3Qoe1xuICAgICAgICAgICAgcmVzb3VyY2VJZCxcbiAgICAgICAgICAgIGZpZWxkUGF0aCxcbiAgICAgICAgICAgIGtleUhhc2gsXG4gICAgICAgICAgfSlcbiAgICAgICAgICBpZiAoIXJlcGxheWVkKSByZXR1cm4geWllbGQqIEVmZmVjdC52b2lkXG5cbiAgICAgICAgICBpZiAocmVwbGF5ZWQucGhhc2UgPT09ICdzdWNjZXNzJykge1xuICAgICAgICAgICAgY29uc3QgZXZlbnQ6IFJlcGxheUxvZy5SZXBsYXlMb2dFdmVudCA9IHtcbiAgICAgICAgICAgICAgX3RhZzogJ1Jlc291cmNlU25hcHNob3QnLFxuICAgICAgICAgICAgICByZXNvdXJjZUlkLFxuICAgICAgICAgICAgICBmaWVsZFBhdGgsXG4gICAgICAgICAgICAgIGtleUhhc2gsXG4gICAgICAgICAgICAgIGNvbmN1cnJlbmN5OiBtb2RlLFxuICAgICAgICAgICAgICBwaGFzZTogJ3N1Y2Nlc3MnLFxuICAgICAgICAgICAgICBzbmFwc2hvdDogcmVwbGF5ZWQuc25hcHNob3QsXG4gICAgICAgICAgICAgIHRpbWVzdGFtcDogRGF0ZS5ub3coKSxcbiAgICAgICAgICAgICAgbW9kdWxlSWQsXG4gICAgICAgICAgICAgIGluc3RhbmNlSWQsXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB5aWVsZCogd3JpdGViYWNrSWZDdXJyZW50S2V5SGFzaChcbiAgICAgICAgICAgICAgYm91bmQsXG4gICAgICAgICAgICAgIGZpZWxkUGF0aCxcbiAgICAgICAgICAgICAga2V5SGFzaCxcbiAgICAgICAgICAgICAgcmVwbGF5ZWQuc25hcHNob3QsXG4gICAgICAgICAgICAgICdzb3VyY2UtcmVmcmVzaCcsXG4gICAgICAgICAgICAgIGBzb3VyY2U6JHtmaWVsZFBhdGh9OnN1Y2Nlc3NgLFxuICAgICAgICAgICAgICBzdGVwLmRlYnVnSW5mbz8uZ3JhcGhOb2RlSWQsXG4gICAgICAgICAgICAgIGV2ZW50LFxuICAgICAgICAgICAgKVxuICAgICAgICAgIH0gZWxzZSBpZiAocmVwbGF5ZWQucGhhc2UgPT09ICdlcnJvcicpIHtcbiAgICAgICAgICAgIGNvbnN0IGV2ZW50OiBSZXBsYXlMb2cuUmVwbGF5TG9nRXZlbnQgPSB7XG4gICAgICAgICAgICAgIF90YWc6ICdSZXNvdXJjZVNuYXBzaG90JyxcbiAgICAgICAgICAgICAgcmVzb3VyY2VJZCxcbiAgICAgICAgICAgICAgZmllbGRQYXRoLFxuICAgICAgICAgICAgICBrZXlIYXNoLFxuICAgICAgICAgICAgICBjb25jdXJyZW5jeTogbW9kZSxcbiAgICAgICAgICAgICAgcGhhc2U6ICdlcnJvcicsXG4gICAgICAgICAgICAgIHNuYXBzaG90OiByZXBsYXllZC5zbmFwc2hvdCxcbiAgICAgICAgICAgICAgdGltZXN0YW1wOiBEYXRlLm5vdygpLFxuICAgICAgICAgICAgICBtb2R1bGVJZCxcbiAgICAgICAgICAgICAgaW5zdGFuY2VJZCxcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHlpZWxkKiB3cml0ZWJhY2tJZkN1cnJlbnRLZXlIYXNoKFxuICAgICAgICAgICAgICBib3VuZCxcbiAgICAgICAgICAgICAgZmllbGRQYXRoLFxuICAgICAgICAgICAgICBrZXlIYXNoLFxuICAgICAgICAgICAgICByZXBsYXllZC5zbmFwc2hvdCxcbiAgICAgICAgICAgICAgJ3NvdXJjZS1yZWZyZXNoJyxcbiAgICAgICAgICAgICAgYHNvdXJjZToke2ZpZWxkUGF0aH06ZXJyb3JgLFxuICAgICAgICAgICAgICBzdGVwLmRlYnVnSW5mbz8uZ3JhcGhOb2RlSWQsXG4gICAgICAgICAgICAgIGV2ZW50LFxuICAgICAgICAgICAgKVxuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiB5aWVsZCogRWZmZWN0LnZvaWRcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHN0YWNrID0geWllbGQqIGdldE1pZGRsZXdhcmVTdGFjaygpXG5cbiAgICAgICAgY29uc3QgcmVnaXN0cnlPcHQgPSB5aWVsZCogRWZmZWN0LnNlcnZpY2VPcHRpb24oUmVzb3VyY2VJbnRlcm5hbC5SZXNvdXJjZVJlZ2lzdHJ5VGFnKVxuICAgICAgICBjb25zdCByZWdpc3RyeSA9IE9wdGlvbi5pc1NvbWUocmVnaXN0cnlPcHQpID8gcmVnaXN0cnlPcHQudmFsdWUgOiB1bmRlZmluZWRcbiAgICAgICAgY29uc3Qgc3BlYyA9IHJlZ2lzdHJ5Py5zcGVjcy5nZXQocmVzb3VyY2VJZClcblxuICAgICAgICBpZiAoIXNwZWMpIHtcbiAgICAgICAgICByZXR1cm4geWllbGQqIEVmZmVjdC52b2lkXG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBsb2FkRWZmZWN0ID0gKHNwZWMubG9hZCBhcyBhbnkpKGtleSkgYXMgRWZmZWN0LkVmZmVjdDxhbnksIGFueSwgYW55PlxuXG4gICAgICAgIGNvbnN0IG1ldGE6IGFueSA9IHtcbiAgICAgICAgICBtb2R1bGVJZCxcbiAgICAgICAgICBpbnN0YW5jZUlkLFxuICAgICAgICAgIGZpZWxkUGF0aCxcbiAgICAgICAgICByZXNvdXJjZUlkLFxuICAgICAgICAgIGtleSxcbiAgICAgICAgICBrZXlIYXNoLFxuICAgICAgICAgIHRyYWl0Tm9kZUlkOiBzdGVwLmRlYnVnSW5mbz8uZ3JhcGhOb2RlSWQsXG4gICAgICAgICAgc3RlcElkOiBzdGVwLmlkLFxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCEodHlwZW9mIG1ldGEub3BTZXEgPT09ICdudW1iZXInICYmIE51bWJlci5pc0Zpbml0ZShtZXRhLm9wU2VxKSkpIHtcbiAgICAgICAgICBjb25zdCBzZXNzaW9uT3B0ID0geWllbGQqIEVmZmVjdC5zZXJ2aWNlT3B0aW9uKFJ1blNlc3Npb25UYWcpXG4gICAgICAgICAgaWYgKE9wdGlvbi5pc1NvbWUoc2Vzc2lvbk9wdCkpIHtcbiAgICAgICAgICAgIGNvbnN0IHNlcUtleSA9IGluc3RhbmNlSWQgPz8gJ2dsb2JhbCdcbiAgICAgICAgICAgIG1ldGEub3BTZXEgPSBzZXNzaW9uT3B0LnZhbHVlLmxvY2FsLm5leHRTZXEoJ29wU2VxJywgc2VxS2V5KVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IG9wID0gRWZmZWN0T3AubWFrZTxhbnksIGFueSwgYW55Pih7XG4gICAgICAgICAga2luZDogJ3RyYWl0LXNvdXJjZScsXG4gICAgICAgICAgbmFtZTogcmVzb3VyY2VJZCxcbiAgICAgICAgICBlZmZlY3Q6IGxvYWRFZmZlY3QsXG4gICAgICAgICAgbWV0YSxcbiAgICAgICAgfSlcblxuICAgICAgICBjb25zdCBleGl0ID0geWllbGQqIEVmZmVjdC5leGl0KEVmZmVjdE9wLnJ1bihvcCwgc3RhY2spKVxuXG4gICAgICAgIC8vIDMpIHdyaXRlYmFjazogdXNlIGEga2V5SGFzaCBnYXRlIHRvIHByZXZlbnQgc3RhbGUgcmVzdWx0cyBmcm9tIHdyaXRpbmcgYmFjayBvbnRvIGEgbmV3IGtleS5cbiAgICAgICAgaWYgKGV4aXQuX3RhZyA9PT0gJ1N1Y2Nlc3MnKSB7XG4gICAgICAgICAgY29uc3Qgc3VjY2Vzc1NuYXBzaG90ID0gU25hcHNob3Quc3VjY2Vzcyh7IGtleUhhc2gsIGRhdGE6IGV4aXQudmFsdWUgfSlcbiAgICAgICAgICBjb25zdCBldmVudDogUmVwbGF5TG9nLlJlcGxheUxvZ0V2ZW50ID0ge1xuICAgICAgICAgICAgX3RhZzogJ1Jlc291cmNlU25hcHNob3QnLFxuICAgICAgICAgICAgcmVzb3VyY2VJZCxcbiAgICAgICAgICAgIGZpZWxkUGF0aCxcbiAgICAgICAgICAgIGtleUhhc2gsXG4gICAgICAgICAgICBjb25jdXJyZW5jeTogbW9kZSxcbiAgICAgICAgICAgIHBoYXNlOiAnc3VjY2VzcycsXG4gICAgICAgICAgICBzbmFwc2hvdDogc3VjY2Vzc1NuYXBzaG90LFxuICAgICAgICAgICAgdGltZXN0YW1wOiBEYXRlLm5vdygpLFxuICAgICAgICAgICAgbW9kdWxlSWQsXG4gICAgICAgICAgICBpbnN0YW5jZUlkLFxuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCB3cm90ZVN1Y2Nlc3MgPSB5aWVsZCogd3JpdGViYWNrSWZDdXJyZW50S2V5SGFzaChcbiAgICAgICAgICAgIGJvdW5kLFxuICAgICAgICAgICAgZmllbGRQYXRoLFxuICAgICAgICAgICAga2V5SGFzaCxcbiAgICAgICAgICAgIHN1Y2Nlc3NTbmFwc2hvdCxcbiAgICAgICAgICAgICdzb3VyY2UtcmVmcmVzaCcsXG4gICAgICAgICAgICBgc291cmNlOiR7ZmllbGRQYXRofTpzdWNjZXNzYCxcbiAgICAgICAgICAgIHN0ZXAuZGVidWdJbmZvPy5ncmFwaE5vZGVJZCxcbiAgICAgICAgICAgIGV2ZW50LFxuICAgICAgICAgIClcbiAgICAgICAgICBpZiAod3JvdGVTdWNjZXNzKSB7XG4gICAgICAgICAgICB5aWVsZCogcmVjb3JkU25hcHNob3QocmVwbGF5TW9kZSwgcmVwbGF5TG9nLCBldmVudClcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc3QgZXJyb3JTbmFwc2hvdCA9IFNuYXBzaG90LmVycm9yKHsga2V5SGFzaCwgZXJyb3I6IGV4aXQuY2F1c2UgfSlcbiAgICAgICAgICBjb25zdCBldmVudDogUmVwbGF5TG9nLlJlcGxheUxvZ0V2ZW50ID0ge1xuICAgICAgICAgICAgX3RhZzogJ1Jlc291cmNlU25hcHNob3QnLFxuICAgICAgICAgICAgcmVzb3VyY2VJZCxcbiAgICAgICAgICAgIGZpZWxkUGF0aCxcbiAgICAgICAgICAgIGtleUhhc2gsXG4gICAgICAgICAgICBjb25jdXJyZW5jeTogbW9kZSxcbiAgICAgICAgICAgIHBoYXNlOiAnZXJyb3InLFxuICAgICAgICAgICAgc25hcHNob3Q6IGVycm9yU25hcHNob3QsXG4gICAgICAgICAgICB0aW1lc3RhbXA6IERhdGUubm93KCksXG4gICAgICAgICAgICBtb2R1bGVJZCxcbiAgICAgICAgICAgIGluc3RhbmNlSWQsXG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnN0IHdyb3RlRXJyb3IgPSB5aWVsZCogd3JpdGViYWNrSWZDdXJyZW50S2V5SGFzaChcbiAgICAgICAgICAgIGJvdW5kLFxuICAgICAgICAgICAgZmllbGRQYXRoLFxuICAgICAgICAgICAga2V5SGFzaCxcbiAgICAgICAgICAgIGVycm9yU25hcHNob3QsXG4gICAgICAgICAgICAnc291cmNlLXJlZnJlc2gnLFxuICAgICAgICAgICAgYHNvdXJjZToke2ZpZWxkUGF0aH06ZXJyb3JgLFxuICAgICAgICAgICAgc3RlcC5kZWJ1Z0luZm8/LmdyYXBoTm9kZUlkLFxuICAgICAgICAgICAgZXZlbnQsXG4gICAgICAgICAgKVxuICAgICAgICAgIGlmICh3cm90ZUVycm9yKSB7XG4gICAgICAgICAgICB5aWVsZCogcmVjb3JkU25hcHNob3QocmVwbGF5TW9kZSwgcmVwbGF5TG9nLCBldmVudClcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pLnBpcGUoRWZmZWN0LmNhdGNoQWxsQ2F1c2UoKCkgPT4gRWZmZWN0LnZvaWQpKVxuXG4gICAgICAvLyBEbyBub3Qgd2FpdCBmb3IgSU8gY29tcGxldGlvbjogZm9ya1Njb3BlZCBpbnRvIHRoZSBydW50aW1lIHNjb3BlIHNvIHVubW91bnQgd2lsbCBpbnRlcnJ1cHQgYXV0b21hdGljYWxseS5cbiAgICAgIGNvbnN0IGZpYmVyID0geWllbGQqIEVmZmVjdC5mb3JrU2NvcGVkKEVmZmVjdC5sb2NhbGx5KFRhc2tSdW5uZXIuaW5TeW5jVHJhbnNhY3Rpb25GaWJlciwgZmFsc2UpKGlvKSlcbiAgICAgIGNvbnN0IG15R2VuID0gKGdlbiArPSAxKVxuICAgICAgaW5GbGlnaHQgPSB7IGdlbjogbXlHZW4sIGZpYmVyLCBrZXlIYXNoIH1cblxuICAgICAgLy8gQWZ0ZXIgaW4tZmxpZ2h0IGNvbXBsZXRlcywgY2xlYW4gdXA7IGluIGV4aGF1c3QtdHJhaWxpbmcgbW9kZSwgcnVuIG9uZSB0cmFpbGluZyBmZXRjaCBpZiBwcmVzZW50LlxuICAgICAgeWllbGQqIEVmZmVjdC5mb3JrU2NvcGVkKFxuICAgICAgICBFZmZlY3QubG9jYWxseShcbiAgICAgICAgICBUYXNrUnVubmVyLmluU3luY1RyYW5zYWN0aW9uRmliZXIsXG4gICAgICAgICAgZmFsc2UsXG4gICAgICAgICkoXG4gICAgICAgICAgRmliZXIuYXdhaXQoZmliZXIpLnBpcGUoXG4gICAgICAgICAgICBFZmZlY3QuemlwUmlnaHQoXG4gICAgICAgICAgICAgIEVmZmVjdC5zeW5jKCgpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoaW5GbGlnaHQgJiYgaW5GbGlnaHQuZ2VuID09PSBteUdlbikge1xuICAgICAgICAgICAgICAgICAgaW5GbGlnaHQgPSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICAgIEVmZmVjdC56aXBSaWdodChcbiAgICAgICAgICAgICAgbW9kZSA9PT0gJ2V4aGF1c3QtdHJhaWxpbmcnXG4gICAgICAgICAgICAgICAgPyBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG5leHQgPSB0cmFpbGluZ1xuICAgICAgICAgICAgICAgICAgICB0cmFpbGluZyA9IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgICAgICBpZiAobmV4dCkge1xuICAgICAgICAgICAgICAgICAgICAgIHlpZWxkKiBzdGFydEZldGNoKG5leHQua2V5LCBuZXh0LmtleUhhc2gsIHJlcGxheU1vZGUsIHJlcGxheUxvZylcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICA6IEVmZmVjdC52b2lkLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICAgIEVmZmVjdC5jYXRjaEFsbENhdXNlKCgpID0+IEVmZmVjdC52b2lkKSxcbiAgICAgICAgICApLFxuICAgICAgICApLFxuICAgICAgKVxuICAgIH0pXG5cbiAgcmVnaXN0ZXIoZmllbGRQYXRoLCAoc3RhdGU6IGFueSkgPT5cbiAgICBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG4gICAgICBjb25zdCB7IG1vZHVsZUlkLCBpbnN0YW5jZUlkIH0gPSBnZXRCb3VuZFNjb3BlKGJvdW5kKVxuICAgICAgY29uc3QgcmVwbGF5TW9kZU9wdCA9IHlpZWxkKiBFZmZlY3Quc2VydmljZU9wdGlvbihSZXBsYXlNb2RlQ29uZmlnVGFnKVxuICAgICAgY29uc3QgcmVwbGF5TW9kZSA9IE9wdGlvbi5pc1NvbWUocmVwbGF5TW9kZU9wdCkgPyByZXBsYXlNb2RlT3B0LnZhbHVlLm1vZGUgOiAnbGl2ZSdcbiAgICAgIGNvbnN0IHJlcGxheUxvZ09wdCA9IHlpZWxkKiBFZmZlY3Quc2VydmljZU9wdGlvbihSZXBsYXlMb2cuUmVwbGF5TG9nKVxuICAgICAgY29uc3QgcmVwbGF5TG9nID0gT3B0aW9uLmlzU29tZShyZXBsYXlMb2dPcHQpID8gcmVwbGF5TG9nT3B0LnZhbHVlIDogdW5kZWZpbmVkXG4gICAgICBjb25zdCBmb3JjZSA9IHlpZWxkKiBGaWJlclJlZi5nZXQoVGFza1J1bm5lci5mb3JjZVNvdXJjZVJlZnJlc2gpXG5cbiAgICAgIGxldCBrZXk6IHVua25vd25cbiAgICAgIHRyeSB7XG4gICAgICAgIGtleSA9IChlbnRyeS5tZXRhIGFzIGFueSkua2V5KHN0YXRlKVxuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIGtleSA9IHVuZGVmaW5lZFxuICAgICAgfVxuXG4gICAgICAvLyBkZXYtbW9kZTogZGV0ZWN0IG1pc21hdGNoIGJldHdlZW4gYWN0dWFsIHJlYWRzIGluIGtleVNlbGVjdG9yIGFuZCBkZWNsYXJlZCBkZXBzIChkaWFnbm9zdGljcyBvbmx5OyBkb2VzIG5vdCBhZmZlY3QgZXhlY3V0aW9uIHNlbWFudGljcykuXG4gICAgICBjb25zdCB0cmFjZUtleSA9IGAke2luc3RhbmNlSWQgPz8gJ3Vua25vd24nfTo6c291cmNlOjoke2ZpZWxkUGF0aH1gXG4gICAgICBpZiAoaXNEZXZFbnYoKSAmJiAoeWllbGQqIG9uY2VJblJ1blNlc3Npb24oYGRlcHNfdHJhY2Vfc2V0dGxlZDoke3RyYWNlS2V5fWApKSkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IHRyYWNlZCA9IERlcHNUcmFjZS50cmFjZSgocykgPT4gKGVudHJ5Lm1ldGEgYXMgYW55KS5rZXkocyksIHN0YXRlKVxuICAgICAgICAgIGNvbnN0IGRpZmYgPSBEZXBzVHJhY2UuZGlmZkRlcHMoKChlbnRyeS5tZXRhIGFzIGFueSkuZGVwcyA/PyBbXSkgYXMgUmVhZG9ubHlBcnJheTxzdHJpbmc+LCB0cmFjZWQucmVhZHMpXG4gICAgICAgICAgaWYgKGRpZmYpIHtcbiAgICAgICAgICAgIHlpZWxkKiBlbWl0RGVwc01pc21hdGNoKHtcbiAgICAgICAgICAgICAgbW9kdWxlSWQsXG4gICAgICAgICAgICAgIGluc3RhbmNlSWQsXG4gICAgICAgICAgICAgIGtpbmQ6ICdzb3VyY2UnLFxuICAgICAgICAgICAgICBmaWVsZFBhdGgsXG4gICAgICAgICAgICAgIGRpZmYsXG4gICAgICAgICAgICB9KVxuICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgLy8gdHJhY2luZyBmYWlsdXJlIHNob3VsZCBuZXZlciBicmVhayByZWZyZXNoIGZsb3dcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBLZXkgYmVjb21lcyBlbXB0eTogc3luY2hyb25vdXNseSBjbGVhciB0byBpZGxlIChhbmQgaW50ZXJydXB0IGluLWZsaWdodCkuXG4gICAgICBpZiAoa2V5ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKGluRmxpZ2h0KSB7XG4gICAgICAgICAgeWllbGQqIEZpYmVyLmludGVycnVwdEZvcmsoaW5GbGlnaHQuZmliZXIpXG4gICAgICAgICAgaW5GbGlnaHQgPSB1bmRlZmluZWRcbiAgICAgICAgfVxuICAgICAgICB0cmFpbGluZyA9IHVuZGVmaW5lZFxuXG4gICAgICAgIGNvbnN0IGlkbGVTbmFwc2hvdCA9IFNuYXBzaG90LmlkbGUoKVxuICAgICAgICBjb25zdCB3cm90ZUlkbGUgPSB5aWVsZCogc2V0U25hcHNob3RJblR4bihcbiAgICAgICAgICBib3VuZCxcbiAgICAgICAgICBmaWVsZFBhdGgsXG4gICAgICAgICAgaWRsZVNuYXBzaG90LFxuICAgICAgICAgICdzb3VyY2UtcmVmcmVzaCcsXG4gICAgICAgICAgYHNvdXJjZToke2ZpZWxkUGF0aH06aWRsZWAsXG4gICAgICAgICAgc3RlcC5kZWJ1Z0luZm8/LmdyYXBoTm9kZUlkLFxuICAgICAgICApXG4gICAgICAgIGlmICh3cm90ZUlkbGUpIHtcbiAgICAgICAgICBjb25zdCBldmVudDogUmVwbGF5TG9nLlJlcGxheUxvZ0V2ZW50ID0ge1xuICAgICAgICAgICAgX3RhZzogJ1Jlc291cmNlU25hcHNob3QnLFxuICAgICAgICAgICAgcmVzb3VyY2VJZCxcbiAgICAgICAgICAgIGZpZWxkUGF0aCxcbiAgICAgICAgICAgIGtleUhhc2g6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIGNvbmN1cnJlbmN5OiBtb2RlLFxuICAgICAgICAgICAgcGhhc2U6ICdpZGxlJyxcbiAgICAgICAgICAgIHNuYXBzaG90OiBpZGxlU25hcHNob3QsXG4gICAgICAgICAgICB0aW1lc3RhbXA6IERhdGUubm93KCksXG4gICAgICAgICAgICBtb2R1bGVJZCxcbiAgICAgICAgICAgIGluc3RhbmNlSWQsXG4gICAgICAgICAgfVxuICAgICAgICAgIHJlY29yZFJlcGxheUV2ZW50KGJvdW5kLCBldmVudClcbiAgICAgICAgICB5aWVsZCogcmVjb3JkU25hcHNob3QocmVwbGF5TW9kZSwgcmVwbGF5TG9nLCBldmVudClcbiAgICAgICAgfVxuICAgICAgICByZXR1cm5cbiAgICAgIH1cblxuICAgICAgY29uc3QgaCA9IGhhc2hLZXkoa2V5KVxuXG4gICAgICAvLyBEZWZhdWx0IHNlbWFudGljczogd2hlbiBhIG5vbi1pZGxlIHNuYXBzaG90IGFscmVhZHkgZXhpc3RzIGZvciB0aGUgc2FtZSBrZXlIYXNoLCByZWZyZXNoIHNob3VsZCBiZSBhIG5vLW9wIHdoZW4gcG9zc2libGVcbiAgICAgIC8vIChhdm9pZCBkdXBsaWNhdGUgSU8vd3JpdGViYWNrKS4gRXhwbGljaXQgcmVmcmVzaC9pbnZhbGlkYXRlIGNhbiBieXBhc3MgdmlhIGZvcmNlLlxuICAgICAgaWYgKCFmb3JjZSkge1xuICAgICAgICBpZiAoaW5GbGlnaHQgJiYgaW5GbGlnaHQua2V5SGFzaCA9PT0gaCkge1xuICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgY3VycmVudFNuYXBzaG90ID0gUm93SWQuZ2V0QXRQYXRoKHN0YXRlLCBmaWVsZFBhdGgpIGFzIGFueVxuICAgICAgICBjb25zdCBjdXJyZW50S2V5SGFzaCA9XG4gICAgICAgICAgY3VycmVudFNuYXBzaG90ICYmIHR5cGVvZiBjdXJyZW50U25hcHNob3QgPT09ICdvYmplY3QnID8gKGN1cnJlbnRTbmFwc2hvdCBhcyBhbnkpLmtleUhhc2ggOiB1bmRlZmluZWRcbiAgICAgICAgY29uc3QgY3VycmVudFN0YXR1cyA9XG4gICAgICAgICAgY3VycmVudFNuYXBzaG90ICYmIHR5cGVvZiBjdXJyZW50U25hcHNob3QgPT09ICdvYmplY3QnID8gKGN1cnJlbnRTbmFwc2hvdCBhcyBhbnkpLnN0YXR1cyA6IHVuZGVmaW5lZFxuICAgICAgICBpZiAoY3VycmVudFN0YXR1cyAmJiBjdXJyZW50U3RhdHVzICE9PSAnaWRsZScgJiYgY3VycmVudEtleUhhc2ggPT09IGgpIHtcbiAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAobW9kZSA9PT0gJ2V4aGF1c3QtdHJhaWxpbmcnICYmIGluRmxpZ2h0KSB7XG4gICAgICAgIC8vIEJ1c3k6IHJlY29yZCB0cmFpbGluZyBhbmQgdXBkYXRlIGxvYWRpbmcgaW1tZWRpYXRlbHk7IHN0YWxlIGluLWZsaWdodCB3cml0ZWJhY2tzIHdpbGwgYmUgYmxvY2tlZCBieSB0aGUga2V5SGFzaCBnYXRlLlxuICAgICAgICB0cmFpbGluZyA9IHsga2V5LCBrZXlIYXNoOiBoIH1cbiAgICAgICAgY29uc3QgbG9hZGluZ1NuYXBzaG90ID0gU25hcHNob3QubG9hZGluZyh7IGtleUhhc2g6IGggfSlcbiAgICAgICAgY29uc3Qgd3JvdGVMb2FkaW5nID0geWllbGQqIHNldFNuYXBzaG90SW5UeG4oXG4gICAgICAgICAgYm91bmQsXG4gICAgICAgICAgZmllbGRQYXRoLFxuICAgICAgICAgIGxvYWRpbmdTbmFwc2hvdCxcbiAgICAgICAgICAnc291cmNlLXJlZnJlc2gnLFxuICAgICAgICAgIGBzb3VyY2U6JHtmaWVsZFBhdGh9OmxvYWRpbmdgLFxuICAgICAgICAgIHN0ZXAuZGVidWdJbmZvPy5ncmFwaE5vZGVJZCxcbiAgICAgICAgKVxuICAgICAgICBpZiAod3JvdGVMb2FkaW5nKSB7XG4gICAgICAgICAgY29uc3QgZXZlbnQ6IFJlcGxheUxvZy5SZXBsYXlMb2dFdmVudCA9IHtcbiAgICAgICAgICAgIF90YWc6ICdSZXNvdXJjZVNuYXBzaG90JyxcbiAgICAgICAgICAgIHJlc291cmNlSWQsXG4gICAgICAgICAgICBmaWVsZFBhdGgsXG4gICAgICAgICAgICBrZXlIYXNoOiBoLFxuICAgICAgICAgICAgY29uY3VycmVuY3k6IG1vZGUsXG4gICAgICAgICAgICBwaGFzZTogJ2xvYWRpbmcnLFxuICAgICAgICAgICAgc25hcHNob3Q6IGxvYWRpbmdTbmFwc2hvdCxcbiAgICAgICAgICAgIHRpbWVzdGFtcDogRGF0ZS5ub3coKSxcbiAgICAgICAgICAgIG1vZHVsZUlkLFxuICAgICAgICAgICAgaW5zdGFuY2VJZCxcbiAgICAgICAgICB9XG4gICAgICAgICAgcmVjb3JkUmVwbGF5RXZlbnQoYm91bmQsIGV2ZW50KVxuICAgICAgICAgIHlpZWxkKiByZWNvcmRTbmFwc2hvdChyZXBsYXlNb2RlLCByZXBsYXlMb2csIGV2ZW50KVxuICAgICAgICB9XG4gICAgICAgIHJldHVyblxuICAgICAgfVxuXG4gICAgICBpZiAobW9kZSA9PT0gJ3N3aXRjaCcgJiYgaW5GbGlnaHQpIHtcbiAgICAgICAgeWllbGQqIEZpYmVyLmludGVycnVwdEZvcmsoaW5GbGlnaHQuZmliZXIpXG4gICAgICAgIGluRmxpZ2h0ID0gdW5kZWZpbmVkXG4gICAgICAgIHRyYWlsaW5nID0gdW5kZWZpbmVkXG4gICAgICB9XG5cbiAgICAgIC8vIHN0YXJ0IGZldGNoIChwZW5kaW5nIHR4ICsgZm9yayBJTylcbiAgICAgIHlpZWxkKiBzdGFydEZldGNoKGtleSwgaCwgcmVwbGF5TW9kZSwgcmVwbGF5TG9nKVxuICAgIH0pLFxuICApXG5cbiAgcmV0dXJuIEVmZmVjdC52b2lkXG59XG4iLCAiZXhwb3J0IGludGVyZmFjZSBEZXBzVHJhY2VSZXN1bHQ8VD4ge1xuICByZWFkb25seSB2YWx1ZTogVFxuICByZWFkb25seSByZWFkczogUmVhZG9ubHlBcnJheTxzdHJpbmc+XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRGVwc0RpZmYge1xuICByZWFkb25seSByZWFkczogUmVhZG9ubHlBcnJheTxzdHJpbmc+XG4gIHJlYWRvbmx5IGRlY2xhcmVkOiBSZWFkb25seUFycmF5PHN0cmluZz5cbiAgcmVhZG9ubHkgbWlzc2luZzogUmVhZG9ubHlBcnJheTxzdHJpbmc+XG4gIHJlYWRvbmx5IHVudXNlZDogUmVhZG9ubHlBcnJheTxzdHJpbmc+XG59XG5cbmNvbnN0IGlzVHJhY2VhYmxlT2JqZWN0ID0gKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgb2JqZWN0ID0+IHtcbiAgaWYgKCF2YWx1ZSB8fCB0eXBlb2YgdmFsdWUgIT09ICdvYmplY3QnKSByZXR1cm4gZmFsc2VcbiAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSByZXR1cm4gdHJ1ZVxuICBpZiAodmFsdWUgaW5zdGFuY2VvZiBEYXRlKSByZXR1cm4gZmFsc2VcbiAgaWYgKHZhbHVlIGluc3RhbmNlb2YgUmVnRXhwKSByZXR1cm4gZmFsc2VcbiAgaWYgKHZhbHVlIGluc3RhbmNlb2YgRXJyb3IpIHJldHVybiBmYWxzZVxuICBpZiAodmFsdWUgaW5zdGFuY2VvZiBNYXApIHJldHVybiBmYWxzZVxuICBpZiAodmFsdWUgaW5zdGFuY2VvZiBTZXQpIHJldHVybiBmYWxzZVxuICBpZiAodmFsdWUgaW5zdGFuY2VvZiBXZWFrTWFwKSByZXR1cm4gZmFsc2VcbiAgaWYgKHZhbHVlIGluc3RhbmNlb2YgV2Vha1NldCkgcmV0dXJuIGZhbHNlXG4gIHJldHVybiB0cnVlXG59XG5cbmNvbnN0IHNob3VsZElnbm9yZUtleSA9IChrZXk6IHN0cmluZyk6IGJvb2xlYW4gPT4ga2V5ID09PSAnX19wcm90b19fJyB8fCBrZXkgPT09ICdwcm90b3R5cGUnIHx8IGtleSA9PT0gJ2NvbnN0cnVjdG9yJ1xuXG5jb25zdCBub3JtYWxpemVSZWFkcyA9IChyZWFkczogUmVhZG9ubHlTZXQ8c3RyaW5nPik6IFJlYWRvbmx5QXJyYXk8c3RyaW5nPiA9PiB7XG4gIGNvbnN0IGFsbCA9IEFycmF5LmZyb20ocmVhZHMpLmZpbHRlcigocCkgPT4gdHlwZW9mIHAgPT09ICdzdHJpbmcnICYmIHAubGVuZ3RoID4gMClcbiAgYWxsLnNvcnQoKVxuXG4gIC8vIERyb3Agc3RyaWN0IHByZWZpeCBwYXRocyAoZS5nLiBpZiBib3RoIHByb2ZpbGUgYW5kIHByb2ZpbGUuaWQgYXJlIHJlYWQsIGtlZXAgb25seSB0aGUgbW9yZSBzcGVjaWZpYyBwcm9maWxlLmlkKS5cbiAgY29uc3QgaXNQcmVmaXggPSAocHJlZml4OiBzdHJpbmcsIGZ1bGw6IHN0cmluZyk6IGJvb2xlYW4gPT4gZnVsbCAhPT0gcHJlZml4ICYmIGZ1bGwuc3RhcnRzV2l0aChwcmVmaXggKyAnLicpXG5cbiAgY29uc3QgcHJ1bmVkOiBBcnJheTxzdHJpbmc+ID0gW11cbiAgZm9yIChjb25zdCBwIG9mIGFsbCkge1xuICAgIGxldCBoYXNNb3JlU3BlY2lmaWMgPSBmYWxzZVxuICAgIGZvciAoY29uc3Qgb3RoZXIgb2YgYWxsKSB7XG4gICAgICBpZiAoaXNQcmVmaXgocCwgb3RoZXIpKSB7XG4gICAgICAgIGhhc01vcmVTcGVjaWZpYyA9IHRydWVcbiAgICAgICAgYnJlYWtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKCFoYXNNb3JlU3BlY2lmaWMpIHtcbiAgICAgIHBydW5lZC5wdXNoKHApXG4gICAgfVxuICB9XG5cbiAgcHJ1bmVkLnNvcnQoKVxuICByZXR1cm4gcHJ1bmVkXG59XG5cbmNvbnN0IGNvdmVycyA9IChkZWNsYXJlZDogc3RyaW5nLCByZWFkOiBzdHJpbmcpOiBib29sZWFuID0+IGRlY2xhcmVkID09PSByZWFkIHx8IHJlYWQuc3RhcnRzV2l0aChkZWNsYXJlZCArICcuJylcblxuZXhwb3J0IGNvbnN0IGRpZmZEZXBzID0gKGRlY2xhcmVkOiBSZWFkb25seUFycmF5PHN0cmluZz4sIHJlYWRzOiBSZWFkb25seUFycmF5PHN0cmluZz4pOiBEZXBzRGlmZiB8IHVuZGVmaW5lZCA9PiB7XG4gIGNvbnN0IGRlY2xhcmVkTGlzdCA9IEFycmF5LmZyb20obmV3IFNldChkZWNsYXJlZCkpLmZpbHRlcigocCkgPT4gdHlwZW9mIHAgPT09ICdzdHJpbmcnICYmIHAubGVuZ3RoID4gMClcbiAgZGVjbGFyZWRMaXN0LnNvcnQoKVxuICBjb25zdCByZWFkTGlzdCA9IEFycmF5LmZyb20obmV3IFNldChyZWFkcykpLmZpbHRlcigocCkgPT4gdHlwZW9mIHAgPT09ICdzdHJpbmcnICYmIHAubGVuZ3RoID4gMClcbiAgcmVhZExpc3Quc29ydCgpXG5cbiAgY29uc3QgbWlzc2luZyA9IHJlYWRMaXN0LmZpbHRlcigocikgPT4gZGVjbGFyZWRMaXN0LmV2ZXJ5KChkKSA9PiAhY292ZXJzKGQsIHIpKSlcbiAgY29uc3QgdW51c2VkID0gZGVjbGFyZWRMaXN0LmZpbHRlcigoZCkgPT4gcmVhZExpc3QuZXZlcnkoKHIpID0+ICFjb3ZlcnMoZCwgcikpKVxuXG4gIGlmIChtaXNzaW5nLmxlbmd0aCA9PT0gMCAmJiB1bnVzZWQubGVuZ3RoID09PSAwKSByZXR1cm4gdW5kZWZpbmVkXG5cbiAgcmV0dXJuIHtcbiAgICByZWFkczogcmVhZExpc3QsXG4gICAgZGVjbGFyZWQ6IGRlY2xhcmVkTGlzdCxcbiAgICBtaXNzaW5nLFxuICAgIHVudXNlZCxcbiAgfVxufVxuXG5leHBvcnQgY29uc3QgdHJhY2UgPSA8VD4oZm46IChzdGF0ZTogYW55KSA9PiBULCBzdGF0ZTogdW5rbm93bik6IERlcHNUcmFjZVJlc3VsdDxUPiA9PiB7XG4gIGlmICghaXNUcmFjZWFibGVPYmplY3Qoc3RhdGUpKSB7XG4gICAgcmV0dXJuIHsgdmFsdWU6IGZuKHN0YXRlIGFzIGFueSksIHJlYWRzOiBbXSB9XG4gIH1cblxuICBjb25zdCByZWFkcyA9IG5ldyBTZXQ8c3RyaW5nPigpXG5cbiAgLy8gcGVyLXRyYWNlIGNhY2hlcyB0byBwcmVzZXJ2ZSByZWZlcmVuY2UgaWRlbnRpdHkgd2l0aGluIHRoZSB0cmFjZWQgY2FsbC5cbiAgY29uc3QgcHJveHlDYWNoZSA9IG5ldyBXZWFrTWFwPG9iamVjdCwgTWFwPHN0cmluZywgYW55Pj4oKVxuICBjb25zdCBwcm94eVRvVGFyZ2V0ID0gbmV3IFdlYWtNYXA8b2JqZWN0LCBvYmplY3Q+KClcblxuICBjb25zdCB3cmFwID0gKHZhbHVlOiB1bmtub3duLCBwYXRoOiBzdHJpbmcpOiB1bmtub3duID0+IHtcbiAgICBpZiAoIWlzVHJhY2VhYmxlT2JqZWN0KHZhbHVlKSkgcmV0dXJuIHZhbHVlXG4gICAgcmV0dXJuIGdldFByb3h5KHZhbHVlIGFzIGFueSwgcGF0aClcbiAgfVxuXG4gIGNvbnN0IHVud3JhcCA9IDxWPih2YWx1ZTogVik6IFYgPT4ge1xuICAgIGlmICh2YWx1ZSAmJiAodHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyB8fCB0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbicpKSB7XG4gICAgICBjb25zdCB0YXJnZXQgPSBwcm94eVRvVGFyZ2V0LmdldCh2YWx1ZSBhcyBhbnkpXG4gICAgICBpZiAodGFyZ2V0KSByZXR1cm4gdGFyZ2V0IGFzIGFueSBhcyBWXG4gICAgfVxuICAgIHJldHVybiB2YWx1ZVxuICB9XG5cbiAgY29uc3QgZ2V0UHJveHkgPSAodGFyZ2V0OiBvYmplY3QsIGJhc2VQYXRoOiBzdHJpbmcpOiBhbnkgPT4ge1xuICAgIGxldCBieVBhdGggPSBwcm94eUNhY2hlLmdldCh0YXJnZXQpXG4gICAgaWYgKCFieVBhdGgpIHtcbiAgICAgIGJ5UGF0aCA9IG5ldyBNYXAoKVxuICAgICAgcHJveHlDYWNoZS5zZXQodGFyZ2V0LCBieVBhdGgpXG4gICAgfVxuXG4gICAgY29uc3QgY2FjaGVkID0gYnlQYXRoLmdldChiYXNlUGF0aClcbiAgICBpZiAoY2FjaGVkKSByZXR1cm4gY2FjaGVkXG5cbiAgICBjb25zdCByZWNvcmQgPSAocGF0aDogc3RyaW5nKSA9PiB7XG4gICAgICBpZiAocGF0aCkgcmVhZHMuYWRkKHBhdGgpXG4gICAgfVxuXG4gICAgY29uc3QgcHJveHkgPSBuZXcgUHJveHkodGFyZ2V0IGFzIGFueSwge1xuICAgICAgZ2V0OiAodCwgcHJvcCwgcmVjZWl2ZXIpID0+IHtcbiAgICAgICAgaWYgKHR5cGVvZiBwcm9wID09PSAnc3ltYm9sJykge1xuICAgICAgICAgIHJldHVybiBSZWZsZWN0LmdldCh0LCBwcm9wLCByZWNlaXZlcilcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBrZXkgPSBTdHJpbmcocHJvcClcbiAgICAgICAgaWYgKHNob3VsZElnbm9yZUtleShrZXkpKSB7XG4gICAgICAgICAgcmV0dXJuIFJlZmxlY3QuZ2V0KHQsIHByb3AsIHJlY2VpdmVyKVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgbmV4dFBhdGggPSBiYXNlUGF0aCA/IGAke2Jhc2VQYXRofS4ke2tleX1gIDoga2V5XG4gICAgICAgIHJlY29yZChuZXh0UGF0aClcblxuICAgICAgICBjb25zdCB2YWx1ZSA9IFJlZmxlY3QuZ2V0KHQsIHByb3AsIHJlY2VpdmVyKSBhcyB1bmtub3duXG4gICAgICAgIHJldHVybiB3cmFwKHZhbHVlLCBuZXh0UGF0aClcbiAgICAgIH0sXG4gICAgICBoYXM6ICh0LCBwcm9wKSA9PiB7XG4gICAgICAgIGlmICh0eXBlb2YgcHJvcCA9PT0gJ3N5bWJvbCcpIHJldHVybiBSZWZsZWN0Lmhhcyh0LCBwcm9wKVxuICAgICAgICBjb25zdCBrZXkgPSBTdHJpbmcocHJvcClcbiAgICAgICAgaWYgKCFzaG91bGRJZ25vcmVLZXkoa2V5KSkge1xuICAgICAgICAgIGNvbnN0IG5leHRQYXRoID0gYmFzZVBhdGggPyBgJHtiYXNlUGF0aH0uJHtrZXl9YCA6IGtleVxuICAgICAgICAgIHJlY29yZChuZXh0UGF0aClcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gUmVmbGVjdC5oYXModCwgcHJvcClcbiAgICAgIH0sXG4gICAgICBvd25LZXlzOiAodCkgPT4ge1xuICAgICAgICBpZiAoYmFzZVBhdGgpIHJlY29yZChiYXNlUGF0aClcbiAgICAgICAgcmV0dXJuIFJlZmxlY3Qub3duS2V5cyh0KVxuICAgICAgfSxcbiAgICAgIGdldE93blByb3BlcnR5RGVzY3JpcHRvcjogKHQsIHByb3ApID0+IHtcbiAgICAgICAgaWYgKHR5cGVvZiBwcm9wID09PSAnc3ltYm9sJykge1xuICAgICAgICAgIHJldHVybiBSZWZsZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih0LCBwcm9wKVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGtleSA9IFN0cmluZyhwcm9wKVxuICAgICAgICBpZiAoIXNob3VsZElnbm9yZUtleShrZXkpKSB7XG4gICAgICAgICAgY29uc3QgbmV4dFBhdGggPSBiYXNlUGF0aCA/IGAke2Jhc2VQYXRofS4ke2tleX1gIDoga2V5XG4gICAgICAgICAgcmVjb3JkKG5leHRQYXRoKVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBSZWZsZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih0LCBwcm9wKVxuICAgICAgfSxcbiAgICAgIHNldDogKCkgPT4ge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgJ1tkZXBzLXRyYWNlXSBBdHRlbXB0ZWQgdG8gbXV0YXRlIHN0YXRlIGR1cmluZyBkZXBzIHRyYWNpbmcgKHN0YXRlIGlzIHJlYWRvbmx5IGluIGRldi1tb2RlIGRpYWdub3N0aWNzKS4nLFxuICAgICAgICApXG4gICAgICB9LFxuICAgICAgZGVmaW5lUHJvcGVydHk6ICgpID0+IHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICdbZGVwcy10cmFjZV0gQXR0ZW1wdGVkIHRvIGRlZmluZSBwcm9wZXJ0eSBvbiBzdGF0ZSBkdXJpbmcgZGVwcyB0cmFjaW5nIChzdGF0ZSBpcyByZWFkb25seSBpbiBkZXYtbW9kZSBkaWFnbm9zdGljcykuJyxcbiAgICAgICAgKVxuICAgICAgfSxcbiAgICAgIGRlbGV0ZVByb3BlcnR5OiAoKSA9PiB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAnW2RlcHMtdHJhY2VdIEF0dGVtcHRlZCB0byBkZWxldGUgcHJvcGVydHkgb24gc3RhdGUgZHVyaW5nIGRlcHMgdHJhY2luZyAoc3RhdGUgaXMgcmVhZG9ubHkgaW4gZGV2LW1vZGUgZGlhZ25vc3RpY3MpLicsXG4gICAgICAgIClcbiAgICAgIH0sXG4gICAgfSlcblxuICAgIGJ5UGF0aC5zZXQoYmFzZVBhdGgsIHByb3h5KVxuICAgIHByb3h5VG9UYXJnZXQuc2V0KHByb3h5LCB0YXJnZXQpXG4gICAgcmV0dXJuIHByb3h5XG4gIH1cblxuICBjb25zdCByb290ID0gZ2V0UHJveHkoc3RhdGUgYXMgYW55LCAnJylcbiAgY29uc3QgdmFsdWUgPSB1bndyYXAoZm4ocm9vdCkpXG5cbiAgcmV0dXJuIHtcbiAgICB2YWx1ZSxcbiAgICByZWFkczogbm9ybWFsaXplUmVhZHMocmVhZHMpLFxuICB9XG59XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFDQSxZQUFZLGVBQWU7OztBQzZCM0IsSUFBTSxvQkFBb0IsQ0FBQyxVQUF3RDtBQUNqRixRQUFNLE1BQU0sb0JBQUksSUFBWTtBQUM1QixhQUFXLFFBQVEsT0FBTztBQUN4QixVQUFNLElBQUksS0FBSyxLQUFLO0FBQ3BCLFFBQUksQ0FBQyxFQUFHO0FBQ1IsUUFBSSxJQUFJLENBQUM7QUFBQSxFQUNYO0FBQ0EsU0FBTyxNQUFNLEtBQUssR0FBRyxFQUFFLEtBQUssQ0FBQyxHQUFHLE1BQU0sRUFBRSxjQUFjLENBQUMsQ0FBQztBQUMxRDtBQUVBLElBQU0sZ0JBQWdCLENBQUMsVUFDckIsT0FBTyxVQUFVLFlBQVksVUFBVSxRQUFRLENBQUMsTUFBTSxRQUFRLEtBQUs7QUFFckUsSUFBTSxvQkFBb0IsQ0FBQyxPQUFnQixVQUF5QztBQUNsRixNQUFJLFVBQVUsS0FBTSxRQUFPO0FBRTNCLE1BQUksT0FBTyxVQUFVLFNBQVUsUUFBTztBQUN0QyxNQUFJLE9BQU8sVUFBVSxVQUFXLFFBQU87QUFDdkMsTUFBSSxPQUFPLFVBQVUs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QUFFLFNBQVMsRUFBRSxDQUFDO0FBQ3ZELGNBQU0sZUFBZSxPQUFPO0FBQUEsVUFDMUI7QUFBQSxVQUNBO0FBQUEsVUFDQTtBQUFBLFVBQ0E7QUFBQSxVQUNBLFVBQVUsU0FBUztBQUFBLFVBQ25CLEtBQUssV0FBVztBQUFBLFFBQ2xCO0FBQ0EsWUFBSSxjQUFjO0FBQ2hCLGdCQUFNLFFBQWtDO0FBQUEsWUFDdEMsTUFBTTtBQUFBLFlBQ047QUFBQSxZQUNBO0FBQUEsWUFDQSxTQUFTO0FBQUEsWUFDVCxhQUFhO0FBQUEsWUFDYixPQUFPO0FBQUEsWUFDUCxVQUFVO0FBQUEsWUFDVixXQUFXLEtBQUssSUFBSTtBQUFBLFlBQ3BCO0FBQUEsWUFDQTtBQUFBLFVBQ0Y7QUFDQSw0QkFBa0IsT0FBTyxLQUFLO0FBQzlCLGlCQUFPLGVBQWUsWUFBWSxXQUFXLEtBQUs7QUFBQSxRQUNwRDtBQUNBO0FBQUEsTUFDRjtBQUVBLFVBQUksU0FBUyxZQUFZLFVBQVU7QUFDakMsZUFBTyxNQUFNLGNBQWMsU0FBUyxLQUFLO0FBQ3pDLG1CQUFXO0FBQ1gsbUJBQVc7QUFBQSxNQUNiO0FBR0EsYUFBTyxXQUFXLEtBQUssR0FBRyxZQUFZLFNBQVM7QUFBQSxJQUNqRCxDQUFDO0FBQUEsRUFDSDtBQUVBLFNBQU8sT0FBTztBQUNoQjsiLAogICJuYW1lcyI6IFsicmVjb3JkIiwgInN0YWJsZVN0cmluZ2lmeSIsICJyZWNvcmQiLCAidmFsdWUiLCAicmVjb3JkIiwgImtleUhhc2giLCAia2V5IiwgInByZXYiLCAicHJldlN0YXR1cyIsICJjb25jdXJyZW5jeSIsICJtb2RlIiwgImluRmxpZ2h0IiwgInRyYWlsaW5nIiwgImdlbiIsICJzdGFydEZldGNoIl0KfQo=
|