@blinkk/root-cms 2.0.0-rc.1 → 2.0.1
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/dist/app.js +226 -20
- package/dist/cli.js +217 -164
- package/dist/{client-AKOLkEwt.d.ts → client-fqtWzfpQ.d.ts} +359 -107
- package/dist/client.d.ts +1 -1
- package/dist/client.js +730 -314
- package/dist/core.d.ts +5 -80
- package/dist/core.js +732 -509
- package/dist/functions.js +721 -299
- package/dist/plugin.d.ts +1 -1
- package/dist/plugin.js +988 -518
- package/dist/project.d.ts +1 -1
- package/dist/project.js +2 -2
- package/dist/richtext.js +0 -1
- package/dist/{schema-ix967Ud0.d.ts → schema-KpQGOA1Z.d.ts} +65 -8
- package/dist/ui/signin.css +0 -1
- package/dist/ui/signin.js +0 -1
- package/dist/ui/ui.css +1 -2
- package/dist/ui/ui.js +142 -103
- package/package.json +20 -16
package/dist/app.js
CHANGED
|
@@ -3,8 +3,181 @@ import crypto from "node:crypto";
|
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
5
|
import { render as renderToString } from "preact-render-to-string";
|
|
6
|
+
|
|
7
|
+
// package.json
|
|
8
|
+
var package_default = {
|
|
9
|
+
name: "@blinkk/root-cms",
|
|
10
|
+
version: "2.0.1",
|
|
11
|
+
author: "s@blinkk.com",
|
|
12
|
+
license: "MIT",
|
|
13
|
+
engines: {
|
|
14
|
+
node: ">=16.0.0"
|
|
15
|
+
},
|
|
16
|
+
repository: {
|
|
17
|
+
type: "git",
|
|
18
|
+
url: "git+https://github.com/blinkk/rootjs.git",
|
|
19
|
+
directory: "packages/root-cms"
|
|
20
|
+
},
|
|
21
|
+
files: [
|
|
22
|
+
"dist/**/*"
|
|
23
|
+
],
|
|
24
|
+
bin: {
|
|
25
|
+
"root-cms": "./bin/root-cms.js"
|
|
26
|
+
},
|
|
27
|
+
type: "module",
|
|
28
|
+
module: "./dist/index.js",
|
|
29
|
+
types: "./dist/index.d.ts",
|
|
30
|
+
exports: {
|
|
31
|
+
".": {
|
|
32
|
+
types: "./dist/core.d.ts",
|
|
33
|
+
import: "./dist/core.js"
|
|
34
|
+
},
|
|
35
|
+
"./client": {
|
|
36
|
+
types: "./dist/client.d.ts",
|
|
37
|
+
import: "./dist/client.js"
|
|
38
|
+
},
|
|
39
|
+
"./core": {
|
|
40
|
+
types: "./dist/core.d.ts",
|
|
41
|
+
import: "./dist/core.js"
|
|
42
|
+
},
|
|
43
|
+
"./functions": {
|
|
44
|
+
types: "./dist/functions.d.ts",
|
|
45
|
+
import: "./dist/functions.js"
|
|
46
|
+
},
|
|
47
|
+
"./plugin": {
|
|
48
|
+
types: "./dist/plugin.d.ts",
|
|
49
|
+
import: "./dist/plugin.js"
|
|
50
|
+
},
|
|
51
|
+
"./project": {
|
|
52
|
+
types: "./dist/project.d.ts",
|
|
53
|
+
import: "./dist/project.js"
|
|
54
|
+
},
|
|
55
|
+
"./richtext": {
|
|
56
|
+
types: "./dist/richtext.d.ts",
|
|
57
|
+
import: "./dist/richtext.js"
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
scripts: {
|
|
61
|
+
build: 'rm -rf dist && concurrently -n "core,signin,ui" npm:build:core npm:build:signin npm:build:ui',
|
|
62
|
+
"build:core": "tsup-node --config=./core/tsup.config.ts",
|
|
63
|
+
"//": "NOTE: esbuild is used here because tsup doesn't currently support aliases.",
|
|
64
|
+
"build:ui": "esbuild ui/ui.tsx --bundle --minify --alias:react=@preact/compat --alias:react-dom=@preact/compat --tsconfig=ui/tsconfig.json --outdir=dist/ui",
|
|
65
|
+
"build:signin": "esbuild signin/signin.tsx --bundle --minify --tsconfig=signin/tsconfig.json --outdir=dist/ui",
|
|
66
|
+
dev: 'rm -rf dist && concurrently -k -n "core,ui" npm:dev:core npm:dev:signin npm:dev:ui',
|
|
67
|
+
"dev:core": "pnpm build:core --watch",
|
|
68
|
+
"dev:signin": "pnpm build:signin --watch",
|
|
69
|
+
"dev:ui": "pnpm build:ui --watch",
|
|
70
|
+
test: "pnpm build && firebase emulators:exec 'vitest run'",
|
|
71
|
+
"test:watch": "pnpm build && firebase emulators:exec 'vitest'"
|
|
72
|
+
},
|
|
73
|
+
dependencies: {
|
|
74
|
+
"@genkit-ai/ai": "1.15.5",
|
|
75
|
+
"@genkit-ai/core": "1.15.5",
|
|
76
|
+
"@genkit-ai/vertexai": "1.15.5",
|
|
77
|
+
"@hello-pangea/dnd": "18.0.1",
|
|
78
|
+
"body-parser": "1.20.2",
|
|
79
|
+
commander: "11.0.0",
|
|
80
|
+
"csv-parse": "5.5.2",
|
|
81
|
+
"csv-stringify": "6.4.4",
|
|
82
|
+
"dts-dom": "3.7.0",
|
|
83
|
+
"fnv-plus": "1.3.1",
|
|
84
|
+
genkit: "1.15.5",
|
|
85
|
+
jsonwebtoken: "9.0.2",
|
|
86
|
+
kleur: "4.1.5",
|
|
87
|
+
sirv: "2.0.3",
|
|
88
|
+
"tiny-glob": "0.2.9"
|
|
89
|
+
},
|
|
90
|
+
"//": "NOTE(stevenle): due to compat issues with mantine and preact, mantine is pinned to v4.2.12",
|
|
91
|
+
devDependencies: {
|
|
92
|
+
"@babel/core": "7.17.9",
|
|
93
|
+
"@blinkk/root": "workspace:*",
|
|
94
|
+
"@editorjs/editorjs": "2.30.8",
|
|
95
|
+
"@editorjs/header": "2.8.8",
|
|
96
|
+
"@editorjs/image": "2.10.2",
|
|
97
|
+
"@editorjs/list": "2.0.6",
|
|
98
|
+
"@editorjs/nested-list": "1.4.3",
|
|
99
|
+
"@editorjs/raw": "2.5.1",
|
|
100
|
+
"@editorjs/table": "2.4.4",
|
|
101
|
+
"@editorjs/underline": "1.2.1",
|
|
102
|
+
"@emotion/react": "11.10.5",
|
|
103
|
+
"@firebase/app-compat": "0.2.19",
|
|
104
|
+
"@firebase/app-types": "0.9.0",
|
|
105
|
+
"@firebase/rules-unit-testing": "3.0.1",
|
|
106
|
+
"@mantine/core": "4.2.12",
|
|
107
|
+
"@mantine/hooks": "4.2.12",
|
|
108
|
+
"@mantine/modals": "4.2.12",
|
|
109
|
+
"@mantine/notifications": "4.2.12",
|
|
110
|
+
"@mantine/spotlight": "4.2.12",
|
|
111
|
+
"@preact/compat": "17.1.2",
|
|
112
|
+
"@tabler/icons-preact": "2.47.0",
|
|
113
|
+
"@types/body-parser": "1.19.3",
|
|
114
|
+
"@types/fnv-plus": "1.3.2",
|
|
115
|
+
"@types/gapi": "0.0.47",
|
|
116
|
+
"@types/gapi.client.drive-v3": "0.0.4",
|
|
117
|
+
"@types/gapi.client.sheets-v4": "0.0.4",
|
|
118
|
+
"@types/google.accounts": "0.0.14",
|
|
119
|
+
"@types/jsonwebtoken": "9.0.1",
|
|
120
|
+
"@types/node": "18.11.8",
|
|
121
|
+
concurrently: "7.6.0",
|
|
122
|
+
esbuild: "0.19.9",
|
|
123
|
+
firebase: "10.5.2",
|
|
124
|
+
"firebase-admin": "11.11.1",
|
|
125
|
+
"firebase-functions": "4.8.0",
|
|
126
|
+
"firebase-tools": "12.9.1",
|
|
127
|
+
"highlight.js": "11.6.0",
|
|
128
|
+
"json-diff-kit": "1.0.29",
|
|
129
|
+
marked: "9.1.1",
|
|
130
|
+
"mdast-util-from-markdown": "2.0.1",
|
|
131
|
+
"mdast-util-gfm": "3.0.0",
|
|
132
|
+
"micromark-extension-gfm": "3.0.0",
|
|
133
|
+
preact: "10.19.3",
|
|
134
|
+
"preact-render-to-string": "6.3.1",
|
|
135
|
+
"preact-router": "4.1.2",
|
|
136
|
+
react: "npm:@preact/compat@^17.1.2",
|
|
137
|
+
"react-dom": "npm:@preact/compat@^17.1.2",
|
|
138
|
+
"react-json-view-compare": "2.0.2",
|
|
139
|
+
tsup: "8.0.1",
|
|
140
|
+
typescript: "5.2.2",
|
|
141
|
+
vite: "5.0.8",
|
|
142
|
+
vitest: "0.34.6"
|
|
143
|
+
},
|
|
144
|
+
peerDependencies: {
|
|
145
|
+
"@blinkk/root": "2.0.1",
|
|
146
|
+
"firebase-admin": ">=11",
|
|
147
|
+
"firebase-functions": ">=4",
|
|
148
|
+
preact: ">=10",
|
|
149
|
+
"preact-render-to-string": ">=5"
|
|
150
|
+
},
|
|
151
|
+
peerDependenciesMeta: {
|
|
152
|
+
"firebase-functions": {
|
|
153
|
+
optional: true
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
// core/project.ts
|
|
159
|
+
var IGNORED_SCHEMA_FOLDERS = ["/appengine/", "/functions/", "/gae/"];
|
|
160
|
+
var SCHEMA_MODULES = import.meta.glob("/**/*.schema.ts", {
|
|
161
|
+
eager: true
|
|
162
|
+
});
|
|
163
|
+
function getProjectSchemas() {
|
|
164
|
+
const schemas = {};
|
|
165
|
+
for (const fileId in SCHEMA_MODULES) {
|
|
166
|
+
if (IGNORED_SCHEMA_FOLDERS.some((prefix) => fileId.startsWith(prefix))) {
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
const schemaModule = SCHEMA_MODULES[fileId];
|
|
170
|
+
if (schemaModule.default) {
|
|
171
|
+
schemas[fileId] = schemaModule.default;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
return schemas;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// core/app.tsx
|
|
6
178
|
import { jsx, jsxs } from "preact/jsx-runtime";
|
|
7
179
|
var __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
180
|
+
var DEFAULT_FAVICON_URL = "https://lh3.googleusercontent.com/ijK50TfQlV_yJw3i-CMlnD6osH4PboZBILZrJcWhoNMEmoyCD5e1bAxXbaOPe5w4gG_Scf37EXrmZ6p8sP2lue5fLZ419m5JyLMs=e385-w256";
|
|
8
181
|
function App(props) {
|
|
9
182
|
return /* @__PURE__ */ jsxs("html", { children: [
|
|
10
183
|
/* @__PURE__ */ jsxs("head", { children: [
|
|
@@ -40,7 +213,7 @@ function App(props) {
|
|
|
40
213
|
"link",
|
|
41
214
|
{
|
|
42
215
|
rel: "icon",
|
|
43
|
-
href:
|
|
216
|
+
href: props.favicon || DEFAULT_FAVICON_URL,
|
|
44
217
|
type: "image/png"
|
|
45
218
|
}
|
|
46
219
|
),
|
|
@@ -74,15 +247,9 @@ function App(props) {
|
|
|
74
247
|
}
|
|
75
248
|
async function renderApp(req, res, options) {
|
|
76
249
|
var _a;
|
|
77
|
-
const collectionModules = import.meta.glob("/collections/*.schema.ts", {
|
|
78
|
-
eager: true
|
|
79
|
-
});
|
|
80
250
|
const collections = {};
|
|
81
|
-
Object.
|
|
82
|
-
|
|
83
|
-
const module = collectionModules[moduleId];
|
|
84
|
-
const collection = module.default;
|
|
85
|
-
collections[collectionId] = collection;
|
|
251
|
+
Object.entries(getCollections()).forEach(([collectionId, collection]) => {
|
|
252
|
+
collections[collectionId] = serializeCollection(collection);
|
|
86
253
|
});
|
|
87
254
|
const rootConfig = options.rootConfig || {};
|
|
88
255
|
const cmsConfig = options.cmsConfig || {};
|
|
@@ -110,26 +277,42 @@ async function renderApp(req, res, options) {
|
|
|
110
277
|
};
|
|
111
278
|
const projectName = cmsConfig.name || cmsConfig.id || "";
|
|
112
279
|
const title = projectName ? `${projectName} \u2013 Root CMS` : "Root CMS";
|
|
113
|
-
const mainHtml = renderToString(
|
|
280
|
+
const mainHtml = renderToString(
|
|
281
|
+
/* @__PURE__ */ jsx(App, { title, ctx, favicon: cmsConfig.favicon })
|
|
282
|
+
);
|
|
114
283
|
let html = `<!doctype html>
|
|
115
284
|
${mainHtml}`;
|
|
116
285
|
const nonce = generateNonce();
|
|
117
286
|
if (req.viteServer) {
|
|
118
287
|
const uiCssPath = path.join(__dirname, "ui/ui.css");
|
|
119
288
|
const uiJsPath = path.join(__dirname, "ui/ui.js");
|
|
120
|
-
const tpl = html.replace("{CSS_URL}", cachebust(`/@fs${uiCssPath}`)).replace("{JS_URL}", cachebust(`/@fs${uiJsPath}`)).replaceAll("{NONCE}", nonce);
|
|
289
|
+
const tpl = html.replace("{CSS_URL}", cachebust(req, `/@fs${uiCssPath}`)).replace("{JS_URL}", cachebust(req, `/@fs${uiJsPath}`)).replaceAll("{NONCE}", nonce);
|
|
121
290
|
html = await req.viteServer.transformIndexHtml(req.originalUrl, tpl);
|
|
122
291
|
html = html.replace(
|
|
123
292
|
'<script type="module" src="/@vite/client"></script>',
|
|
124
293
|
`<script type="module" src="/@vite/client" nonce="${nonce}"></script>`
|
|
125
294
|
);
|
|
126
295
|
} else {
|
|
127
|
-
html = html.replace("{CSS_URL}", cachebust("/cms/static/ui.css")).replace("{JS_URL}", cachebust("/cms/static/ui.js")).replaceAll("{NONCE}", nonce);
|
|
296
|
+
html = html.replace("{CSS_URL}", cachebust(req, "/cms/static/ui.css")).replace("{JS_URL}", cachebust(req, "/cms/static/ui.js")).replaceAll("{NONCE}", nonce);
|
|
128
297
|
}
|
|
129
298
|
res.setHeader("Content-Type", "text/html");
|
|
130
299
|
setSecurityHeaders(options, req, res, nonce);
|
|
131
300
|
res.send(html);
|
|
132
301
|
}
|
|
302
|
+
function serializeCollection(collection) {
|
|
303
|
+
return {
|
|
304
|
+
id: collection.id,
|
|
305
|
+
name: collection.name ?? collection.id,
|
|
306
|
+
description: collection.description,
|
|
307
|
+
domain: collection.domain,
|
|
308
|
+
url: collection.url,
|
|
309
|
+
previewUrl: collection.previewUrl,
|
|
310
|
+
preview: collection.preview,
|
|
311
|
+
slugRegex: collection.slugRegex,
|
|
312
|
+
autolock: collection.autolock,
|
|
313
|
+
autolockReason: collection.autolockReason
|
|
314
|
+
};
|
|
315
|
+
}
|
|
133
316
|
function SignIn(props) {
|
|
134
317
|
return /* @__PURE__ */ jsxs("html", { children: [
|
|
135
318
|
/* @__PURE__ */ jsxs("head", { children: [
|
|
@@ -158,7 +341,7 @@ function SignIn(props) {
|
|
|
158
341
|
"link",
|
|
159
342
|
{
|
|
160
343
|
rel: "icon",
|
|
161
|
-
href:
|
|
344
|
+
href: props.favicon || DEFAULT_FAVICON_URL,
|
|
162
345
|
type: "image/png"
|
|
163
346
|
}
|
|
164
347
|
),
|
|
@@ -187,27 +370,50 @@ async function renderSignIn(req, res, options) {
|
|
|
187
370
|
name: options.cmsConfig.name || options.cmsConfig.id || "",
|
|
188
371
|
firebaseConfig: options.cmsConfig.firebaseConfig
|
|
189
372
|
};
|
|
190
|
-
const mainHtml = renderToString(
|
|
373
|
+
const mainHtml = renderToString(
|
|
374
|
+
/* @__PURE__ */ jsx(
|
|
375
|
+
SignIn,
|
|
376
|
+
{
|
|
377
|
+
title: "Sign in",
|
|
378
|
+
ctx,
|
|
379
|
+
favicon: options.cmsConfig.favicon
|
|
380
|
+
}
|
|
381
|
+
)
|
|
382
|
+
);
|
|
191
383
|
let html = `<!doctype html>
|
|
192
384
|
${mainHtml}`;
|
|
193
385
|
const nonce = generateNonce();
|
|
194
386
|
if (req.viteServer) {
|
|
195
387
|
const cssPath = path.join(__dirname, "ui/signin.css");
|
|
196
388
|
const jsPath = path.join(__dirname, "ui/signin.js");
|
|
197
|
-
const tpl = html.replace("{CSS_URL}", cachebust(`/@fs${cssPath}`)).replace("{JS_URL}", cachebust(`/@fs${jsPath}`)).replaceAll("{NONCE}", nonce);
|
|
389
|
+
const tpl = html.replace("{CSS_URL}", cachebust(req, `/@fs${cssPath}`)).replace("{JS_URL}", cachebust(req, `/@fs${jsPath}`)).replaceAll("{NONCE}", nonce);
|
|
198
390
|
html = await req.viteServer.transformIndexHtml(req.originalUrl, tpl);
|
|
199
391
|
html = html.replace(
|
|
200
392
|
'<script type="module" src="/@vite/client"></script>',
|
|
201
393
|
`<script type="module" src="/@vite/client" nonce="${nonce}"></script>`
|
|
202
394
|
);
|
|
203
395
|
} else {
|
|
204
|
-
html = html.replace("{CSS_URL}", cachebust("/cms/static/signin.css")).replace("{JS_URL}", cachebust("/cms/static/signin.js")).replaceAll("{NONCE}", nonce);
|
|
396
|
+
html = html.replace("{CSS_URL}", cachebust(req, "/cms/static/signin.css")).replace("{JS_URL}", cachebust(req, "/cms/static/signin.js")).replaceAll("{NONCE}", nonce);
|
|
205
397
|
}
|
|
206
398
|
res.setHeader("Content-Type", "text/html");
|
|
207
399
|
setSecurityHeaders(options, req, res, nonce);
|
|
208
400
|
res.status(403);
|
|
209
401
|
res.send(html);
|
|
210
402
|
}
|
|
403
|
+
function getCollections() {
|
|
404
|
+
const collections = {};
|
|
405
|
+
const schemas = getProjectSchemas();
|
|
406
|
+
Object.entries(schemas).forEach(([fileId, schema]) => {
|
|
407
|
+
if (fileId.startsWith("/collections/")) {
|
|
408
|
+
const collectionId = parseCollectionId(fileId);
|
|
409
|
+
collections[collectionId] = { ...schema, id: collectionId };
|
|
410
|
+
}
|
|
411
|
+
});
|
|
412
|
+
return collections;
|
|
413
|
+
}
|
|
414
|
+
function parseCollectionId(fileId) {
|
|
415
|
+
return path.basename(fileId).split(".")[0];
|
|
416
|
+
}
|
|
211
417
|
function generateNonce() {
|
|
212
418
|
return crypto.randomBytes(16).toString("base64");
|
|
213
419
|
}
|
|
@@ -243,12 +449,12 @@ function getRefererOrigin(req) {
|
|
|
243
449
|
const refererOrigin = `${parsedReferer.protocol}//${parsedReferer.hostname}`;
|
|
244
450
|
return refererOrigin;
|
|
245
451
|
}
|
|
246
|
-
function cachebust(url) {
|
|
247
|
-
const
|
|
248
|
-
return `${url}?c=${
|
|
452
|
+
function cachebust(req, url) {
|
|
453
|
+
const value = req.hostname === "localhost" ? Math.floor((/* @__PURE__ */ new Date()).getTime() / 1e3) : package_default.version;
|
|
454
|
+
return `${url}?c=${value}`;
|
|
249
455
|
}
|
|
250
456
|
export {
|
|
457
|
+
getCollections,
|
|
251
458
|
renderApp,
|
|
252
459
|
renderSignIn
|
|
253
460
|
};
|
|
254
|
-
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vY29yZS9hcHAudHN4Il0sCiAgInNvdXJjZXNDb250ZW50IjogWyJpbXBvcnQgY3J5cHRvIGZyb20gJ25vZGU6Y3J5cHRvJztcbmltcG9ydCBwYXRoIGZyb20gJ25vZGU6cGF0aCc7XG5pbXBvcnQge2ZpbGVVUkxUb1BhdGh9IGZyb20gJ25vZGU6dXJsJztcbmltcG9ydCB7UmVxdWVzdCwgUmVzcG9uc2UsIFJvb3RDb25maWd9IGZyb20gJ0BibGlua2svcm9vdCc7XG5pbXBvcnQge3JlbmRlciBhcyByZW5kZXJUb1N0cmluZ30gZnJvbSAncHJlYWN0LXJlbmRlci10by1zdHJpbmcnO1xuaW1wb3J0IHtDTVNQbHVnaW5PcHRpb25zfSBmcm9tICcuL3BsdWdpbi5qcyc7XG5pbXBvcnQge0NvbGxlY3Rpb259IGZyb20gJy4vc2NoZW1hLmpzJztcblxuY29uc3QgX19kaXJuYW1lID0gcGF0aC5kaXJuYW1lKGZpbGVVUkxUb1BhdGgoaW1wb3J0Lm1ldGEudXJsKSk7XG5cbmludGVyZmFjZSBBcHBQcm9wcyB7XG4gIHRpdGxlOiBzdHJpbmc7XG4gIGN0eDogYW55O1xufVxuXG5mdW5jdGlvbiBBcHAocHJvcHM6IEFwcFByb3BzKSB7XG4gIHJldHVybiAoXG4gICAgPGh0bWw+XG4gICAgICA8aGVhZD5cbiAgICAgICAgPG1ldGEgY2hhcnNldD1cInV0Zi04XCIgLz5cbiAgICAgICAgPHRpdGxlPntwcm9wcy50aXRsZX08L3RpdGxlPlxuICAgICAgICA8bWV0YSBuYW1lPVwicm9ib3RzXCIgY29udGVudD1cIm5vaW5kZXhcIiAvPlxuICAgICAgICA8bGluayByZWw9XCJwcmVjb25uZWN0XCIgaHJlZj1cImh0dHBzOi8vZm9udHMuZ29vZ2xlYXBpcy5jb21cIiAvPlxuICAgICAgICA8bGlua1xuICAgICAgICAgIHJlbD1cInByZWNvbm5lY3RcIlxuICAgICAgICAgIGhyZWY9XCJodHRwczovL2ZvbnRzLmdzdGF0aWMuY29tXCJcbiAgICAgICAgICBjcm9zc09yaWdpbj1cImFub255bW91c1wiXG4gICAgICAgIC8+XG4gICAgICAgIDxsaW5rXG4gICAgICAgICAgcmVsPVwic3R5bGVzaGVldFwiXG4gICAgICAgICAgaHJlZj1cImh0dHBzOi8vZm9udHMuZ29vZ2xlYXBpcy5jb20vY3NzMj9mYW1pbHk9SW50ZXI6d2dodEAzMDA7NDAwOzUwMDs2MDA7NzAwOzkwMCZkaXNwbGF5PXN3YXBcIlxuICAgICAgICAgIG5vbmNlPVwie05PTkNFfVwiXG4gICAgICAgIC8+XG4gICAgICAgIDxsaW5rXG4gICAgICAgICAgcmVsPVwic3R5bGVzaGVldFwiXG4gICAgICAgICAgaHJlZj1cImh0dHBzOi8vZm9udHMuZ29vZ2xlYXBpcy5jb20vY3NzMj9mYW1pbHk9R29vZ2xlK1NhbnM6d2dodEA1MDAmZGlzcGxheT1zd2FwXCJcbiAgICAgICAgICBub25jZT1cIntOT05DRX1cIlxuICAgICAgICAvPlxuICAgICAgICA8bGlua1xuICAgICAgICAgIHJlbD1cImljb25cIlxuICAgICAgICAgIGhyZWY9XCJodHRwczovL2xoMy5nb29nbGV1c2VyY29udGVudC5jb20vaWpLNTBUZlFsVl95SnczaS1DTWxuRDZvc0g0UGJvWkJJTFpySmNXaG9OTUVtb3lDRDVlMWJBeFhiYU9QZTV3NGdHX1NjZjM3RVhybVo2cDhzUDJsdWU1ZkxaNDE5bTVKeUxNcz1lMzg1LXcyNTZcIlxuICAgICAgICAgIHR5cGU9XCJpbWFnZS9wbmdcIlxuICAgICAgICAvPlxuICAgICAgICA8bGlua1xuICAgICAgICAgIHJlbD1cInN0eWxlc2hlZXRcIlxuICAgICAgICAgIGhyZWY9XCJodHRwczovL2NkbmpzLmNsb3VkZmxhcmUuY29tL2FqYXgvbGlicy9oaWdobGlnaHQuanMvMTEuNi4wL3N0eWxlcy9hdG9tLW9uZS1saWdodC5taW4uY3NzXCJcbiAgICAgICAgICBub25jZT1cIntOT05DRX1cIlxuICAgICAgICAvPlxuICAgICAgICA8bGluayByZWw9XCJzdHlsZXNoZWV0XCIgaHJlZj1cIntDU1NfVVJMfVwiIG5vbmNlPVwie05PTkNFfVwiIC8+XG4gICAgICA8L2hlYWQ+XG4gICAgICA8Ym9keT5cbiAgICAgICAgPGRpdiBpZD1cInJvb3RcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cImJvb3RzdHJhcFwiPlxuICAgICAgICAgICAgPGgxIGNsYXNzTmFtZT1cImJvb3RzdHJhcF9fbG9hZGluZ1wiPkxvYWRpbmcuLi48L2gxPlxuICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJib290c3RyYXAtZXJyb3JcIj5cbiAgICAgICAgICAgICAgSWYgdGhpcyBwYWdlIGZhaWxzIHRvIGxvYWQsIHRyeSBhIGZvcmNlIHJlZnJlc2ggYnkgaG9sZGluZyB0aGVcbiAgICAgICAgICAgICAgc2hpZnQga2V5IHdoaWxlIHJlZnJlc2hpbmcgdGhlIHBhZ2UuXG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxzY3JpcHRcbiAgICAgICAgICBkYW5nZXJvdXNseVNldElubmVySFRNTD17e1xuICAgICAgICAgICAgX19odG1sOiBgd2luZG93Ll9fUk9PVF9DVFggPSAke0pTT04uc3RyaW5naWZ5KHByb3BzLmN0eCl9YCxcbiAgICAgICAgICB9fVxuICAgICAgICAgIG5vbmNlPVwie05PTkNFfVwiXG4gICAgICAgIC8+XG4gICAgICAgIDxzY3JpcHQgdHlwZT1cIm1vZHVsZVwiIHNyYz1cIntKU19VUkx9XCIgbm9uY2U9XCJ7Tk9OQ0V9XCI+PC9zY3JpcHQ+XG4gICAgICA8L2JvZHk+XG4gICAgPC9odG1sPlxuICApO1xufVxuXG5pbnRlcmZhY2UgUmVuZGVyT3B0aW9ucyB7XG4gIHJvb3RDb25maWc6IFJvb3RDb25maWc7XG4gIGNtc0NvbmZpZzogQ01TUGx1Z2luT3B0aW9ucztcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJlbmRlckFwcChcbiAgcmVxOiBSZXF1ZXN0LFxuICByZXM6IFJlc3BvbnNlLFxuICBvcHRpb25zOiBSZW5kZXJPcHRpb25zXG4pIHtcbiAgY29uc3QgY29sbGVjdGlvbk1vZHVsZXMgPSBpbXBvcnQubWV0YS5nbG9iKCcvY29sbGVjdGlvbnMvKi5zY2hlbWEudHMnLCB7XG4gICAgZWFnZXI6IHRydWUsXG4gIH0pIGFzIGFueTtcbiAgY29uc3QgY29sbGVjdGlvbnM6IFJlY29yZDxzdHJpbmcsIENvbGxlY3Rpb24+ID0ge307XG4gIE9iamVjdC5rZXlzKGNvbGxlY3Rpb25Nb2R1bGVzKS5mb3JFYWNoKChtb2R1bGVJZDogc3RyaW5nKSA9PiB7XG4gICAgY29uc3QgY29sbGVjdGlvbklkID0gcGF0aC5wYXJzZShtb2R1bGVJZCkuYmFzZS5zcGxpdCgnLicpWzBdO1xuICAgIGNvbnN0IG1vZHVsZSA9IGNvbGxlY3Rpb25Nb2R1bGVzW21vZHVsZUlkXTtcbiAgICBjb25zdCBjb2xsZWN0aW9uID0gbW9kdWxlLmRlZmF1bHQgYXMgQ29sbGVjdGlvbjtcbiAgICBjb2xsZWN0aW9uc1tjb2xsZWN0aW9uSWRdID0gY29sbGVjdGlvbjtcbiAgfSk7XG4gIGNvbnN0IHJvb3RDb25maWcgPSBvcHRpb25zLnJvb3RDb25maWcgfHwge307XG4gIGNvbnN0IGNtc0NvbmZpZyA9IG9wdGlvbnMuY21zQ29uZmlnIHx8IHt9O1xuICBsZXQgZ2NpID0gY21zQ29uZmlnLmdjaTtcbiAgaWYgKGdjaSA9PT0gdHJ1ZSkge1xuICAgIGdjaSA9ICdodHRwczovL2djaS5yb290anMuZGV2JztcbiAgfVxuICBjb25zdCBjdHggPSB7XG4gICAgcm9vdENvbmZpZzoge1xuICAgICAgcHJvamVjdElkOiBjbXNDb25maWcuaWQgfHwgJ2RlZmF1bHQnLFxuICAgICAgcHJvamVjdE5hbWU6IGNtc0NvbmZpZy5uYW1lIHx8IGNtc0NvbmZpZy5pZCB8fCAnJyxcbiAgICAgIGRvbWFpbjogcm9vdENvbmZpZy5kb21haW4gfHwgJ2h0dHBzOi8vZXhhbXBsZS5jb20nLFxuICAgICAgYmFzZTogcm9vdENvbmZpZy5iYXNlIHx8ICcvJyxcbiAgICAgIGdjaTogZ2NpLFxuICAgICAgaTE4bjogcm9vdENvbmZpZy5pMThuLFxuICAgICAgc2VydmVyOiB7XG4gICAgICAgIHRyYWlsaW5nU2xhc2g6IHJvb3RDb25maWcuc2VydmVyPy50cmFpbGluZ1NsYXNoLFxuICAgICAgfSxcbiAgICB9LFxuICAgIGZpcmViYXNlQ29uZmlnOiBjbXNDb25maWcuZmlyZWJhc2VDb25maWcsXG4gICAgZ2FwaTogY21zQ29uZmlnLmdhcGksXG4gICAgY29sbGVjdGlvbnM6IGNvbGxlY3Rpb25zLFxuICAgIHNpZGViYXI6IGNtc0NvbmZpZy5zaWRlYmFyLFxuICAgIGV4cGVyaW1lbnRzOiBjbXNDb25maWcuZXhwZXJpbWVudHMsXG4gIH07XG4gIGNvbnN0IHByb2plY3ROYW1lID0gY21zQ29uZmlnLm5hbWUgfHwgY21zQ29uZmlnLmlkIHx8ICcnO1xuICBjb25zdCB0aXRsZSA9IHByb2plY3ROYW1lID8gYCR7cHJvamVjdE5hbWV9IFx1MjAxMyBSb290IENNU2AgOiAnUm9vdCBDTVMnO1xuXG4gIGNvbnN0IG1haW5IdG1sID0gcmVuZGVyVG9TdHJpbmcoPEFwcCB0aXRsZT17dGl0bGV9IGN0eD17Y3R4fSAvPik7XG4gIGxldCBodG1sID0gYDwhZG9jdHlwZSBodG1sPlxcbiR7bWFpbkh0bWx9YDtcbiAgY29uc3Qgbm9uY2UgPSBnZW5lcmF0ZU5vbmNlKCk7XG4gIGlmIChyZXEudml0ZVNlcnZlcikge1xuICAgIGNvbnN0IHVpQ3NzUGF0aCA9IHBhdGguam9pbihfX2Rpcm5hbWUsICd1aS91aS5jc3MnKTtcbiAgICBjb25zdCB1aUpzUGF0aCA9IHBhdGguam9pbihfX2Rpcm5hbWUsICd1aS91aS5qcycpO1xuICAgIGNvbnN0IHRwbCA9IGh0bWxcbiAgICAgIC5yZXBsYWNlKCd7Q1NTX1VSTH0nLCBjYWNoZWJ1c3QoYC9AZnMke3VpQ3NzUGF0aH1gKSlcbiAgICAgIC5yZXBsYWNlKCd7SlNfVVJMfScsIGNhY2hlYnVzdChgL0BmcyR7dWlKc1BhdGh9YCkpXG4gICAgICAucmVwbGFjZUFsbCgne05PTkNFfScsIG5vbmNlKTtcbiAgICBodG1sID0gYXdhaXQgcmVxLnZpdGVTZXJ2ZXIhLnRyYW5zZm9ybUluZGV4SHRtbChyZXEub3JpZ2luYWxVcmwsIHRwbCk7XG4gICAgaHRtbCA9IGh0bWwucmVwbGFjZShcbiAgICAgICc8c2NyaXB0IHR5cGU9XCJtb2R1bGVcIiBzcmM9XCIvQHZpdGUvY2xpZW50XCI+PC9zY3JpcHQ+JyxcbiAgICAgIGA8c2NyaXB0IHR5cGU9XCJtb2R1bGVcIiBzcmM9XCIvQHZpdGUvY2xpZW50XCIgbm9uY2U9XCIke25vbmNlfVwiPjwvc2NyaXB0PmBcbiAgICApO1xuICB9IGVsc2Uge1xuICAgIGh0bWwgPSBodG1sXG4gICAgICAucmVwbGFjZSgne0NTU19VUkx9JywgY2FjaGVidXN0KCcvY21zL3N0YXRpYy91aS5jc3MnKSlcbiAgICAgIC5yZXBsYWNlKCd7SlNfVVJMfScsIGNhY2hlYnVzdCgnL2Ntcy9zdGF0aWMvdWkuanMnKSlcbiAgICAgIC5yZXBsYWNlQWxsKCd7Tk9OQ0V9Jywgbm9uY2UpO1xuICB9XG4gIHJlcy5zZXRIZWFkZXIoJ0NvbnRlbnQtVHlwZScsICd0ZXh0L2h0bWwnKTtcbiAgc2V0U2VjdXJpdHlIZWFkZXJzKG9wdGlvbnMsIHJlcSwgcmVzLCBub25jZSk7XG4gIHJlcy5zZW5kKGh0bWwpO1xufVxuXG5pbnRlcmZhY2UgU2lnbkluUHJvcHMge1xuICB0aXRsZTogc3RyaW5nO1xuICBjdHg6IGFueTtcbn1cblxuZnVuY3Rpb24gU2lnbkluKHByb3BzOiBTaWduSW5Qcm9wcykge1xuICByZXR1cm4gKFxuICAgIDxodG1sPlxuICAgICAgPGhlYWQ+XG4gICAgICAgIDxtZXRhIGNoYXJzZXQ9XCJ1dGYtOFwiIC8+XG4gICAgICAgIDx0aXRsZT57cHJvcHMudGl0bGV9PC90aXRsZT5cbiAgICAgICAgPG1ldGEgbmFtZT1cInJvYm90c1wiIGNvbnRlbnQ9XCJub2luZGV4XCIgLz5cbiAgICAgICAgPGxpbmsgcmVsPVwicHJlY29ubmVjdFwiIGhyZWY9XCJodHRwczovL2ZvbnRzLmdvb2dsZWFwaXMuY29tXCIgLz5cbiAgICAgICAgPG1ldGEgbmFtZT1cInZpZXdwb3J0XCIgY29udGVudD1cIndpZHRoPWRldmljZS13aWR0aCwgaW5pdGlhbC1zY2FsZT0xLjBcIiAvPlxuICAgICAgICA8bGlua1xuICAgICAgICAgIHJlbD1cInByZWNvbm5lY3RcIlxuICAgICAgICAgIGhyZWY9XCJodHRwczovL2ZvbnRzLmdzdGF0aWMuY29tXCJcbiAgICAgICAgICBjcm9zc09yaWdpbj1cImFub255bW91c1wiXG4gICAgICAgIC8+XG4gICAgICAgIDxsaW5rXG4gICAgICAgICAgcmVsPVwic3R5bGVzaGVldFwiXG4gICAgICAgICAgaHJlZj1cImh0dHBzOi8vZm9udHMuZ29vZ2xlYXBpcy5jb20vY3NzP2ZhbWlseT1Hb29nbGUrU2Fuczo0MDAsNTAwJmRpc3BsYXk9c3dhcFwiXG4gICAgICAgICAgbm9uY2U9XCJ7Tk9OQ0V9XCJcbiAgICAgICAgLz5cbiAgICAgICAgPGxpbmtcbiAgICAgICAgICByZWw9XCJpY29uXCJcbiAgICAgICAgICBocmVmPVwiaHR0cHM6Ly9saDMuZ29vZ2xldXNlcmNvbnRlbnQuY29tL2lqSzUwVGZRbFZfeUp3M2ktQ01sbkQ2b3NINFBib1pCSUxackpjV2hvTk1FbW95Q0Q1ZTFiQXhYYmFPUGU1dzRnR19TY2YzN0VYcm1aNnA4c1AybHVlNWZMWjQxOW01SnlMTXM9ZTM4NS13MjU2XCJcbiAgICAgICAgICB0eXBlPVwiaW1hZ2UvcG5nXCJcbiAgICAgICAgLz5cbiAgICAgICAgPGxpbmsgcmVsPVwic3R5bGVzaGVldFwiIGhyZWY9XCJ7Q1NTX1VSTH1cIiBub25jZT1cIntOT05DRX1cIiAvPlxuICAgICAgPC9oZWFkPlxuICAgICAgPGJvZHk+XG4gICAgICAgIDxkaXYgaWQ9XCJyb290XCI+XG4gICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJib290c3RyYXBcIj5cbiAgICAgICAgICAgIDxoMSBjbGFzc05hbWU9XCJib290c3RyYXBfX2xvYWRpbmdcIj5Mb2FkaW5nLi4uPC9oMT5cbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiYm9vdHN0cmFwLWVycm9yXCI+XG4gICAgICAgICAgICAgIElmIHRoaXMgcGFnZSBmYWlscyB0byBsb2FkLCB0cnkgYSBmb3JjZSByZWZyZXNoIGJ5IGhvbGRpbmcgdGhlXG4gICAgICAgICAgICAgIHNoaWZ0IGtleSB3aGlsZSByZWZyZXNoaW5nIHRoZSBwYWdlLlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8c2NyaXB0XG4gICAgICAgICAgZGFuZ2Vyb3VzbHlTZXRJbm5lckhUTUw9e3tcbiAgICAgICAgICAgIF9faHRtbDogYHdpbmRvdy5fX1JPT1RfQ1RYID0gJHtKU09OLnN0cmluZ2lmeShwcm9wcy5jdHgpfWAsXG4gICAgICAgICAgfX1cbiAgICAgICAgICBub25jZT1cIntOT05DRX1cIlxuICAgICAgICAvPlxuICAgICAgICA8c2NyaXB0IHR5cGU9XCJtb2R1bGVcIiBzcmM9XCJ7SlNfVVJMfVwiIG5vbmNlPVwie05PTkNFfVwiPjwvc2NyaXB0PlxuICAgICAgPC9ib2R5PlxuICAgIDwvaHRtbD5cbiAgKTtcbn1cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZW5kZXJTaWduSW4oXG4gIHJlcTogUmVxdWVzdCxcbiAgcmVzOiBSZXNwb25zZSxcbiAgb3B0aW9uczogUmVuZGVyT3B0aW9uc1xuKSB7XG4gIGNvbnN0IGN0eCA9IHtcbiAgICBuYW1lOiBvcHRpb25zLmNtc0NvbmZpZy5uYW1lIHx8IG9wdGlvbnMuY21zQ29uZmlnLmlkIHx8ICcnLFxuICAgIGZpcmViYXNlQ29uZmlnOiBvcHRpb25zLmNtc0NvbmZpZy5maXJlYmFzZUNvbmZpZyxcbiAgfTtcbiAgY29uc3QgbWFpbkh0bWwgPSByZW5kZXJUb1N0cmluZyg8U2lnbkluIHRpdGxlPVwiU2lnbiBpblwiIGN0eD17Y3R4fSAvPik7XG4gIGxldCBodG1sID0gYDwhZG9jdHlwZSBodG1sPlxcbiR7bWFpbkh0bWx9YDtcbiAgY29uc3Qgbm9uY2UgPSBnZW5lcmF0ZU5vbmNlKCk7XG4gIGlmIChyZXEudml0ZVNlcnZlcikge1xuICAgIGNvbnN0IGNzc1BhdGggPSBwYXRoLmpvaW4oX19kaXJuYW1lLCAndWkvc2lnbmluLmNzcycpO1xuICAgIGNvbnN0IGpzUGF0aCA9IHBhdGguam9pbihfX2Rpcm5hbWUsICd1aS9zaWduaW4uanMnKTtcbiAgICBjb25zdCB0cGwgPSBodG1sXG4gICAgICAucmVwbGFjZSgne0NTU19VUkx9JywgY2FjaGVidXN0KGAvQGZzJHtjc3NQYXRofWApKVxuICAgICAgLnJlcGxhY2UoJ3tKU19VUkx9JywgY2FjaGVidXN0KGAvQGZzJHtqc1BhdGh9YCkpXG4gICAgICAucmVwbGFjZUFsbCgne05PTkNFfScsIG5vbmNlKTtcbiAgICBodG1sID0gYXdhaXQgcmVxLnZpdGVTZXJ2ZXIhLnRyYW5zZm9ybUluZGV4SHRtbChyZXEub3JpZ2luYWxVcmwsIHRwbCk7XG4gICAgaHRtbCA9IGh0bWwucmVwbGFjZShcbiAgICAgICc8c2NyaXB0IHR5cGU9XCJtb2R1bGVcIiBzcmM9XCIvQHZpdGUvY2xpZW50XCI+PC9zY3JpcHQ+JyxcbiAgICAgIGA8c2NyaXB0IHR5cGU9XCJtb2R1bGVcIiBzcmM9XCIvQHZpdGUvY2xpZW50XCIgbm9uY2U9XCIke25vbmNlfVwiPjwvc2NyaXB0PmBcbiAgICApO1xuICB9IGVsc2Uge1xuICAgIGh0bWwgPSBodG1sXG4gICAgICAucmVwbGFjZSgne0NTU19VUkx9JywgY2FjaGVidXN0KCcvY21zL3N0YXRpYy9zaWduaW4uY3NzJykpXG4gICAgICAucmVwbGFjZSgne0pTX1VSTH0nLCBjYWNoZWJ1c3QoJy9jbXMvc3RhdGljL3NpZ25pbi5qcycpKVxuICAgICAgLnJlcGxhY2VBbGwoJ3tOT05DRX0nLCBub25jZSk7XG4gIH1cbiAgcmVzLnNldEhlYWRlcignQ29udGVudC1UeXBlJywgJ3RleHQvaHRtbCcpO1xuICBzZXRTZWN1cml0eUhlYWRlcnMob3B0aW9ucywgcmVxLCByZXMsIG5vbmNlKTtcbiAgcmVzLnN0YXR1cyg0MDMpO1xuICByZXMuc2VuZChodG1sKTtcbn1cblxuZnVuY3Rpb24gZ2VuZXJhdGVOb25jZSgpIHtcbiAgcmV0dXJuIGNyeXB0by5yYW5kb21CeXRlcygxNikudG9TdHJpbmcoJ2Jhc2U2NCcpO1xufVxuXG5mdW5jdGlvbiBzZXRTZWN1cml0eUhlYWRlcnMoXG4gIG9wdGlvbnM6IFJlbmRlck9wdGlvbnMsXG4gIHJlcTogUmVxdWVzdCxcbiAgcmVzOiBSZXNwb25zZSxcbiAgbm9uY2U6IHN0cmluZ1xuKSB7XG4gIHJlcy5zZXRIZWFkZXIoXG4gICAgJ3N0cmljdC10cmFuc3BvcnQtc2VjdXJpdHknLFxuICAgICdtYXgtYWdlPTYzMDcyMDAwOyBpbmNsdWRlU3ViZG9tYWluczsgcHJlbG9hZCdcbiAgKTtcbiAgcmVzLnNldEhlYWRlcigneC1jb250ZW50LXR5cGUtb3B0aW9ucycsICdub3NuaWZmJyk7XG4gIHJlcy5zZXRIZWFkZXIoJ3gteHNzLXByb3RlY3Rpb24nLCAnMTsgbW9kZT1ibG9jaycpO1xuXG4gIGNvbnN0IGZyYW1lQW5jZXN0b3JzID0gW1wiJ3NlbGYnXCJdO1xuICBjb25zdCBhbGxvd2VkSWZyYW1lT3JpZ2lucyA9IG9wdGlvbnMuY21zQ29uZmlnLmFsbG93ZWRJZnJhbWVPcmlnaW5zO1xuICBpZiAoYWxsb3dlZElmcmFtZU9yaWdpbnMgJiYgYWxsb3dlZElmcmFtZU9yaWdpbnMubGVuZ3RoID4gMCkge1xuICAgIGNvbnN0IHJlZmVyZXJPcmlnaW4gPSBnZXRSZWZlcmVyT3JpZ2luKHJlcSk7XG4gICAgaWYgKGFsbG93ZWRJZnJhbWVPcmlnaW5zLmluY2x1ZGVzKHJlZmVyZXJPcmlnaW4pKSB7XG4gICAgICBmcmFtZUFuY2VzdG9ycy5wdXNoKHJlZmVyZXJPcmlnaW4pO1xuICAgIH1cbiAgfVxuXG4gIC8vIGh0dHBzOi8vY3NwLndpdGhnb29nbGUuY29tL2RvY3Mvc3RyaWN0LWNzcC5odG1sXG4gIGNvbnN0IGRpcmVjdGl2ZXMgPSBbXG4gICAgXCJiYXNlLXVyaSAnbm9uZSdcIixcbiAgICBcIm9iamVjdC1zcmMgJ25vbmUnXCIsXG4gICAgYHNjcmlwdC1zcmMgJ25vbmNlLSR7bm9uY2V9JyAndW5zYWZlLWlubGluZScgJ3Vuc2FmZS1ldmFsJyAnc3RyaWN0LWR5bmFtaWMnIGh0dHBzOiBodHRwOmAsXG4gICAgYGZyYW1lLWFuY2VzdG9ycyAke2ZyYW1lQW5jZXN0b3JzLmpvaW4oJyAnKX1gLFxuICBdO1xuICByZXMuc2V0SGVhZGVyKCdjb250ZW50LXNlY3VyaXR5LXBvbGljeS1yZXBvcnQtb25seScsIGRpcmVjdGl2ZXMuam9pbignOyAnKSk7XG59XG5cbmZ1bmN0aW9uIGdldFJlZmVyZXJPcmlnaW4ocmVxOiBSZXF1ZXN0KTogc3RyaW5nIHtcbiAgY29uc3QgcmVmZXJlclVybCA9IHJlcS5oZWFkZXJzLnJlZmVyZXI7XG4gIGlmICghcmVmZXJlclVybCkge1xuICAgIHJldHVybiAnJztcbiAgfVxuICBjb25zdCBwYXJzZWRSZWZlcmVyID0gbmV3IFVSTChyZWZlcmVyVXJsKTtcbiAgY29uc3QgcmVmZXJlck9yaWdpbiA9IGAke3BhcnNlZFJlZmVyZXIucHJvdG9jb2x9Ly8ke3BhcnNlZFJlZmVyZXIuaG9zdG5hbWV9YDtcbiAgcmV0dXJuIHJlZmVyZXJPcmlnaW47XG59XG5cbmZ1bmN0aW9uIGNhY2hlYnVzdCh1cmw6IHN0cmluZykge1xuICBjb25zdCB0cyA9IE1hdGguZmxvb3IobmV3IERhdGUoKS5nZXRUaW1lKCkgLyAxMDAwKTtcbiAgcmV0dXJuIGAke3VybH0/Yz0ke3RzfWA7XG59XG4iXSwKICAibWFwcGluZ3MiOiAiO0FBQUEsT0FBTyxZQUFZO0FBQ25CLE9BQU8sVUFBVTtBQUNqQixTQUFRLHFCQUFvQjtBQUU1QixTQUFRLFVBQVUsc0JBQXFCO0FBY2pDLFNBQ0UsS0FERjtBQVZOLElBQU0sWUFBWSxLQUFLLFFBQVEsY0FBYyxZQUFZLEdBQUcsQ0FBQztBQU83RCxTQUFTLElBQUksT0FB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
|