@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
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
// @logix/core subpath bundles for @logix/sandbox
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
// ../logix-core/src/internal/state-trait/rowid.ts
|
|
5
|
+
var parseSegments = (path) => {
|
|
6
|
+
if (!path) return [];
|
|
7
|
+
return path.split(".").map((seg) => /^[0-9]+$/.test(seg) ? Number(seg) : seg);
|
|
8
|
+
};
|
|
9
|
+
var getAtPath = (state, path) => {
|
|
10
|
+
if (!path || state == null) return state;
|
|
11
|
+
const segments = parseSegments(path);
|
|
12
|
+
let current = state;
|
|
13
|
+
for (const seg of segments) {
|
|
14
|
+
if (current == null) return void 0;
|
|
15
|
+
if (typeof seg === "number") {
|
|
16
|
+
current = Array.isArray(current) ? current[seg] : current[String(seg)];
|
|
17
|
+
continue;
|
|
18
|
+
}
|
|
19
|
+
current = current[seg];
|
|
20
|
+
}
|
|
21
|
+
return current;
|
|
22
|
+
};
|
|
23
|
+
var setAtPathMutating = (draft, path, value) => {
|
|
24
|
+
if (!path) return;
|
|
25
|
+
const segments = parseSegments(path);
|
|
26
|
+
if (segments.length === 0) return;
|
|
27
|
+
let current = draft;
|
|
28
|
+
for (let i = 0; i < segments.length - 1; i++) {
|
|
29
|
+
const key = segments[i];
|
|
30
|
+
const nextKey = segments[i + 1];
|
|
31
|
+
const next = current?.[key];
|
|
32
|
+
if (next == null || typeof next !== "object") {
|
|
33
|
+
current[key] = typeof nextKey === "number" ? [] : {};
|
|
34
|
+
}
|
|
35
|
+
current = current[key];
|
|
36
|
+
}
|
|
37
|
+
const last = segments[segments.length - 1];
|
|
38
|
+
current[last] = value;
|
|
39
|
+
};
|
|
40
|
+
var unsetAtPathMutating = (draft, path) => {
|
|
41
|
+
if (!path) return;
|
|
42
|
+
const segments = parseSegments(path);
|
|
43
|
+
if (segments.length === 0) return;
|
|
44
|
+
let current = draft;
|
|
45
|
+
for (let i = 0; i < segments.length - 1; i++) {
|
|
46
|
+
const key = segments[i];
|
|
47
|
+
const next = current?.[key];
|
|
48
|
+
if (next == null || typeof next !== "object") {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
current = next;
|
|
52
|
+
}
|
|
53
|
+
const last = segments[segments.length - 1];
|
|
54
|
+
if (Array.isArray(current) && typeof last === "number") {
|
|
55
|
+
current[last] = void 0;
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
if (current && typeof current === "object") {
|
|
59
|
+
delete current[last];
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
var parseListItemFieldPath = (fieldPath) => {
|
|
63
|
+
const raw = typeof fieldPath === "string" ? fieldPath.trim() : "";
|
|
64
|
+
if (!raw) return void 0;
|
|
65
|
+
const segments = raw.split(".").filter(Boolean);
|
|
66
|
+
let lastListSeg = -1;
|
|
67
|
+
for (let i = 0; i < segments.length; i++) {
|
|
68
|
+
if (segments[i].endsWith("[]")) lastListSeg = i;
|
|
69
|
+
}
|
|
70
|
+
if (lastListSeg < 0) return void 0;
|
|
71
|
+
const strip = (seg) => seg.endsWith("[]") ? seg.slice(0, -2) : seg;
|
|
72
|
+
const listPath = segments.slice(0, lastListSeg + 1).map(strip).join(".");
|
|
73
|
+
const itemPath = segments.slice(lastListSeg + 1).map(strip).join(".");
|
|
74
|
+
return { listPath, itemPath };
|
|
75
|
+
};
|
|
76
|
+
var toListItemValuePath = (listPath, index, itemPath) => itemPath ? `${listPath}.${index}.${itemPath}` : `${listPath}.${index}`;
|
|
77
|
+
var readTrackBy = (item, trackBy) => {
|
|
78
|
+
if (!item || typeof item !== "object") return void 0;
|
|
79
|
+
const segments = trackBy.split(".");
|
|
80
|
+
let current = item;
|
|
81
|
+
for (const seg of segments) {
|
|
82
|
+
if (current == null) return void 0;
|
|
83
|
+
current = current[seg];
|
|
84
|
+
}
|
|
85
|
+
return current;
|
|
86
|
+
};
|
|
87
|
+
var didReorderByReference = (prevItems, nextItems) => {
|
|
88
|
+
const buckets = /* @__PURE__ */ new Map();
|
|
89
|
+
for (let i = 0; i < prevItems.length; i++) {
|
|
90
|
+
const item = prevItems[i];
|
|
91
|
+
const list = buckets.get(item) ?? [];
|
|
92
|
+
list.push(i);
|
|
93
|
+
buckets.set(item, list);
|
|
94
|
+
}
|
|
95
|
+
for (let nextIndex = 0; nextIndex < nextItems.length; nextIndex++) {
|
|
96
|
+
const item = nextItems[nextIndex];
|
|
97
|
+
const q = buckets.get(item);
|
|
98
|
+
if (!q || q.length === 0) continue;
|
|
99
|
+
const prevIndex = q.shift();
|
|
100
|
+
if (prevIndex !== nextIndex) {
|
|
101
|
+
return true;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return false;
|
|
105
|
+
};
|
|
106
|
+
var hasStableTrackByKeys = (items, trackBy) => items.every((item) => readTrackBy(item, trackBy) !== void 0);
|
|
107
|
+
var isSameTrackBySequence = (prevItems, nextItems, trackBy) => {
|
|
108
|
+
if (prevItems.length !== nextItems.length) return false;
|
|
109
|
+
for (let i = 0; i < prevItems.length; i++) {
|
|
110
|
+
if (!Object.is(readTrackBy(prevItems[i], trackBy), readTrackBy(nextItems[i], trackBy))) {
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return true;
|
|
115
|
+
};
|
|
116
|
+
var reconcileIds = (prev, nextItems, trackBy, makeRowId) => {
|
|
117
|
+
const nextRowId = makeRowId ?? /* @__PURE__ */ (() => {
|
|
118
|
+
let rowSeq = 0;
|
|
119
|
+
return () => {
|
|
120
|
+
rowSeq += 1;
|
|
121
|
+
return `r${rowSeq}`;
|
|
122
|
+
};
|
|
123
|
+
})();
|
|
124
|
+
if (!prev) {
|
|
125
|
+
return {
|
|
126
|
+
ids: nextItems.map(() => nextRowId()),
|
|
127
|
+
removed: []
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
if (prev.itemsRef === nextItems) {
|
|
131
|
+
return {
|
|
132
|
+
ids: prev.ids,
|
|
133
|
+
removed: []
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
const sameLength = prev.itemsRef.length === nextItems.length;
|
|
137
|
+
if (sameLength) {
|
|
138
|
+
if (trackBy) {
|
|
139
|
+
const canUseKeys = hasStableTrackByKeys(prev.itemsRef, trackBy) && hasStableTrackByKeys(nextItems, trackBy);
|
|
140
|
+
if (canUseKeys) {
|
|
141
|
+
if (isSameTrackBySequence(prev.itemsRef, nextItems, trackBy)) {
|
|
142
|
+
return {
|
|
143
|
+
ids: prev.ids,
|
|
144
|
+
removed: []
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
} else {
|
|
148
|
+
if (!didReorderByReference(prev.itemsRef, nextItems)) {
|
|
149
|
+
return {
|
|
150
|
+
ids: prev.ids,
|
|
151
|
+
removed: []
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
} else if (!didReorderByReference(prev.itemsRef, nextItems)) {
|
|
156
|
+
return {
|
|
157
|
+
ids: prev.ids,
|
|
158
|
+
removed: []
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
const keyOf = (item) => {
|
|
163
|
+
if (!trackBy) return item;
|
|
164
|
+
const k = readTrackBy(item, trackBy);
|
|
165
|
+
return k !== void 0 ? k : item;
|
|
166
|
+
};
|
|
167
|
+
const buckets = /* @__PURE__ */ new Map();
|
|
168
|
+
for (let i = 0; i < prev.itemsRef.length; i++) {
|
|
169
|
+
const key = keyOf(prev.itemsRef[i]);
|
|
170
|
+
const list = buckets.get(key) ?? [];
|
|
171
|
+
list.push(prev.ids[i]);
|
|
172
|
+
buckets.set(key, list);
|
|
173
|
+
}
|
|
174
|
+
const ids = [];
|
|
175
|
+
for (let i = 0; i < nextItems.length; i++) {
|
|
176
|
+
const key = keyOf(nextItems[i]);
|
|
177
|
+
const list = buckets.get(key);
|
|
178
|
+
if (list && list.length > 0) {
|
|
179
|
+
ids.push(list.shift());
|
|
180
|
+
} else {
|
|
181
|
+
ids.push(nextRowId());
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
const removed = [];
|
|
185
|
+
for (const list of buckets.values()) {
|
|
186
|
+
removed.push(...list);
|
|
187
|
+
}
|
|
188
|
+
return { ids, removed };
|
|
189
|
+
};
|
|
190
|
+
var buildIndexById = (ids) => {
|
|
191
|
+
const map = /* @__PURE__ */ new Map();
|
|
192
|
+
for (let i = 0; i < ids.length; i++) {
|
|
193
|
+
map.set(ids[i], i);
|
|
194
|
+
}
|
|
195
|
+
return map;
|
|
196
|
+
};
|
|
197
|
+
var RowIdStore = class {
|
|
198
|
+
constructor(instanceId) {
|
|
199
|
+
this.instanceId = instanceId;
|
|
200
|
+
this.lists = /* @__PURE__ */ new Map();
|
|
201
|
+
this.removalListeners = /* @__PURE__ */ new Map();
|
|
202
|
+
this.rowIdIndex = /* @__PURE__ */ new Map();
|
|
203
|
+
this.nextRowSeq = 0;
|
|
204
|
+
this.listKey = (listPath, parentRowId) => parentRowId ? `${listPath}@@${parentRowId}` : listPath;
|
|
205
|
+
this.makeRowId = () => {
|
|
206
|
+
this.nextRowSeq += 1;
|
|
207
|
+
return this.instanceId ? `${this.instanceId}::r${this.nextRowSeq}` : `r${this.nextRowSeq}`;
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
notifyRemoved(listPath, rowId) {
|
|
211
|
+
const listeners = this.removalListeners.get(listPath);
|
|
212
|
+
if (!listeners || listeners.size === 0) return;
|
|
213
|
+
for (const fn of listeners) {
|
|
214
|
+
try {
|
|
215
|
+
fn(rowId);
|
|
216
|
+
} catch {
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
removeDescendants(parentRowId) {
|
|
221
|
+
const keys = [];
|
|
222
|
+
for (const [k, st] of this.lists.entries()) {
|
|
223
|
+
if (st.parentRowId === parentRowId) keys.push(k);
|
|
224
|
+
}
|
|
225
|
+
for (const key of keys) {
|
|
226
|
+
const st = this.lists.get(key);
|
|
227
|
+
if (!st) continue;
|
|
228
|
+
this.lists.delete(key);
|
|
229
|
+
for (let i = 0; i < st.ids.length; i++) {
|
|
230
|
+
const rowId = st.ids[i];
|
|
231
|
+
this.rowIdIndex.delete(rowId);
|
|
232
|
+
this.notifyRemoved(st.listPath, rowId);
|
|
233
|
+
this.removeDescendants(rowId);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
onRemoved(listPath, listener) {
|
|
238
|
+
const set = this.removalListeners.get(listPath) ?? /* @__PURE__ */ new Set();
|
|
239
|
+
set.add(listener);
|
|
240
|
+
this.removalListeners.set(listPath, set);
|
|
241
|
+
return () => {
|
|
242
|
+
const current = this.removalListeners.get(listPath);
|
|
243
|
+
if (!current) return;
|
|
244
|
+
current.delete(listener);
|
|
245
|
+
if (current.size === 0) this.removalListeners.delete(listPath);
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
getRowId(listPath, index, parentRowId) {
|
|
249
|
+
const state = this.lists.get(this.listKey(listPath, parentRowId));
|
|
250
|
+
return state ? state.ids[index] : void 0;
|
|
251
|
+
}
|
|
252
|
+
getIndex(listPath, rowId) {
|
|
253
|
+
const info = this.rowIdIndex.get(rowId);
|
|
254
|
+
if (!info) return void 0;
|
|
255
|
+
if (info.listPath !== listPath) return void 0;
|
|
256
|
+
return info.index;
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* ensureList:
|
|
260
|
+
* - 让指定 listPath 的 RowID 映射与当前 items 对齐;
|
|
261
|
+
* - 返回最新的 ids(index -> RowId)。
|
|
262
|
+
*/
|
|
263
|
+
ensureList(listPath, items, trackBy, parentRowId) {
|
|
264
|
+
const key = this.listKey(listPath, parentRowId);
|
|
265
|
+
const prev = this.lists.get(key);
|
|
266
|
+
const { ids, removed } = reconcileIds(prev, items, trackBy ?? prev?.trackBy, this.makeRowId);
|
|
267
|
+
const next = {
|
|
268
|
+
listPath,
|
|
269
|
+
parentRowId,
|
|
270
|
+
itemsRef: items,
|
|
271
|
+
ids,
|
|
272
|
+
indexById: buildIndexById(ids),
|
|
273
|
+
trackBy: trackBy ?? prev?.trackBy
|
|
274
|
+
};
|
|
275
|
+
this.lists.set(key, next);
|
|
276
|
+
if (removed.length > 0) {
|
|
277
|
+
for (const rowId of removed) {
|
|
278
|
+
this.rowIdIndex.delete(rowId);
|
|
279
|
+
this.notifyRemoved(listPath, rowId);
|
|
280
|
+
this.removeDescendants(rowId);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
for (let i = 0; i < ids.length; i++) {
|
|
284
|
+
const rowId = ids[i];
|
|
285
|
+
this.rowIdIndex.set(rowId, { key, listPath, index: i });
|
|
286
|
+
}
|
|
287
|
+
return ids;
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* updateAll:
|
|
291
|
+
* - 在每次提交后对齐所有已知 list 的 RowID 映射;
|
|
292
|
+
* - configs 来自 StateTraitProgram.spec 中的 list 声明(可携带 trackBy)。
|
|
293
|
+
*/
|
|
294
|
+
updateAll(state, configs) {
|
|
295
|
+
const cfgByPath = /* @__PURE__ */ new Map();
|
|
296
|
+
const paths = [];
|
|
297
|
+
for (const cfg of configs) {
|
|
298
|
+
if (!cfg || typeof cfg.path !== "string") continue;
|
|
299
|
+
const p = cfg.path.trim();
|
|
300
|
+
if (!p) continue;
|
|
301
|
+
cfgByPath.set(p, cfg);
|
|
302
|
+
paths.push(p);
|
|
303
|
+
}
|
|
304
|
+
const pathSet = new Set(paths);
|
|
305
|
+
const parentOf = (path) => {
|
|
306
|
+
const segments = path.split(".").filter(Boolean);
|
|
307
|
+
let best;
|
|
308
|
+
for (let i = 1; i < segments.length; i++) {
|
|
309
|
+
const prefix = segments.slice(0, i).join(".");
|
|
310
|
+
if (pathSet.has(prefix)) best = prefix;
|
|
311
|
+
}
|
|
312
|
+
return best;
|
|
313
|
+
};
|
|
314
|
+
const parentByPath = /* @__PURE__ */ new Map();
|
|
315
|
+
const suffixByPath = /* @__PURE__ */ new Map();
|
|
316
|
+
const childrenByParent = /* @__PURE__ */ new Map();
|
|
317
|
+
for (const path of paths) {
|
|
318
|
+
const parent = parentOf(path);
|
|
319
|
+
parentByPath.set(path, parent);
|
|
320
|
+
const suffix = parent ? path.slice(parent.length + 1) : path;
|
|
321
|
+
suffixByPath.set(path, suffix);
|
|
322
|
+
const list = childrenByParent.get(parent) ?? [];
|
|
323
|
+
list.push(path);
|
|
324
|
+
childrenByParent.set(parent, list);
|
|
325
|
+
}
|
|
326
|
+
const roots = (childrenByParent.get(void 0) ?? []).slice().sort((a, b) => a.localeCompare(b));
|
|
327
|
+
const visit = (listPath, parentRowId, listValue) => {
|
|
328
|
+
const cfg = cfgByPath.get(listPath);
|
|
329
|
+
const items = Array.isArray(listValue) ? listValue : [];
|
|
330
|
+
const ids = this.ensureList(listPath, items, cfg?.trackBy, parentRowId);
|
|
331
|
+
const children = (childrenByParent.get(listPath) ?? []).slice().sort((a, b) => a.localeCompare(b));
|
|
332
|
+
if (children.length === 0) return;
|
|
333
|
+
for (let i = 0; i < items.length; i++) {
|
|
334
|
+
const row = items[i];
|
|
335
|
+
const rowId = ids[i];
|
|
336
|
+
if (!rowId) continue;
|
|
337
|
+
for (const childPath of children) {
|
|
338
|
+
const suffix = suffixByPath.get(childPath) ?? "";
|
|
339
|
+
const childValue = suffix ? getAtPath(row, suffix) : void 0;
|
|
340
|
+
visit(childPath, rowId, childValue);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
};
|
|
344
|
+
for (const root of roots) {
|
|
345
|
+
const value = getAtPath(state, root);
|
|
346
|
+
visit(root, void 0, value);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
};
|
|
350
|
+
var collectListConfigs = (spec) => {
|
|
351
|
+
const configs = [];
|
|
352
|
+
for (const key in spec) {
|
|
353
|
+
if (!Object.prototype.hasOwnProperty.call(spec, key)) continue;
|
|
354
|
+
const raw = spec[key];
|
|
355
|
+
if (!raw || typeof raw !== "object") continue;
|
|
356
|
+
const tag = raw._tag;
|
|
357
|
+
if (tag !== "StateTraitList") continue;
|
|
358
|
+
const trackBy = raw.identityHint?.trackBy;
|
|
359
|
+
configs.push({
|
|
360
|
+
path: key,
|
|
361
|
+
trackBy: typeof trackBy === "string" ? trackBy : void 0
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
return configs;
|
|
365
|
+
};
|
|
366
|
+
|
|
367
|
+
// ../logix-core/src/internal/runtime/core/ReplayLog.ts
|
|
368
|
+
import { Context, Effect, Layer } from "../effect.js";
|
|
369
|
+
var ReplayLog = class extends Context.Tag("@logix/core/ReplayLog")() {
|
|
370
|
+
};
|
|
371
|
+
var snapshot = Effect.gen(function* () {
|
|
372
|
+
const log = yield* ReplayLog;
|
|
373
|
+
return yield* log.snapshot;
|
|
374
|
+
});
|
|
375
|
+
var resetCursor = Effect.gen(function* () {
|
|
376
|
+
const log = yield* ReplayLog;
|
|
377
|
+
yield* log.resetCursor;
|
|
378
|
+
});
|
|
379
|
+
|
|
380
|
+
export {
|
|
381
|
+
ReplayLog,
|
|
382
|
+
getAtPath,
|
|
383
|
+
setAtPathMutating,
|
|
384
|
+
unsetAtPathMutating,
|
|
385
|
+
parseListItemFieldPath,
|
|
386
|
+
toListItemValuePath,
|
|
387
|
+
RowIdStore,
|
|
388
|
+
collectListConfigs
|
|
389
|
+
};
|
|
390
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vLi4vbG9naXgtY29yZS9zcmMvaW50ZXJuYWwvc3RhdGUtdHJhaXQvcm93aWQudHMiLCAiLi4vLi4vLi4vLi4vbG9naXgtY29yZS9zcmMvaW50ZXJuYWwvcnVudGltZS9jb3JlL1JlcGxheUxvZy50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiZXhwb3J0IHR5cGUgUm93SWQgPSBzdHJpbmdcblxuZXhwb3J0IGludGVyZmFjZSBMaXN0Q29uZmlnIHtcbiAgcmVhZG9ubHkgcGF0aDogc3RyaW5nXG4gIHJlYWRvbmx5IHRyYWNrQnk/OiBzdHJpbmdcbn1cblxuZXhwb3J0IHR5cGUgTGlzdFJlbW92YWxMaXN0ZW5lciA9IChyb3dJZDogUm93SWQpID0+IHZvaWRcblxudHlwZSBTZWdtZW50ID0gc3RyaW5nIHwgbnVtYmVyXG5cbmNvbnN0IHBhcnNlU2VnbWVudHMgPSAocGF0aDogc3RyaW5nKTogUmVhZG9ubHlBcnJheTxTZWdtZW50PiA9PiB7XG4gIGlmICghcGF0aCkgcmV0dXJuIFtdXG4gIHJldHVybiBwYXRoLnNwbGl0KCcuJykubWFwKChzZWcpID0+ICgvXlswLTldKyQvLnRlc3Qoc2VnKSA/IE51bWJlcihzZWcpIDogc2VnKSlcbn1cblxuZXhwb3J0IGNvbnN0IGdldEF0UGF0aCA9IChzdGF0ZTogYW55LCBwYXRoOiBzdHJpbmcpOiBhbnkgPT4ge1xuICBpZiAoIXBhdGggfHwgc3RhdGUgPT0gbnVsbCkgcmV0dXJuIHN0YXRlXG4gIGNvbnN0IHNlZ21lbnRzID0gcGFyc2VTZWdtZW50cyhwYXRoKVxuICBsZXQgY3VycmVudDogYW55ID0gc3RhdGVcbiAgZm9yIChjb25zdCBzZWcgb2Ygc2VnbWVudHMpIHtcbiAgICBpZiAoY3VycmVudCA9PSBudWxsKSByZXR1cm4gdW5kZWZpbmVkXG4gICAgaWYgKHR5cGVvZiBzZWcgPT09ICdudW1iZXInKSB7XG4gICAgICBjdXJyZW50ID0gQXJyYXkuaXNBcnJheShjdXJyZW50KSA/IGN1cnJlbnRbc2VnXSA6IGN1cnJlbnRbU3RyaW5nKHNlZyldXG4gICAgICBjb250aW51ZVxuICAgIH1cbiAgICBjdXJyZW50ID0gY3VycmVudFtzZWddXG4gIH1cbiAgcmV0dXJuIGN1cnJlbnRcbn1cblxuZXhwb3J0IGNvbnN0IHNldEF0UGF0aE11dGF0aW5nID0gKGRyYWZ0OiBhbnksIHBhdGg6IHN0cmluZywgdmFsdWU6IGFueSk6IHZvaWQgPT4ge1xuICBpZiAoIXBhdGgpIHJldHVyblxuICBjb25zdCBzZWdtZW50cyA9IHBhcnNlU2VnbWVudHMocGF0aClcbiAgaWYgKHNlZ21lbnRzLmxlbmd0aCA9PT0gMCkgcmV0dXJuXG5cbiAgbGV0IGN1cnJlbnQ6IGFueSA9IGRyYWZ0XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgc2VnbWVudHMubGVuZ3RoIC0gMTsgaSsrKSB7XG4gICAgY29uc3Qga2V5ID0gc2VnbWVudHNbaV0hXG4gICAgY29uc3QgbmV4dEtleSA9IHNlZ21lbnRzW2kgKyAxXSFcblxuICAgIGNvbnN0IG5leHQgPSBjdXJyZW50Py5ba2V5IGFzIGFueV1cbiAgICBpZiAobmV4dCA9PSBudWxsIHx8IHR5cGVvZiBuZXh0ICE9PSAnb2JqZWN0Jykge1xuICAgICAgY3VycmVudFtrZXkgYXMgYW55XSA9IHR5cGVvZiBuZXh0S2V5ID09PSAnbnVtYmVyJyA/IFtdIDoge31cbiAgICB9XG4gICAgY3VycmVudCA9IGN1cnJlbnRba2V5IGFzIGFueV1cbiAgfVxuXG4gIGNvbnN0IGxhc3QgPSBzZWdtZW50c1tzZWdtZW50cy5sZW5ndGggLSAxXSFcbiAgY3VycmVudFtsYXN0IGFzIGFueV0gPSB2YWx1ZVxufVxuXG5leHBvcnQgY29uc3QgdW5zZXRBdFBhdGhNdXRhdGluZyA9IChkcmFmdDogYW55LCBwYXRoOiBzdHJpbmcpOiB2b2lkID0+IHtcbiAgaWYgKCFwYXRoKSByZXR1cm5cbiAgY29uc3Qgc2VnbWVudHMgPSBwYXJzZVNlZ21lbnRzKHBhdGgpXG4gIGlmIChzZWdtZW50cy5sZW5ndGggPT09IDApIHJldHVyblxuXG4gIGxldCBjdXJyZW50OiBhbnkgPSBkcmFmdFxuICBmb3IgKGxldCBpID0gMDsgaSA8IHNlZ21lbnRzLmxlbmd0aCAtIDE7IGkrKykge1xuICAgIGNvbnN0IGtleSA9IHNlZ21lbnRzW2ldIVxuICAgIGNvbnN0IG5leHQgPSBjdXJyZW50Py5ba2V5IGFzIGFueV1cbiAgICBpZiAobmV4dCA9PSBudWxsIHx8IHR5cGVvZiBuZXh0ICE9PSAnb2JqZWN0Jykge1xuICAgICAgcmV0dXJuXG4gICAgfVxuICAgIGN1cnJlbnQgPSBuZXh0XG4gIH1cblxuICBjb25zdCBsYXN0ID0gc2VnbWVudHNbc2VnbWVudHMubGVuZ3RoIC0gMV0hXG4gIGlmIChBcnJheS5pc0FycmF5KGN1cnJlbnQpICYmIHR5cGVvZiBsYXN0ID09PSAnbnVtYmVyJykge1xuICAgIGN1cnJlbnRbbGFzdF0gPSB1bmRlZmluZWRcbiAgICByZXR1cm5cbiAgfVxuXG4gIGlmIChjdXJyZW50ICYmIHR5cGVvZiBjdXJyZW50ID09PSAnb2JqZWN0Jykge1xuICAgIGRlbGV0ZSBjdXJyZW50W2xhc3QgYXMgYW55XVxuICB9XG59XG5cbmV4cG9ydCBjb25zdCBqb2luUGF0aCA9IChwcmVmaXg6IHN0cmluZywgc3VmZml4OiBzdHJpbmcpOiBzdHJpbmcgPT4ge1xuICBpZiAoIXByZWZpeCkgcmV0dXJuIHN1ZmZpeFxuICBpZiAoIXN1ZmZpeCkgcmV0dXJuIHByZWZpeFxuICByZXR1cm4gYCR7cHJlZml4fS4ke3N1ZmZpeH1gXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTGlzdEl0ZW1GaWVsZFBhdGgge1xuICByZWFkb25seSBsaXN0UGF0aDogc3RyaW5nXG4gIHJlYWRvbmx5IGl0ZW1QYXRoOiBzdHJpbmdcbn1cblxuLyoqXG4gKiBwYXJzZUxpc3RJdGVtRmllbGRQYXRoXHVGRjFBXG4gKiAtIFx1OEJDNlx1NTIyQlx1NUY2Mlx1NTk4MiBcIml0ZW1zW10ucHJvZmlsZVJlc291cmNlXCIgXHU3Njg0IGxpc3QuaXRlbSBcdTVCNTdcdTZCQjVcdThERUZcdTVGODRcdUZGMUJcbiAqIC0gXHU2NTJGXHU2MzAxXHU1OTFBXHU1QzQyXHU1RDRDXHU1OTU3XHU2NTcwXHU3RUM0XHVGRjFBXHU4RkQ0XHU1NkRFXHUyMDFDXHU2NzAwXHU1MTg1XHU1QzQyIGxpc3RcdTIwMURcdTc2ODQgbGlzdFBhdGggXHU0RTBFXHU1MTc2IGl0ZW1QYXRoXHUzMDAyXG4gKi9cbmV4cG9ydCBjb25zdCBwYXJzZUxpc3RJdGVtRmllbGRQYXRoID0gKGZpZWxkUGF0aDogc3RyaW5nKTogTGlzdEl0ZW1GaWVsZFBhdGggfCB1bmRlZmluZWQgPT4ge1xuICBjb25zdCByYXcgPSB0eXBlb2YgZmllbGRQYXRoID09PSAnc3RyaW5nJyA/IGZpZWxkUGF0aC50cmltKCkgOiAnJ1xuICBpZiAoIXJhdykgcmV0dXJuIHVuZGVmaW5lZFxuXG4gIGNvbnN0IHNlZ21lbnRzID0gcmF3LnNwbGl0KCcuJykuZmlsdGVyKEJvb2xlYW4pXG4gIGxldCBsYXN0TGlzdFNlZyA9IC0xXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgc2VnbWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoc2VnbWVudHNbaV0hLmVuZHNXaXRoKCdbXScpKSBsYXN0TGlzdFNlZyA9IGlcbiAgfVxuICBpZiAobGFzdExpc3RTZWcgPCAwKSByZXR1cm4gdW5kZWZpbmVkXG5cbiAgY29uc3Qgc3RyaXAgPSAoc2VnOiBzdHJpbmcpOiBzdHJpbmcgPT4gKHNlZy5lbmRzV2l0aCgnW10nKSA/IHNlZy5zbGljZSgwLCAtMikgOiBzZWcpXG5cbiAgY29uc3QgbGlzdFBhdGggPSBzZWdtZW50c1xuICAgIC5zbGljZSgwLCBsYXN0TGlzdFNlZyArIDEpXG4gICAgLm1hcChzdHJpcClcbiAgICAuam9pbignLicpXG5cbiAgY29uc3QgaXRlbVBhdGggPSBzZWdtZW50c1xuICAgIC5zbGljZShsYXN0TGlzdFNlZyArIDEpXG4gICAgLm1hcChzdHJpcClcbiAgICAuam9pbignLicpXG5cbiAgcmV0dXJuIHsgbGlzdFBhdGgsIGl0ZW1QYXRoIH1cbn1cblxuZXhwb3J0IGNvbnN0IHRvTGlzdEl0ZW1WYWx1ZVBhdGggPSAobGlzdFBhdGg6IHN0cmluZywgaW5kZXg6IG51bWJlciwgaXRlbVBhdGg6IHN0cmluZyk6IHN0cmluZyA9PlxuICBpdGVtUGF0aCA/IGAke2xpc3RQYXRofS4ke2luZGV4fS4ke2l0ZW1QYXRofWAgOiBgJHtsaXN0UGF0aH0uJHtpbmRleH1gXG5cbnR5cGUgTGlzdFN0YXRlID0ge1xuICByZWFkb25seSBsaXN0UGF0aDogc3RyaW5nXG4gIHJlYWRvbmx5IHBhcmVudFJvd0lkPzogUm93SWRcbiAgcmVhZG9ubHkgaXRlbXNSZWY6IFJlYWRvbmx5QXJyYXk8dW5rbm93bj5cbiAgcmVhZG9ubHkgaWRzOiBSZWFkb25seUFycmF5PFJvd0lkPlxuICByZWFkb25seSBpbmRleEJ5SWQ6IFJlYWRvbmx5TWFwPFJvd0lkLCBudW1iZXI+XG4gIHJlYWRvbmx5IHRyYWNrQnk/OiBzdHJpbmdcbn1cblxuY29uc3QgcmVhZFRyYWNrQnkgPSAoaXRlbTogdW5rbm93biwgdHJhY2tCeTogc3RyaW5nKTogdW5rbm93biA9PiB7XG4gIGlmICghaXRlbSB8fCB0eXBlb2YgaXRlbSAhPT0gJ29iamVjdCcpIHJldHVybiB1bmRlZmluZWRcbiAgY29uc3Qgc2VnbWVudHMgPSB0cmFja0J5LnNwbGl0KCcuJylcbiAgbGV0IGN1cnJlbnQ6IGFueSA9IGl0ZW1cbiAgZm9yIChjb25zdCBzZWcgb2Ygc2VnbWVudHMpIHtcbiAgICBpZiAoY3VycmVudCA9PSBudWxsKSByZXR1cm4gdW5kZWZpbmVkXG4gICAgY3VycmVudCA9IGN1cnJlbnRbc2VnIGFzIGFueV1cbiAgfVxuICByZXR1cm4gY3VycmVudFxufVxuXG5jb25zdCBkaWRSZW9yZGVyQnlSZWZlcmVuY2UgPSAocHJldkl0ZW1zOiBSZWFkb25seUFycmF5PHVua25vd24+LCBuZXh0SXRlbXM6IFJlYWRvbmx5QXJyYXk8dW5rbm93bj4pOiBib29sZWFuID0+IHtcbiAgY29uc3QgYnVja2V0cyA9IG5ldyBNYXA8dW5rbm93biwgQXJyYXk8bnVtYmVyPj4oKVxuICBmb3IgKGxldCBpID0gMDsgaSA8IHByZXZJdGVtcy5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGl0ZW0gPSBwcmV2SXRlbXNbaV1cbiAgICBjb25zdCBsaXN0ID0gYnVja2V0cy5nZXQoaXRlbSkgPz8gW11cbiAgICBsaXN0LnB1c2goaSlcbiAgICBidWNrZXRzLnNldChpdGVtLCBsaXN0KVxuICB9XG5cbiAgZm9yIChsZXQgbmV4dEluZGV4ID0gMDsgbmV4dEluZGV4IDwgbmV4dEl0ZW1zLmxlbmd0aDsgbmV4dEluZGV4KyspIHtcbiAgICBjb25zdCBpdGVtID0gbmV4dEl0ZW1zW25leHRJbmRleF1cbiAgICBjb25zdCBxID0gYnVja2V0cy5nZXQoaXRlbSlcbiAgICBpZiAoIXEgfHwgcS5sZW5ndGggPT09IDApIGNvbnRpbnVlXG4gICAgY29uc3QgcHJldkluZGV4ID0gcS5zaGlmdCgpIVxuICAgIGlmIChwcmV2SW5kZXggIT09IG5leHRJbmRleCkge1xuICAgICAgcmV0dXJuIHRydWVcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZmFsc2Vcbn1cblxuY29uc3QgaGFzU3RhYmxlVHJhY2tCeUtleXMgPSAoaXRlbXM6IFJlYWRvbmx5QXJyYXk8dW5rbm93bj4sIHRyYWNrQnk6IHN0cmluZyk6IGJvb2xlYW4gPT5cbiAgaXRlbXMuZXZlcnkoKGl0ZW0pID0+IHJlYWRUcmFja0J5KGl0ZW0sIHRyYWNrQnkpICE9PSB1bmRlZmluZWQpXG5cbmNvbnN0IGlzU2FtZVRyYWNrQnlTZXF1ZW5jZSA9IChcbiAgcHJldkl0ZW1zOiBSZWFkb25seUFycmF5PHVua25vd24+LFxuICBuZXh0SXRlbXM6IFJlYWRvbmx5QXJyYXk8dW5rbm93bj4sXG4gIHRyYWNrQnk6IHN0cmluZyxcbik6IGJvb2xlYW4gPT4ge1xuICBpZiAocHJldkl0ZW1zLmxlbmd0aCAhPT0gbmV4dEl0ZW1zLmxlbmd0aCkgcmV0dXJuIGZhbHNlXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgcHJldkl0ZW1zLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKCFPYmplY3QuaXMocmVhZFRyYWNrQnkocHJldkl0ZW1zW2ldLCB0cmFja0J5KSwgcmVhZFRyYWNrQnkobmV4dEl0ZW1zW2ldLCB0cmFja0J5KSkpIHtcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cbiAgfVxuICByZXR1cm4gdHJ1ZVxufVxuXG5jb25zdCByZWNvbmNpbGVJZHMgPSAoXG4gIHByZXY6IExpc3RTdGF0ZSB8IHVuZGVmaW5lZCxcbiAgbmV4dEl0ZW1zOiBSZWFkb25seUFycmF5PHVua25vd24+LFxuICB0cmFja0J5Pzogc3RyaW5nLFxuICBtYWtlUm93SWQ/OiAoKSA9PiBSb3dJZCxcbik6IHsgcmVhZG9ubHkgaWRzOiBSZWFkb25seUFycmF5PFJvd0lkPjsgcmVhZG9ubHkgcmVtb3ZlZDogUmVhZG9ubHlBcnJheTxSb3dJZD4gfSA9PiB7XG4gIGNvbnN0IG5leHRSb3dJZCA9XG4gICAgbWFrZVJvd0lkID8/XG4gICAgKCgpID0+IHtcbiAgICAgIGxldCByb3dTZXEgPSAwXG4gICAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICByb3dTZXEgKz0gMVxuICAgICAgICByZXR1cm4gYHIke3Jvd1NlcX1gXG4gICAgICB9XG4gICAgfSkoKVxuXG4gIGlmICghcHJldikge1xuICAgIHJldHVybiB7XG4gICAgICBpZHM6IG5leHRJdGVtcy5tYXAoKCkgPT4gbmV4dFJvd0lkKCkpLFxuICAgICAgcmVtb3ZlZDogW10sXG4gICAgfVxuICB9XG5cbiAgaWYgKHByZXYuaXRlbXNSZWYgPT09IG5leHRJdGVtcykge1xuICAgIHJldHVybiB7XG4gICAgICBpZHM6IHByZXYuaWRzLFxuICAgICAgcmVtb3ZlZDogW10sXG4gICAgfVxuICB9XG5cbiAgLy8gXHU5MUNEXHU4OTgxXHVGRjFBXHU0RkREXHU2MzAxIFJvd0lkIFx1NTcyOFx1MjAxQ1x1OTc1RVx1N0VEM1x1Njc4NFx1NTNEOFx1NjZGNFx1MjAxRFx1RkYwOFx1NEVDNVx1NUI1N1x1NkJCNVx1NjZGNFx1NjVCMC9cdTVCRjlcdThDNjFcdTUxNEJcdTk2ODZcdUZGMDlcdTRFMEJcdTc2ODRcdTdBMzNcdTVCOUFcdTYwMjdcdUZGMENcbiAgLy8gXHU1NDI2XHU1MjE5IGluLWZsaWdodCAvIFx1N0YxM1x1NUI1OCBcdTRGMUFcdTg4QUJcdTY1RTBcdTYxMEZcdTRFNDlcdTU3MzBcdTU5MzFcdTY1NDhcdTMwMDJcbiAgY29uc3Qgc2FtZUxlbmd0aCA9IHByZXYuaXRlbXNSZWYubGVuZ3RoID09PSBuZXh0SXRlbXMubGVuZ3RoXG4gIGlmIChzYW1lTGVuZ3RoKSB7XG4gICAgLy8gdHJhY2tCeSBcdTU3M0FcdTY2NkZcdUZGMUFcdTgyRTUga2V5IFx1NUU4Rlx1NTIxN1x1NEUwMFx1ODFGNFx1RkYwQ1x1NTIxOVx1NTNFRlx1NzZGNFx1NjNBNVx1NTkwRFx1NzUyOFx1NjVFNyBpZHNcdUZGMUJcbiAgICAvLyBcdTU0MjZcdTUyMTlcdTVGQzVcdTk4N0JcdThENzAga2V5LWJhc2VkIHJlY29uY2lsZVx1RkYwOFx1OTA3Rlx1NTE0RCBjbG9uZSArIHJlb3JkZXIgXHU2NUY2XHU4QkVGXHU1MjI0XHU0RTNBXHUyMDFDXHU2NzJBXHU5MUNEXHU2MzkyXHUyMDFEXHVGRjA5XHUzMDAyXG4gICAgaWYgKHRyYWNrQnkpIHtcbiAgICAgIGNvbnN0IGNhblVzZUtleXMgPSBoYXNTdGFibGVUcmFja0J5S2V5cyhwcmV2Lml0ZW1zUmVmLCB0cmFja0J5KSAmJiBoYXNTdGFibGVUcmFja0J5S2V5cyhuZXh0SXRlbXMsIHRyYWNrQnkpXG4gICAgICBpZiAoY2FuVXNlS2V5cykge1xuICAgICAgICBpZiAoaXNTYW1lVHJhY2tCeVNlcXVlbmNlKHByZXYuaXRlbXNSZWYsIG5leHRJdGVtcywgdHJhY2tCeSkpIHtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgaWRzOiBwcmV2LmlkcyxcbiAgICAgICAgICAgIHJlbW92ZWQ6IFtdLFxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gdHJhY2tCeSBrZXkgXHU0RTBEXHU1M0VGXHU3NTI4XHU2NUY2XHU5MDAwXHU1NkRFXHU1MjMwXHU1RjE1XHU3NTI4XHU3RUE3XHU0RkE2XHU2RDRCXHVGRjA4XHU1QzNEXHU5MUNGXHU0RkREXHU2MzAxXHUyMDFDXHU1MTRCXHU5Njg2XHU0RjQ2XHU0RTBEXHU5MUNEXHU2MzkyXHUyMDFEXHU3Njg0XHU3QTMzXHU1QjlBXHU2MDI3XHVGRjA5XHUzMDAyXG4gICAgICAgIGlmICghZGlkUmVvcmRlckJ5UmVmZXJlbmNlKHByZXYuaXRlbXNSZWYsIG5leHRJdGVtcykpIHtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgaWRzOiBwcmV2LmlkcyxcbiAgICAgICAgICAgIHJlbW92ZWQ6IFtdLFxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoIWRpZFJlb3JkZXJCeVJlZmVyZW5jZShwcmV2Lml0ZW1zUmVmLCBuZXh0SXRlbXMpKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBpZHM6IHByZXYuaWRzLFxuICAgICAgICByZW1vdmVkOiBbXSxcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBjb25zdCBrZXlPZiA9IChpdGVtOiB1bmtub3duKTogdW5rbm93biA9PiB7XG4gICAgaWYgKCF0cmFja0J5KSByZXR1cm4gaXRlbVxuICAgIGNvbnN0IGsgPSByZWFkVHJhY2tCeShpdGVtLCB0cmFja0J5KVxuICAgIHJldHVybiBrICE9PSB1bmRlZmluZWQgPyBrIDogaXRlbVxuICB9XG5cbiAgY29uc3QgYnVja2V0cyA9IG5ldyBNYXA8dW5rbm93biwgQXJyYXk8Um93SWQ+PigpXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgcHJldi5pdGVtc1JlZi5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGtleSA9IGtleU9mKHByZXYuaXRlbXNSZWZbaV0pXG4gICAgY29uc3QgbGlzdCA9IGJ1Y2tldHMuZ2V0KGtleSkgPz8gW11cbiAgICBsaXN0LnB1c2gocHJldi5pZHNbaV0hKVxuICAgIGJ1Y2tldHMuc2V0KGtleSwgbGlzdClcbiAgfVxuXG4gIGNvbnN0IGlkczogQXJyYXk8Um93SWQ+ID0gW11cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBuZXh0SXRlbXMubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBrZXkgPSBrZXlPZihuZXh0SXRlbXNbaV0pXG4gICAgY29uc3QgbGlzdCA9IGJ1Y2tldHMuZ2V0KGtleSlcbiAgICBpZiAobGlzdCAmJiBsaXN0Lmxlbmd0aCA+IDApIHtcbiAgICAgIGlkcy5wdXNoKGxpc3Quc2hpZnQoKSEpXG4gICAgfSBlbHNlIHtcbiAgICAgIGlkcy5wdXNoKG5leHRSb3dJZCgpKVxuICAgIH1cbiAgfVxuXG4gIGNvbnN0IHJlbW92ZWQ6IEFycmF5PFJvd0lkPiA9IFtdXG4gIGZvciAoY29uc3QgbGlzdCBvZiBidWNrZXRzLnZhbHVlcygpKSB7XG4gICAgcmVtb3ZlZC5wdXNoKC4uLmxpc3QpXG4gIH1cblxuICByZXR1cm4geyBpZHMsIHJlbW92ZWQgfVxufVxuXG5jb25zdCBidWlsZEluZGV4QnlJZCA9IChpZHM6IFJlYWRvbmx5QXJyYXk8Um93SWQ+KTogUmVhZG9ubHlNYXA8Um93SWQsIG51bWJlcj4gPT4ge1xuICBjb25zdCBtYXAgPSBuZXcgTWFwPFJvd0lkLCBudW1iZXI+KClcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBpZHMubGVuZ3RoOyBpKyspIHtcbiAgICBtYXAuc2V0KGlkc1tpXSEsIGkpXG4gIH1cbiAgcmV0dXJuIG1hcFxufVxuXG5leHBvcnQgY2xhc3MgUm93SWRTdG9yZSB7XG4gIHByaXZhdGUgcmVhZG9ubHkgbGlzdHMgPSBuZXcgTWFwPHN0cmluZywgTGlzdFN0YXRlPigpXG4gIHByaXZhdGUgcmVhZG9ubHkgcmVtb3ZhbExpc3RlbmVycyA9IG5ldyBNYXA8c3RyaW5nLCBTZXQ8TGlzdFJlbW92YWxMaXN0ZW5lcj4+KClcbiAgcHJpdmF0ZSByZWFkb25seSByb3dJZEluZGV4ID0gbmV3IE1hcDxcbiAgICBSb3dJZCxcbiAgICB7IHJlYWRvbmx5IGtleTogc3RyaW5nOyByZWFkb25seSBsaXN0UGF0aDogc3RyaW5nOyByZWFkb25seSBpbmRleDogbnVtYmVyIH1cbiAgPigpXG4gIHByaXZhdGUgbmV4dFJvd1NlcSA9IDBcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IGluc3RhbmNlSWQ/OiBzdHJpbmcpIHt9XG5cbiAgcHJpdmF0ZSBsaXN0S2V5ID0gKGxpc3RQYXRoOiBzdHJpbmcsIHBhcmVudFJvd0lkPzogUm93SWQpOiBzdHJpbmcgPT5cbiAgICBwYXJlbnRSb3dJZCA/IGAke2xpc3RQYXRofUBAJHtwYXJlbnRSb3dJZH1gIDogbGlzdFBhdGhcblxuICBwcml2YXRlIG1ha2VSb3dJZCA9ICgpOiBSb3dJZCA9PiB7XG4gICAgdGhpcy5uZXh0Um93U2VxICs9IDFcbiAgICByZXR1cm4gdGhpcy5pbnN0YW5jZUlkID8gYCR7dGhpcy5pbnN0YW5jZUlkfTo6ciR7dGhpcy5uZXh0Um93U2VxfWAgOiBgciR7dGhpcy5uZXh0Um93U2VxfWBcbiAgfVxuXG4gIHByaXZhdGUgbm90aWZ5UmVtb3ZlZChsaXN0UGF0aDogc3RyaW5nLCByb3dJZDogUm93SWQpOiB2b2lkIHtcbiAgICBjb25zdCBsaXN0ZW5lcnMgPSB0aGlzLnJlbW92YWxMaXN0ZW5lcnMuZ2V0KGxpc3RQYXRoKVxuICAgIGlmICghbGlzdGVuZXJzIHx8IGxpc3RlbmVycy5zaXplID09PSAwKSByZXR1cm5cbiAgICBmb3IgKGNvbnN0IGZuIG9mIGxpc3RlbmVycykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgZm4ocm93SWQpXG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgLy8gbGlzdGVuZXIgZmFpbHVyZXMgc2hvdWxkIG5ldmVyIGJyZWFrIHJ1bnRpbWUgYmVoYXZpb3JcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHJlbW92ZURlc2NlbmRhbnRzKHBhcmVudFJvd0lkOiBSb3dJZCk6IHZvaWQge1xuICAgIGNvbnN0IGtleXM6IEFycmF5PHN0cmluZz4gPSBbXVxuICAgIGZvciAoY29uc3QgW2ssIHN0XSBvZiB0aGlzLmxpc3RzLmVudHJpZXMoKSkge1xuICAgICAgaWYgKHN0LnBhcmVudFJvd0lkID09PSBwYXJlbnRSb3dJZCkga2V5cy5wdXNoKGspXG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBrZXkgb2Yga2V5cykge1xuICAgICAgY29uc3Qgc3QgPSB0aGlzLmxpc3RzLmdldChrZXkpXG4gICAgICBpZiAoIXN0KSBjb250aW51ZVxuICAgICAgdGhpcy5saXN0cy5kZWxldGUoa2V5KVxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzdC5pZHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29uc3Qgcm93SWQgPSBzdC5pZHNbaV0hXG4gICAgICAgIHRoaXMucm93SWRJbmRleC5kZWxldGUocm93SWQpXG4gICAgICAgIHRoaXMubm90aWZ5UmVtb3ZlZChzdC5saXN0UGF0aCwgcm93SWQpXG4gICAgICAgIHRoaXMucmVtb3ZlRGVzY2VuZGFudHMocm93SWQpXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgb25SZW1vdmVkKGxpc3RQYXRoOiBzdHJpbmcsIGxpc3RlbmVyOiBMaXN0UmVtb3ZhbExpc3RlbmVyKTogKCkgPT4gdm9pZCB7XG4gICAgY29uc3Qgc2V0ID0gdGhpcy5yZW1vdmFsTGlzdGVuZXJzLmdldChsaXN0UGF0aCkgPz8gbmV3IFNldDxMaXN0UmVtb3ZhbExpc3RlbmVyPigpXG4gICAgc2V0LmFkZChsaXN0ZW5lcilcbiAgICB0aGlzLnJlbW92YWxMaXN0ZW5lcnMuc2V0KGxpc3RQYXRoLCBzZXQpXG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIGNvbnN0IGN1cnJlbnQgPSB0aGlzLnJlbW92YWxMaXN0ZW5lcnMuZ2V0KGxpc3RQYXRoKVxuICAgICAgaWYgKCFjdXJyZW50KSByZXR1cm5cbiAgICAgIGN1cnJlbnQuZGVsZXRlKGxpc3RlbmVyKVxuICAgICAgaWYgKGN1cnJlbnQuc2l6ZSA9PT0gMCkgdGhpcy5yZW1vdmFsTGlzdGVuZXJzLmRlbGV0ZShsaXN0UGF0aClcbiAgICB9XG4gIH1cblxuICBnZXRSb3dJZChsaXN0UGF0aDogc3RyaW5nLCBpbmRleDogbnVtYmVyLCBwYXJlbnRSb3dJZD86IFJvd0lkKTogUm93SWQgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IHN0YXRlID0gdGhpcy5saXN0cy5nZXQodGhpcy5saXN0S2V5KGxpc3RQYXRoLCBwYXJlbnRSb3dJZCkpXG4gICAgcmV0dXJuIHN0YXRlID8gc3RhdGUuaWRzW2luZGV4XSA6IHVuZGVmaW5lZFxuICB9XG5cbiAgZ2V0SW5kZXgobGlzdFBhdGg6IHN0cmluZywgcm93SWQ6IFJvd0lkKTogbnVtYmVyIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBpbmZvID0gdGhpcy5yb3dJZEluZGV4LmdldChyb3dJZClcbiAgICBpZiAoIWluZm8pIHJldHVybiB1bmRlZmluZWRcbiAgICBpZiAoaW5mby5saXN0UGF0aCAhPT0gbGlzdFBhdGgpIHJldHVybiB1bmRlZmluZWRcbiAgICByZXR1cm4gaW5mby5pbmRleFxuICB9XG5cbiAgLyoqXG4gICAqIGVuc3VyZUxpc3RcdUZGMUFcbiAgICogLSBcdThCQTlcdTYzMDdcdTVCOUEgbGlzdFBhdGggXHU3Njg0IFJvd0lEIFx1NjYyMFx1NUMwNFx1NEUwRVx1NUY1M1x1NTI0RCBpdGVtcyBcdTVCRjlcdTlGNTBcdUZGMUJcbiAgICogLSBcdThGRDRcdTU2REVcdTY3MDBcdTY1QjBcdTc2ODQgaWRzXHVGRjA4aW5kZXggLT4gUm93SWRcdUZGMDlcdTMwMDJcbiAgICovXG4gIGVuc3VyZUxpc3QoXG4gICAgbGlzdFBhdGg6IHN0cmluZyxcbiAgICBpdGVtczogUmVhZG9ubHlBcnJheTx1bmtub3duPixcbiAgICB0cmFja0J5Pzogc3RyaW5nLFxuICAgIHBhcmVudFJvd0lkPzogUm93SWQsXG4gICk6IFJlYWRvbmx5QXJyYXk8Um93SWQ+IHtcbiAgICBjb25zdCBrZXkgPSB0aGlzLmxpc3RLZXkobGlzdFBhdGgsIHBhcmVudFJvd0lkKVxuICAgIGNvbnN0IHByZXYgPSB0aGlzLmxpc3RzLmdldChrZXkpXG4gICAgY29uc3QgeyBpZHMsIHJlbW92ZWQgfSA9IHJlY29uY2lsZUlkcyhwcmV2LCBpdGVtcywgdHJhY2tCeSA/PyBwcmV2Py50cmFja0J5LCB0aGlzLm1ha2VSb3dJZClcblxuICAgIGNvbnN0IG5leHQ6IExpc3RTdGF0ZSA9IHtcbiAgICAgIGxpc3RQYXRoLFxuICAgICAgcGFyZW50Um93SWQsXG4gICAgICBpdGVtc1JlZjogaXRlbXMsXG4gICAgICBpZHMsXG4gICAgICBpbmRleEJ5SWQ6IGJ1aWxkSW5kZXhCeUlkKGlkcyksXG4gICAgICB0cmFja0J5OiB0cmFja0J5ID8/IHByZXY/LnRyYWNrQnksXG4gICAgfVxuICAgIHRoaXMubGlzdHMuc2V0KGtleSwgbmV4dClcblxuICAgIGlmIChyZW1vdmVkLmxlbmd0aCA+IDApIHtcbiAgICAgIGZvciAoY29uc3Qgcm93SWQgb2YgcmVtb3ZlZCkge1xuICAgICAgICB0aGlzLnJvd0lkSW5kZXguZGVsZXRlKHJvd0lkKVxuICAgICAgICB0aGlzLm5vdGlmeVJlbW92ZWQobGlzdFBhdGgsIHJvd0lkKVxuICAgICAgICB0aGlzLnJlbW92ZURlc2NlbmRhbnRzKHJvd0lkKVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFx1NTIzN1x1NjVCMCByb3dJZCBcdTIxOTIgaW5kZXggXHU3Njg0XHU1M0NEXHU1NDExXHU2NjIwXHU1QzA0XHVGRjA4XHU1MTQxXHU4QkI4IGluZGV4IFx1NTNEOFx1NTMxNlx1RkYwOVx1MzAwMlxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaWRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCByb3dJZCA9IGlkc1tpXSFcbiAgICAgIHRoaXMucm93SWRJbmRleC5zZXQocm93SWQsIHsga2V5LCBsaXN0UGF0aCwgaW5kZXg6IGkgfSlcbiAgICB9XG5cbiAgICByZXR1cm4gaWRzXG4gIH1cblxuICAvKipcbiAgICogdXBkYXRlQWxsXHVGRjFBXG4gICAqIC0gXHU1NzI4XHU2QkNGXHU2QjIxXHU2M0QwXHU0RUE0XHU1NDBFXHU1QkY5XHU5RjUwXHU2MjQwXHU2NzA5XHU1REYyXHU3N0U1IGxpc3QgXHU3Njg0IFJvd0lEIFx1NjYyMFx1NUMwNFx1RkYxQlxuICAgKiAtIGNvbmZpZ3MgXHU2NzY1XHU4MUVBIFN0YXRlVHJhaXRQcm9ncmFtLnNwZWMgXHU0RTJEXHU3Njg0IGxpc3QgXHU1OEYwXHU2NjBFXHVGRjA4XHU1M0VGXHU2NDNBXHU1RTI2IHRyYWNrQnlcdUZGMDlcdTMwMDJcbiAgICovXG4gIHVwZGF0ZUFsbChzdGF0ZTogdW5rbm93biwgY29uZmlnczogUmVhZG9ubHlBcnJheTxMaXN0Q29uZmlnPik6IHZvaWQge1xuICAgIGNvbnN0IGNmZ0J5UGF0aCA9IG5ldyBNYXA8c3RyaW5nLCBMaXN0Q29uZmlnPigpXG4gICAgY29uc3QgcGF0aHM6IEFycmF5PHN0cmluZz4gPSBbXVxuICAgIGZvciAoY29uc3QgY2ZnIG9mIGNvbmZpZ3MpIHtcbiAgICAgIGlmICghY2ZnIHx8IHR5cGVvZiBjZmcucGF0aCAhPT0gJ3N0cmluZycpIGNvbnRpbnVlXG4gICAgICBjb25zdCBwID0gY2ZnLnBhdGgudHJpbSgpXG4gICAgICBpZiAoIXApIGNvbnRpbnVlXG4gICAgICBjZmdCeVBhdGguc2V0KHAsIGNmZylcbiAgICAgIHBhdGhzLnB1c2gocClcbiAgICB9XG5cbiAgICBjb25zdCBwYXRoU2V0ID0gbmV3IFNldChwYXRocylcblxuICAgIGNvbnN0IHBhcmVudE9mID0gKHBhdGg6IHN0cmluZyk6IHN0cmluZyB8IHVuZGVmaW5lZCA9PiB7XG4gICAgICBjb25zdCBzZWdtZW50cyA9IHBhdGguc3BsaXQoJy4nKS5maWx0ZXIoQm9vbGVhbilcbiAgICAgIGxldCBiZXN0OiBzdHJpbmcgfCB1bmRlZmluZWRcbiAgICAgIGZvciAobGV0IGkgPSAxOyBpIDwgc2VnbWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29uc3QgcHJlZml4ID0gc2VnbWVudHMuc2xpY2UoMCwgaSkuam9pbignLicpXG4gICAgICAgIGlmIChwYXRoU2V0LmhhcyhwcmVmaXgpKSBiZXN0ID0gcHJlZml4XG4gICAgICB9XG4gICAgICByZXR1cm4gYmVzdFxuICAgIH1cblxuICAgIGNvbnN0IHBhcmVudEJ5UGF0aCA9IG5ldyBNYXA8c3RyaW5nLCBzdHJpbmcgfCB1bmRlZmluZWQ+KClcbiAgICBjb25zdCBzdWZmaXhCeVBhdGggPSBuZXcgTWFwPHN0cmluZywgc3RyaW5nPigpXG4gICAgY29uc3QgY2hpbGRyZW5CeVBhcmVudCA9IG5ldyBNYXA8c3RyaW5nIHwgdW5kZWZpbmVkLCBBcnJheTxzdHJpbmc+PigpXG5cbiAgICBmb3IgKGNvbnN0IHBhdGggb2YgcGF0aHMpIHtcbiAgICAgIGNvbnN0IHBhcmVudCA9IHBhcmVudE9mKHBhdGgpXG4gICAgICBwYXJlbnRCeVBhdGguc2V0KHBhdGgsIHBhcmVudClcbiAgICAgIGNvbnN0IHN1ZmZpeCA9IHBhcmVudCA/IHBhdGguc2xpY2UocGFyZW50Lmxlbmd0aCArIDEpIDogcGF0aFxuICAgICAgc3VmZml4QnlQYXRoLnNldChwYXRoLCBzdWZmaXgpXG4gICAgICBjb25zdCBsaXN0ID0gY2hpbGRyZW5CeVBhcmVudC5nZXQocGFyZW50KSA/PyBbXVxuICAgICAgbGlzdC5wdXNoKHBhdGgpXG4gICAgICBjaGlsZHJlbkJ5UGFyZW50LnNldChwYXJlbnQsIGxpc3QpXG4gICAgfVxuXG4gICAgLy8gcm9vdHMgZmlyc3QgKGFuZCBkZXRlcm1pbmlzdGljIHRyYXZlcnNhbClcbiAgICBjb25zdCByb290cyA9IChjaGlsZHJlbkJ5UGFyZW50LmdldCh1bmRlZmluZWQpID8/IFtdKS5zbGljZSgpLnNvcnQoKGEsIGIpID0+IGEubG9jYWxlQ29tcGFyZShiKSlcblxuICAgIGNvbnN0IHZpc2l0ID0gKGxpc3RQYXRoOiBzdHJpbmcsIHBhcmVudFJvd0lkOiBSb3dJZCB8IHVuZGVmaW5lZCwgbGlzdFZhbHVlOiB1bmtub3duKTogdm9pZCA9PiB7XG4gICAgICBjb25zdCBjZmcgPSBjZmdCeVBhdGguZ2V0KGxpc3RQYXRoKVxuICAgICAgY29uc3QgaXRlbXMgPSBBcnJheS5pc0FycmF5KGxpc3RWYWx1ZSkgPyAobGlzdFZhbHVlIGFzIFJlYWRvbmx5QXJyYXk8dW5rbm93bj4pIDogW11cbiAgICAgIGNvbnN0IGlkcyA9IHRoaXMuZW5zdXJlTGlzdChsaXN0UGF0aCwgaXRlbXMsIGNmZz8udHJhY2tCeSwgcGFyZW50Um93SWQpXG5cbiAgICAgIGNvbnN0IGNoaWxkcmVuID0gKGNoaWxkcmVuQnlQYXJlbnQuZ2V0KGxpc3RQYXRoKSA/PyBbXSkuc2xpY2UoKS5zb3J0KChhLCBiKSA9PiBhLmxvY2FsZUNvbXBhcmUoYikpXG4gICAgICBpZiAoY2hpbGRyZW4ubGVuZ3RoID09PSAwKSByZXR1cm5cblxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBpdGVtcy5sZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCByb3cgPSBpdGVtc1tpXVxuICAgICAgICBjb25zdCByb3dJZCA9IGlkc1tpXVxuICAgICAgICBpZiAoIXJvd0lkKSBjb250aW51ZVxuICAgICAgICBmb3IgKGNvbnN0IGNoaWxkUGF0aCBvZiBjaGlsZHJlbikge1xuICAgICAgICAgIGNvbnN0IHN1ZmZpeCA9IHN1ZmZpeEJ5UGF0aC5nZXQoY2hpbGRQYXRoKSA/PyAnJ1xuICAgICAgICAgIGNvbnN0IGNoaWxkVmFsdWUgPSBzdWZmaXggPyBnZXRBdFBhdGgocm93IGFzIGFueSwgc3VmZml4KSA6IHVuZGVmaW5lZFxuICAgICAgICAgIHZpc2l0KGNoaWxkUGF0aCwgcm93SWQsIGNoaWxkVmFsdWUpXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHJvb3Qgb2Ygcm9vdHMpIHtcbiAgICAgIGNvbnN0IHZhbHVlID0gZ2V0QXRQYXRoKHN0YXRlIGFzIGFueSwgcm9vdClcbiAgICAgIHZpc2l0KHJvb3QsIHVuZGVmaW5lZCwgdmFsdWUpXG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBjb25zdCBjb2xsZWN0TGlzdENvbmZpZ3MgPSAoc3BlYzogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pOiBSZWFkb25seUFycmF5PExpc3RDb25maWc+ID0+IHtcbiAgY29uc3QgY29uZmlnczogQXJyYXk8TGlzdENvbmZpZz4gPSBbXVxuICBmb3IgKGNvbnN0IGtleSBpbiBzcGVjKSB7XG4gICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoc3BlYywga2V5KSkgY29udGludWVcbiAgICBjb25zdCByYXcgPSBzcGVjW2tleV1cbiAgICBpZiAoIXJhdyB8fCB0eXBlb2YgcmF3ICE9PSAnb2JqZWN0JykgY29udGludWVcbiAgICBjb25zdCB0YWcgPSAocmF3IGFzIGFueSkuX3RhZ1xuICAgIGlmICh0YWcgIT09ICdTdGF0ZVRyYWl0TGlzdCcpIGNvbnRpbnVlXG4gICAgY29uc3QgdHJhY2tCeSA9IChyYXcgYXMgYW55KS5pZGVudGl0eUhpbnQ/LnRyYWNrQnlcbiAgICBjb25maWdzLnB1c2goe1xuICAgICAgcGF0aDoga2V5LFxuICAgICAgdHJhY2tCeTogdHlwZW9mIHRyYWNrQnkgPT09ICdzdHJpbmcnID8gdHJhY2tCeSA6IHVuZGVmaW5lZCxcbiAgICB9KVxuICB9XG4gIHJldHVybiBjb25maWdzXG59XG4iLCAiaW1wb3J0IHsgQ29udGV4dCwgRWZmZWN0LCBMYXllciB9IGZyb20gJ2VmZmVjdCdcblxuZXhwb3J0IHR5cGUgUmVzb3VyY2VTbmFwc2hvdFBoYXNlID0gJ2lkbGUnIHwgJ2xvYWRpbmcnIHwgJ3N1Y2Nlc3MnIHwgJ2Vycm9yJ1xuXG5leHBvcnQgdHlwZSBSZXBsYXlMb2dFdmVudCA9XG4gIHwge1xuICAgICAgcmVhZG9ubHkgX3RhZzogJ1Jlc291cmNlU25hcHNob3QnXG4gICAgICByZWFkb25seSByZXNvdXJjZUlkOiBzdHJpbmdcbiAgICAgIHJlYWRvbmx5IGZpZWxkUGF0aDogc3RyaW5nXG4gICAgICByZWFkb25seSBrZXlIYXNoPzogc3RyaW5nXG4gICAgICAvKipcbiAgICAgICAqIFx1NTNFRlx1OTAwOVx1RkYxQXNvdXJjZSBcdTc2ODRcdTVFNzZcdTUzRDFcdTdCNTZcdTc1NjVcdUZGMDhcdTRGOEJcdTU5ODIgXCJzd2l0Y2hcIiAvIFwiZXhoYXVzdC10cmFpbGluZ1wiXHVGRjA5XHUzMDAyXG4gICAgICAgKiAtIFx1NUZDNVx1OTg3Qlx1NEZERFx1NjMwMSBTbGltICYgXHU1M0VGXHU1RThGXHU1MjE3XHU1MzE2XHVGRjFCXG4gICAgICAgKiAtIFx1NzUyOFx1NEU4RSBEZXZ0b29scy9cdTU2REVcdTY1M0VcdTg5RTNcdTkxQ0FcdTIwMUNcdTRFM0FcdTRGNTVcdTY1RTdcdTdFRDNcdTY3OUNcdTg4QUJcdTRFMjJcdTVGMDMvXHU0RTNBXHU0RjU1IHRyYWlsaW5nIFx1NTNEMVx1NzUxRlx1MjAxRFx1MzAwMlxuICAgICAgICovXG4gICAgICByZWFkb25seSBjb25jdXJyZW5jeT86IHN0cmluZ1xuICAgICAgcmVhZG9ubHkgcGhhc2U6IFJlc291cmNlU25hcHNob3RQaGFzZVxuICAgICAgcmVhZG9ubHkgc25hcHNob3Q6IHVua25vd25cbiAgICAgIHJlYWRvbmx5IHRpbWVzdGFtcDogbnVtYmVyXG4gICAgICByZWFkb25seSBtb2R1bGVJZD86IHN0cmluZ1xuICAgICAgcmVhZG9ubHkgaW5zdGFuY2VJZD86IHN0cmluZ1xuICAgIH1cbiAgfCB7XG4gICAgICByZWFkb25seSBfdGFnOiAnSW52YWxpZGF0ZVJlcXVlc3QnXG4gICAgICByZWFkb25seSB0aW1lc3RhbXA6IG51bWJlclxuICAgICAgcmVhZG9ubHkgbW9kdWxlSWQ/OiBzdHJpbmdcbiAgICAgIHJlYWRvbmx5IGluc3RhbmNlSWQ/OiBzdHJpbmdcbiAgICAgIHJlYWRvbmx5IGtpbmQ6ICdyZXNvdXJjZScgfCAncXVlcnknXG4gICAgICByZWFkb25seSB0YXJnZXQ6IHN0cmluZ1xuICAgICAgcmVhZG9ubHkgbWV0YT86IHVua25vd25cbiAgICB9XG5cbmV4cG9ydCB0eXBlIFJlc291cmNlU25hcHNob3RFdmVudCA9IEV4dHJhY3Q8UmVwbGF5TG9nRXZlbnQsIHsgcmVhZG9ubHkgX3RhZzogJ1Jlc291cmNlU25hcHNob3QnIH0+XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVwbGF5TG9nU2VydmljZSB7XG4gIHJlYWRvbmx5IHJlY29yZDogKGV2ZW50OiBSZXBsYXlMb2dFdmVudCkgPT4gRWZmZWN0LkVmZmVjdDx2b2lkPlxuICByZWFkb25seSBzbmFwc2hvdDogRWZmZWN0LkVmZmVjdDxSZWFkb25seUFycmF5PFJlcGxheUxvZ0V2ZW50Pj5cbiAgcmVhZG9ubHkgcmVzZXRDdXJzb3I6IEVmZmVjdC5FZmZlY3Q8dm9pZD5cbiAgcmVhZG9ubHkgY29uc3VtZU5leHQ6IChwcmVkaWNhdGU6IChldmVudDogUmVwbGF5TG9nRXZlbnQpID0+IGJvb2xlYW4pID0+IEVmZmVjdC5FZmZlY3Q8UmVwbGF5TG9nRXZlbnQgfCB1bmRlZmluZWQ+XG4gIHJlYWRvbmx5IGNvbnN1bWVOZXh0UmVzb3VyY2VTbmFwc2hvdDogKHBhcmFtczoge1xuICAgIHJlYWRvbmx5IHJlc291cmNlSWQ6IHN0cmluZ1xuICAgIHJlYWRvbmx5IGZpZWxkUGF0aDogc3RyaW5nXG4gICAgcmVhZG9ubHkga2V5SGFzaD86IHN0cmluZ1xuICAgIHJlYWRvbmx5IHBoYXNlPzogUmVzb3VyY2VTbmFwc2hvdFBoYXNlXG4gIH0pID0+IEVmZmVjdC5FZmZlY3Q8UmVzb3VyY2VTbmFwc2hvdEV2ZW50IHwgdW5kZWZpbmVkPlxufVxuXG5leHBvcnQgY2xhc3MgUmVwbGF5TG9nIGV4dGVuZHMgQ29udGV4dC5UYWcoJ0Bsb2dpeC9jb3JlL1JlcGxheUxvZycpPFJlcGxheUxvZywgUmVwbGF5TG9nU2VydmljZT4oKSB7fVxuXG5leHBvcnQgY29uc3QgbWFrZSA9IChpbml0aWFsPzogUmVhZG9ubHlBcnJheTxSZXBsYXlMb2dFdmVudD4pOiBSZXBsYXlMb2dTZXJ2aWNlID0+IHtcbiAgY29uc3QgZXZlbnRzOiBBcnJheTxSZXBsYXlMb2dFdmVudD4gPSBpbml0aWFsID8gQXJyYXkuZnJvbShpbml0aWFsKSA6IFtdXG4gIGxldCBjdXJzb3IgPSAwXG5cbiAgY29uc3QgY29uc3VtZU5leHQgPSAocHJlZGljYXRlOiAoZXZlbnQ6IFJlcGxheUxvZ0V2ZW50KSA9PiBib29sZWFuKTogRWZmZWN0LkVmZmVjdDxSZXBsYXlMb2dFdmVudCB8IHVuZGVmaW5lZD4gPT5cbiAgICBFZmZlY3Quc3luYygoKSA9PiB7XG4gICAgICBmb3IgKGxldCBpID0gY3Vyc29yOyBpIDwgZXZlbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IGV2ZW50ID0gZXZlbnRzW2ldXG4gICAgICAgIGlmICghcHJlZGljYXRlKGV2ZW50KSkgY29udGludWVcbiAgICAgICAgY3Vyc29yID0gaSArIDFcbiAgICAgICAgcmV0dXJuIGV2ZW50XG4gICAgICB9XG4gICAgICByZXR1cm4gdW5kZWZpbmVkXG4gICAgfSlcblxuICBjb25zdCBjb25zdW1lTmV4dFJlc291cmNlU25hcHNob3QgPSAocGFyYW1zOiB7XG4gICAgcmVhZG9ubHkgcmVzb3VyY2VJZDogc3RyaW5nXG4gICAgcmVhZG9ubHkgZmllbGRQYXRoOiBzdHJpbmdcbiAgICByZWFkb25seSBrZXlIYXNoPzogc3RyaW5nXG4gICAgcmVhZG9ubHkgcGhhc2U/OiBSZXNvdXJjZVNuYXBzaG90UGhhc2VcbiAgfSk6IEVmZmVjdC5FZmZlY3Q8UmVzb3VyY2VTbmFwc2hvdEV2ZW50IHwgdW5kZWZpbmVkPiA9PlxuICAgIGNvbnN1bWVOZXh0KChldmVudCk6IGV2ZW50IGlzIFJlc291cmNlU25hcHNob3RFdmVudCA9PiB7XG4gICAgICBpZiAoZXZlbnQuX3RhZyAhPT0gJ1Jlc291cmNlU25hcHNob3QnKSByZXR1cm4gZmFsc2VcbiAgICAgIGlmIChldmVudC5yZXNvdXJjZUlkICE9PSBwYXJhbXMucmVzb3VyY2VJZCkgcmV0dXJuIGZhbHNlXG4gICAgICBpZiAoZXZlbnQuZmllbGRQYXRoICE9PSBwYXJhbXMuZmllbGRQYXRoKSByZXR1cm4gZmFsc2VcbiAgICAgIGlmIChwYXJhbXMua2V5SGFzaCAhPT0gdW5kZWZpbmVkICYmIGV2ZW50LmtleUhhc2ggIT09IHBhcmFtcy5rZXlIYXNoKSB7XG4gICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgfVxuICAgICAgaWYgKHBhcmFtcy5waGFzZSAhPT0gdW5kZWZpbmVkICYmIGV2ZW50LnBoYXNlICE9PSBwYXJhbXMucGhhc2UpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICB9XG4gICAgICByZXR1cm4gdHJ1ZVxuICAgIH0pLnBpcGUoRWZmZWN0Lm1hcCgoZXZlbnQpID0+IGV2ZW50IGFzIFJlc291cmNlU25hcHNob3RFdmVudCB8IHVuZGVmaW5lZCkpXG5cbiAgcmV0dXJuIHtcbiAgICByZWNvcmQ6IChldmVudCkgPT4gRWZmZWN0LnN5bmMoKCkgPT4gZXZlbnRzLnB1c2goZXZlbnQpKSxcbiAgICBzbmFwc2hvdDogRWZmZWN0LnN5bmMoKCkgPT4gZXZlbnRzLnNsaWNlKCkpLFxuICAgIHJlc2V0Q3Vyc29yOiBFZmZlY3Quc3luYygoKSA9PiB7XG4gICAgICBjdXJzb3IgPSAwXG4gICAgfSksXG4gICAgY29uc3VtZU5leHQsXG4gICAgY29uc3VtZU5leHRSZXNvdXJjZVNuYXBzaG90LFxuICB9XG59XG5cbmV4cG9ydCBjb25zdCBsYXllciA9IChpbml0aWFsPzogUmVhZG9ubHlBcnJheTxSZXBsYXlMb2dFdmVudD4pOiBMYXllci5MYXllcjxSZXBsYXlMb2csIG5ldmVyLCBuZXZlcj4gPT5cbiAgTGF5ZXIuc3VjY2VlZChSZXBsYXlMb2csIG1ha2UoaW5pdGlhbCkpXG5cbmV4cG9ydCBjb25zdCByZWNvcmQgPSAoZXZlbnQ6IFJlcGxheUxvZ0V2ZW50KTogRWZmZWN0LkVmZmVjdDx2b2lkLCBuZXZlciwgUmVwbGF5TG9nPiA9PlxuICBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG4gICAgY29uc3QgbG9nID0geWllbGQqIFJlcGxheUxvZ1xuICAgIHlpZWxkKiBsb2cucmVjb3JkKGV2ZW50KVxuICB9KVxuXG5leHBvcnQgY29uc3Qgc25hcHNob3Q6IEVmZmVjdC5FZmZlY3Q8UmVhZG9ubHlBcnJheTxSZXBsYXlMb2dFdmVudD4sIG5ldmVyLCBSZXBsYXlMb2c+ID0gRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICBjb25zdCBsb2cgPSB5aWVsZCogUmVwbGF5TG9nXG4gIHJldHVybiB5aWVsZCogbG9nLnNuYXBzaG90XG59KVxuXG5leHBvcnQgY29uc3QgcmVzZXRDdXJzb3I6IEVmZmVjdC5FZmZlY3Q8dm9pZCwgbmV2ZXIsIFJlcGxheUxvZz4gPSBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG4gIGNvbnN0IGxvZyA9IHlpZWxkKiBSZXBsYXlMb2dcbiAgeWllbGQqIGxvZy5yZXNldEN1cnNvclxufSlcblxuZXhwb3J0IGNvbnN0IGNvbnN1bWVOZXh0UmVzb3VyY2VTbmFwc2hvdCA9IChwYXJhbXM6IHtcbiAgcmVhZG9ubHkgcmVzb3VyY2VJZDogc3RyaW5nXG4gIHJlYWRvbmx5IGZpZWxkUGF0aDogc3RyaW5nXG4gIHJlYWRvbmx5IGtleUhhc2g/OiBzdHJpbmdcbiAgcmVhZG9ubHkgcGhhc2U/OiBSZXNvdXJjZVNuYXBzaG90UGhhc2Vcbn0pOiBFZmZlY3QuRWZmZWN0PFJlc291cmNlU25hcHNob3RFdmVudCB8IHVuZGVmaW5lZCwgbmV2ZXIsIFJlcGxheUxvZz4gPT5cbiAgRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgIGNvbnN0IGxvZyA9IHlpZWxkKiBSZXBsYXlMb2dcbiAgICByZXR1cm4geWllbGQqIGxvZy5jb25zdW1lTmV4dFJlc291cmNlU25hcHNob3QocGFyYW1zKVxuICB9KVxuIl0sCiAgIm1hcHBpbmdzIjogIjs7OztBQVdBLElBQU0sZ0JBQWdCLENBQUMsU0FBeUM7QUFDOUQsTUFBSSxDQUFDLEtBQU0sUUFBTyxDQUFDO0FBQ25CLFNBQU8sS0FBSyxNQUFNLEdBQUcsRUFBRSxJQUFJ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QUFFLEtBQUssQ0FBQyxHQUFHLE1BQU0sRUFBRSxjQUFjLENBQUMsQ0FBQztBQUNqRyxVQUFJLFNBQVMsV0FBVyxFQUFHO0FBRTNCLGVBQVMsSUFBSSxHQUFHLElBQUksTUFBTSxRQUFRLEtBQUs7QUFDckMsY0FBTSxNQUFNLE1BQU0sQ0FBQztBQUNuQixjQUFNLFFBQVEsSUFBSSxDQUFDO0FBQ25CLFlBQUksQ0FBQyxNQUFPO0FBQ1osbUJBQVcsYUFBYSxVQUFVO0FBQ2hDLGdCQUFNLFNBQVMsYUFBYSxJQUFJLFNBQVMsS0FBSztBQUM5QyxnQkFBTSxhQUFhLFNBQVMsVUFBVSxLQUFZLE1BQU0sSUFBSTtBQUM1RCxnQkFBTSxXQUFXLE9BQU8sVUFBVTtBQUFBLFFBQ3BDO0FBQUEsTUFDRjtBQUFBLElBQ0Y7QUFFQSxlQUFXLFFBQVEsT0FBTztBQUN4QixZQUFNLFFBQVEsVUFBVSxPQUFjLElBQUk7QUFDMUMsWUFBTSxNQUFNLFFBQVcsS0FBSztBQUFBLElBQzlCO0FBQUEsRUFDRjtBQUNGO0FBRU8sSUFBTSxxQkFBcUIsQ0FBQyxTQUE2RDtBQUM5RixRQUFNLFVBQTZCLENBQUM7QUFDcEMsYUFBVyxPQUFPLE1BQU07QUFDdEIsUUFBSSxDQUFDLE9BQU8sVUFBVSxlQUFlLEtBQUssTUFBTSxHQUFHLEVBQUc7QUFDdEQsVUFBTSxNQUFNLEtBQUssR0FBRztBQUNwQixRQUFJLENBQUMsT0FBTyxPQUFPLFFBQVEsU0FBVTtBQUNyQyxVQUFNLE1BQU8sSUFBWTtBQUN6QixRQUFJLFFBQVEsaUJBQWtCO0FBQzlCLFVBQU0sVUFBVyxJQUFZLGNBQWM7QUFDM0MsWUFBUSxLQUFLO0FBQUEsTUFDWCxNQUFNO0FBQUEsTUFDTixTQUFTLE9BQU8sWUFBWSxXQUFXLFVBQVU7QUFBQSxJQUNuRCxDQUFDO0FBQUEsRUFDSDtBQUNBLFNBQU87QUFDVDs7O0FDeGVBLFNBQVMsU0FBUyxRQUFRLGFBQWE7QUErQ2hDLElBQU0sWUFBTixjQUF3QixRQUFRLElBQUksdUJBQXVCLEVBQStCLEVBQUU7QUFBQztBQXdEN0YsSUFBTSxXQUEyRSxPQUFPLElBQUksYUFBYTtBQUM5RyxRQUFNLE1BQU0sT0FBTztBQUNuQixTQUFPLE9BQU8sSUFBSTtBQUNwQixDQUFDO0FBRU0sSUFBTSxjQUFxRCxPQUFPLElBQUksYUFBYTtBQUN4RixRQUFNLE1BQU0sT0FBTztBQUNuQixTQUFPLElBQUk7QUFDYixDQUFDOyIsCiAgIm5hbWVzIjogW10KfQo=
|