@workflow/builders 5.0.0-beta.3 → 5.0.0-beta.30

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.
Files changed (134) hide show
  1. package/dist/apply-swc-transform.d.ts +7 -2
  2. package/dist/apply-swc-transform.d.ts.map +1 -1
  3. package/dist/apply-swc-transform.js +10 -4
  4. package/dist/base-builder-logging.test.d.ts +2 -0
  5. package/dist/base-builder-logging.test.d.ts.map +1 -0
  6. package/dist/base-builder-logging.test.js +99 -0
  7. package/dist/base-builder.d.ts +127 -13
  8. package/dist/base-builder.d.ts.map +1 -1
  9. package/dist/base-builder.js +812 -102
  10. package/dist/build-queue.js +1 -1
  11. package/dist/config-helpers.d.ts +4 -1
  12. package/dist/config-helpers.d.ts.map +1 -1
  13. package/dist/config-helpers.js +63 -1
  14. package/dist/config-helpers.test.d.ts +2 -0
  15. package/dist/config-helpers.test.d.ts.map +1 -0
  16. package/dist/config-helpers.test.js +17 -0
  17. package/dist/constants.d.ts +31 -5
  18. package/dist/constants.d.ts.map +1 -1
  19. package/dist/constants.js +71 -19
  20. package/dist/constants.test.d.ts +2 -0
  21. package/dist/constants.test.d.ts.map +1 -0
  22. package/dist/constants.test.js +40 -0
  23. package/dist/discover-entries-esbuild-plugin.d.ts +3 -1
  24. package/dist/discover-entries-esbuild-plugin.d.ts.map +1 -1
  25. package/dist/discover-entries-esbuild-plugin.js +24 -4
  26. package/dist/discover-entries-esbuild-plugin.test.js +1 -1
  27. package/dist/esbuild-tsconfig.js +1 -1
  28. package/dist/esbuild-tsconfig.test.js +1 -1
  29. package/dist/external-package-warning.test.d.ts +2 -0
  30. package/dist/external-package-warning.test.d.ts.map +1 -0
  31. package/dist/external-package-warning.test.js +219 -0
  32. package/dist/fast-discovery.d.ts +20 -0
  33. package/dist/fast-discovery.d.ts.map +1 -0
  34. package/dist/fast-discovery.js +774 -0
  35. package/dist/fast-discovery.test.d.ts +2 -0
  36. package/dist/fast-discovery.test.d.ts.map +1 -0
  37. package/dist/fast-discovery.test.js +336 -0
  38. package/dist/get-input-files.test.js +34 -2
  39. package/dist/index.d.ts +8 -3
  40. package/dist/index.d.ts.map +1 -1
  41. package/dist/index.js +9 -4
  42. package/dist/module-specifier.d.ts +20 -2
  43. package/dist/module-specifier.d.ts.map +1 -1
  44. package/dist/module-specifier.js +92 -17
  45. package/dist/module-specifier.test.js +45 -3
  46. package/dist/node-compat-banner.d.ts +15 -0
  47. package/dist/node-compat-banner.d.ts.map +1 -0
  48. package/dist/node-compat-banner.js +15 -0
  49. package/dist/node-module-esbuild-plugin.d.ts.map +1 -1
  50. package/dist/node-module-esbuild-plugin.js +73 -23
  51. package/dist/node-module-esbuild-plugin.test.js +97 -1
  52. package/dist/optional-otel-api.d.ts +14 -0
  53. package/dist/optional-otel-api.d.ts.map +1 -0
  54. package/dist/optional-otel-api.js +14 -0
  55. package/dist/optional-pg-native-alias.d.ts +2 -0
  56. package/dist/optional-pg-native-alias.d.ts.map +1 -0
  57. package/dist/optional-pg-native-alias.js +3 -0
  58. package/dist/optional-pg-native.d.ts +3 -0
  59. package/dist/optional-pg-native.d.ts.map +1 -0
  60. package/dist/optional-pg-native.js +3 -0
  61. package/dist/optional-typescript-alias.d.ts +2 -0
  62. package/dist/optional-typescript-alias.d.ts.map +1 -0
  63. package/dist/optional-typescript-alias.js +3 -0
  64. package/dist/optional-typescript.d.ts +3 -0
  65. package/dist/optional-typescript.d.ts.map +1 -0
  66. package/dist/optional-typescript.js +9 -0
  67. package/dist/pseudo-package-esbuild-plugin.js +1 -1
  68. package/dist/pseudo-package-esbuild-plugin.test.js +1 -1
  69. package/dist/request-converter.js +1 -1
  70. package/dist/resolve-sourcemap.test.d.ts +2 -0
  71. package/dist/resolve-sourcemap.test.d.ts.map +1 -0
  72. package/dist/resolve-sourcemap.test.js +194 -0
  73. package/dist/serde-checker.js +1 -1
  74. package/dist/standalone.d.ts +0 -3
  75. package/dist/standalone.d.ts.map +1 -1
  76. package/dist/standalone.js +12 -41
  77. package/dist/step-source-registration.test.d.ts +2 -0
  78. package/dist/step-source-registration.test.d.ts.map +1 -0
  79. package/dist/step-source-registration.test.js +82 -0
  80. package/dist/swc-esbuild-plugin.d.ts +10 -0
  81. package/dist/swc-esbuild-plugin.d.ts.map +1 -1
  82. package/dist/swc-esbuild-plugin.js +116 -14
  83. package/dist/swc-esbuild-plugin.test.js +370 -6
  84. package/dist/transform-utils.d.ts.map +1 -1
  85. package/dist/transform-utils.js +45 -6
  86. package/dist/transform-utils.test.js +78 -6
  87. package/dist/types.d.ts +38 -2
  88. package/dist/types.d.ts.map +1 -1
  89. package/dist/types.js +1 -1
  90. package/dist/vercel-build-output-api.d.ts +0 -2
  91. package/dist/vercel-build-output-api.d.ts.map +1 -1
  92. package/dist/vercel-build-output-api.js +31 -59
  93. package/dist/workflow-alias.js +1 -1
  94. package/dist/workflow-alias.test.js +1 -1
  95. package/dist/workflows-extractor.js +8 -3
  96. package/dist/workflows-extractor.test.d.ts +2 -0
  97. package/dist/workflows-extractor.test.d.ts.map +1 -0
  98. package/dist/workflows-extractor.test.js +70 -0
  99. package/dist/world-target.d.ts +20 -0
  100. package/dist/world-target.d.ts.map +1 -0
  101. package/dist/world-target.js +74 -0
  102. package/dist/world-target.test.d.ts +2 -0
  103. package/dist/world-target.test.d.ts.map +1 -0
  104. package/dist/world-target.test.js +106 -0
  105. package/package.json +9 -7
  106. package/dist/apply-swc-transform.js.map +0 -1
  107. package/dist/base-builder.js.map +0 -1
  108. package/dist/build-queue.js.map +0 -1
  109. package/dist/config-helpers.js.map +0 -1
  110. package/dist/constants.js.map +0 -1
  111. package/dist/discover-entries-esbuild-plugin.js.map +0 -1
  112. package/dist/discover-entries-esbuild-plugin.test.js.map +0 -1
  113. package/dist/esbuild-tsconfig.js.map +0 -1
  114. package/dist/esbuild-tsconfig.test.js.map +0 -1
  115. package/dist/get-input-files.test.js.map +0 -1
  116. package/dist/index.js.map +0 -1
  117. package/dist/module-specifier.js.map +0 -1
  118. package/dist/module-specifier.test.js.map +0 -1
  119. package/dist/node-module-esbuild-plugin.js.map +0 -1
  120. package/dist/node-module-esbuild-plugin.test.js.map +0 -1
  121. package/dist/pseudo-package-esbuild-plugin.js.map +0 -1
  122. package/dist/pseudo-package-esbuild-plugin.test.js.map +0 -1
  123. package/dist/request-converter.js.map +0 -1
  124. package/dist/serde-checker.js.map +0 -1
  125. package/dist/standalone.js.map +0 -1
  126. package/dist/swc-esbuild-plugin.js.map +0 -1
  127. package/dist/swc-esbuild-plugin.test.js.map +0 -1
  128. package/dist/transform-utils.js.map +0 -1
  129. package/dist/transform-utils.test.js.map +0 -1
  130. package/dist/types.js.map +0 -1
  131. package/dist/vercel-build-output-api.js.map +0 -1
  132. package/dist/workflow-alias.js.map +0 -1
  133. package/dist/workflow-alias.test.js.map +0 -1
  134. package/dist/workflows-extractor.js.map +0 -1
@@ -1,9 +1,11 @@
1
1
  import { readFile } from 'node:fs/promises';
2
2
  import { relative } from 'node:path';
3
3
  import { promisify } from 'node:util';
4
+ import { WorkflowBuildError } from '@workflow/errors';
4
5
  import enhancedResolveOrig from 'enhanced-resolve';
5
6
  import { applySwcTransform, } from './apply-swc-transform.js';
6
7
  import { jsTsRegex, parentHasChild, } from './discover-entries-esbuild-plugin.js';
8
+ import { resolveModuleSpecifier } from './module-specifier.js';
7
9
  import { resolveWorkflowAliasRelativePath } from './workflow-alias.js';
8
10
  const NODE_RESOLVE_OPTIONS = {
9
11
  dependencyType: 'commonjs',
@@ -39,10 +41,59 @@ const NODE_ESM_RESOLVE_OPTIONS = {
39
41
  dependencyType: 'esm',
40
42
  conditionNames: ['node', 'import'],
41
43
  };
44
+ function normalizePath(path) {
45
+ return path.replace(/\\/g, '/');
46
+ }
47
+ function formatIdLocation(location) {
48
+ return `${location.filePath}#${location.name}`;
49
+ }
50
+ function assertUniqueManifestIds(entriesByFile, ids, getId, label) {
51
+ const entriesByFileList = Object.entries(entriesByFile || {});
52
+ for (const [filePath, entries] of entriesByFileList) {
53
+ for (const [name, data] of Object.entries(entries)) {
54
+ const id = getId(data);
55
+ const existing = ids.get(id);
56
+ const current = { filePath, name };
57
+ if (existing &&
58
+ (existing.filePath !== current.filePath ||
59
+ existing.name !== current.name)) {
60
+ const idName = label === 'step' ? 'workflow step ID' : 'workflow ID';
61
+ const functionName = `${label} function`;
62
+ const capitalizedLabel = label === 'step' ? 'Step' : 'Workflow';
63
+ throw new WorkflowBuildError(`Duplicate ${idName} "${id}" generated for ${formatIdLocation(existing)} and ${formatIdLocation(current)}.`, {
64
+ hint: `${capitalizedLabel} IDs must be unique across a build. ` +
65
+ `If you own one of the colliding files, rename the ${functionName} or export ` +
66
+ `the package file through a unique package subpath. If the collision is in a ` +
67
+ `transitive dependency you don't control, file an issue with the upstream ` +
68
+ `package or pin to a non-colliding version.`,
69
+ });
70
+ }
71
+ ids.set(id, current);
72
+ }
73
+ }
74
+ }
75
+ function mergeWorkflowManifest(target, incoming, stepIds, workflowIds) {
76
+ assertUniqueManifestIds(incoming.steps, stepIds, (data) => data.stepId, 'step');
77
+ assertUniqueManifestIds(incoming.workflows, workflowIds, (data) => data.workflowId, 'workflow');
78
+ target.workflows = Object.assign(target.workflows || {}, incoming.workflows);
79
+ target.steps = Object.assign(target.steps || {}, incoming.steps);
80
+ target.classes = Object.assign(target.classes || {}, incoming.classes);
81
+ }
42
82
  export function createSwcPlugin(options) {
43
83
  return {
44
84
  name: 'swc-workflow-plugin',
45
85
  setup(build) {
86
+ let stepIdsForCurrentBuild = new Map();
87
+ let workflowIdsForCurrentBuild = new Map();
88
+ build.onStart(() => {
89
+ stepIdsForCurrentBuild = new Map();
90
+ workflowIdsForCurrentBuild = new Map();
91
+ if (options.workflowManifest) {
92
+ delete options.workflowManifest.steps;
93
+ delete options.workflowManifest.workflows;
94
+ delete options.workflowManifest.classes;
95
+ }
96
+ });
46
97
  // everything is external unless explicitly configured
47
98
  // to be bundled
48
99
  const cjsResolver = promisify(enhancedResolveOrig.create(NODE_RESOLVE_OPTIONS));
@@ -75,17 +126,33 @@ export function createSwcPlugin(options) {
75
126
  const specifier = args.path;
76
127
  const specifierIsPath = specifier.startsWith('.') || specifier.startsWith('/');
77
128
  let resolvedPath;
78
- // Determines whether the external path should be relativized
79
- // (project-local file) or kept as a bare specifier (npm package).
80
- let shouldMakeRelative = specifierIsPath;
129
+ // Path-style specifiers (./foo, ../foo, /abs/path) externalize as
130
+ // relative paths from `outdir`. Bare specifiers (npm packages)
131
+ // externalize as-is so Node can resolve them at runtime.
132
+ const shouldMakeRelative = specifierIsPath;
81
133
  if (specifierIsPath) {
82
134
  resolvedPath = await enhancedResolve(args.resolveDir, specifier);
83
135
  }
84
136
  else {
85
137
  // Resolve from project root so nested deps aren't externalized
86
138
  resolvedPath = await enhancedResolve(build.initialOptions.absWorkingDir || process.cwd(), specifier).catch(() => undefined); // swallow so esbuild fallback below can try
87
- // Fall back to esbuild for aliases/tsconfig paths,
88
- // but only accept project-local results
139
+ // Fall back to esbuild for aliases/tsconfig paths.
140
+ //
141
+ // If the specifier resolves to a project-local file via an
142
+ // alias/path mapping (e.g. tsconfig `paths`, esbuild `alias`,
143
+ // self-referencing package names like `@my-pkg/lib/foo`), we
144
+ // bundle it inline rather than externalizing.
145
+ //
146
+ // Externalizing such files is unsafe: we'd emit a relative
147
+ // import to the original source on disk, but that source can
148
+ // contain further alias imports. At runtime, Node's ESM loader
149
+ // doesn't know about tsconfig paths or build-time aliases, so
150
+ // those transitive imports throw `ERR_MODULE_NOT_FOUND` /
151
+ // `Package subpath ... is not defined by "exports"`.
152
+ //
153
+ // Bundling inline ensures alias-based imports are resolved at
154
+ // build time (where the alias map is known) and the runtime
155
+ // never sees an unresolvable specifier.
89
156
  if (!resolvedPath) {
90
157
  const esbuildResult = await build.resolve(specifier, {
91
158
  resolveDir: args.resolveDir,
@@ -99,15 +166,34 @@ export function createSwcPlugin(options) {
99
166
  .replace(/\\/g, '/')
100
167
  .includes('/node_modules/');
101
168
  if (isProjectLocalFile) {
102
- resolvedPath = esbuildResult.path;
103
- shouldMakeRelative = true;
169
+ // Let esbuild bundle this aliased project-local file inline
170
+ // (return null to defer to esbuild's normal pipeline). The
171
+ // SWC `onLoad` handler will still process it.
172
+ return null;
173
+ }
174
+ else if (options.entriesToBundle &&
175
+ esbuildResult.path?.endsWith('.node')) {
176
+ return {
177
+ external: true,
178
+ path: specifier,
179
+ };
104
180
  }
105
181
  }
106
182
  }
107
183
  if (!resolvedPath)
108
184
  return null;
109
185
  // Normalize to forward slashes for cross-platform comparison
110
- const normalizedResolvedPath = resolvedPath.replace(/\\/g, '/');
186
+ const normalizedResolvedPath = normalizePath(resolvedPath);
187
+ const workingDir = build.initialOptions.absWorkingDir || process.cwd();
188
+ const projectRoot = options.projectRoot || workingDir;
189
+ const moduleSpecifierRoot = options.moduleSpecifierRoot || projectRoot;
190
+ if (options.entriesToBundle &&
191
+ normalizedResolvedPath.endsWith('.node')) {
192
+ return {
193
+ external: true,
194
+ path: specifier,
195
+ };
196
+ }
111
197
  // Check if this module is a discovered entry whose SWC-transformed
112
198
  // code contains side effects (workflow/step/class registration).
113
199
  // Override the package.json "sideEffects": false so esbuild does not
@@ -128,6 +214,17 @@ export function createSwcPlugin(options) {
128
214
  shouldBundle = true;
129
215
  break;
130
216
  }
217
+ // Bundle project-local source files that are imported by a
218
+ // step/serde entry so direct runtime loaders do not see raw TS
219
+ // extensionless imports. Keep package dependencies external
220
+ // unless they are themselves in entriesToBundle or are parents
221
+ // of a discovered workflow/step/serde file via the check above.
222
+ if (options.bundleTransitiveLocalStepDependencies &&
223
+ isProjectLocalFile(normalizedResolvedPath, moduleSpecifierRoot) &&
224
+ parentHasChild(normalizedEntry, normalizedResolvedPath)) {
225
+ shouldBundle = true;
226
+ break;
227
+ }
131
228
  }
132
229
  if (shouldBundle) {
133
230
  // Let esbuild bundle this entry, but override sideEffects if needed.
@@ -201,6 +298,7 @@ export function createSwcPlugin(options) {
201
298
  // The filename parameter is used to generate workflowId/stepId, so it must be relative
202
299
  const workingDir = build.initialOptions.absWorkingDir || process.cwd();
203
300
  const projectRoot = options.projectRoot || workingDir;
301
+ const moduleSpecifierRoot = options.moduleSpecifierRoot || projectRoot;
204
302
  // Normalize paths: convert backslashes to forward slashes and remove trailing slashes
205
303
  const normalizedWorkingDir = workingDir
206
304
  .replace(/\\/g, '/')
@@ -212,7 +310,7 @@ export function createSwcPlugin(options) {
212
310
  const lowerWd = normalizedWorkingDir.toLowerCase();
213
311
  const lowerPath = normalizedPath.toLowerCase();
214
312
  let relativeFilepath;
215
- if (lowerPath.startsWith(lowerWd + '/')) {
313
+ if (lowerPath.startsWith(`${lowerWd}/`)) {
216
314
  // File is under working directory - manually calculate relative path
217
315
  // This ensures we get a relative path even with drive letter casing issues
218
316
  relativeFilepath = normalizedPath.substring(normalizedWorkingDir.length + 1);
@@ -247,13 +345,11 @@ export function createSwcPlugin(options) {
247
345
  relativeFilepath = normalizedPath.split('/').pop() || 'unknown.ts';
248
346
  }
249
347
  const { code: transformedCode, workflowManifest } = await applySwcTransform(relativeFilepath, normalizedSource, options.mode, args.path, // Pass absolute path for module specifier resolution
250
- projectRoot);
348
+ projectRoot, moduleSpecifierRoot);
251
349
  if (!options.workflowManifest) {
252
350
  options.workflowManifest = {};
253
351
  }
254
- options.workflowManifest.workflows = Object.assign(options.workflowManifest.workflows || {}, workflowManifest.workflows);
255
- options.workflowManifest.steps = Object.assign(options.workflowManifest.steps || {}, workflowManifest.steps);
256
- options.workflowManifest.classes = Object.assign(options.workflowManifest.classes || {}, workflowManifest.classes);
352
+ mergeWorkflowManifest(options.workflowManifest, workflowManifest, stepIdsForCurrentBuild, workflowIdsForCurrentBuild);
257
353
  return {
258
354
  contents: transformedCode,
259
355
  loader,
@@ -275,4 +371,10 @@ export function createSwcPlugin(options) {
275
371
  },
276
372
  };
277
373
  }
278
- //# sourceMappingURL=swc-esbuild-plugin.js.map
374
+ function isProjectLocalFile(filePath, projectRoot) {
375
+ if (normalizePath(filePath).includes('/node_modules/')) {
376
+ return false;
377
+ }
378
+ return (resolveModuleSpecifier(filePath, projectRoot).moduleSpecifier === undefined);
379
+ }
380
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3djLWVzYnVpbGQtcGx1Z2luLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3N3Yy1lc2J1aWxkLXBsdWdpbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDNUMsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUNyQyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQ3RDLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ3RELE9BQU8sbUJBQW1CLE1BQU0sa0JBQWtCLENBQUM7QUFFbkQsT0FBTyxFQUNMLGlCQUFpQixHQUVsQixNQUFNLDBCQUEwQixDQUFDO0FBQ2xDLE9BQU8sRUFDTCxTQUFTLEVBQ1QsY0FBYyxHQUNmLE1BQU0sc0NBQXNDLENBQUM7QUFDOUMsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDL0QsT0FBTyxFQUFFLGdDQUFnQyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUEwQ3ZFLE1BQU0sb0JBQW9CLEdBQUc7SUFDM0IsY0FBYyxFQUFFLFVBQVU7SUFDMUIsT0FBTyxFQUFFLENBQUMsY0FBYyxDQUFDO0lBQ3pCLGFBQWEsRUFBRSxDQUFDLFNBQVMsQ0FBQztJQUMxQixhQUFhLEVBQUUsQ0FBQyxTQUFTLENBQUM7SUFDMUIsY0FBYyxFQUFFLENBQUMsTUFBTSxFQUFFLFNBQVMsQ0FBQztJQUNuQyxnQkFBZ0IsRUFBRSxDQUFDLGNBQWMsQ0FBQztJQUNsQyxVQUFVLEVBQUU7UUFDVixLQUFLO1FBQ0wsTUFBTTtRQUNOLE1BQU07UUFDTixNQUFNO1FBQ04sTUFBTTtRQUNOLE1BQU07UUFDTixLQUFLO1FBQ0wsTUFBTTtRQUNOLE9BQU87UUFDUCxPQUFPO0tBQ1I7SUFDRCxpQkFBaUIsRUFBRSxLQUFLO0lBQ3hCLFFBQVEsRUFBRSxJQUFJO0lBQ2QsVUFBVSxFQUFFLENBQUMsTUFBTSxDQUFDO0lBQ3BCLFNBQVMsRUFBRSxDQUFDLE9BQU8sQ0FBQztJQUNwQixLQUFLLEVBQUUsRUFBRTtJQUNULGNBQWMsRUFBRSxLQUFLO0lBQ3JCLGNBQWMsRUFBRSxLQUFLO0lBQ3JCLGNBQWMsRUFBRSxLQUFLO0lBQ3JCLFlBQVksRUFBRSxFQUFFO0NBQ2pCLENBQUM7QUFFRixNQUFNLHdCQUF3QixHQUFHO0lBQy9CLEdBQUcsb0JBQW9CO0lBQ3ZCLGNBQWMsRUFBRSxLQUFLO0lBQ3JCLGNBQWMsRUFBRSxDQUFDLE1BQU0sRUFBRSxRQUFRLENBQUM7Q0FDbkMsQ0FBQztBQUVGLFNBQVMsYUFBYSxDQUFDLElBQVk7SUFDakMsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsQ0FBQztBQUNsQyxDQUFDO0FBT0QsU0FBUyxnQkFBZ0IsQ0FBQyxRQUFvQjtJQUM1QyxPQUFPLEdBQUcsUUFBUSxDQUFDLFFBQVEsSUFBSSxRQUFRLENBQUMsSUFBSSxFQUFFLENBQUM7QUFDakQsQ0FBQztBQUVELFNBQVMsdUJBQXVCLENBQzlCLGFBQXdFLEVBQ3hFLEdBQTRCLEVBQzVCLEtBQW9FLEVBQ3BFLEtBQTBCO0lBRTFCLE1BQU0saUJBQWlCLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FBQyxhQUFhLElBQUksRUFBRSxDQUUzRCxDQUFDO0lBQ0YsS0FBSyxNQUFNLENBQUMsUUFBUSxFQUFFLE9BQU8sQ0FBQyxJQUFJLGlCQUFpQixFQUFFLENBQUM7UUFDcEQsS0FBSyxNQUFNLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJLE1BQU0sQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztZQUNuRCxNQUFNLEVBQUUsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDdkIsTUFBTSxRQUFRLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUM3QixNQUFNLE9BQU8sR0FBRyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsQ0FBQztZQUNuQyxJQUNFLFFBQVE7Z0JBQ1IsQ0FBQyxRQUFRLENBQUMsUUFBUSxLQUFLLE9BQU8sQ0FBQyxRQUFRO29CQUNyQyxRQUFRLENBQUMsSUFBSSxLQUFLLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFDakMsQ0FBQztnQkFDRCxNQUFNLE1BQU0sR0FBRyxLQUFLLEtBQUssTUFBTSxDQUFDLENBQUMsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDLENBQUMsYUFBYSxDQUFDO2dCQUNyRSxNQUFNLFlBQVksR0FBRyxHQUFHLEtBQUssV0FBVyxDQUFDO2dCQUN6QyxNQUFNLGdCQUFnQixHQUFHLEtBQUssS0FBSyxNQUFNLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDO2dCQUNoRSxNQUFNLElBQUksa0JBQWtCLENBQzFCLGFBQWEsTUFBTSxLQUFLLEVBQUUsbUJBQW1CLGdCQUFnQixDQUFDLFFBQVEsQ0FBQyxRQUFRLGdCQUFnQixDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQzNHO29CQUNFLElBQUksRUFDRixHQUFHLGdCQUFnQixzQ0FBc0M7d0JBQ3pELHFEQUFxRCxZQUFZLGFBQWE7d0JBQzlFLDhFQUE4RTt3QkFDOUUsMkVBQTJFO3dCQUMzRSw0Q0FBNEM7aUJBQy9DLENBQ0YsQ0FBQztZQUNKLENBQUM7WUFDRCxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxPQUFPLENBQUMsQ0FBQztRQUN2QixDQUFDO0lBQ0gsQ0FBQztBQUNILENBQUM7QUFFRCxTQUFTLHFCQUFxQixDQUM1QixNQUF3QixFQUN4QixRQUEwQixFQUMxQixPQUFnQyxFQUNoQyxXQUFvQztJQUVwQyx1QkFBdUIsQ0FDckIsUUFBUSxDQUFDLEtBQUssRUFDZCxPQUFPLEVBQ1AsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFFLElBQTJCLENBQUMsTUFBTSxFQUM3QyxNQUFNLENBQ1AsQ0FBQztJQUNGLHVCQUF1QixDQUNyQixRQUFRLENBQUMsU0FBUyxFQUNsQixXQUFXLEVBQ1gsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFFLElBQStCLENBQUMsVUFBVSxFQUNyRCxVQUFVLENBQ1gsQ0FBQztJQUVGLE1BQU0sQ0FBQyxTQUFTLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsU0FBUyxJQUFJLEVBQUUsRUFBRSxRQUFRLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDN0UsTUFBTSxDQUFDLEtBQUssR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLElBQUksRUFBRSxFQUFFLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNqRSxNQUFNLENBQUMsT0FBTyxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLE9BQU8sSUFBSSxFQUFFLEVBQUUsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQ3pFLENBQUM7QUFFRCxNQUFNLFVBQVUsZUFBZSxDQUFDLE9BQXlCO0lBQ3ZELE9BQU87UUFDTCxJQUFJLEVBQUUscUJBQXFCO1FBQzNCLEtBQUssQ0FBQyxLQUFLO1lBQ1QsSUFBSSxzQkFBc0IsR0FBRyxJQUFJLEdBQUcsRUFBc0IsQ0FBQztZQUMzRCxJQUFJLDBCQUEwQixHQUFHLElBQUksR0FBRyxFQUFzQixDQUFDO1lBRS9ELEtBQUssQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFO2dCQUNqQixzQkFBc0IsR0FBRyxJQUFJLEdBQUcsRUFBRSxDQUFDO2dCQUNuQywwQkFBMEIsR0FBRyxJQUFJLEdBQUcsRUFBRSxDQUFDO2dCQUN2QyxJQUFJLE9BQU8sQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO29CQUM3QixPQUFPLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUM7b0JBQ3RDLE9BQU8sT0FBTyxDQUFDLGdCQUFnQixDQUFDLFNBQVMsQ0FBQztvQkFDMUMsT0FBTyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxDQUFDO2dCQUMxQyxDQUFDO1lBQ0gsQ0FBQyxDQUFDLENBQUM7WUFFSCxzREFBc0Q7WUFDdEQsZ0JBQWdCO1lBQ2hCLE1BQU0sV0FBVyxHQUFHLFNBQVMsQ0FDM0IsbUJBQW1CLENBQUMsTUFBTSxDQUFDLG9CQUFvQixDQUFDLENBQ2pELENBQUM7WUFDRixNQUFNLFdBQVcsR0FBRyxTQUFTLENBQzNCLG1CQUFtQixDQUFDLE1BQU0sQ0FBQyx3QkFBd0IsQ0FBQyxDQUNyRCxDQUFDO1lBRUYsTUFBTSxlQUFlLEdBQUcsS0FBSyxFQUFFLE9BQWUsRUFBRSxJQUFZLEVBQUUsRUFBRTtnQkFDOUQsSUFBSSxDQUFDO29CQUNILE9BQU8sTUFBTSxXQUFXLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFDO2dCQUMxQyxDQUFDO2dCQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7b0JBQ1gsT0FBTyxXQUFXLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFDO2dCQUNwQyxDQUFDO1lBQ0gsQ0FBQyxDQUFDO1lBRUYsdUVBQXVFO1lBQ3ZFLE1BQU0sMkJBQTJCLEdBQUcsSUFBSSxHQUFHLENBQ3pDLE9BQU8sQ0FBQyxpQkFBaUIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQzdELENBQUM7WUFFRixLQUFLLENBQUMsU0FBUyxDQUFDLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsRUFBRTtnQkFDL0MsSUFBSSxJQUFJLENBQUMsVUFBVSxFQUFFLGFBQWE7b0JBQUUsT0FBTyxJQUFJLENBQUM7Z0JBRWhELElBQ0UsQ0FBQyxPQUFPLENBQUMsZUFBZTtvQkFDeEIsMkJBQTJCLENBQUMsSUFBSSxLQUFLLENBQUMsRUFDdEMsQ0FBQztvQkFDRCxPQUFPLElBQUksQ0FBQztnQkFDZCxDQUFDO2dCQUVELG1FQUFtRTtnQkFDbkUsc0VBQXNFO2dCQUN0RSxpRUFBaUU7Z0JBQ2pFLG1FQUFtRTtnQkFDbkUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxlQUFlLElBQUksSUFBSSxDQUFDLElBQUksS0FBSyxrQkFBa0IsRUFBRSxDQUFDO29CQUNqRSxPQUFPLElBQUksQ0FBQztnQkFDZCxDQUFDO2dCQUVELElBQUksQ0FBQztvQkFDSCxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDO29CQUM1QixNQUFNLGVBQWUsR0FDbkIsU0FBUyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsSUFBSSxTQUFTLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDO29CQUV6RCxJQUFJLFlBQXdDLENBQUM7b0JBQzdDLGtFQUFrRTtvQkFDbEUsK0RBQStEO29CQUMvRCx5REFBeUQ7b0JBQ3pELE1BQU0sa0JBQWtCLEdBQUcsZUFBZSxDQUFDO29CQUUzQyxJQUFJLGVBQWUsRUFBRSxDQUFDO3dCQUNwQixZQUFZLEdBQUcsTUFBTSxlQUFlLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxTQUFTLENBQUMsQ0FBQztvQkFDbkUsQ0FBQzt5QkFBTSxDQUFDO3dCQUNOLCtEQUErRDt3QkFDL0QsWUFBWSxHQUFHLE1BQU0sZUFBZSxDQUNsQyxLQUFLLENBQUMsY0FBYyxDQUFDLGFBQWEsSUFBSSxPQUFPLENBQUMsR0FBRyxFQUFFLEVBQ25ELFNBQVMsQ0FDVixDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLDRDQUE0Qzt3QkFFdEUsbURBQW1EO3dCQUNuRCxFQUFFO3dCQUNGLDJEQUEyRDt3QkFDM0QsOERBQThEO3dCQUM5RCw2REFBNkQ7d0JBQzdELDhDQUE4Qzt3QkFDOUMsRUFBRTt3QkFDRiwyREFBMkQ7d0JBQzNELDZEQUE2RDt3QkFDN0QsK0RBQStEO3dCQUMvRCw4REFBOEQ7d0JBQzlELDBEQUEwRDt3QkFDMUQscURBQXFEO3dCQUNyRCxFQUFFO3dCQUNGLDhEQUE4RDt3QkFDOUQsNERBQTREO3dCQUM1RCx3Q0FBd0M7d0JBQ3hDLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQzs0QkFDbEIsTUFBTSxhQUFhLEdBQUcsTUFBTSxLQUFLLENBQUMsT0FBTyxDQUFDLFNBQVMsRUFBRTtnQ0FDbkQsVUFBVSxFQUFFLElBQUksQ0FBQyxVQUFVO2dDQUMzQixJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUk7Z0NBQ2YsVUFBVSxFQUFFLEVBQUUsYUFBYSxFQUFFLElBQUksRUFBRTs2QkFDcEMsQ0FBQyxDQUFDOzRCQUNILE1BQU0sVUFBVSxHQUNkLENBQUMsQ0FBQyxhQUFhLENBQUMsSUFBSSxJQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUM7NEJBQ3ZELE1BQU0sa0JBQWtCLEdBQ3RCLFVBQVU7Z0NBQ1YsQ0FBQyxhQUFhLENBQUMsUUFBUTtnQ0FDdkIsQ0FBQyxhQUFhLENBQUMsSUFBSTtxQ0FDaEIsT0FBTyxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUM7cUNBQ25CLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDOzRCQUNoQyxJQUFJLGtCQUFrQixFQUFFLENBQUM7Z0NBQ3ZCLDREQUE0RDtnQ0FDNUQsMkRBQTJEO2dDQUMzRCw4Q0FBOEM7Z0NBQzlDLE9BQU8sSUFBSSxDQUFDOzRCQUNkLENBQUM7aUNBQU0sSUFDTCxPQUFPLENBQUMsZUFBZTtnQ0FDdkIsYUFBYSxDQUFDLElBQUksRUFBRSxRQUFRLENBQUMsT0FBTyxDQUFDLEVBQ3JDLENBQUM7Z0NBQ0QsT0FBTztvQ0FDTCxRQUFRLEVBQUUsSUFBSTtvQ0FDZCxJQUFJLEVBQUUsU0FBUztpQ0FDaEIsQ0FBQzs0QkFDSixDQUFDO3dCQUNILENBQUM7b0JBQ0gsQ0FBQztvQkFFRCxJQUFJLENBQUMsWUFBWTt3QkFBRSxPQUFPLElBQUksQ0FBQztvQkFFL0IsNkRBQTZEO29CQUM3RCxNQUFNLHNCQUFzQixHQUFHLGFBQWEsQ0FBQyxZQUFZLENBQUMsQ0FBQztvQkFDM0QsTUFBTSxVQUFVLEdBQ2QsS0FBSyxDQUFDLGNBQWMsQ0FBQyxhQUFhLElBQUksT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDO29CQUN0RCxNQUFNLFdBQVcsR0FBRyxPQUFPLENBQUMsV0FBVyxJQUFJLFVBQVUsQ0FBQztvQkFDdEQsTUFBTSxtQkFBbUIsR0FDdkIsT0FBTyxDQUFDLG1CQUFtQixJQUFJLFdBQVcsQ0FBQztvQkFFN0MsSUFDRSxPQUFPLENBQUMsZUFBZTt3QkFDdkIsc0JBQXNCLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxFQUN4QyxDQUFDO3dCQUNELE9BQU87NEJBQ0wsUUFBUSxFQUFFLElBQUk7NEJBQ2QsSUFBSSxFQUFFLFNBQVM7eUJBQ2hCLENBQUM7b0JBQ0osQ0FBQztvQkFFRCxtRUFBbUU7b0JBQ25FLGlFQUFpRTtvQkFDakUscUVBQXFFO29CQUNyRSxzQ0FBc0M7b0JBQ3RDLE1BQU0sY0FBYyxHQUFHLDJCQUEyQixDQUFDLEdBQUcsQ0FDcEQsc0JBQXNCLENBQ3ZCLENBQUM7b0JBRUYsSUFBSSxPQUFPLENBQUMsZUFBZSxFQUFFLENBQUM7d0JBQzVCLElBQUksWUFBWSxHQUFHLEtBQUssQ0FBQzt3QkFDekIsS0FBSyxNQUFNLGFBQWEsSUFBSSxPQUFPLENBQUMsZUFBZSxFQUFFLENBQUM7NEJBQ3BELE1BQU0sZUFBZSxHQUFHLGFBQWEsQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQyxDQUFDOzRCQUUxRCxJQUFJLHNCQUFzQixLQUFLLGVBQWUsRUFBRSxDQUFDO2dDQUMvQyxZQUFZLEdBQUcsSUFBSSxDQUFDO2dDQUNwQixNQUFNOzRCQUNSLENBQUM7NEJBRUQsa0RBQWtEOzRCQUNsRCxvREFBb0Q7NEJBQ3BELGdEQUFnRDs0QkFDaEQsSUFBSSxjQUFjLENBQUMsc0JBQXNCLEVBQUUsZUFBZSxDQUFDLEVBQUUsQ0FBQztnQ0FDNUQsWUFBWSxHQUFHLElBQUksQ0FBQztnQ0FDcEIsTUFBTTs0QkFDUixDQUFDOzRCQUVELDJEQUEyRDs0QkFDM0QsK0RBQStEOzRCQUMvRCw0REFBNEQ7NEJBQzVELCtEQUErRDs0QkFDL0QsZ0VBQWdFOzRCQUNoRSxJQUNFLE9BQU8sQ0FBQyxxQ0FBcUM7Z0NBQzdDLGtCQUFrQixDQUNoQixzQkFBc0IsRUFDdEIsbUJBQW1CLENBQ3BCO2dDQUNELGNBQWMsQ0FBQyxlQUFlLEVBQUUsc0JBQXNCLENBQUMsRUFDdkQsQ0FBQztnQ0FDRCxZQUFZLEdBQUcsSUFBSSxDQUFDO2dDQUNwQixNQUFNOzRCQUNSLENBQUM7d0JBQ0gsQ0FBQzt3QkFFRCxJQUFJLFlBQVksRUFBRSxDQUFDOzRCQUNqQixxRUFBcUU7NEJBQ3JFLHFFQUFxRTs0QkFDckUsdUVBQXVFOzRCQUN2RSx1RUFBdUU7NEJBQ3ZFLGlEQUFpRDs0QkFDakQsT0FBTyxjQUFjO2dDQUNuQixDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsWUFBWSxFQUFFLFdBQVcsRUFBRSxJQUFJLEVBQUU7Z0NBQzNDLENBQUMsQ0FBQyxJQUFJLENBQUM7d0JBQ1gsQ0FBQzt3QkFFRCxJQUFJLFlBQW9CLENBQUM7d0JBQ3pCLElBQUksa0JBQWtCLEVBQUUsQ0FBQzs0QkFDdkIsd0RBQXdEOzRCQUN4RCw0REFBNEQ7NEJBQzVELDBEQUEwRDs0QkFDMUQsNERBQTREOzRCQUM1RCw2REFBNkQ7NEJBQzdELHlDQUF5Qzs0QkFDekMsSUFBSSxzQkFBc0IsQ0FBQyxRQUFRLENBQUMsZ0JBQWdCLENBQUMsRUFBRSxDQUFDO2dDQUN0RCxPQUFPLElBQUksQ0FBQyxDQUFDLHdCQUF3Qjs0QkFDdkMsQ0FBQzs0QkFFRCxZQUFZLEdBQUcsUUFBUSxDQUNyQixPQUFPLENBQUMsTUFBTSxJQUFJLE9BQU8sQ0FBQyxHQUFHLEVBQUUsRUFDL0IsWUFBWSxDQUNiLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsQ0FBQzs0QkFFdEIsSUFBSSxPQUFPLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztnQ0FDaEMsK0RBQStEO2dDQUMvRCwrREFBK0Q7Z0NBQy9ELFlBQVksR0FBRyxZQUFZO3FDQUN4QixPQUFPLENBQUMsU0FBUyxFQUFFLEtBQUssQ0FBQztxQ0FDekIsT0FBTyxDQUFDLFFBQVEsRUFBRSxNQUFNLENBQUM7cUNBQ3pCLE9BQU8sQ0FBQyxRQUFRLEVBQUUsTUFBTSxDQUFDLENBQUM7NEJBQy9CLENBQUM7d0JBQ0gsQ0FBQzs2QkFBTSxDQUFDOzRCQUNOLFlBQVksR0FBRyxTQUFTLENBQUM7d0JBQzNCLENBQUM7d0JBRUQsT0FBTzs0QkFDTCxRQUFRLEVBQUUsSUFBSTs0QkFDZCxJQUFJLEVBQUUsWUFBWTs0QkFDbEIsV0FBVyxFQUFFLGNBQWMsSUFBSSxTQUFTO3lCQUN6QyxDQUFDO29CQUNKLENBQUM7b0JBRUQsOERBQThEO29CQUM5RCxxRUFBcUU7b0JBQ3JFLHVFQUF1RTtvQkFDdkUsdUVBQXVFO29CQUN2RSxpREFBaUQ7b0JBQ2pELE9BQU8sY0FBYzt3QkFDbkIsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLFlBQVksRUFBRSxXQUFXLEVBQUUsSUFBSSxFQUFFO3dCQUMzQyxDQUFDLENBQUMsSUFBSSxDQUFDO2dCQUNYLENBQUM7Z0JBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxDQUFBLENBQUM7Z0JBQ2QsT0FBTyxJQUFJLENBQUM7WUFDZCxDQUFDLENBQUMsQ0FBQztZQUVILHlDQUF5QztZQUN6QyxLQUFLLENBQUMsTUFBTSxDQUFDLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsRUFBRTtnQkFDakQseUNBQXlDO2dCQUN6QyxJQUFJLENBQUM7b0JBQ0gsMkNBQTJDO29CQUMzQyxJQUFJLE1BQU0sR0FBeUIsSUFBSSxDQUFDO29CQUN4QyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7d0JBQy9CLE1BQU0sR0FBRyxLQUFLLENBQUM7b0JBQ2pCLENBQUM7eUJBQU0sSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDO3dCQUN0QyxNQUFNLEdBQUcsS0FBSyxDQUFDO29CQUNqQixDQUFDO29CQUNELE1BQU0sTUFBTSxHQUFHLE1BQU0sUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUM7b0JBQ2pELE1BQU0sZ0JBQWdCLEdBQUcsTUFBTTt5QkFDNUIsT0FBTyxDQUFDLHVDQUF1QyxFQUFFLFFBQVEsQ0FBQzt5QkFDMUQsT0FBTyxDQUFDLHVDQUF1QyxFQUFFLFFBQVEsQ0FBQyxDQUFDO29CQUU5RCx5Q0FBeUM7b0JBQ3pDLHVGQUF1RjtvQkFDdkYsTUFBTSxVQUFVLEdBQ2QsS0FBSyxDQUFDLGNBQWMsQ0FBQyxhQUFhLElBQUksT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDO29CQUN0RCxNQUFNLFdBQVcsR0FBRyxPQUFPLENBQUMsV0FBVyxJQUFJLFVBQVUsQ0FBQztvQkFDdEQsTUFBTSxtQkFBbUIsR0FDdkIsT0FBTyxDQUFDLG1CQUFtQixJQUFJLFdBQVcsQ0FBQztvQkFDN0Msc0ZBQXNGO29CQUN0RixNQUFNLG9CQUFvQixHQUFHLFVBQVU7eUJBQ3BDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDO3lCQUNuQixPQUFPLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO29CQUN0QixNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUM7b0JBRXJELCtFQUErRTtvQkFDL0UsaUZBQWlGO29CQUNqRiwyREFBMkQ7b0JBQzNELE1BQU0sT0FBTyxHQUFHLG9CQUFvQixDQUFDLFdBQVcsRUFBRSxDQUFDO29CQUNuRCxNQUFNLFNBQVMsR0FBRyxjQUFjLENBQUMsV0FBVyxFQUFFLENBQUM7b0JBRS9DLElBQUksZ0JBQXdCLENBQUM7b0JBQzdCLElBQUksU0FBUyxDQUFDLFVBQVUsQ0FBQyxHQUFHLE9BQU8sR0FBRyxDQUFDLEVBQUUsQ0FBQzt3QkFDeEMscUVBQXFFO3dCQUNyRSwyRUFBMkU7d0JBQzNFLGdCQUFnQixHQUFHLGNBQWMsQ0FBQyxTQUFTLENBQ3pDLG9CQUFvQixDQUFDLE1BQU0sR0FBRyxDQUFDLENBQ2hDLENBQUM7b0JBQ0osQ0FBQzt5QkFBTSxJQUFJLFNBQVMsS0FBSyxPQUFPLEVBQUUsQ0FBQzt3QkFDakMsZ0NBQWdDO3dCQUNoQyxnQkFBZ0IsR0FBRyxHQUFHLENBQUM7b0JBQ3pCLENBQUM7eUJBQU0sQ0FBQzt3QkFDTixzRkFBc0Y7d0JBQ3RGLGdCQUFnQixHQUFHLFFBQVEsQ0FDekIsb0JBQW9CLEVBQ3BCLGNBQWMsQ0FDZixDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUM7d0JBRXRCLHdEQUF3RDt3QkFDeEQsb0VBQW9FO3dCQUNwRSxJQUFJLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDOzRCQUN2QyxNQUFNLG1CQUFtQixHQUN2QixNQUFNLGdDQUFnQyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsVUFBVSxDQUFDLENBQUM7NEJBQ2hFLElBQUksbUJBQW1CLEVBQUUsQ0FBQztnQ0FDeEIsZ0JBQWdCLEdBQUcsbUJBQW1CLENBQUM7NEJBQ3pDLENBQUM7aUNBQU0sQ0FBQztnQ0FDTixnQkFBZ0IsR0FBRyxnQkFBZ0I7cUNBQ2hDLEtBQUssQ0FBQyxHQUFHLENBQUM7cUNBQ1YsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxJQUFJLEtBQUssSUFBSSxDQUFDO3FDQUMvQixJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7NEJBQ2YsQ0FBQzt3QkFDSCxDQUFDO29CQUNILENBQUM7b0JBRUQsb0VBQW9FO29CQUNwRSxJQUNFLGdCQUFnQixDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUM7d0JBQzlCLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsRUFDaEMsQ0FBQzt3QkFDRCxpRkFBaUY7d0JBQ2pGLE9BQU8sQ0FBQyxLQUFLLENBQ1gsK0NBQStDLGdCQUFnQixFQUFFLENBQ2xFLENBQUM7d0JBQ0YsZ0JBQWdCLEdBQUcsY0FBYyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsSUFBSSxZQUFZLENBQUM7b0JBQ3JFLENBQUM7b0JBRUQsTUFBTSxFQUFFLElBQUksRUFBRSxlQUFlLEVBQUUsZ0JBQWdCLEVBQUUsR0FDL0MsTUFBTSxpQkFBaUIsQ0FDckIsZ0JBQWdCLEVBQ2hCLGdCQUFnQixFQUNoQixPQUFPLENBQUMsSUFBSSxFQUNaLElBQUksQ0FBQyxJQUFJLEVBQUUscURBQXFEO29CQUNoRSxXQUFXLEVBQ1gsbUJBQW1CLENBQ3BCLENBQUM7b0JBRUosSUFBSSxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO3dCQUM5QixPQUFPLENBQUMsZ0JBQWdCLEdBQUcsRUFBRSxDQUFDO29CQUNoQyxDQUFDO29CQUVELHFCQUFxQixDQUNuQixPQUFPLENBQUMsZ0JBQWdCLEVBQ3hCLGdCQUFnQixFQUNoQixzQkFBc0IsRUFDdEIsMEJBQTBCLENBQzNCLENBQUM7b0JBRUYsT0FBTzt3QkFDTCxRQUFRLEVBQUUsZUFBZTt3QkFDekIsTUFBTTtxQkFDUCxDQUFDO2dCQUNKLENBQUM7Z0JBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztvQkFDZixNQUFNLFlBQVksR0FDaEIsS0FBSyxZQUFZLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO29CQUN6RCxPQUFPLENBQUMsS0FBSyxDQUNYLDRCQUE0QixJQUFJLENBQUMsSUFBSSxHQUFHLEVBQ3hDLFlBQVksQ0FDYixDQUFDO29CQUNGLE9BQU87d0JBQ0wsTUFBTSxFQUFFOzRCQUNOO2dDQUNFLElBQUksRUFBRSx5QkFBeUIsWUFBWSxFQUFFO2dDQUM3QyxRQUFRLEVBQUUsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUU7NkJBQ2xEO3lCQUNGO3FCQUNGLENBQUM7Z0JBQ0osQ0FBQztZQUNILENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztLQUNGLENBQUM7QUFDSixDQUFDO0FBRUQsU0FBUyxrQkFBa0IsQ0FBQyxRQUFnQixFQUFFLFdBQW1CO0lBQy9ELElBQUksYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFLENBQUM7UUFDdkQsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBRUQsT0FBTyxDQUNMLHNCQUFzQixDQUFDLFFBQVEsRUFBRSxXQUFXLENBQUMsQ0FBQyxlQUFlLEtBQUssU0FBUyxDQUM1RSxDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHJlYWRGaWxlIH0gZnJvbSAnbm9kZTpmcy9wcm9taXNlcyc7XG5pbXBvcnQgeyByZWxhdGl2ZSB9IGZyb20gJ25vZGU6cGF0aCc7XG5pbXBvcnQgeyBwcm9taXNpZnkgfSBmcm9tICdub2RlOnV0aWwnO1xuaW1wb3J0IHsgV29ya2Zsb3dCdWlsZEVycm9yIH0gZnJvbSAnQHdvcmtmbG93L2Vycm9ycyc7XG5pbXBvcnQgZW5oYW5jZWRSZXNvbHZlT3JpZyBmcm9tICdlbmhhbmNlZC1yZXNvbHZlJztcbmltcG9ydCB0eXBlIHsgUGx1Z2luIH0gZnJvbSAnZXNidWlsZCc7XG5pbXBvcnQge1xuICBhcHBseVN3Y1RyYW5zZm9ybSxcbiAgdHlwZSBXb3JrZmxvd01hbmlmZXN0LFxufSBmcm9tICcuL2FwcGx5LXN3Yy10cmFuc2Zvcm0uanMnO1xuaW1wb3J0IHtcbiAganNUc1JlZ2V4LFxuICBwYXJlbnRIYXNDaGlsZCxcbn0gZnJvbSAnLi9kaXNjb3Zlci1lbnRyaWVzLWVzYnVpbGQtcGx1Z2luLmpzJztcbmltcG9ydCB7IHJlc29sdmVNb2R1bGVTcGVjaWZpZXIgfSBmcm9tICcuL21vZHVsZS1zcGVjaWZpZXIuanMnO1xuaW1wb3J0IHsgcmVzb2x2ZVdvcmtmbG93QWxpYXNSZWxhdGl2ZVBhdGggfSBmcm9tICcuL3dvcmtmbG93LWFsaWFzLmpzJztcblxuZXhwb3J0IGludGVyZmFjZSBTd2NQbHVnaW5PcHRpb25zIHtcbiAgbW9kZTogJ3N0ZXAnIHwgJ3dvcmtmbG93JztcbiAgZW50cmllc1RvQnVuZGxlPzogc3RyaW5nW107XG4gIG91dGRpcj86IHN0cmluZztcbiAgcHJvamVjdFJvb3Q/OiBzdHJpbmc7XG4gIG1vZHVsZVNwZWNpZmllclJvb3Q/OiBzdHJpbmc7XG4gIHdvcmtmbG93TWFuaWZlc3Q/OiBXb3JrZmxvd01hbmlmZXN0O1xuICAvKipcbiAgICogUmV3cml0ZSBUeXBlU2NyaXB0IGV4dGVuc2lvbnMgKC50cywgLnRzeCwgLm10cywgLmN0cykgdG8gdGhlaXIgSlNcbiAgICogZXF1aXZhbGVudHMgKC5qcywgLm1qcywgLmNqcykgaW4gZXh0ZXJuYWxpemVkIGltcG9ydCBwYXRocy5cbiAgICpcbiAgICogRW5hYmxlIHRoaXMgd2hlbiB0aGUgb3V0cHV0IGJ1bmRsZSBpcyBjb25zdW1lZCBkaXJlY3RseSBieSBOb2RlJ3MgbmF0aXZlXG4gICAqIEVTTSBsb2FkZXIgKGUuZy4gdml0ZXN0KSwgd2hpY2ggY2Fubm90IHJlc29sdmUgLnRzIGV4dGVuc2lvbnMuXG4gICAqXG4gICAqIExlYXZlIGRpc2FibGVkIChkZWZhdWx0KSB3aGVuIGEgZG93bnN0cmVhbSBidW5kbGVyICh3ZWJwYWNrLCBWaXRlLCBldGMuKVxuICAgKiBoYW5kbGVzIHJlc29sdXRpb24g4oCUIHRob3NlIHRvb2xzIHJlc29sdmUgLnRzIG5hdGl2ZWx5IGFuZCByZXdyaXRpbmdcbiAgICogYnJlYWtzIHRoZW0gYmVjYXVzZSB0aGUgLmpzIGZpbGUgZG9lc24ndCBleGlzdCBvbiBkaXNrLlxuICAgKi9cbiAgcmV3cml0ZVRzRXh0ZW5zaW9ucz86IGJvb2xlYW47XG4gIC8qKlxuICAgKiBCdW5kbGUgcHJvamVjdC1sb2NhbCBmaWxlcyB0aGF0IGFyZSB0cmFuc2l0aXZlbHkgaW1wb3J0ZWQgYnkgc3RlcCBlbnRyaWVzLlxuICAgKlxuICAgKiBLZWVwIHRoaXMgZGlzYWJsZWQgd2hlbiBhIGRvd25zdHJlYW0gYnVuZGxlciBjb25zdW1lcyB0aGUgZ2VuZXJhdGVkIHN0ZXBcbiAgICogYnVuZGxlIGJlY2F1c2UgdGhhdCBidW5kbGVyIGNhbiByZXNvbHZlIHRoZSBleHRlcm5hbGl6ZWQgbG9jYWwgaW1wb3J0cy5cbiAgICogRW5hYmxlIGl0IGZvciBkaXJlY3QgcnVudGltZSBsb2FkaW5nLCB3aGVyZSBOb2RlIGltcG9ydHMgdGhlIGdlbmVyYXRlZCBzdGVwXG4gICAqIGJ1bmRsZSBmcm9tIGRpc2sgd2l0aG91dCBhIGxhdGVyIGJ1bmRsaW5nIHBhc3MuXG4gICAqL1xuICBidW5kbGVUcmFuc2l0aXZlTG9jYWxTdGVwRGVwZW5kZW5jaWVzPzogYm9vbGVhbjtcbiAgLyoqXG4gICAqIEFic29sdXRlIGZpbGUgcGF0aHMgb2YgZGlzY292ZXJlZCB3b3JrZmxvdy9zdGVwL3NlcmRlIGVudHJpZXMgd2hvc2VcbiAgICogaW1wb3J0cyBtdXN0IGJlIHRyZWF0ZWQgYXMgc2lkZS1lZmZlY3RmdWwuXG4gICAqXG4gICAqIFRoZSBTV0MgY29tcGlsZXIgdHJhbnNmb3JtIGluamVjdHMgcmVnaXN0cmF0aW9uIGNhbGxzICh3b3JrZmxvdyBJRHMsXG4gICAqIHN0ZXAgSURzLCBjbGFzcyBzZXJpYWxpemF0aW9uLCBldGMuKSBpbnRvIHRoZXNlIGZpbGVzLiBXaXRob3V0IHRoaXNcbiAgICogb3ZlcnJpZGUsIGVzYnVpbGQgaG9ub3VycyBgXCJzaWRlRWZmZWN0c1wiOiBmYWxzZWAgZnJvbSB0aGUgcGFja2FnZSdzXG4gICAqIGBwYWNrYWdlLmpzb25gIGFuZCBzaWxlbnRseSBkcm9wcyBiYXJlIGltcG9ydHMgb2YgdGhlc2UgbW9kdWxlcy5cbiAgICovXG4gIHNpZGVFZmZlY3RFbnRyaWVzPzogc3RyaW5nW107XG59XG5cbmNvbnN0IE5PREVfUkVTT0xWRV9PUFRJT05TID0ge1xuICBkZXBlbmRlbmN5VHlwZTogJ2NvbW1vbmpzJyxcbiAgbW9kdWxlczogWydub2RlX21vZHVsZXMnXSxcbiAgZXhwb3J0c0ZpZWxkczogWydleHBvcnRzJ10sXG4gIGltcG9ydHNGaWVsZHM6IFsnaW1wb3J0cyddLFxuICBjb25kaXRpb25OYW1lczogWydub2RlJywgJ3JlcXVpcmUnXSxcbiAgZGVzY3JpcHRpb25GaWxlczogWydwYWNrYWdlLmpzb24nXSxcbiAgZXh0ZW5zaW9uczogW1xuICAgICcudHMnLFxuICAgICcudHN4JyxcbiAgICAnLm10cycsXG4gICAgJy5jdHMnLFxuICAgICcuY2pzJyxcbiAgICAnLm1qcycsXG4gICAgJy5qcycsXG4gICAgJy5qc3gnLFxuICAgICcuanNvbicsXG4gICAgJy5ub2RlJyxcbiAgXSxcbiAgZW5mb3JjZUV4dGVuc2lvbnM6IGZhbHNlLFxuICBzeW1saW5rczogdHJ1ZSxcbiAgbWFpbkZpZWxkczogWydtYWluJ10sXG4gIG1haW5GaWxlczogWydpbmRleCddLFxuICByb290czogW10sXG4gIGZ1bGx5U3BlY2lmaWVkOiBmYWxzZSxcbiAgcHJlZmVyUmVsYXRpdmU6IGZhbHNlLFxuICBwcmVmZXJBYnNvbHV0ZTogZmFsc2UsXG4gIHJlc3RyaWN0aW9uczogW10sXG59O1xuXG5jb25zdCBOT0RFX0VTTV9SRVNPTFZFX09QVElPTlMgPSB7XG4gIC4uLk5PREVfUkVTT0xWRV9PUFRJT05TLFxuICBkZXBlbmRlbmN5VHlwZTogJ2VzbScsXG4gIGNvbmRpdGlvbk5hbWVzOiBbJ25vZGUnLCAnaW1wb3J0J10sXG59O1xuXG5mdW5jdGlvbiBub3JtYWxpemVQYXRoKHBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBwYXRoLnJlcGxhY2UoL1xcXFwvZywgJy8nKTtcbn1cblxudHlwZSBJZExvY2F0aW9uID0ge1xuICBmaWxlUGF0aDogc3RyaW5nO1xuICBuYW1lOiBzdHJpbmc7XG59O1xuXG5mdW5jdGlvbiBmb3JtYXRJZExvY2F0aW9uKGxvY2F0aW9uOiBJZExvY2F0aW9uKTogc3RyaW5nIHtcbiAgcmV0dXJuIGAke2xvY2F0aW9uLmZpbGVQYXRofSMke2xvY2F0aW9uLm5hbWV9YDtcbn1cblxuZnVuY3Rpb24gYXNzZXJ0VW5pcXVlTWFuaWZlc3RJZHMoXG4gIGVudHJpZXNCeUZpbGU6IFdvcmtmbG93TWFuaWZlc3RbJ3N0ZXBzJ10gfCBXb3JrZmxvd01hbmlmZXN0Wyd3b3JrZmxvd3MnXSxcbiAgaWRzOiBNYXA8c3RyaW5nLCBJZExvY2F0aW9uPixcbiAgZ2V0SWQ6IChkYXRhOiB7IHN0ZXBJZDogc3RyaW5nIH0gfCB7IHdvcmtmbG93SWQ6IHN0cmluZyB9KSA9PiBzdHJpbmcsXG4gIGxhYmVsOiAnc3RlcCcgfCAnd29ya2Zsb3cnXG4pOiB2b2lkIHtcbiAgY29uc3QgZW50cmllc0J5RmlsZUxpc3QgPSBPYmplY3QuZW50cmllcyhlbnRyaWVzQnlGaWxlIHx8IHt9KSBhcyBBcnJheTxcbiAgICBbc3RyaW5nLCBSZWNvcmQ8c3RyaW5nLCB7IHN0ZXBJZDogc3RyaW5nIH0gfCB7IHdvcmtmbG93SWQ6IHN0cmluZyB9Pl1cbiAgPjtcbiAgZm9yIChjb25zdCBbZmlsZVBhdGgsIGVudHJpZXNdIG9mIGVudHJpZXNCeUZpbGVMaXN0KSB7XG4gICAgZm9yIChjb25zdCBbbmFtZSwgZGF0YV0gb2YgT2JqZWN0LmVudHJpZXMoZW50cmllcykpIHtcbiAgICAgIGNvbnN0IGlkID0gZ2V0SWQoZGF0YSk7XG4gICAgICBjb25zdCBleGlzdGluZyA9IGlkcy5nZXQoaWQpO1xuICAgICAgY29uc3QgY3VycmVudCA9IHsgZmlsZVBhdGgsIG5hbWUgfTtcbiAgICAgIGlmIChcbiAgICAgICAgZXhpc3RpbmcgJiZcbiAgICAgICAgKGV4aXN0aW5nLmZpbGVQYXRoICE9PSBjdXJyZW50LmZpbGVQYXRoIHx8XG4gICAgICAgICAgZXhpc3RpbmcubmFtZSAhPT0gY3VycmVudC5uYW1lKVxuICAgICAgKSB7XG4gICAgICAgIGNvbnN0IGlkTmFtZSA9IGxhYmVsID09PSAnc3RlcCcgPyAnd29ya2Zsb3cgc3RlcCBJRCcgOiAnd29ya2Zsb3cgSUQnO1xuICAgICAgICBjb25zdCBmdW5jdGlvbk5hbWUgPSBgJHtsYWJlbH0gZnVuY3Rpb25gO1xuICAgICAgICBjb25zdCBjYXBpdGFsaXplZExhYmVsID0gbGFiZWwgPT09ICdzdGVwJyA/ICdTdGVwJyA6ICdXb3JrZmxvdyc7XG4gICAgICAgIHRocm93IG5ldyBXb3JrZmxvd0J1aWxkRXJyb3IoXG4gICAgICAgICAgYER1cGxpY2F0ZSAke2lkTmFtZX0gXCIke2lkfVwiIGdlbmVyYXRlZCBmb3IgJHtmb3JtYXRJZExvY2F0aW9uKGV4aXN0aW5nKX0gYW5kICR7Zm9ybWF0SWRMb2NhdGlvbihjdXJyZW50KX0uYCxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBoaW50OlxuICAgICAgICAgICAgICBgJHtjYXBpdGFsaXplZExhYmVsfSBJRHMgbXVzdCBiZSB1bmlxdWUgYWNyb3NzIGEgYnVpbGQuIGAgK1xuICAgICAgICAgICAgICBgSWYgeW91IG93biBvbmUgb2YgdGhlIGNvbGxpZGluZyBmaWxlcywgcmVuYW1lIHRoZSAke2Z1bmN0aW9uTmFtZX0gb3IgZXhwb3J0IGAgK1xuICAgICAgICAgICAgICBgdGhlIHBhY2thZ2UgZmlsZSB0aHJvdWdoIGEgdW5pcXVlIHBhY2thZ2Ugc3VicGF0aC4gSWYgdGhlIGNvbGxpc2lvbiBpcyBpbiBhIGAgK1xuICAgICAgICAgICAgICBgdHJhbnNpdGl2ZSBkZXBlbmRlbmN5IHlvdSBkb24ndCBjb250cm9sLCBmaWxlIGFuIGlzc3VlIHdpdGggdGhlIHVwc3RyZWFtIGAgK1xuICAgICAgICAgICAgICBgcGFja2FnZSBvciBwaW4gdG8gYSBub24tY29sbGlkaW5nIHZlcnNpb24uYCxcbiAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBpZHMuc2V0KGlkLCBjdXJyZW50KTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gbWVyZ2VXb3JrZmxvd01hbmlmZXN0KFxuICB0YXJnZXQ6IFdvcmtmbG93TWFuaWZlc3QsXG4gIGluY29taW5nOiBXb3JrZmxvd01hbmlmZXN0LFxuICBzdGVwSWRzOiBNYXA8c3RyaW5nLCBJZExvY2F0aW9uPixcbiAgd29ya2Zsb3dJZHM6IE1hcDxzdHJpbmcsIElkTG9jYXRpb24+XG4pOiB2b2lkIHtcbiAgYXNzZXJ0VW5pcXVlTWFuaWZlc3RJZHMoXG4gICAgaW5jb21pbmcuc3RlcHMsXG4gICAgc3RlcElkcyxcbiAgICAoZGF0YSkgPT4gKGRhdGEgYXMgeyBzdGVwSWQ6IHN0cmluZyB9KS5zdGVwSWQsXG4gICAgJ3N0ZXAnXG4gICk7XG4gIGFzc2VydFVuaXF1ZU1hbmlmZXN0SWRzKFxuICAgIGluY29taW5nLndvcmtmbG93cyxcbiAgICB3b3JrZmxvd0lkcyxcbiAgICAoZGF0YSkgPT4gKGRhdGEgYXMgeyB3b3JrZmxvd0lkOiBzdHJpbmcgfSkud29ya2Zsb3dJZCxcbiAgICAnd29ya2Zsb3cnXG4gICk7XG5cbiAgdGFyZ2V0LndvcmtmbG93cyA9IE9iamVjdC5hc3NpZ24odGFyZ2V0LndvcmtmbG93cyB8fCB7fSwgaW5jb21pbmcud29ya2Zsb3dzKTtcbiAgdGFyZ2V0LnN0ZXBzID0gT2JqZWN0LmFzc2lnbih0YXJnZXQuc3RlcHMgfHwge30sIGluY29taW5nLnN0ZXBzKTtcbiAgdGFyZ2V0LmNsYXNzZXMgPSBPYmplY3QuYXNzaWduKHRhcmdldC5jbGFzc2VzIHx8IHt9LCBpbmNvbWluZy5jbGFzc2VzKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVN3Y1BsdWdpbihvcHRpb25zOiBTd2NQbHVnaW5PcHRpb25zKTogUGx1Z2luIHtcbiAgcmV0dXJuIHtcbiAgICBuYW1lOiAnc3djLXdvcmtmbG93LXBsdWdpbicsXG4gICAgc2V0dXAoYnVpbGQpIHtcbiAgICAgIGxldCBzdGVwSWRzRm9yQ3VycmVudEJ1aWxkID0gbmV3IE1hcDxzdHJpbmcsIElkTG9jYXRpb24+KCk7XG4gICAgICBsZXQgd29ya2Zsb3dJZHNGb3JDdXJyZW50QnVpbGQgPSBuZXcgTWFwPHN0cmluZywgSWRMb2NhdGlvbj4oKTtcblxuICAgICAgYnVpbGQub25TdGFydCgoKSA9PiB7XG4gICAgICAgIHN0ZXBJZHNGb3JDdXJyZW50QnVpbGQgPSBuZXcgTWFwKCk7XG4gICAgICAgIHdvcmtmbG93SWRzRm9yQ3VycmVudEJ1aWxkID0gbmV3IE1hcCgpO1xuICAgICAgICBpZiAob3B0aW9ucy53b3JrZmxvd01hbmlmZXN0KSB7XG4gICAgICAgICAgZGVsZXRlIG9wdGlvbnMud29ya2Zsb3dNYW5pZmVzdC5zdGVwcztcbiAgICAgICAgICBkZWxldGUgb3B0aW9ucy53b3JrZmxvd01hbmlmZXN0LndvcmtmbG93cztcbiAgICAgICAgICBkZWxldGUgb3B0aW9ucy53b3JrZmxvd01hbmlmZXN0LmNsYXNzZXM7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICAvLyBldmVyeXRoaW5nIGlzIGV4dGVybmFsIHVubGVzcyBleHBsaWNpdGx5IGNvbmZpZ3VyZWRcbiAgICAgIC8vIHRvIGJlIGJ1bmRsZWRcbiAgICAgIGNvbnN0IGNqc1Jlc29sdmVyID0gcHJvbWlzaWZ5KFxuICAgICAgICBlbmhhbmNlZFJlc29sdmVPcmlnLmNyZWF0ZShOT0RFX1JFU09MVkVfT1BUSU9OUylcbiAgICAgICk7XG4gICAgICBjb25zdCBlc21SZXNvbHZlciA9IHByb21pc2lmeShcbiAgICAgICAgZW5oYW5jZWRSZXNvbHZlT3JpZy5jcmVhdGUoTk9ERV9FU01fUkVTT0xWRV9PUFRJT05TKVxuICAgICAgKTtcblxuICAgICAgY29uc3QgZW5oYW5jZWRSZXNvbHZlID0gYXN5bmMgKGNvbnRleHQ6IHN0cmluZywgcGF0aDogc3RyaW5nKSA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgcmV0dXJuIGF3YWl0IGVzbVJlc29sdmVyKGNvbnRleHQsIHBhdGgpO1xuICAgICAgICB9IGNhdGNoIChfKSB7XG4gICAgICAgICAgcmV0dXJuIGNqc1Jlc29sdmVyKGNvbnRleHQsIHBhdGgpO1xuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICAvLyBQcmUtY29tcHV0ZSB0aGUgbm9ybWFsaXplZCBzaWRlLWVmZmVjdCBlbnRyaWVzIHNldCBmb3IgTygxKSBsb29rdXBzLlxuICAgICAgY29uc3Qgbm9ybWFsaXplZFNpZGVFZmZlY3RFbnRyaWVzID0gbmV3IFNldChcbiAgICAgICAgb3B0aW9ucy5zaWRlRWZmZWN0RW50cmllcz8ubWFwKChlKSA9PiBlLnJlcGxhY2UoL1xcXFwvZywgJy8nKSlcbiAgICAgICk7XG5cbiAgICAgIGJ1aWxkLm9uUmVzb2x2ZSh7IGZpbHRlcjogLy4qLyB9LCBhc3luYyAoYXJncykgPT4ge1xuICAgICAgICBpZiAoYXJncy5wbHVnaW5EYXRhPy5za2lwU3djUGx1Z2luKSByZXR1cm4gbnVsbDtcblxuICAgICAgICBpZiAoXG4gICAgICAgICAgIW9wdGlvbnMuZW50cmllc1RvQnVuZGxlICYmXG4gICAgICAgICAgbm9ybWFsaXplZFNpZGVFZmZlY3RFbnRyaWVzLnNpemUgPT09IDBcbiAgICAgICAgKSB7XG4gICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBXaGVuIG9ubHkgc2lkZUVmZmVjdEVudHJpZXMgaXMgc2V0IChubyBlbnRyaWVzVG9CdW5kbGUpLCB3ZSBvbmx5XG4gICAgICAgIC8vIG5lZWQgdG8gb3ZlcnJpZGUgc2lkZUVmZmVjdHMgZm9yIHRvcC1sZXZlbCBiYXJlIGltcG9ydHMg4oCUIHR5cGljYWxseVxuICAgICAgICAvLyBmcm9tIHRoZSB2aXJ0dWFsIGVudHJ5LiBTa2lwIHJlc29sdXRpb24gZm9yIHRyYW5zaXRpdmUgaW1wb3J0c1xuICAgICAgICAvLyAoZHluYW1pYyBpbXBvcnRzLCByZXF1aXJlcywgZXRjLikgdG8gYXZvaWQgdW5uZWNlc3Nhcnkgb3ZlcmhlYWQuXG4gICAgICAgIGlmICghb3B0aW9ucy5lbnRyaWVzVG9CdW5kbGUgJiYgYXJncy5raW5kICE9PSAnaW1wb3J0LXN0YXRlbWVudCcpIHtcbiAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3Qgc3BlY2lmaWVyID0gYXJncy5wYXRoO1xuICAgICAgICAgIGNvbnN0IHNwZWNpZmllcklzUGF0aCA9XG4gICAgICAgICAgICBzcGVjaWZpZXIuc3RhcnRzV2l0aCgnLicpIHx8IHNwZWNpZmllci5zdGFydHNXaXRoKCcvJyk7XG5cbiAgICAgICAgICBsZXQgcmVzb2x2ZWRQYXRoOiBzdHJpbmcgfCBmYWxzZSB8IHVuZGVmaW5lZDtcbiAgICAgICAgICAvLyBQYXRoLXN0eWxlIHNwZWNpZmllcnMgKC4vZm9vLCAuLi9mb28sIC9hYnMvcGF0aCkgZXh0ZXJuYWxpemUgYXNcbiAgICAgICAgICAvLyByZWxhdGl2ZSBwYXRocyBmcm9tIGBvdXRkaXJgLiBCYXJlIHNwZWNpZmllcnMgKG5wbSBwYWNrYWdlcylcbiAgICAgICAgICAvLyBleHRlcm5hbGl6ZSBhcy1pcyBzbyBOb2RlIGNhbiByZXNvbHZlIHRoZW0gYXQgcnVudGltZS5cbiAgICAgICAgICBjb25zdCBzaG91bGRNYWtlUmVsYXRpdmUgPSBzcGVjaWZpZXJJc1BhdGg7XG5cbiAgICAgICAgICBpZiAoc3BlY2lmaWVySXNQYXRoKSB7XG4gICAgICAgICAgICByZXNvbHZlZFBhdGggPSBhd2FpdCBlbmhhbmNlZFJlc29sdmUoYXJncy5yZXNvbHZlRGlyLCBzcGVjaWZpZXIpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBSZXNvbHZlIGZyb20gcHJvamVjdCByb290IHNvIG5lc3RlZCBkZXBzIGFyZW4ndCBleHRlcm5hbGl6ZWRcbiAgICAgICAgICAgIHJlc29sdmVkUGF0aCA9IGF3YWl0IGVuaGFuY2VkUmVzb2x2ZShcbiAgICAgICAgICAgICAgYnVpbGQuaW5pdGlhbE9wdGlvbnMuYWJzV29ya2luZ0RpciB8fCBwcm9jZXNzLmN3ZCgpLFxuICAgICAgICAgICAgICBzcGVjaWZpZXJcbiAgICAgICAgICAgICkuY2F0Y2goKCkgPT4gdW5kZWZpbmVkKTsgLy8gc3dhbGxvdyBzbyBlc2J1aWxkIGZhbGxiYWNrIGJlbG93IGNhbiB0cnlcblxuICAgICAgICAgICAgLy8gRmFsbCBiYWNrIHRvIGVzYnVpbGQgZm9yIGFsaWFzZXMvdHNjb25maWcgcGF0aHMuXG4gICAgICAgICAgICAvL1xuICAgICAgICAgICAgLy8gSWYgdGhlIHNwZWNpZmllciByZXNvbHZlcyB0byBhIHByb2plY3QtbG9jYWwgZmlsZSB2aWEgYW5cbiAgICAgICAgICAgIC8vIGFsaWFzL3BhdGggbWFwcGluZyAoZS5nLiB0c2NvbmZpZyBgcGF0aHNgLCBlc2J1aWxkIGBhbGlhc2AsXG4gICAgICAgICAgICAvLyBzZWxmLXJlZmVyZW5jaW5nIHBhY2thZ2UgbmFtZXMgbGlrZSBgQG15LXBrZy9saWIvZm9vYCksIHdlXG4gICAgICAgICAgICAvLyBidW5kbGUgaXQgaW5saW5lIHJhdGhlciB0aGFuIGV4dGVybmFsaXppbmcuXG4gICAgICAgICAgICAvL1xuICAgICAgICAgICAgLy8gRXh0ZXJuYWxpemluZyBzdWNoIGZpbGVzIGlzIHVuc2FmZTogd2UnZCBlbWl0IGEgcmVsYXRpdmVcbiAgICAgICAgICAgIC8vIGltcG9ydCB0byB0aGUgb3JpZ2luYWwgc291cmNlIG9uIGRpc2ssIGJ1dCB0aGF0IHNvdXJjZSBjYW5cbiAgICAgICAgICAgIC8vIGNvbnRhaW4gZnVydGhlciBhbGlhcyBpbXBvcnRzLiBBdCBydW50aW1lLCBOb2RlJ3MgRVNNIGxvYWRlclxuICAgICAgICAgICAgLy8gZG9lc24ndCBrbm93IGFib3V0IHRzY29uZmlnIHBhdGhzIG9yIGJ1aWxkLXRpbWUgYWxpYXNlcywgc29cbiAgICAgICAgICAgIC8vIHRob3NlIHRyYW5zaXRpdmUgaW1wb3J0cyB0aHJvdyBgRVJSX01PRFVMRV9OT1RfRk9VTkRgIC9cbiAgICAgICAgICAgIC8vIGBQYWNrYWdlIHN1YnBhdGggLi4uIGlzIG5vdCBkZWZpbmVkIGJ5IFwiZXhwb3J0c1wiYC5cbiAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAvLyBCdW5kbGluZyBpbmxpbmUgZW5zdXJlcyBhbGlhcy1iYXNlZCBpbXBvcnRzIGFyZSByZXNvbHZlZCBhdFxuICAgICAgICAgICAgLy8gYnVpbGQgdGltZSAod2hlcmUgdGhlIGFsaWFzIG1hcCBpcyBrbm93bikgYW5kIHRoZSBydW50aW1lXG4gICAgICAgICAgICAvLyBuZXZlciBzZWVzIGFuIHVucmVzb2x2YWJsZSBzcGVjaWZpZXIuXG4gICAgICAgICAgICBpZiAoIXJlc29sdmVkUGF0aCkge1xuICAgICAgICAgICAgICBjb25zdCBlc2J1aWxkUmVzdWx0ID0gYXdhaXQgYnVpbGQucmVzb2x2ZShzcGVjaWZpZXIsIHtcbiAgICAgICAgICAgICAgICByZXNvbHZlRGlyOiBhcmdzLnJlc29sdmVEaXIsXG4gICAgICAgICAgICAgICAga2luZDogYXJncy5raW5kLFxuICAgICAgICAgICAgICAgIHBsdWdpbkRhdGE6IHsgc2tpcFN3Y1BsdWdpbjogdHJ1ZSB9LFxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgY29uc3QgZGlkUmVzb2x2ZSA9XG4gICAgICAgICAgICAgICAgISFlc2J1aWxkUmVzdWx0LnBhdGggJiYgIWVzYnVpbGRSZXN1bHQuZXJyb3JzLmxlbmd0aDtcbiAgICAgICAgICAgICAgY29uc3QgaXNQcm9qZWN0TG9jYWxGaWxlID1cbiAgICAgICAgICAgICAgICBkaWRSZXNvbHZlICYmXG4gICAgICAgICAgICAgICAgIWVzYnVpbGRSZXN1bHQuZXh0ZXJuYWwgJiZcbiAgICAgICAgICAgICAgICAhZXNidWlsZFJlc3VsdC5wYXRoXG4gICAgICAgICAgICAgICAgICAucmVwbGFjZSgvXFxcXC9nLCAnLycpXG4gICAgICAgICAgICAgICAgICAuaW5jbHVkZXMoJy9ub2RlX21vZHVsZXMvJyk7XG4gICAgICAgICAgICAgIGlmIChpc1Byb2plY3RMb2NhbEZpbGUpIHtcbiAgICAgICAgICAgICAgICAvLyBMZXQgZXNidWlsZCBidW5kbGUgdGhpcyBhbGlhc2VkIHByb2plY3QtbG9jYWwgZmlsZSBpbmxpbmVcbiAgICAgICAgICAgICAgICAvLyAocmV0dXJuIG51bGwgdG8gZGVmZXIgdG8gZXNidWlsZCdzIG5vcm1hbCBwaXBlbGluZSkuIFRoZVxuICAgICAgICAgICAgICAgIC8vIFNXQyBgb25Mb2FkYCBoYW5kbGVyIHdpbGwgc3RpbGwgcHJvY2VzcyBpdC5cbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgICAgICAgICBvcHRpb25zLmVudHJpZXNUb0J1bmRsZSAmJlxuICAgICAgICAgICAgICAgIGVzYnVpbGRSZXN1bHQucGF0aD8uZW5kc1dpdGgoJy5ub2RlJylcbiAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgIGV4dGVybmFsOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgcGF0aDogc3BlY2lmaWVyLFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoIXJlc29sdmVkUGF0aCkgcmV0dXJuIG51bGw7XG5cbiAgICAgICAgICAvLyBOb3JtYWxpemUgdG8gZm9yd2FyZCBzbGFzaGVzIGZvciBjcm9zcy1wbGF0Zm9ybSBjb21wYXJpc29uXG4gICAgICAgICAgY29uc3Qgbm9ybWFsaXplZFJlc29sdmVkUGF0aCA9IG5vcm1hbGl6ZVBhdGgocmVzb2x2ZWRQYXRoKTtcbiAgICAgICAgICBjb25zdCB3b3JraW5nRGlyID1cbiAgICAgICAgICAgIGJ1aWxkLmluaXRpYWxPcHRpb25zLmFic1dvcmtpbmdEaXIgfHwgcHJvY2Vzcy5jd2QoKTtcbiAgICAgICAgICBjb25zdCBwcm9qZWN0Um9vdCA9IG9wdGlvbnMucHJvamVjdFJvb3QgfHwgd29ya2luZ0RpcjtcbiAgICAgICAgICBjb25zdCBtb2R1bGVTcGVjaWZpZXJSb290ID1cbiAgICAgICAgICAgIG9wdGlvbnMubW9kdWxlU3BlY2lmaWVyUm9vdCB8fCBwcm9qZWN0Um9vdDtcblxuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIG9wdGlvbnMuZW50cmllc1RvQnVuZGxlICYmXG4gICAgICAgICAgICBub3JtYWxpemVkUmVzb2x2ZWRQYXRoLmVuZHNXaXRoKCcubm9kZScpXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICBleHRlcm5hbDogdHJ1ZSxcbiAgICAgICAgICAgICAgcGF0aDogc3BlY2lmaWVyLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBDaGVjayBpZiB0aGlzIG1vZHVsZSBpcyBhIGRpc2NvdmVyZWQgZW50cnkgd2hvc2UgU1dDLXRyYW5zZm9ybWVkXG4gICAgICAgICAgLy8gY29kZSBjb250YWlucyBzaWRlIGVmZmVjdHMgKHdvcmtmbG93L3N0ZXAvY2xhc3MgcmVnaXN0cmF0aW9uKS5cbiAgICAgICAgICAvLyBPdmVycmlkZSB0aGUgcGFja2FnZS5qc29uIFwic2lkZUVmZmVjdHNcIjogZmFsc2Ugc28gZXNidWlsZCBkb2VzIG5vdFxuICAgICAgICAgIC8vIGRyb3AgYmFyZSBpbXBvcnRzIG9mIHRoZXNlIG1vZHVsZXMuXG4gICAgICAgICAgY29uc3QgaGFzU2lkZUVmZmVjdHMgPSBub3JtYWxpemVkU2lkZUVmZmVjdEVudHJpZXMuaGFzKFxuICAgICAgICAgICAgbm9ybWFsaXplZFJlc29sdmVkUGF0aFxuICAgICAgICAgICk7XG5cbiAgICAgICAgICBpZiAob3B0aW9ucy5lbnRyaWVzVG9CdW5kbGUpIHtcbiAgICAgICAgICAgIGxldCBzaG91bGRCdW5kbGUgPSBmYWxzZTtcbiAgICAgICAgICAgIGZvciAoY29uc3QgZW50cnlUb0J1bmRsZSBvZiBvcHRpb25zLmVudHJpZXNUb0J1bmRsZSkge1xuICAgICAgICAgICAgICBjb25zdCBub3JtYWxpemVkRW50cnkgPSBlbnRyeVRvQnVuZGxlLnJlcGxhY2UoL1xcXFwvZywgJy8nKTtcblxuICAgICAgICAgICAgICBpZiAobm9ybWFsaXplZFJlc29sdmVkUGF0aCA9PT0gbm9ybWFsaXplZEVudHJ5KSB7XG4gICAgICAgICAgICAgICAgc2hvdWxkQnVuZGxlID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIC8vIGlmIHRoZSBjdXJyZW50IGVudHJ5IGltcG9ydHMgYSBjaGlsZCB0aGF0IG5lZWRzXG4gICAgICAgICAgICAgIC8vIHRvIGJlIGJ1bmRsZWQgdGhlbiBpdCBuZWVkcyB0byBhbHNvIGJlIGJ1bmRsZWQgc29cbiAgICAgICAgICAgICAgLy8gdGhhdCB0aGUgY2hpbGQgY2FuIGhhdmUgb3VyIHRyYW5zZm9ybSBhcHBsaWVkXG4gICAgICAgICAgICAgIGlmIChwYXJlbnRIYXNDaGlsZChub3JtYWxpemVkUmVzb2x2ZWRQYXRoLCBub3JtYWxpemVkRW50cnkpKSB7XG4gICAgICAgICAgICAgICAgc2hvdWxkQnVuZGxlID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIC8vIEJ1bmRsZSBwcm9qZWN0LWxvY2FsIHNvdXJjZSBmaWxlcyB0aGF0IGFyZSBpbXBvcnRlZCBieSBhXG4gICAgICAgICAgICAgIC8vIHN0ZXAvc2VyZGUgZW50cnkgc28gZGlyZWN0IHJ1bnRpbWUgbG9hZGVycyBkbyBub3Qgc2VlIHJhdyBUU1xuICAgICAgICAgICAgICAvLyBleHRlbnNpb25sZXNzIGltcG9ydHMuIEtlZXAgcGFja2FnZSBkZXBlbmRlbmNpZXMgZXh0ZXJuYWxcbiAgICAgICAgICAgICAgLy8gdW5sZXNzIHRoZXkgYXJlIHRoZW1zZWx2ZXMgaW4gZW50cmllc1RvQnVuZGxlIG9yIGFyZSBwYXJlbnRzXG4gICAgICAgICAgICAgIC8vIG9mIGEgZGlzY292ZXJlZCB3b3JrZmxvdy9zdGVwL3NlcmRlIGZpbGUgdmlhIHRoZSBjaGVjayBhYm92ZS5cbiAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgIG9wdGlvbnMuYnVuZGxlVHJhbnNpdGl2ZUxvY2FsU3RlcERlcGVuZGVuY2llcyAmJlxuICAgICAgICAgICAgICAgIGlzUHJvamVjdExvY2FsRmlsZShcbiAgICAgICAgICAgICAgICAgIG5vcm1hbGl6ZWRSZXNvbHZlZFBhdGgsXG4gICAgICAgICAgICAgICAgICBtb2R1bGVTcGVjaWZpZXJSb290XG4gICAgICAgICAgICAgICAgKSAmJlxuICAgICAgICAgICAgICAgIHBhcmVudEhhc0NoaWxkKG5vcm1hbGl6ZWRFbnRyeSwgbm9ybWFsaXplZFJlc29sdmVkUGF0aClcbiAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgc2hvdWxkQnVuZGxlID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoc2hvdWxkQnVuZGxlKSB7XG4gICAgICAgICAgICAgIC8vIExldCBlc2J1aWxkIGJ1bmRsZSB0aGlzIGVudHJ5LCBidXQgb3ZlcnJpZGUgc2lkZUVmZmVjdHMgaWYgbmVlZGVkLlxuICAgICAgICAgICAgICAvLyBXZSBtdXN0IHJldHVybiB0aGUgcmVzb2x2ZWQgYHBhdGhgIGFsb25nc2lkZSBgc2lkZUVmZmVjdHNgIGJlY2F1c2VcbiAgICAgICAgICAgICAgLy8gcmV0dXJuaW5nIG9ubHkgYHsgc2lkZUVmZmVjdHM6IHRydWUgfWAgd2l0aG91dCBhIHBhdGggY2F1c2VzIGVzYnVpbGRcbiAgICAgICAgICAgICAgLy8gdG8gZmFsbCB0aHJvdWdoIHRvIGl0cyBvd24gcmVzb2x2ZXIsIHdoaWNoIHJlLXJlYWRzIHRoZSBwYWNrYWdlLmpzb25cbiAgICAgICAgICAgICAgLy8gYW5kIGFwcGxpZXMgYFwic2lkZUVmZmVjdHNcIjogZmFsc2VgIGZyb20gdGhlcmUuXG4gICAgICAgICAgICAgIHJldHVybiBoYXNTaWRlRWZmZWN0c1xuICAgICAgICAgICAgICAgID8geyBwYXRoOiByZXNvbHZlZFBhdGgsIHNpZGVFZmZlY3RzOiB0cnVlIH1cbiAgICAgICAgICAgICAgICA6IG51bGw7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGxldCBleHRlcm5hbFBhdGg6IHN0cmluZztcbiAgICAgICAgICAgIGlmIChzaG91bGRNYWtlUmVsYXRpdmUpIHtcbiAgICAgICAgICAgICAgLy8gV2hlbiB0aGUgcmVzb2x2ZWQgZmlsZSBsaXZlcyBpbnNpZGUgbm9kZV9tb2R1bGVzLCBsZXRcbiAgICAgICAgICAgICAgLy8gZXNidWlsZCBidW5kbGUgaXQgcmF0aGVyIHRoYW4gZXh0ZXJuYWxpemluZyB3aXRoIGEgZGVlcGx5XG4gICAgICAgICAgICAgIC8vIG5lc3RlZCByZWxhdGl2ZSBwYXRoLiBEb3duc3RyZWFtIGJ1bmRsZXJzIChSb2xsdXAvVml0ZSlcbiAgICAgICAgICAgICAgLy8gY2FuJ3QgcmV3cml0ZSBvcGFxdWUgYF9fcmVxdWlyZSgpYCBjYWxscyBpbiBDSlMgc2hpbXMsIHNvXG4gICAgICAgICAgICAgIC8vIHJlbGF0aXZlIHBhdGhzIGNvbXB1dGVkIGZvciBgb3V0ZGlyYCBicmVhayBvbmNlIHRoZSBvdXRwdXRcbiAgICAgICAgICAgICAgLy8gaXMgcmVidW5kbGVkIHRvIGEgZGlmZmVyZW50IGRpcmVjdG9yeS5cbiAgICAgICAgICAgICAgaWYgKG5vcm1hbGl6ZWRSZXNvbHZlZFBhdGguaW5jbHVkZXMoJy9ub2RlX21vZHVsZXMvJykpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsgLy8gbGV0IGVzYnVpbGQgYnVuZGxlIGl0XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBleHRlcm5hbFBhdGggPSByZWxhdGl2ZShcbiAgICAgICAgICAgICAgICBvcHRpb25zLm91dGRpciB8fCBwcm9jZXNzLmN3ZCgpLFxuICAgICAgICAgICAgICAgIHJlc29sdmVkUGF0aFxuICAgICAgICAgICAgICApLnJlcGxhY2UoL1xcXFwvZywgJy8nKTtcblxuICAgICAgICAgICAgICBpZiAob3B0aW9ucy5yZXdyaXRlVHNFeHRlbnNpb25zKSB7XG4gICAgICAgICAgICAgICAgLy8gUmV3cml0ZSBUeXBlU2NyaXB0IGV4dGVuc2lvbnMgdG8gdGhlaXIgSlMgZXF1aXZhbGVudHMgc28gdGhlXG4gICAgICAgICAgICAgICAgLy8gZXh0ZXJuYWxpemVkIGltcG9ydCBpcyBsb2FkYWJsZSBieSBOb2RlJ3MgbmF0aXZlIEVTTSBsb2FkZXIuXG4gICAgICAgICAgICAgICAgZXh0ZXJuYWxQYXRoID0gZXh0ZXJuYWxQYXRoXG4gICAgICAgICAgICAgICAgICAucmVwbGFjZSgvXFwudHN4PyQvLCAnLmpzJylcbiAgICAgICAgICAgICAgICAgIC5yZXBsYWNlKC9cXC5tdHMkLywgJy5tanMnKVxuICAgICAgICAgICAgICAgICAgLnJlcGxhY2UoL1xcLmN0cyQvLCAnLmNqcycpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBleHRlcm5hbFBhdGggPSBzcGVjaWZpZXI7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgIGV4dGVybmFsOiB0cnVlLFxuICAgICAgICAgICAgICBwYXRoOiBleHRlcm5hbFBhdGgsXG4gICAgICAgICAgICAgIHNpZGVFZmZlY3RzOiBoYXNTaWRlRWZmZWN0cyB8fCB1bmRlZmluZWQsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIE5vIGVudHJpZXNUb0J1bmRsZSDigJQgb25seSBvdmVycmlkZSBzaWRlRWZmZWN0cyB3aGVuIG5lZWRlZC5cbiAgICAgICAgICAvLyBXZSBtdXN0IHJldHVybiB0aGUgcmVzb2x2ZWQgYHBhdGhgIGFsb25nc2lkZSBgc2lkZUVmZmVjdHNgIGJlY2F1c2VcbiAgICAgICAgICAvLyByZXR1cm5pbmcgb25seSBgeyBzaWRlRWZmZWN0czogdHJ1ZSB9YCB3aXRob3V0IGEgcGF0aCBjYXVzZXMgZXNidWlsZFxuICAgICAgICAgIC8vIHRvIGZhbGwgdGhyb3VnaCB0byBpdHMgb3duIHJlc29sdmVyLCB3aGljaCByZS1yZWFkcyB0aGUgcGFja2FnZS5qc29uXG4gICAgICAgICAgLy8gYW5kIGFwcGxpZXMgYFwic2lkZUVmZmVjdHNcIjogZmFsc2VgIGZyb20gdGhlcmUuXG4gICAgICAgICAgcmV0dXJuIGhhc1NpZGVFZmZlY3RzXG4gICAgICAgICAgICA/IHsgcGF0aDogcmVzb2x2ZWRQYXRoLCBzaWRlRWZmZWN0czogdHJ1ZSB9XG4gICAgICAgICAgICA6IG51bGw7XG4gICAgICAgIH0gY2F0Y2ggKF8pIHt9XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfSk7XG5cbiAgICAgIC8vIEhhbmRsZSBUeXBlU2NyaXB0IGFuZCBKYXZhU2NyaXB0IGZpbGVzXG4gICAgICBidWlsZC5vbkxvYWQoeyBmaWx0ZXI6IGpzVHNSZWdleCB9LCBhc3luYyAoYXJncykgPT4ge1xuICAgICAgICAvLyBEZXRlcm1pbmUgaWYgdGhpcyBpcyBhIFR5cGVTY3JpcHQgZmlsZVxuICAgICAgICB0cnkge1xuICAgICAgICAgIC8vIERldGVybWluZSB0aGUgbG9hZGVyIGJhc2VkIG9uIHRoZSBvdXRwdXRcbiAgICAgICAgICBsZXQgbG9hZGVyOiAnanMnIHwgJ2pzeCcgfCAndHN4JyA9ICdqcyc7XG4gICAgICAgICAgaWYgKGFyZ3MucGF0aC5lbmRzV2l0aCgnLmpzeCcpKSB7XG4gICAgICAgICAgICBsb2FkZXIgPSAnanN4JztcbiAgICAgICAgICB9IGVsc2UgaWYgKGFyZ3MucGF0aC5lbmRzV2l0aCgnLnRzeCcpKSB7XG4gICAgICAgICAgICBsb2FkZXIgPSAndHN4JztcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc3Qgc291cmNlID0gYXdhaXQgcmVhZEZpbGUoYXJncy5wYXRoLCAndXRmOCcpO1xuICAgICAgICAgIGNvbnN0IG5vcm1hbGl6ZWRTb3VyY2UgPSBzb3VyY2VcbiAgICAgICAgICAgIC5yZXBsYWNlKC9yZXF1aXJlXFwoXFxzKihbJ1wiXSlzZXJ2ZXItb25seVxcMVxccypcXCkvZywgJ3ZvaWQgMCcpXG4gICAgICAgICAgICAucmVwbGFjZSgvcmVxdWlyZVxcKFxccyooWydcIl0pY2xpZW50LW9ubHlcXDFcXHMqXFwpL2csICd2b2lkIDAnKTtcblxuICAgICAgICAgIC8vIENhbGN1bGF0ZSByZWxhdGl2ZSBwYXRoIGZvciBTV0MgcGx1Z2luXG4gICAgICAgICAgLy8gVGhlIGZpbGVuYW1lIHBhcmFtZXRlciBpcyB1c2VkIHRvIGdlbmVyYXRlIHdvcmtmbG93SWQvc3RlcElkLCBzbyBpdCBtdXN0IGJlIHJlbGF0aXZlXG4gICAgICAgICAgY29uc3Qgd29ya2luZ0RpciA9XG4gICAgICAgICAgICBidWlsZC5pbml0aWFsT3B0aW9ucy5hYnNXb3JraW5nRGlyIHx8IHByb2Nlc3MuY3dkKCk7XG4gICAgICAgICAgY29uc3QgcHJvamVjdFJvb3QgPSBvcHRpb25zLnByb2plY3RSb290IHx8IHdvcmtpbmdEaXI7XG4gICAgICAgICAgY29uc3QgbW9kdWxlU3BlY2lmaWVyUm9vdCA9XG4gICAgICAgICAgICBvcHRpb25zLm1vZHVsZVNwZWNpZmllclJvb3QgfHwgcHJvamVjdFJvb3Q7XG4gICAgICAgICAgLy8gTm9ybWFsaXplIHBhdGhzOiBjb252ZXJ0IGJhY2tzbGFzaGVzIHRvIGZvcndhcmQgc2xhc2hlcyBhbmQgcmVtb3ZlIHRyYWlsaW5nIHNsYXNoZXNcbiAgICAgICAgICBjb25zdCBub3JtYWxpemVkV29ya2luZ0RpciA9IHdvcmtpbmdEaXJcbiAgICAgICAgICAgIC5yZXBsYWNlKC9cXFxcL2csICcvJylcbiAgICAgICAgICAgIC5yZXBsYWNlKC9cXC8kLywgJycpO1xuICAgICAgICAgIGNvbnN0IG5vcm1hbGl6ZWRQYXRoID0gYXJncy5wYXRoLnJlcGxhY2UoL1xcXFwvZywgJy8nKTtcblxuICAgICAgICAgIC8vIFdpbmRvd3MgZml4OiBBbHdheXMgZG8gY2FzZS1pbnNlbnNpdGl2ZSBwYXRoIGNvbXBhcmlzb24gYXMgdGhlIFBSSU1BUlkgbG9naWNcbiAgICAgICAgICAvLyB0byB3b3JrIGFyb3VuZCBub2RlOnBhdGgucmVsYXRpdmUoKSBub3QgcmVjb2duaXppbmcgcGF0aHMgd2l0aCBkaWZmZXJlbnQgZHJpdmVcbiAgICAgICAgICAvLyBsZXR0ZXIgY2FzaW5nIChlLmcuLCBEOiB2cyBkOikgYXMgYmVpbmcgaW4gdGhlIHNhbWUgdHJlZVxuICAgICAgICAgIGNvbnN0IGxvd2VyV2QgPSBub3JtYWxpemVkV29ya2luZ0Rpci50b0xvd2VyQ2FzZSgpO1xuICAgICAgICAgIGNvbnN0IGxvd2VyUGF0aCA9IG5vcm1hbGl6ZWRQYXRoLnRvTG93ZXJDYXNlKCk7XG5cbiAgICAgICAgICBsZXQgcmVsYXRpdmVGaWxlcGF0aDogc3RyaW5nO1xuICAgICAgICAgIGlmIChsb3dlclBhdGguc3RhcnRzV2l0aChgJHtsb3dlcldkfS9gKSkge1xuICAgICAgICAgICAgLy8gRmlsZSBpcyB1bmRlciB3b3JraW5nIGRpcmVjdG9yeSAtIG1hbnVhbGx5IGNhbGN1bGF0ZSByZWxhdGl2ZSBwYXRoXG4gICAgICAgICAgICAvLyBUaGlzIGVuc3VyZXMgd2UgZ2V0IGEgcmVsYXRpdmUgcGF0aCBldmVuIHdpdGggZHJpdmUgbGV0dGVyIGNhc2luZyBpc3N1ZXNcbiAgICAgICAgICAgIHJlbGF0aXZlRmlsZXBhdGggPSBub3JtYWxpemVkUGF0aC5zdWJzdHJpbmcoXG4gICAgICAgICAgICAgIG5vcm1hbGl6ZWRXb3JraW5nRGlyLmxlbmd0aCArIDFcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSBlbHNlIGlmIChsb3dlclBhdGggPT09IGxvd2VyV2QpIHtcbiAgICAgICAgICAgIC8vIEZpbGUgSVMgdGhlIHdvcmtpbmcgZGlyZWN0b3J5XG4gICAgICAgICAgICByZWxhdGl2ZUZpbGVwYXRoID0gJy4nO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBGaWxlIGlzIG91dHNpZGUgd29ya2luZyBkaXJlY3RvcnkgLSB1c2UgcmVsYXRpdmUoKSBhbmQgc3RyaXAgLi4vIHByZWZpeGVzIGlmIG5lZWRlZFxuICAgICAgICAgICAgcmVsYXRpdmVGaWxlcGF0aCA9IHJlbGF0aXZlKFxuICAgICAgICAgICAgICBub3JtYWxpemVkV29ya2luZ0RpcixcbiAgICAgICAgICAgICAgbm9ybWFsaXplZFBhdGhcbiAgICAgICAgICAgICkucmVwbGFjZSgvXFxcXC9nLCAnLycpO1xuXG4gICAgICAgICAgICAvLyBIYW5kbGUgZmlsZXMgZGlzY292ZXJlZCBvdXRzaWRlIHRoZSB3b3JraW5nIGRpcmVjdG9yeVxuICAgICAgICAgICAgLy8gVGhlc2UgY29tZSBiYWNrIGFzIC4uL3BhdGgvdG8vZmlsZSwgYnV0IHdlIHdhbnQganVzdCBwYXRoL3RvL2ZpbGVcbiAgICAgICAgICAgIGlmIChyZWxhdGl2ZUZpbGVwYXRoLnN0YXJ0c1dpdGgoJy4uLycpKSB7XG4gICAgICAgICAgICAgIGNvbnN0IGFsaWFzZWRSZWxhdGl2ZVBhdGggPVxuICAgICAgICAgICAgICAgIGF3YWl0IHJlc29sdmVXb3JrZmxvd0FsaWFzUmVsYXRpdmVQYXRoKGFyZ3MucGF0aCwgd29ya2luZ0Rpcik7XG4gICAgICAgICAgICAgIGlmIChhbGlhc2VkUmVsYXRpdmVQYXRoKSB7XG4gICAgICAgICAgICAgICAgcmVsYXRpdmVGaWxlcGF0aCA9IGFsaWFzZWRSZWxhdGl2ZVBhdGg7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmVsYXRpdmVGaWxlcGF0aCA9IHJlbGF0aXZlRmlsZXBhdGhcbiAgICAgICAgICAgICAgICAgIC5zcGxpdCgnLycpXG4gICAgICAgICAgICAgICAgICAuZmlsdGVyKChwYXJ0KSA9PiBwYXJ0ICE9PSAnLi4nKVxuICAgICAgICAgICAgICAgICAgLmpvaW4oJy8nKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIEZpbmFsIHNhZmV0eSBjaGVjayAtIGVuc3VyZSB3ZSBuZXZlciBwYXNzIGFuIGFic29sdXRlIHBhdGggdG8gU1dDXG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgcmVsYXRpdmVGaWxlcGF0aC5pbmNsdWRlcygnOicpIHx8XG4gICAgICAgICAgICByZWxhdGl2ZUZpbGVwYXRoLnN0YXJ0c1dpdGgoJy8nKVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgLy8gVGhpcyBzaG91bGQgbmV2ZXIgaGFwcGVuLCBidXQgaWYgaXQgZG9lcywgdXNlIGp1c3QgdGhlIGZpbGVuYW1lIGFzIGxhc3QgcmVzb3J0XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKFxuICAgICAgICAgICAgICBgW0VSUk9SXSByZWxhdGl2ZUZpbGVwYXRoIGlzIHN0aWxsIGFic29sdXRlOiAke3JlbGF0aXZlRmlsZXBhdGh9YFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHJlbGF0aXZlRmlsZXBhdGggPSBub3JtYWxpemVkUGF0aC5zcGxpdCgnLycpLnBvcCgpIHx8ICd1bmtub3duLnRzJztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCB7IGNvZGU6IHRyYW5zZm9ybWVkQ29kZSwgd29ya2Zsb3dNYW5pZmVzdCB9ID1cbiAgICAgICAgICAgIGF3YWl0IGFwcGx5U3djVHJhbnNmb3JtKFxuICAgICAgICAgICAgICByZWxhdGl2ZUZpbGVwYXRoLFxuICAgICAgICAgICAgICBub3JtYWxpemVkU291cmNlLFxuICAgICAgICAgICAgICBvcHRpb25zLm1vZGUsXG4gICAgICAgICAgICAgIGFyZ3MucGF0aCwgLy8gUGFzcyBhYnNvbHV0ZSBwYXRoIGZvciBtb2R1bGUgc3BlY2lmaWVyIHJlc29sdXRpb25cbiAgICAgICAgICAgICAgcHJvamVjdFJvb3QsXG4gICAgICAgICAgICAgIG1vZHVsZVNwZWNpZmllclJvb3RcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICBpZiAoIW9wdGlvbnMud29ya2Zsb3dNYW5pZmVzdCkge1xuICAgICAgICAgICAgb3B0aW9ucy53b3JrZmxvd01hbmlmZXN0ID0ge307XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgbWVyZ2VXb3JrZmxvd01hbmlmZXN0KFxuICAgICAgICAgICAgb3B0aW9ucy53b3JrZmxvd01hbmlmZXN0LFxuICAgICAgICAgICAgd29ya2Zsb3dNYW5pZmVzdCxcbiAgICAgICAgICAgIHN0ZXBJZHNGb3JDdXJyZW50QnVpbGQsXG4gICAgICAgICAgICB3b3JrZmxvd0lkc0ZvckN1cnJlbnRCdWlsZFxuICAgICAgICAgICk7XG5cbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY29udGVudHM6IHRyYW5zZm9ybWVkQ29kZSxcbiAgICAgICAgICAgIGxvYWRlcixcbiAgICAgICAgICB9O1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIGNvbnN0IGVycm9yTWVzc2FnZSA9XG4gICAgICAgICAgICBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvcik7XG4gICAgICAgICAgY29uc29sZS5lcnJvcihcbiAgICAgICAgICAgIGDinYwgU1dDIHRyYW5zZm9ybSBlcnJvciBpbiAke2FyZ3MucGF0aH06YCxcbiAgICAgICAgICAgIGVycm9yTWVzc2FnZVxuICAgICAgICAgICk7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGVycm9yczogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdGV4dDogYFNXQyB0cmFuc2Zvcm0gZmFpbGVkOiAke2Vycm9yTWVzc2FnZX1gLFxuICAgICAgICAgICAgICAgIGxvY2F0aW9uOiB7IGZpbGU6IGFyZ3MucGF0aCwgbGluZTogMCwgY29sdW1uOiAwIH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0sXG4gIH07XG59XG5cbmZ1bmN0aW9uIGlzUHJvamVjdExvY2FsRmlsZShmaWxlUGF0aDogc3RyaW5nLCBwcm9qZWN0Um9vdDogc3RyaW5nKTogYm9vbGVhbiB7XG4gIGlmIChub3JtYWxpemVQYXRoKGZpbGVQYXRoKS5pbmNsdWRlcygnL25vZGVfbW9kdWxlcy8nKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiAoXG4gICAgcmVzb2x2ZU1vZHVsZVNwZWNpZmllcihmaWxlUGF0aCwgcHJvamVjdFJvb3QpLm1vZHVsZVNwZWNpZmllciA9PT0gdW5kZWZpbmVkXG4gICk7XG59XG4iXX0=