@brainfish-ai/devdoc 0.1.32 → 0.1.33

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.
@@ -1,13 +1,47 @@
1
1
  ---
2
2
  name: sync-docs
3
- description: Analyze existing documentation against codebase and identify/fix outdated content
3
+ description: Analyze existing documentation against codebase and identify/fix outdated content. Reads docType from docs.json config.
4
4
  ---
5
5
 
6
6
  ## Instructions
7
7
 
8
8
  When syncing documentation with the codebase:
9
9
 
10
- ### Step 1: Build Documentation Inventory
10
+ ### Step 0: Locate Source Code
11
+
12
+ First, determine where the source code is relative to current directory:
13
+ - If `docs.json` exists here → you're in docs folder, source code is in `../`
14
+ - If `package.json` and `src/` exist here → you're at repo root
15
+ - Check both current directory AND parent directory for source files
16
+
17
+ ### Step 1: Get Documentation Type from Config
18
+
19
+ **Read `docs.json` and check for `docType` field:**
20
+
21
+ ```json
22
+ {
23
+ "docType": "api" // "internal" | "api" | "product"
24
+ }
25
+ ```
26
+
27
+ **If `docType` is set:** Use that value automatically.
28
+
29
+ **If `docType` is NOT set, detect from structure:**
30
+ - Has `architecture/`, `development/` → "internal"
31
+ - Has `api-reference/`, `sdks/` → "api"
32
+ - Has `features/`, `tutorials/` → "product"
33
+
34
+ **If still unclear, ask:**
35
+ "What type of documentation is this?
36
+ 1. internal - for your team
37
+ 2. api - for developers using your product
38
+ 3. product - for end users"
39
+
40
+ **After user answers, save to docs.json:**
41
+ Add `"docType": "{choice}"` to docs.json so it's remembered.
42
+ Tell user: "Saved docType to docs.json - you won't be asked again."
43
+
44
+ ### Step 2: Build Documentation Inventory
11
45
 
12
46
  Scan all MDX files and extract:
13
47
  - Documented functions, classes, components
@@ -7,60 +7,114 @@ globs: ["**/README.md", "**/package.json", "**/src/**", "**/lib/**"]
7
7
 
8
8
  When asked to bootstrap or generate initial documentation:
9
9
 
10
- ## Analysis Checklist
10
+ ## Step 1: Check for docType Configuration
11
+
12
+ **Read `docs.json` and check for `docType` field:**
13
+
14
+ ```json
15
+ {
16
+ "name": "Project Name",
17
+ "docType": "api" // "internal" | "api" | "product"
18
+ }
19
+ ```
20
+
21
+ **If `docType` is set:** Use that value automatically. Tell user: "Using docType: {type} from docs.json"
22
+
23
+ **If `docType` is NOT set, ask:**
24
+
25
+ "What type of documentation are you creating?
26
+ 1. **internal** - For your team: setup guides, architecture
27
+ 2. **api** - For developers using your product: API reference, SDKs
28
+ 3. **product** - For end users: feature guides, tutorials"
29
+
30
+ **After user answers, immediately save to docs.json:**
31
+ Add `"docType": "{choice}"` to docs.json so it's saved for future use.
32
+ Tell user: "Saved docType: {type} to docs.json - you won't be asked again."
33
+
34
+ ## Step 2: Locate Source Code
35
+
36
+ - If `docs.json` exists → you're in docs folder, source is in `../`
37
+ - If `package.json` + `src/` exist → you're at repo root
38
+ - Otherwise, ask user for source code path
39
+
40
+ ## Step 3: Analysis Checklist
11
41
 
12
42
  1. Read README.md for project overview
13
- 2. Check package.json for:
14
- - Project name and description
15
- - Dependencies (to understand tech stack)
16
- - Scripts (for CLI documentation)
43
+ 2. Check package.json for name, description, dependencies, scripts
17
44
  3. Scan source directory structure
18
45
  4. Identify API endpoints or exported functions
19
- 5. Look for existing OpenAPI/GraphQL specs
46
+ 5. Look for OpenAPI/GraphQL specs
20
47
  6. Check for example files or tests
21
48
 
22
- ## Documentation Generation Order
49
+ ## Step 4: Generate Based on docType
23
50
 
24
- 1. index.mdx (homepage) - from README
25
- 2. quickstart.mdx - installation + basic usage
26
- 3. API reference - from specs or code analysis
27
- 4. Feature guides - from major modules
28
-
29
- ## Always Include
30
-
31
- - Real code examples from the codebase
32
- - Accurate installation commands
33
- - Links between related pages
34
- - TODO comments for sections needing review
35
-
36
- ## File Structure to Generate
51
+ ### docType: "internal"
52
+ ```
53
+ docs/
54
+ ├── docs.json (with "docType": "internal")
55
+ ├── index.mdx # Project overview
56
+ ├── getting-started/
57
+ │ ├── setup.mdx # Dev environment setup
58
+ │ ├── prerequisites.mdx
59
+ │ └── first-contribution.mdx
60
+ ├── architecture/
61
+ │ ├── overview.mdx # System design
62
+ │ └── folder-structure.mdx
63
+ ├── development/
64
+ │ ├── workflow.mdx # Git workflow, PR process
65
+ │ ├── testing.mdx
66
+ │ └── deployment.mdx
67
+ └── contributing.mdx
68
+ ```
37
69
 
70
+ ### docType: "api"
38
71
  ```
39
72
  docs/
40
- ├── docs.json # Navigation config
41
- ├── index.mdx # Homepage
42
- ├── quickstart.mdx # Getting started
73
+ ├── docs.json (with "docType": "api")
74
+ ├── index.mdx # Product intro
75
+ ├── quickstart.mdx # 5-minute getting started
76
+ ├── authentication.mdx # API keys, OAuth
43
77
  ├── guides/
44
- │ └── overview.mdx # Architecture
45
- ├── api-reference/ # If API exists
78
+ │ └── overview.mdx
79
+ ├── api-reference/
46
80
  │ ├── introduction.mdx
81
+ │ ├── errors.mdx
47
82
  │ └── openapi.json
48
- └── theme.json # Theme config
83
+ ├── sdks/ # If SDKs exist
84
+ │ └── ...
85
+ └── changelog.mdx
86
+ ```
87
+
88
+ ### docType: "product"
89
+ ```
90
+ docs/
91
+ ├── docs.json (with "docType": "product")
92
+ ├── index.mdx # Product overview
93
+ ├── getting-started/
94
+ │ ├── quickstart.mdx
95
+ │ └── key-concepts.mdx
96
+ ├── features/
97
+ │ └── {feature}.mdx
98
+ ├── tutorials/
99
+ │ └── {workflow}.mdx
100
+ ├── troubleshooting/
101
+ │ ├── common-issues.mdx
102
+ │ └── faq.mdx
103
+ └── release-notes.mdx
49
104
  ```
50
105
 
51
- ## Content Extraction
106
+ ## Content Guidelines by docType
52
107
 
53
- | Source | Documentation |
54
- |--------|---------------|
55
- | README.md | Homepage, overview |
56
- | package.json | Name, version, scripts |
57
- | src/index.ts | Main exports |
58
- | tests/ | Usage examples |
59
- | .env.example | Configuration options |
108
+ | docType | Focus | Tone | Code |
109
+ |---------|-------|------|------|
110
+ | internal | Setup, architecture, processes | Technical | Heavy |
111
+ | api | Endpoints, auth, examples | Technical | Heavy |
112
+ | product | Features, workflows, FAQs | Friendly | Minimal |
60
113
 
61
114
  ## Quality Guidelines
62
115
 
63
116
  - Extract real examples, don't fabricate
64
- - Note areas needing human review
117
+ - Note areas needing human review with TODO
65
118
  - Generate SEO-friendly descriptions
66
- - Include all installation steps
119
+ - Match tone to audience
120
+ - Always set `docType` in generated docs.json
@@ -7,7 +7,34 @@ globs: ["**/*.mdx", "**/docs.json"]
7
7
 
8
8
  When asked to sync, update, or check documentation:
9
9
 
10
- ## Analysis Process
10
+ ## Step 1: Locate Source Code
11
+
12
+ - If `docs.json` exists here → source code is in `../`
13
+ - If `package.json` + `src/` exist → you're at repo root
14
+ - Check both current directory AND parent for source files
15
+
16
+ ## Step 2: Get Documentation Type from Config
17
+
18
+ **Read `docs.json` for `docType` field:**
19
+
20
+ ```json
21
+ { "docType": "api" } // "internal" | "api" | "product"
22
+ ```
23
+
24
+ **If `docType` is set:** Use that value automatically.
25
+
26
+ **If `docType` is NOT set, detect from structure:**
27
+ - Has `architecture/`, `development/` → "internal"
28
+ - Has `api-reference/`, `sdks/` → "api"
29
+ - Has `features/`, `tutorials/` → "product"
30
+
31
+ **If still unclear, ask:** "What type of documentation is this?"
32
+
33
+ **After user answers, save to docs.json:**
34
+ Add `"docType": "{choice}"` to docs.json.
35
+ Tell user: "Saved docType to docs.json - you won't be asked again."
36
+
37
+ ## Step 3: Analysis Process
11
38
 
12
39
  1. Compare documented APIs against source code exports
13
40
  2. Verify code examples compile/run correctly
@@ -15,6 +42,24 @@ When asked to sync, update, or check documentation:
15
42
  4. Validate all internal links resolve
16
43
  5. Identify new features needing documentation
17
44
 
45
+ ## Type-Specific Checks
46
+
47
+ ### For docType: "internal"
48
+ - Dev setup instructions still work
49
+ - Architecture diagrams match current code
50
+ - Internal tool versions are current
51
+
52
+ ### For docType: "api"
53
+ - API endpoints match OpenAPI spec
54
+ - Auth examples are correct
55
+ - SDK versions are current
56
+ - Error codes are complete
57
+
58
+ ### For docType: "product"
59
+ - Screenshots match current UI
60
+ - Feature descriptions are accurate
61
+ - Tutorials still work
62
+
18
63
  ## Common Outdated Patterns
19
64
 
20
65
  - Function signatures that changed
@@ -32,16 +77,6 @@ When asked to sync, update, or check documentation:
32
77
  - Create stubs for undocumented new features
33
78
  - Mark deprecated features with Warning callout
34
79
 
35
- ## Detection Checklist
36
-
37
- | Check | How to Verify |
38
- |-------|---------------|
39
- | Function exists | Search source for export |
40
- | Signature matches | Compare params and return type |
41
- | Version current | Check package.json |
42
- | Route exists | Search API routes |
43
- | Component props | Check TypeScript interface |
44
-
45
80
  ## Update Patterns
46
81
 
47
82
  ### Changed Signature
@@ -2,6 +2,15 @@
2
2
 
3
3
  This is a DevDoc documentation project using MDX (Markdown + React components).
4
4
 
5
+ ## Source Code Location
6
+
7
+ If this docs folder is inside a larger repository, the source code is in the parent directory:
8
+ - Source code: `../src/` or `../lib/`
9
+ - Package config: `../package.json`
10
+ - README: `../README.md`
11
+
12
+ When generating documentation, always check the parent directory (`../`) for source code to document.
13
+
5
14
  ## Project Structure
6
15
 
7
16
  ```
@@ -1,6 +1,7 @@
1
1
  type AITool = 'claude' | 'cursor' | 'both';
2
2
  interface AIOptions {
3
3
  tool?: AITool;
4
+ update?: boolean;
4
5
  }
5
6
  export declare function ai(options: AIOptions): Promise<void>;
6
7
  export {};
@@ -125,27 +125,29 @@ function getTemplateDir() {
125
125
  }
126
126
  /**
127
127
  * Copy CLAUDE.md to project root
128
+ * Returns 'created' | 'updated' | 'skipped'
128
129
  */
129
130
  function copyClaudeMd(projectPath, templateDir) {
130
131
  const sourcePath = path_1.default.join(templateDir, 'CLAUDE.md');
131
132
  const destPath = path_1.default.join(projectPath, 'CLAUDE.md');
132
133
  if (!fs_extra_1.default.existsSync(sourcePath)) {
133
- logger_1.logger.warn('CLAUDE.md template not found');
134
- return false;
134
+ return 'skipped';
135
135
  }
136
+ const existed = fs_extra_1.default.existsSync(destPath);
136
137
  fs_extra_1.default.copySync(sourcePath, destPath);
137
- return true;
138
+ return existed ? 'updated' : 'created';
138
139
  }
139
140
  /**
140
141
  * Copy Claude Code skills to .claude/skills/
142
+ * Returns array of { skill, status: 'created' | 'updated' }
141
143
  */
142
144
  function copyClaudeSkills(projectPath, templateDir) {
143
- const copied = [];
145
+ const results = [];
144
146
  const sourceSkillsDir = path_1.default.join(templateDir, '.claude', 'skills');
145
147
  const destSkillsDir = path_1.default.join(projectPath, '.claude', 'skills');
146
148
  if (!fs_extra_1.default.existsSync(sourceSkillsDir)) {
147
149
  logger_1.logger.warn('Claude skills template directory not found');
148
- return copied;
150
+ return results;
149
151
  }
150
152
  // Ensure destination directory exists
151
153
  fs_extra_1.default.ensureDirSync(destSkillsDir);
@@ -153,22 +155,24 @@ function copyClaudeSkills(projectPath, templateDir) {
153
155
  const sourceDir = path_1.default.join(sourceSkillsDir, skill);
154
156
  const destDir = path_1.default.join(destSkillsDir, skill);
155
157
  if (fs_extra_1.default.existsSync(sourceDir)) {
158
+ const existed = fs_extra_1.default.existsSync(destDir);
156
159
  fs_extra_1.default.copySync(sourceDir, destDir);
157
- copied.push(skill);
160
+ results.push({ skill, status: existed ? 'updated' : 'created' });
158
161
  }
159
162
  }
160
- return copied;
163
+ return results;
161
164
  }
162
165
  /**
163
166
  * Copy Cursor rules to .cursor/rules/
167
+ * Returns array of { rule, status: 'created' | 'updated' }
164
168
  */
165
169
  function copyCursorRules(projectPath, templateDir) {
166
- const copied = [];
170
+ const results = [];
167
171
  const sourceRulesDir = path_1.default.join(templateDir, '.cursor', 'rules');
168
172
  const destRulesDir = path_1.default.join(projectPath, '.cursor', 'rules');
169
173
  if (!fs_extra_1.default.existsSync(sourceRulesDir)) {
170
174
  logger_1.logger.warn('Cursor rules template directory not found');
171
- return copied;
175
+ return results;
172
176
  }
173
177
  // Ensure destination directory exists
174
178
  fs_extra_1.default.ensureDirSync(destRulesDir);
@@ -176,17 +180,36 @@ function copyCursorRules(projectPath, templateDir) {
176
180
  const sourcePath = path_1.default.join(sourceRulesDir, rule);
177
181
  const destPath = path_1.default.join(destRulesDir, rule);
178
182
  if (fs_extra_1.default.existsSync(sourcePath)) {
183
+ const existed = fs_extra_1.default.existsSync(destPath);
179
184
  fs_extra_1.default.copySync(sourcePath, destPath);
180
- copied.push(rule);
185
+ results.push({ rule, status: existed ? 'updated' : 'created' });
181
186
  }
182
187
  }
183
- return copied;
188
+ return results;
189
+ }
190
+ /**
191
+ * Check if AI tools are already installed
192
+ */
193
+ function checkExistingInstallation(projectPath) {
194
+ const claudeDir = path_1.default.join(projectPath, '.claude', 'skills');
195
+ const cursorDir = path_1.default.join(projectPath, '.cursor', 'rules');
196
+ return {
197
+ claude: fs_extra_1.default.existsSync(claudeDir) && fs_extra_1.default.readdirSync(claudeDir).length > 0,
198
+ cursor: fs_extra_1.default.existsSync(cursorDir) && fs_extra_1.default.readdirSync(cursorDir).some(f => f.startsWith('devdoc')),
199
+ };
184
200
  }
185
201
  async function ai(options) {
186
- console.log();
187
- logger_1.logger.info('DevDoc AI Agent Setup');
188
202
  console.log();
189
203
  const projectPath = process.cwd();
204
+ const existing = checkExistingInstallation(projectPath);
205
+ const isUpdate = options.update || existing.claude || existing.cursor;
206
+ if (isUpdate) {
207
+ logger_1.logger.info('DevDoc AI Agent Update');
208
+ }
209
+ else {
210
+ logger_1.logger.info('DevDoc AI Agent Setup');
211
+ }
212
+ console.log();
190
213
  // Check if this is a DevDoc project
191
214
  const docsJsonPath = path_1.default.join(projectPath, 'docs.json');
192
215
  const hasDocsJson = fs_extra_1.default.existsSync(docsJsonPath);
@@ -206,44 +229,82 @@ async function ai(options) {
206
229
  // Get tool selection if not provided
207
230
  let tool = options.tool || 'both';
208
231
  if (!options.tool) {
209
- const toolChoices = [
210
- { value: 'both', label: 'Both - Claude Code and Cursor' },
211
- { value: 'claude', label: 'Claude Code - Skills and CLAUDE.md' },
212
- { value: 'cursor', label: 'Cursor - Rules (.cursor/rules/)' },
213
- ];
214
- tool = await promptSelect('Which AI tool do you use?', toolChoices);
232
+ // If updating, default to updating what's already installed
233
+ if (isUpdate && existing.claude && !existing.cursor) {
234
+ tool = 'claude';
235
+ }
236
+ else if (isUpdate && existing.cursor && !existing.claude) {
237
+ tool = 'cursor';
238
+ }
239
+ else {
240
+ const toolChoices = [
241
+ { value: 'both', label: 'Both - Claude Code and Cursor' },
242
+ { value: 'claude', label: 'Claude Code - Skills and CLAUDE.md' },
243
+ { value: 'cursor', label: 'Cursor - Rules (.cursor/rules/)' },
244
+ ];
245
+ tool = await promptSelect('Which AI tool do you use?', toolChoices);
246
+ }
215
247
  }
216
248
  console.log();
217
- logger_1.logger.info('Setting up AI agent configuration...');
249
+ if (isUpdate) {
250
+ logger_1.logger.info('Updating AI agent configuration...');
251
+ }
252
+ else {
253
+ logger_1.logger.info('Setting up AI agent configuration...');
254
+ }
218
255
  console.log();
219
- const results = {
220
- claudeMd: false,
221
- claudeSkills: [],
222
- cursorRules: [],
223
- };
256
+ let createdCount = 0;
257
+ let updatedCount = 0;
224
258
  // Setup Claude Code
225
259
  if (tool === 'claude' || tool === 'both') {
226
260
  // Copy CLAUDE.md
227
- results.claudeMd = copyClaudeMd(projectPath, templateDir);
228
- if (results.claudeMd) {
261
+ const claudeMdStatus = copyClaudeMd(projectPath, templateDir);
262
+ if (claudeMdStatus === 'created') {
229
263
  logger_1.logger.success('Created CLAUDE.md');
264
+ createdCount++;
265
+ }
266
+ else if (claudeMdStatus === 'updated') {
267
+ logger_1.logger.success('Updated CLAUDE.md');
268
+ updatedCount++;
230
269
  }
231
270
  // Copy skills
232
- results.claudeSkills = copyClaudeSkills(projectPath, templateDir);
233
- for (const skill of results.claudeSkills) {
234
- logger_1.logger.success(`Created .claude/skills/${skill}/SKILL.md`);
271
+ const skillResults = copyClaudeSkills(projectPath, templateDir);
272
+ for (const { skill, status } of skillResults) {
273
+ if (status === 'created') {
274
+ logger_1.logger.success(`Created .claude/skills/${skill}/SKILL.md`);
275
+ createdCount++;
276
+ }
277
+ else {
278
+ logger_1.logger.success(`Updated .claude/skills/${skill}/SKILL.md`);
279
+ updatedCount++;
280
+ }
235
281
  }
236
282
  }
237
283
  // Setup Cursor
238
284
  if (tool === 'cursor' || tool === 'both') {
239
- results.cursorRules = copyCursorRules(projectPath, templateDir);
240
- for (const rule of results.cursorRules) {
241
- logger_1.logger.success(`Created .cursor/rules/${rule}`);
285
+ const ruleResults = copyCursorRules(projectPath, templateDir);
286
+ for (const { rule, status } of ruleResults) {
287
+ if (status === 'created') {
288
+ logger_1.logger.success(`Created .cursor/rules/${rule}`);
289
+ createdCount++;
290
+ }
291
+ else {
292
+ logger_1.logger.success(`Updated .cursor/rules/${rule}`);
293
+ updatedCount++;
294
+ }
242
295
  }
243
296
  }
244
297
  // Summary
245
298
  console.log();
246
- logger_1.logger.success('AI agent configuration complete!');
299
+ if (updatedCount > 0 && createdCount > 0) {
300
+ logger_1.logger.success(`AI agent configuration complete! (${createdCount} created, ${updatedCount} updated)`);
301
+ }
302
+ else if (updatedCount > 0) {
303
+ logger_1.logger.success(`AI agent configuration updated! (${updatedCount} files)`);
304
+ }
305
+ else {
306
+ logger_1.logger.success('AI agent configuration complete!');
307
+ }
247
308
  console.log();
248
309
  if (tool === 'claude' || tool === 'both') {
249
310
  console.log('Available Claude Code commands:');
@@ -276,5 +337,9 @@ async function ai(options) {
276
337
  console.log(' Cursor: Ask "generate initial documentation from this repo"');
277
338
  }
278
339
  console.log();
340
+ if (isUpdate) {
341
+ console.log('Tip: Restart Claude Code or Cursor to load the updated skills/rules.');
342
+ console.log();
343
+ }
279
344
  }
280
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY2xpL2NvbW1hbmRzL2FpLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBcUxBLGdCQTZHQztBQWxTRCxnREFBd0I7QUFDeEIsd0RBQTBCO0FBQzFCLCtDQUE0QztBQVE1QyxzQ0FBc0M7QUFDdEMsS0FBSyxVQUFVLE1BQU0sQ0FBQyxRQUFnQixFQUFFLFlBQXFCO0lBQzNELE1BQU0sUUFBUSxHQUFHLHdEQUFhLFVBQVUsR0FBQyxDQUFDO0lBQzFDLE1BQU0sRUFBRSxHQUFHLFFBQVEsQ0FBQyxlQUFlLENBQUM7UUFDbEMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxLQUFLO1FBQ3BCLE1BQU0sRUFBRSxPQUFPLENBQUMsTUFBTTtLQUN2QixDQUFDLENBQUM7SUFFSCxPQUFPLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUU7UUFDN0IsTUFBTSxlQUFlLEdBQUcsWUFBWTtZQUNsQyxDQUFDLENBQUMsR0FBRyxRQUFRLEtBQUssWUFBWSxLQUFLO1lBQ25DLENBQUMsQ0FBQyxHQUFHLFFBQVEsSUFBSSxDQUFDO1FBRXBCLEVBQUUsQ0FBQyxRQUFRLENBQUMsZUFBZSxFQUFFLENBQUMsTUFBTSxFQUFFLEVBQUU7WUFDdEMsRUFBRSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ1gsT0FBTyxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsSUFBSSxZQUFZLElBQUksRUFBRSxDQUFDLENBQUM7UUFDL0MsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUM7QUFFRCxLQUFLLFVBQVUsWUFBWSxDQUFDLFFBQWdCLEVBQUUsT0FBMkM7SUFDdkYsT0FBTyxDQUFDLEdBQUcsQ0FBQyxLQUFLLFFBQVEsSUFBSSxDQUFDLENBQUM7SUFDL0IsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLE1BQU0s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LENBQUMsMENBQTBDLENBQUMsQ0FBQztRQUN4RCxPQUFPLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDZCxPQUFPLENBQUMsR0FBRyxDQUFDLGtDQUFrQyxDQUFDLENBQUM7UUFDaEQsT0FBTyxDQUFDLEdBQUcsQ0FBQywwREFBMEQsQ0FBQyxDQUFDO1FBQ3hFLE9BQU8sQ0FBQyxHQUFHLENBQUMsK0NBQStDLENBQUMsQ0FBQztRQUM3RCxPQUFPLENBQUMsR0FBRyxDQUFDLHdDQUF3QyxDQUFDLENBQUM7UUFDdEQsT0FBTyxDQUFDLEdBQUcsQ0FBQyw2Q0FBNkMsQ0FBQyxDQUFDO1FBQzNELE9BQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQztJQUNoQixDQUFDO0lBRUQsT0FBTyxDQUFDLEdBQUcsQ0FBQyxjQUFjLENBQUMsQ0FBQztJQUM1QixJQUFJLElBQUksS0FBSyxRQUFRLElBQUksSUFBSSxLQUFLLE1BQU0sRUFBRSxDQUFDO1FBQ3pDLE9BQU8sQ0FBQyxHQUFHLENBQUMsZ0NBQWdDLENBQUMsQ0FBQztJQUNoRCxDQUFDO0lBQ0QsSUFBSSxJQUFJLEtBQUssUUFBUSxJQUFJLElBQUksS0FBSyxNQUFNLEVBQUUsQ0FBQztRQUN6QyxPQUFPLENBQUMsR0FBRyxDQUFDLCtEQUErRCxDQUFDLENBQUM7SUFDL0UsQ0FBQztJQUNELE9BQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUNoQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgZnMgZnJvbSAnZnMtZXh0cmEnO1xuaW1wb3J0IHsgbG9nZ2VyIH0gZnJvbSAnLi4vLi4vdXRpbHMvbG9nZ2VyJztcblxudHlwZSBBSVRvb2wgPSAnY2xhdWRlJyB8ICdjdXJzb3InIHwgJ2JvdGgnO1xuXG5pbnRlcmZhY2UgQUlPcHRpb25zIHtcbiAgdG9vbD86IEFJVG9vbDtcbn1cblxuLy8gU2ltcGxlIHByb21wdCBoZWxwZXIgdXNpbmcgcmVhZGxpbmVcbmFzeW5jIGZ1bmN0aW9uIHByb21wdChxdWVzdGlvbjogc3RyaW5nLCBkZWZhdWx0VmFsdWU/OiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4ge1xuICBjb25zdCByZWFkbGluZSA9IGF3YWl0IGltcG9ydCgncmVhZGxpbmUnKTtcbiAgY29uc3QgcmwgPSByZWFkbGluZS5jcmVhdGVJbnRlcmZhY2Uoe1xuICAgIGlucHV0OiBwcm9jZXNzLnN0ZGluLFxuICAgIG91dHB1dDogcHJvY2Vzcy5zdGRvdXQsXG4gIH0pO1xuXG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgIGNvbnN0IGRpc3BsYXlRdWVzdGlvbiA9IGRlZmF1bHRWYWx1ZSBcbiAgICAgID8gYCR7cXVlc3Rpb259ICgke2RlZmF1bHRWYWx1ZX0pOiBgXG4gICAgICA6IGAke3F1ZXN0aW9ufTogYDtcbiAgICBcbiAgICBybC5xdWVzdGlvbihkaXNwbGF5UXVlc3Rpb24sIChhbnN3ZXIpID0+IHtcbiAgICAgIHJsLmNsb3NlKCk7XG4gICAgICByZXNvbHZlKGFuc3dlci50cmltKCkgfHwgZGVmYXVsdFZhbHVlIHx8ICcnKTtcbiAgICB9KTtcbiAgfSk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHByb21wdFNlbGVjdChxdWVzdGlvbjogc3RyaW5nLCBjaG9pY2VzOiB7IHZhbHVlOiBzdHJpbmc7IGxhYmVsOiBzdHJpbmcgfVtdKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgY29uc29sZS5sb2coYFxcbiR7cXVlc3Rpb259XFxuYCk7XG4gIGNob2ljZXMuZm9yRWFjaCgoY2hvaWNlLCBpKSA9PiB7XG4gICAgY29uc29sZS5sb2coYCAgJHtpICsgMX0uICR7Y2hvaWNlLmxhYmVsfWApO1xuICB9KTtcbiAgY29uc29sZS5sb2coKTtcbiAgXG4gIGNvbnN0IHJlYWRsaW5lID0gYXdhaXQgaW1wb3J0KCdyZWFkbGluZScpO1xuICBjb25zdCBybCA9IHJlYWRsaW5lLmNyZWF0ZUludGVyZmFjZSh7XG4gICAgaW5wdXQ6IHByb2Nlc3Muc3RkaW4sXG4gICAgb3V0cHV0OiBwcm9jZXNzLnN0ZG91dCxcbiAgfSk7XG5cbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgcmwucXVlc3Rpb24oJ0VudGVyIG51bWJlcjogJywgKGFuc3dlcikgPT4ge1xuICAgICAgcmwuY2xvc2UoKTtcbiAgICAgIGNvbnN0IGluZGV4ID0gcGFyc2VJbnQoYW5zd2VyLnRyaW0oKSwgMTApIC0gMTtcbiAgICAgIGlmIChpbmRleCA+PSAwICYmIGluZGV4IDwgY2hvaWNlcy5sZW5ndGgpIHtcbiAgICAgICAgcmVzb2x2ZShjaG9pY2VzW2luZGV4XS52YWx1ZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBEZWZhdWx0IHRvIGZpcnN0IGNob2ljZVxuICAgICAgICByZXNvbHZlKGNob2ljZXNbMF0udmFsdWUpO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcbn1cblxuLy8gQ2xhdWRlIENvZGUgc2tpbGxzIHRvIGNyZWF0ZVxuY29uc3QgQ0xBVURFX1NLSUxMUyA9IFtcbiAgJ2Jvb3RzdHJhcC1kb2NzJyxcbiAgJ21pZ3JhdGUtZG9jcycsXG4gICdpbXBvcnQtYXBpLXNwZWMnLFxuICAnc3luYy1kb2NzJyxcbiAgJ2NoZWNrLWRvY3MnLFxuICAnY3JlYXRlLWRvYy1wYWdlJyxcbiAgJ3VwZGF0ZS1kb2NzLWpzb24nLFxuICAnZ2VuZXJhdGUtYXBpLWRvY3MnLFxuICAnZG9jcy1mcm9tLWNvZGUnLFxuXTtcblxuLy8gQ3Vyc29yIHJ1bGVzIHRvIGNyZWF0ZVxuY29uc3QgQ1VSU09SX1JVTEVTID0gW1xuICAnZGV2ZG9jLm1kYycsXG4gICdkZXZkb2MtYm9vdHN0cmFwLm1kYycsXG4gICdkZXZkb2MtbWlncmF0ZS5tZGMnLFxuICAnZGV2ZG9jLXN5bmMubWRjJyxcbl07XG5cbi8qKlxuICogR2V0IHRoZSBBSSBhZ2VudHMgdGVtcGxhdGUgZGlyZWN0b3J5IHBhdGggKGhhbmRsZXMgYm90aCBkZXZlbG9wbWVudCBhbmQgaW5zdGFsbGVkIHBhY2thZ2Ugc2NlbmFyaW9zKVxuICovXG5mdW5jdGlvbiBnZXRUZW1wbGF0ZURpcigpOiBzdHJpbmcge1xuICAvLyBUcnkgcmVsYXRpdmUgdG8gY29tcGlsZWQgZGlzdCAocGFja2FnZXMvZGV2ZG9jL2Rpc3QvY2xpL2NvbW1hbmRzIC0+IHBhY2thZ2VzL2RldmRvYy9haS1hZ2VudHMpXG4gIGxldCB0ZW1wbGF0ZURpciA9IHBhdGguam9pbihfX2Rpcm5hbWUsICcuLicsICcuLicsICcuLicsICdhaS1hZ2VudHMnKTtcbiAgXG4gIGlmIChmcy5leGlzdHNTeW5jKHRlbXBsYXRlRGlyKSkge1xuICAgIHJldHVybiB0ZW1wbGF0ZURpcjtcbiAgfVxuICBcbiAgLy8gVHJ5IHJlbGF0aXZlIHRvIHNvdXJjZSAocGFja2FnZXMvZGV2ZG9jL3NyYy9jbGkvY29tbWFuZHMgLT4gcGFja2FnZXMvZGV2ZG9jL2FpLWFnZW50cylcbiAgdGVtcGxhdGVEaXIgPSBwYXRoLmpvaW4oX19kaXJuYW1lLCAnLi4nLCAnLi4nLCAnLi4nLCAnYWktYWdlbnRzJyk7XG4gIFxuICBpZiAoZnMuZXhpc3RzU3luYyh0ZW1wbGF0ZURpcikpIHtcbiAgICByZXR1cm4gdGVtcGxhdGVEaXI7XG4gIH1cbiAgXG4gIC8vIFRyeSBkZXZkb2MvdGVtcGxhdGVzIGF0IHJlcG8gcm9vdCAoZGV2ZWxvcG1lbnQgLSBtb25vcmVwbyBzdHJ1Y3R1cmUpXG4gIC8vIF9fZGlybmFtZSBpcyBwYWNrYWdlcy9kZXZkb2MvZGlzdC9jbGkvY29tbWFuZHMgLT4gZ28gdXAgNSBsZXZlbHMgdG8gcmVwbyByb290XG4gIHRlbXBsYXRlRGlyID0gcGF0aC5qb2luKF9fZGlybmFtZSwgJy4uJywgJy4uJywgJy4uJywgJy4uJywgJy4uJywgJ2RldmRvYycsICd0ZW1wbGF0ZXMnLCAnc3RhcnRlcicpO1xuICBcbiAgaWYgKGZzLmV4aXN0c1N5bmModGVtcGxhdGVEaXIpKSB7XG4gICAgcmV0dXJuIHRlbXBsYXRlRGlyO1xuICB9XG4gIFxuICB0aHJvdyBuZXcgRXJyb3IoJ0NvdWxkIG5vdCBmaW5kIHRlbXBsYXRlIGRpcmVjdG9yeScpO1xufVxuXG4vKipcbiAqIENvcHkgQ0xBVURFLm1kIHRvIHByb2plY3Qgcm9vdFxuICovXG5mdW5jdGlvbiBjb3B5Q2xhdWRlTWQocHJvamVjdFBhdGg6IHN0cmluZywgdGVtcGxhdGVEaXI6IHN0cmluZyk6IGJvb2xlYW4ge1xuICBjb25zdCBzb3VyY2VQYXRoID0gcGF0aC5qb2luKHRlbXBsYXRlRGlyLCAnQ0xBVURFLm1kJyk7XG4gIGNvbnN0IGRlc3RQYXRoID0gcGF0aC5qb2luKHByb2plY3RQYXRoLCAnQ0xBVURFLm1kJyk7XG4gIFxuICBpZiAoIWZzLmV4aXN0c1N5bmMoc291cmNlUGF0aCkpIHtcbiAgICBsb2dnZXIud2FybignQ0xBVURFLm1kIHRlbXBsYXRlIG5vdCBmb3VuZCcpO1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBcbiAgZnMuY29weVN5bmMoc291cmNlUGF0aCwgZGVzdFBhdGgpO1xuICByZXR1cm4gdHJ1ZTtcbn1cblxuLyoqXG4gKiBDb3B5IENsYXVkZSBDb2RlIHNraWxscyB0byAuY2xhdWRlL3NraWxscy9cbiAqL1xuZnVuY3Rpb24gY29weUNsYXVkZVNraWxscyhwcm9qZWN0UGF0aDogc3RyaW5nLCB0ZW1wbGF0ZURpcjogc3RyaW5nKTogc3RyaW5nW10ge1xuICBjb25zdCBjb3BpZWQ6IHN0cmluZ1tdID0gW107XG4gIGNvbnN0IHNvdXJjZVNraWxsc0RpciA9IHBhdGguam9pbih0ZW1wbGF0ZURpciwgJy5jbGF1ZGUnLCAnc2tpbGxzJyk7XG4gIGNvbnN0IGRlc3RTa2lsbHNEaXIgPSBwYXRoLmpvaW4ocHJvamVjdFBhdGgsICcuY2xhdWRlJywgJ3NraWxscycpO1xuICBcbiAgaWYgKCFmcy5leGlzdHNTeW5jKHNvdXJjZVNraWxsc0RpcikpIHtcbiAgICBsb2dnZXIud2FybignQ2xhdWRlIHNraWxscyB0ZW1wbGF0ZSBkaXJlY3Rvcnkgbm90IGZvdW5kJyk7XG4gICAgcmV0dXJuIGNvcGllZDtcbiAgfVxuICBcbiAgLy8gRW5zdXJlIGRlc3RpbmF0aW9uIGRpcmVjdG9yeSBleGlzdHNcbiAgZnMuZW5zdXJlRGlyU3luYyhkZXN0U2tpbGxzRGlyKTtcbiAgXG4gIGZvciAoY29uc3Qgc2tpbGwgb2YgQ0xBVURFX1NLSUxMUykge1xuICAgIGNvbnN0IHNvdXJjZURpciA9IHBhdGguam9pbihzb3VyY2VTa2lsbHNEaXIsIHNraWxsKTtcbiAgICBjb25zdCBkZXN0RGlyID0gcGF0aC5qb2luKGRlc3RTa2lsbHNEaXIsIHNraWxsKTtcbiAgICBcbiAgICBpZiAoZnMuZXhpc3RzU3luYyhzb3VyY2VEaXIpKSB7XG4gICAgICBmcy5jb3B5U3luYyhzb3VyY2VEaXIsIGRlc3REaXIpO1xuICAgICAgY29waWVkLnB1c2goc2tpbGwpO1xuICAgIH1cbiAgfVxuICBcbiAgcmV0dXJuIGNvcGllZDtcbn1cblxuLyoqXG4gKiBDb3B5IEN1cnNvciBydWxlcyB0byAuY3Vyc29yL3J1bGVzL1xuICovXG5mdW5jdGlvbiBjb3B5Q3Vyc29yUnVsZXMocHJvamVjdFBhdGg6IHN0cmluZywgdGVtcGxhdGVEaXI6IHN0cmluZyk6IHN0cmluZ1tdIHtcbiAgY29uc3QgY29waWVkOiBzdHJpbmdbXSA9IFtdO1xuICBjb25zdCBzb3VyY2VSdWxlc0RpciA9IHBhdGguam9pbih0ZW1wbGF0ZURpciwgJy5jdXJzb3InLCAncnVsZXMnKTtcbiAgY29uc3QgZGVzdFJ1bGVzRGlyID0gcGF0aC5qb2luKHByb2plY3RQYXRoLCAnLmN1cnNvcicsICdydWxlcycpO1xuICBcbiAgaWYgKCFmcy5leGlzdHNTeW5jKHNvdXJjZVJ1bGVzRGlyKSkge1xuICAgIGxvZ2dlci53YXJuKCdDdXJzb3IgcnVsZXMgdGVtcGxhdGUgZGlyZWN0b3J5IG5vdCBmb3VuZCcpO1xuICAgIHJldHVybiBjb3BpZWQ7XG4gIH1cbiAgXG4gIC8vIEVuc3VyZSBkZXN0aW5hdGlvbiBkaXJlY3RvcnkgZXhpc3RzXG4gIGZzLmVuc3VyZURpclN5bmMoZGVzdFJ1bGVzRGlyKTtcbiAgXG4gIGZvciAoY29uc3QgcnVsZSBvZiBDVVJTT1JfUlVMRVMpIHtcbiAgICBjb25zdCBzb3VyY2VQYXRoID0gcGF0aC5qb2luKHNvdXJjZVJ1bGVzRGlyLCBydWxlKTtcbiAgICBjb25zdCBkZXN0UGF0aCA9IHBhdGguam9pbihkZXN0UnVsZXNEaXIsIHJ1bGUpO1xuICAgIFxuICAgIGlmIChmcy5leGlzdHNTeW5jKHNvdXJjZVBhdGgpKSB7XG4gICAgICBmcy5jb3B5U3luYyhzb3VyY2VQYXRoLCBkZXN0UGF0aCk7XG4gICAgICBjb3BpZWQucHVzaChydWxlKTtcbiAgICB9XG4gIH1cbiAgXG4gIHJldHVybiBjb3BpZWQ7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBhaShvcHRpb25zOiBBSU9wdGlvbnMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc29sZS5sb2coKTtcbiAgbG9nZ2VyLmluZm8oJ0RldkRvYyBBSSBBZ2VudCBTZXR1cCcpO1xuICBjb25zb2xlLmxvZygpO1xuXG4gIGNvbnN0IHByb2plY3RQYXRoID0gcHJvY2Vzcy5jd2QoKTtcbiAgXG4gIC8vIENoZWNrIGlmIHRoaXMgaXMgYSBEZXZEb2MgcHJvamVjdFxuICBjb25zdCBkb2NzSnNvblBhdGggPSBwYXRoLmpvaW4ocHJvamVjdFBhdGgsICdkb2NzLmpzb24nKTtcbiAgY29uc3QgaGFzRG9jc0pzb24gPSBmcy5leGlzdHNTeW5jKGRvY3NKc29uUGF0aCk7XG4gIFxuICBpZiAoIWhhc0RvY3NKc29uKSB7XG4gICAgbG9nZ2VyLndhcm4oJ05vIGRvY3MuanNvbiBmb3VuZC4gVGhpcyBtYXkgbm90IGJlIGEgRGV2RG9jIHByb2plY3QuJyk7XG4gICAgY29uc29sZS5sb2coKTtcbiAgfVxuXG4gIC8vIEdldCB0ZW1wbGF0ZSBkaXJlY3RvcnlcbiAgbGV0IHRlbXBsYXRlRGlyOiBzdHJpbmc7XG4gIHRyeSB7XG4gICAgdGVtcGxhdGVEaXIgPSBnZXRUZW1wbGF0ZURpcigpO1xuICB9IGNhdGNoIHtcbiAgICBsb2dnZXIuZXJyb3IoJ0NvdWxkIG5vdCBmaW5kIEFJIGFnZW50IHRlbXBsYXRlcy4gUGxlYXNlIGVuc3VyZSBEZXZEb2MgaXMgaW5zdGFsbGVkIGNvcnJlY3RseS4nKTtcbiAgICBwcm9jZXNzLmV4aXQoMSk7XG4gIH1cblxuICAvLyBHZXQgdG9vbCBzZWxlY3Rpb24gaWYgbm90IHByb3ZpZGVkXG4gIGxldCB0b29sOiBBSVRvb2wgPSBvcHRpb25zLnRvb2wgfHwgJ2JvdGgnO1xuICBcbiAgaWYgKCFvcHRpb25zLnRvb2wpIHtcbiAgICBjb25zdCB0b29sQ2hvaWNlcyA9IFtcbiAgICAgIHsgdmFsdWU6ICdib3RoJywgbGFiZWw6ICdCb3RoIC0gQ2xhdWRlIENvZGUgYW5kIEN1cnNvcicgfSxcbiAgICAgIHsgdmFsdWU6ICdjbGF1ZGUnLCBsYWJlbDogJ0NsYXVkZSBDb2RlIC0gU2tpbGxzIGFuZCBDTEFVREUubWQnIH0sXG4gICAgICB7IHZhbHVlOiAnY3Vyc29yJywgbGFiZWw6ICdDdXJzb3IgLSBSdWxlcyAoLmN1cnNvci9ydWxlcy8pJyB9LFxuICAgIF07XG5cbiAgICB0b29sID0gYXdhaXQgcHJvbXB0U2VsZWN0KCdXaGljaCBBSSB0b29sIGRvIHlvdSB1c2U/JywgdG9vbENob2ljZXMpIGFzIEFJVG9vbDtcbiAgfVxuXG4gIGNvbnNvbGUubG9nKCk7XG4gIGxvZ2dlci5pbmZvKCdTZXR0aW5nIHVwIEFJIGFnZW50IGNvbmZpZ3VyYXRpb24uLi4nKTtcbiAgY29uc29sZS5sb2coKTtcblxuICBjb25zdCByZXN1bHRzID0ge1xuICAgIGNsYXVkZU1kOiBmYWxzZSxcbiAgICBjbGF1ZGVTa2lsbHM6IFtdIGFzIHN0cmluZ1tdLFxuICAgIGN1cnNvclJ1bGVzOiBbXSBhcyBzdHJpbmdbXSxcbiAgfTtcblxuICAvLyBTZXR1cCBDbGF1ZGUgQ29kZVxuICBpZiAodG9vbCA9PT0gJ2NsYXVkZScgfHwgdG9vbCA9PT0gJ2JvdGgnKSB7XG4gICAgLy8gQ29weSBDTEFVREUubWRcbiAgICByZXN1bHRzLmNsYXVkZU1kID0gY29weUNsYXVkZU1kKHByb2plY3RQYXRoLCB0ZW1wbGF0ZURpcik7XG4gICAgaWYgKHJlc3VsdHMuY2xhdWRlTWQpIHtcbiAgICAgIGxvZ2dlci5zdWNjZXNzKCdDcmVhdGVkIENMQVVERS5tZCcpO1xuICAgIH1cbiAgICBcbiAgICAvLyBDb3B5IHNraWxsc1xuICAgIHJlc3VsdHMuY2xhdWRlU2tpbGxzID0gY29weUNsYXVkZVNraWxscyhwcm9qZWN0UGF0aCwgdGVtcGxhdGVEaXIpO1xuICAgIGZvciAoY29uc3Qgc2tpbGwgb2YgcmVzdWx0cy5jbGF1ZGVTa2lsbHMpIHtcbiAgICAgIGxvZ2dlci5zdWNjZXNzKGBDcmVhdGVkIC5jbGF1ZGUvc2tpbGxzLyR7c2tpbGx9L1NLSUxMLm1kYCk7XG4gICAgfVxuICB9XG5cbiAgLy8gU2V0dXAgQ3Vyc29yXG4gIGlmICh0b29sID09PSAnY3Vyc29yJyB8fCB0b29sID09PSAnYm90aCcpIHtcbiAgICByZXN1bHRzLmN1cnNvclJ1bGVzID0gY29weUN1cnNvclJ1bGVzKHByb2plY3RQYXRoLCB0ZW1wbGF0ZURpcik7XG4gICAgZm9yIChjb25zdCBydWxlIG9mIHJlc3VsdHMuY3Vyc29yUnVsZXMpIHtcbiAgICAgIGxvZ2dlci5zdWNjZXNzKGBDcmVhdGVkIC5jdXJzb3IvcnVsZXMvJHtydWxlfWApO1xuICAgIH1cbiAgfVxuXG4gIC8vIFN1bW1hcnlcbiAgY29uc29sZS5sb2coKTtcbiAgbG9nZ2VyLnN1Y2Nlc3MoJ0FJIGFnZW50IGNvbmZpZ3VyYXRpb24gY29tcGxldGUhJyk7XG4gIGNvbnNvbGUubG9nKCk7XG5cbiAgaWYgKHRvb2wgPT09ICdjbGF1ZGUnIHx8IHRvb2wgPT09ICdib3RoJykge1xuICAgIGNvbnNvbGUubG9nKCdBdmFpbGFibGUgQ2xhdWRlIENvZGUgY29tbWFuZHM6Jyk7XG4gICAgY29uc29sZS5sb2coJyAgL2Jvb3RzdHJhcC1kb2NzICAgIC0gQW5hbHl6ZSByZXBvIGFuZCBnZW5lcmF0ZSBpbml0aWFsIGRvY3VtZW50YXRpb24nKTtcbiAgICBjb25zb2xlLmxvZygnICAvbWlncmF0ZS1kb2NzICAgICAgLSBNaWdyYXRlIGZyb20gTWludGxpZnksIERvY3VzYXVydXMsIEdpdEJvb2ssIGV0Yy4nKTtcbiAgICBjb25zb2xlLmxvZygnICAvaW1wb3J0LWFwaS1zcGVjICAgLSBJbXBvcnQgT3BlbkFQSSwgR3JhcGhRTCwgb3IgQXN5bmNBUEkgc3BlY3MnKTtcbiAgICBjb25zb2xlLmxvZygnICAvc3luYy1kb2NzICAgICAgICAgLSBGaW5kIGFuZCBmaXggb3V0ZGF0ZWQgZG9jdW1lbnRhdGlvbicpO1xuICAgIGNvbnNvbGUubG9nKCcgIC9jaGVjay1kb2NzICAgICAgICAtIFF1aWNrIGhlYWx0aCBjaGVjayB3aXRob3V0IGNoYW5nZXMnKTtcbiAgICBjb25zb2xlLmxvZygnICAvY3JlYXRlLWRvYy1wYWdlICAgLSBDcmVhdGUgYSBuZXcgZG9jdW1lbnRhdGlvbiBwYWdlJyk7XG4gICAgY29uc29sZS5sb2coJyAgL3VwZGF0ZS1kb2NzLWpzb24gIC0gQWRkIHBhZ2VzIHRvIG5hdmlnYXRpb24nKTtcbiAgICBjb25zb2xlLmxvZygnICAvZ2VuZXJhdGUtYXBpLWRvY3MgLSBHZW5lcmF0ZSBBUEkgZG9jdW1lbnRhdGlvbicpO1xuICAgIGNvbnNvbGUubG9nKCcgIC9kb2NzLWZyb20tY29kZSAgICAtIEdlbmVyYXRlIGRvY3MgZnJvbSBzcGVjaWZpYyBjb2RlIGZpbGVzJyk7XG4gICAgY29uc29sZS5sb2coKTtcbiAgfVxuXG4gIGlmICh0b29sID09PSAnY3Vyc29yJyB8fCB0b29sID09PSAnYm90aCcpIHtcbiAgICBjb25zb2xlLmxvZygnQ3Vyc29yIHJ1bGVzIGNvbmZpZ3VyZWQgZm9yICoubWR4IGZpbGVzLicpO1xuICAgIGNvbnNvbGUubG9nKCk7XG4gICAgY29uc29sZS5sb2coJ1N1Z2dlc3RlZCBwcm9tcHRzIGluIEFnZW50IG1vZGU6Jyk7XG4gICAgY29uc29sZS5sb2coJyAgXCJBbmFseXplIHRoaXMgcmVwbyBhbmQgZ2VuZXJhdGUgaW5pdGlhbCBkb2N1bWVudGF0aW9uXCInKTtcbiAgICBjb25zb2xlLmxvZygnICBcIk1pZ3JhdGUgbXkgTWludGxpZnkgZG9jcyB0byBEZXZEb2MgZm9ybWF0XCInKTtcbiAgICBjb25zb2xlLmxvZygnICBcIkNoZWNrIG15IGRvY3MgZm9yIG91dGRhdGVkIGNvbnRlbnRcIicpO1xuICAgIGNvbnNvbGUubG9nKCcgIFwiQ3JlYXRlIGEgbmV3IGd1aWRlIGFib3V0IGF1dGhlbnRpY2F0aW9uXCInKTtcbiAgICBjb25zb2xlLmxvZygpO1xuICB9XG5cbiAgY29uc29sZS5sb2coJ1F1aWNrIHN0YXJ0OicpO1xuICBpZiAodG9vbCA9PT0gJ2NsYXVkZScgfHwgdG9vbCA9PT0gJ2JvdGgnKSB7XG4gICAgY29uc29sZS5sb2coJyAgQ2xhdWRlIENvZGU6IC9ib290c3RyYXAtZG9jcycpO1xuICB9XG4gIGlmICh0b29sID09PSAnY3Vyc29yJyB8fCB0b29sID09PSAnYm90aCcpIHtcbiAgICBjb25zb2xlLmxvZygnICBDdXJzb3I6IEFzayBcImdlbmVyYXRlIGluaXRpYWwgZG9jdW1lbnRhdGlvbiBmcm9tIHRoaXMgcmVwb1wiJyk7XG4gIH1cbiAgY29uc29sZS5sb2coKTtcbn1cbiJdfQ==
345
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY2xpL2NvbW1hbmRzL2FpLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBd01BLGdCQXVKQztBQS9WRCxnREFBd0I7QUFDeEIsd0RBQTBCO0FBQzFCLCtDQUE0QztBQVM1QyxzQ0FBc0M7QUFDdEMsS0FBSyxVQUFVLE1BQU0sQ0FBQyxRQUFnQixFQUFFLFlBQXFCO0lBQzNELE1BQU0sUUFBUSxHQUFHLHdEQUFhLFVBQVUsR0FBQyxDQUFDO0lBQzFDLE1BQU0sRUFBRSxHQUFHLFFBQVEsQ0FBQyxlQUFlLENBQUM7UUFDbEMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxLQUFLO1FBQ3BCLE1BQU0sRUFBRSxPQUFPLENBQUMsTUFBTTtLQUN2QixDQUFDLENBQUM7SUFFSCxPQUFPLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUU7UUFDN0IsTUFBTSxlQUFlLEdBQUcsWUFBWTtZQUNsQyxDQUFDLENBQUMsR0FBRyxRQUFRLEtBQUssWUFBWSxLQUFLO1lBQ25DLENBQUMsQ0FBQyxHQUFHLFFBQVEsSUFBSSxDQUFDO1FBRXBCLEVBQUUsQ0FBQyxRQUFRLENBQUMsZUFBZSxFQUFFLENBQUMsTUFBTSxFQUFFLEVBQUU7WUFDdEMsRUFBRSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ1gsT0FBTyxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsSUFBSSxZQUFZLElBQUksRUFBRSxDQUFDLENBQUM7UUFDL0MsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUM7QUFFRCxLQUFLLFVBQVUsWUFBWSxDQUFDLFFBQWdCLEVBQUUsT0FBMkM7SUFDdkYsT0FBTyxDQUFDLEdBQUcsQ0FBQyxLQUFLLFFBQVEsSUFBSSxDQUFDLENBQUM7SUFDL0IsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLE1BQU0s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QUMsc0VBQXNFLENBQUMsQ0FBQztRQUNwRixPQUFPLENBQUMsR0FBRyxFQUFFLENBQUM7SUFDaEIsQ0FBQztBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCBmcyBmcm9tICdmcy1leHRyYSc7XG5pbXBvcnQgeyBsb2dnZXIgfSBmcm9tICcuLi8uLi91dGlscy9sb2dnZXInO1xuXG50eXBlIEFJVG9vbCA9ICdjbGF1ZGUnIHwgJ2N1cnNvcicgfCAnYm90aCc7XG5cbmludGVyZmFjZSBBSU9wdGlvbnMge1xuICB0b29sPzogQUlUb29sO1xuICB1cGRhdGU/OiBib29sZWFuO1xufVxuXG4vLyBTaW1wbGUgcHJvbXB0IGhlbHBlciB1c2luZyByZWFkbGluZVxuYXN5bmMgZnVuY3Rpb24gcHJvbXB0KHF1ZXN0aW9uOiBzdHJpbmcsIGRlZmF1bHRWYWx1ZT86IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPiB7XG4gIGNvbnN0IHJlYWRsaW5lID0gYXdhaXQgaW1wb3J0KCdyZWFkbGluZScpO1xuICBjb25zdCBybCA9IHJlYWRsaW5lLmNyZWF0ZUludGVyZmFjZSh7XG4gICAgaW5wdXQ6IHByb2Nlc3Muc3RkaW4sXG4gICAgb3V0cHV0OiBwcm9jZXNzLnN0ZG91dCxcbiAgfSk7XG5cbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgY29uc3QgZGlzcGxheVF1ZXN0aW9uID0gZGVmYXVsdFZhbHVlIFxuICAgICAgPyBgJHtxdWVzdGlvbn0gKCR7ZGVmYXVsdFZhbHVlfSk6IGBcbiAgICAgIDogYCR7cXVlc3Rpb259OiBgO1xuICAgIFxuICAgIHJsLnF1ZXN0aW9uKGRpc3BsYXlRdWVzdGlvbiwgKGFuc3dlcikgPT4ge1xuICAgICAgcmwuY2xvc2UoKTtcbiAgICAgIHJlc29sdmUoYW5zd2VyLnRyaW0oKSB8fCBkZWZhdWx0VmFsdWUgfHwgJycpO1xuICAgIH0pO1xuICB9KTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gcHJvbXB0U2VsZWN0KHF1ZXN0aW9uOiBzdHJpbmcsIGNob2ljZXM6IHsgdmFsdWU6IHN0cmluZzsgbGFiZWw6IHN0cmluZyB9W10pOiBQcm9taXNlPHN0cmluZz4ge1xuICBjb25zb2xlLmxvZyhgXFxuJHtxdWVzdGlvbn1cXG5gKTtcbiAgY2hvaWNlcy5mb3JFYWNoKChjaG9pY2UsIGkpID0+IHtcbiAgICBjb25zb2xlLmxvZyhgICAke2kgKyAxfS4gJHtjaG9pY2UubGFiZWx9YCk7XG4gIH0pO1xuICBjb25zb2xlLmxvZygpO1xuICBcbiAgY29uc3QgcmVhZGxpbmUgPSBhd2FpdCBpbXBvcnQoJ3JlYWRsaW5lJyk7XG4gIGNvbnN0IHJsID0gcmVhZGxpbmUuY3JlYXRlSW50ZXJmYWNlKHtcbiAgICBpbnB1dDogcHJvY2Vzcy5zdGRpbixcbiAgICBvdXRwdXQ6IHByb2Nlc3Muc3Rkb3V0LFxuICB9KTtcblxuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICBybC5xdWVzdGlvbignRW50ZXIgbnVtYmVyOiAnLCAoYW5zd2VyKSA9PiB7XG4gICAgICBybC5jbG9zZSgpO1xuICAgICAgY29uc3QgaW5kZXggPSBwYXJzZUludChhbnN3ZXIudHJpbSgpLCAxMCkgLSAxO1xuICAgICAgaWYgKGluZGV4ID49IDAgJiYgaW5kZXggPCBjaG9pY2VzLmxlbmd0aCkge1xuICAgICAgICByZXNvbHZlKGNob2ljZXNbaW5kZXhdLnZhbHVlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIERlZmF1bHQgdG8gZmlyc3QgY2hvaWNlXG4gICAgICAgIHJlc29sdmUoY2hvaWNlc1swXS52YWx1ZSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xufVxuXG4vLyBDbGF1ZGUgQ29kZSBza2lsbHMgdG8gY3JlYXRlXG5jb25zdCBDTEFVREVfU0tJTExTID0gW1xuICAnYm9vdHN0cmFwLWRvY3MnLFxuICAnbWlncmF0ZS1kb2NzJyxcbiAgJ2ltcG9ydC1hcGktc3BlYycsXG4gICdzeW5jLWRvY3MnLFxuICAnY2hlY2stZG9jcycsXG4gICdjcmVhdGUtZG9jLXBhZ2UnLFxuICAndXBkYXRlLWRvY3MtanNvbicsXG4gICdnZW5lcmF0ZS1hcGktZG9jcycsXG4gICdkb2NzLWZyb20tY29kZScsXG5dO1xuXG4vLyBDdXJzb3IgcnVsZXMgdG8gY3JlYXRlXG5jb25zdCBDVVJTT1JfUlVMRVMgPSBbXG4gICdkZXZkb2MubWRjJyxcbiAgJ2RldmRvYy1ib290c3RyYXAubWRjJyxcbiAgJ2RldmRvYy1taWdyYXRlLm1kYycsXG4gICdkZXZkb2Mtc3luYy5tZGMnLFxuXTtcblxuLyoqXG4gKiBHZXQgdGhlIEFJIGFnZW50cyB0ZW1wbGF0ZSBkaXJlY3RvcnkgcGF0aCAoaGFuZGxlcyBib3RoIGRldmVsb3BtZW50IGFuZCBpbnN0YWxsZWQgcGFja2FnZSBzY2VuYXJpb3MpXG4gKi9cbmZ1bmN0aW9uIGdldFRlbXBsYXRlRGlyKCk6IHN0cmluZyB7XG4gIC8vIFRyeSByZWxhdGl2ZSB0byBjb21waWxlZCBkaXN0IChwYWNrYWdlcy9kZXZkb2MvZGlzdC9jbGkvY29tbWFuZHMgLT4gcGFja2FnZXMvZGV2ZG9jL2FpLWFnZW50cylcbiAgbGV0IHRlbXBsYXRlRGlyID0gcGF0aC5qb2luKF9fZGlybmFtZSwgJy4uJywgJy4uJywgJy4uJywgJ2FpLWFnZW50cycpO1xuICBcbiAgaWYgKGZzLmV4aXN0c1N5bmModGVtcGxhdGVEaXIpKSB7XG4gICAgcmV0dXJuIHRlbXBsYXRlRGlyO1xuICB9XG4gIFxuICAvLyBUcnkgcmVsYXRpdmUgdG8gc291cmNlIChwYWNrYWdlcy9kZXZkb2Mvc3JjL2NsaS9jb21tYW5kcyAtPiBwYWNrYWdlcy9kZXZkb2MvYWktYWdlbnRzKVxuICB0ZW1wbGF0ZURpciA9IHBhdGguam9pbihfX2Rpcm5hbWUsICcuLicsICcuLicsICcuLicsICdhaS1hZ2VudHMnKTtcbiAgXG4gIGlmIChmcy5leGlzdHNTeW5jKHRlbXBsYXRlRGlyKSkge1xuICAgIHJldHVybiB0ZW1wbGF0ZURpcjtcbiAgfVxuICBcbiAgLy8gVHJ5IGRldmRvYy90ZW1wbGF0ZXMgYXQgcmVwbyByb290IChkZXZlbG9wbWVudCAtIG1vbm9yZXBvIHN0cnVjdHVyZSlcbiAgLy8gX19kaXJuYW1lIGlzIHBhY2thZ2VzL2RldmRvYy9kaXN0L2NsaS9jb21tYW5kcyAtPiBnbyB1cCA1IGxldmVscyB0byByZXBvIHJvb3RcbiAgdGVtcGxhdGVEaXIgPSBwYXRoLmpvaW4oX19kaXJuYW1lLCAnLi4nLCAnLi4nLCAnLi4nLCAnLi4nLCAnLi4nLCAnZGV2ZG9jJywgJ3RlbXBsYXRlcycsICdzdGFydGVyJyk7XG4gIFxuICBpZiAoZnMuZXhpc3RzU3luYyh0ZW1wbGF0ZURpcikpIHtcbiAgICByZXR1cm4gdGVtcGxhdGVEaXI7XG4gIH1cbiAgXG4gIHRocm93IG5ldyBFcnJvcignQ291bGQgbm90IGZpbmQgdGVtcGxhdGUgZGlyZWN0b3J5Jyk7XG59XG5cbi8qKlxuICogQ29weSBDTEFVREUubWQgdG8gcHJvamVjdCByb290XG4gKiBSZXR1cm5zICdjcmVhdGVkJyB8ICd1cGRhdGVkJyB8ICdza2lwcGVkJ1xuICovXG5mdW5jdGlvbiBjb3B5Q2xhdWRlTWQocHJvamVjdFBhdGg6IHN0cmluZywgdGVtcGxhdGVEaXI6IHN0cmluZyk6ICdjcmVhdGVkJyB8ICd1cGRhdGVkJyB8ICdza2lwcGVkJyB7XG4gIGNvbnN0IHNvdXJjZVBhdGggPSBwYXRoLmpvaW4odGVtcGxhdGVEaXIsICdDTEFVREUubWQnKTtcbiAgY29uc3QgZGVzdFBhdGggPSBwYXRoLmpvaW4ocHJvamVjdFBhdGgsICdDTEFVREUubWQnKTtcbiAgXG4gIGlmICghZnMuZXhpc3RzU3luYyhzb3VyY2VQYXRoKSkge1xuICAgIHJldHVybiAnc2tpcHBlZCc7XG4gIH1cbiAgXG4gIGNvbnN0IGV4aXN0ZWQgPSBmcy5leGlzdHNTeW5jKGRlc3RQYXRoKTtcbiAgZnMuY29weVN5bmMoc291cmNlUGF0aCwgZGVzdFBhdGgpO1xuICByZXR1cm4gZXhpc3RlZCA/ICd1cGRhdGVkJyA6ICdjcmVhdGVkJztcbn1cblxuLyoqXG4gKiBDb3B5IENsYXVkZSBDb2RlIHNraWxscyB0byAuY2xhdWRlL3NraWxscy9cbiAqIFJldHVybnMgYXJyYXkgb2YgeyBza2lsbCwgc3RhdHVzOiAnY3JlYXRlZCcgfCAndXBkYXRlZCcgfVxuICovXG5mdW5jdGlvbiBjb3B5Q2xhdWRlU2tpbGxzKHByb2plY3RQYXRoOiBzdHJpbmcsIHRlbXBsYXRlRGlyOiBzdHJpbmcpOiB7IHNraWxsOiBzdHJpbmc7IHN0YXR1czogJ2NyZWF0ZWQnIHwgJ3VwZGF0ZWQnIH1bXSB7XG4gIGNvbnN0IHJlc3VsdHM6IHsgc2tpbGw6IHN0cmluZzsgc3RhdHVzOiAnY3JlYXRlZCcgfCAndXBkYXRlZCcgfVtdID0gW107XG4gIGNvbnN0IHNvdXJjZVNraWxsc0RpciA9IHBhdGguam9pbih0ZW1wbGF0ZURpciwgJy5jbGF1ZGUnLCAnc2tpbGxzJyk7XG4gIGNvbnN0IGRlc3RTa2lsbHNEaXIgPSBwYXRoLmpvaW4ocHJvamVjdFBhdGgsICcuY2xhdWRlJywgJ3NraWxscycpO1xuICBcbiAgaWYgKCFmcy5leGlzdHNTeW5jKHNvdXJjZVNraWxsc0RpcikpIHtcbiAgICBsb2dnZXIud2FybignQ2xhdWRlIHNraWxscyB0ZW1wbGF0ZSBkaXJlY3Rvcnkgbm90IGZvdW5kJyk7XG4gICAgcmV0dXJuIHJlc3VsdHM7XG4gIH1cbiAgXG4gIC8vIEVuc3VyZSBkZXN0aW5hdGlvbiBkaXJlY3RvcnkgZXhpc3RzXG4gIGZzLmVuc3VyZURpclN5bmMoZGVzdFNraWxsc0Rpcik7XG4gIFxuICBmb3IgKGNvbnN0IHNraWxsIG9mIENMQVVERV9TS0lMTFMpIHtcbiAgICBjb25zdCBzb3VyY2VEaXIgPSBwYXRoLmpvaW4oc291cmNlU2tpbGxzRGlyLCBza2lsbCk7XG4gICAgY29uc3QgZGVzdERpciA9IHBhdGguam9pbihkZXN0U2tpbGxzRGlyLCBza2lsbCk7XG4gICAgXG4gICAgaWYgKGZzLmV4aXN0c1N5bmMoc291cmNlRGlyKSkge1xuICAgICAgY29uc3QgZXhpc3RlZCA9IGZzLmV4aXN0c1N5bmMoZGVzdERpcik7XG4gICAgICBmcy5jb3B5U3luYyhzb3VyY2VEaXIsIGRlc3REaXIpO1xuICAgICAgcmVzdWx0cy5wdXNoKHsgc2tpbGwsIHN0YXR1czogZXhpc3RlZCA/ICd1cGRhdGVkJyA6ICdjcmVhdGVkJyB9KTtcbiAgICB9XG4gIH1cbiAgXG4gIHJldHVybiByZXN1bHRzO1xufVxuXG4vKipcbiAqIENvcHkgQ3Vyc29yIHJ1bGVzIHRvIC5jdXJzb3IvcnVsZXMvXG4gKiBSZXR1cm5zIGFycmF5IG9mIHsgcnVsZSwgc3RhdHVzOiAnY3JlYXRlZCcgfCAndXBkYXRlZCcgfVxuICovXG5mdW5jdGlvbiBjb3B5Q3Vyc29yUnVsZXMocHJvamVjdFBhdGg6IHN0cmluZywgdGVtcGxhdGVEaXI6IHN0cmluZyk6IHsgcnVsZTogc3RyaW5nOyBzdGF0dXM6ICdjcmVhdGVkJyB8ICd1cGRhdGVkJyB9W10ge1xuICBjb25zdCByZXN1bHRzOiB7IHJ1bGU6IHN0cmluZzsgc3RhdHVzOiAnY3JlYXRlZCcgfCAndXBkYXRlZCcgfVtdID0gW107XG4gIGNvbnN0IHNvdXJjZVJ1bGVzRGlyID0gcGF0aC5qb2luKHRlbXBsYXRlRGlyLCAnLmN1cnNvcicsICdydWxlcycpO1xuICBjb25zdCBkZXN0UnVsZXNEaXIgPSBwYXRoLmpvaW4ocHJvamVjdFBhdGgsICcuY3Vyc29yJywgJ3J1bGVzJyk7XG4gIFxuICBpZiAoIWZzLmV4aXN0c1N5bmMoc291cmNlUnVsZXNEaXIpKSB7XG4gICAgbG9nZ2VyLndhcm4oJ0N1cnNvciBydWxlcyB0ZW1wbGF0ZSBkaXJlY3Rvcnkgbm90IGZvdW5kJyk7XG4gICAgcmV0dXJuIHJlc3VsdHM7XG4gIH1cbiAgXG4gIC8vIEVuc3VyZSBkZXN0aW5hdGlvbiBkaXJlY3RvcnkgZXhpc3RzXG4gIGZzLmVuc3VyZURpclN5bmMoZGVzdFJ1bGVzRGlyKTtcbiAgXG4gIGZvciAoY29uc3QgcnVsZSBvZiBDVVJTT1JfUlVMRVMpIHtcbiAgICBjb25zdCBzb3VyY2VQYXRoID0gcGF0aC5qb2luKHNvdXJjZVJ1bGVzRGlyLCBydWxlKTtcbiAgICBjb25zdCBkZXN0UGF0aCA9IHBhdGguam9pbihkZXN0UnVsZXNEaXIsIHJ1bGUpO1xuICAgIFxuICAgIGlmIChmcy5leGlzdHNTeW5jKHNvdXJjZVBhdGgpKSB7XG4gICAgICBjb25zdCBleGlzdGVkID0gZnMuZXhpc3RzU3luYyhkZXN0UGF0aCk7XG4gICAgICBmcy5jb3B5U3luYyhzb3VyY2VQYXRoLCBkZXN0UGF0aCk7XG4gICAgICByZXN1bHRzLnB1c2goeyBydWxlLCBzdGF0dXM6IGV4aXN0ZWQgPyAndXBkYXRlZCcgOiAnY3JlYXRlZCcgfSk7XG4gICAgfVxuICB9XG4gIFxuICByZXR1cm4gcmVzdWx0cztcbn1cblxuLyoqXG4gKiBDaGVjayBpZiBBSSB0b29scyBhcmUgYWxyZWFkeSBpbnN0YWxsZWRcbiAqL1xuZnVuY3Rpb24gY2hlY2tFeGlzdGluZ0luc3RhbGxhdGlvbihwcm9qZWN0UGF0aDogc3RyaW5nKTogeyBjbGF1ZGU6IGJvb2xlYW47IGN1cnNvcjogYm9vbGVhbiB9IHtcbiAgY29uc3QgY2xhdWRlRGlyID0gcGF0aC5qb2luKHByb2plY3RQYXRoLCAnLmNsYXVkZScsICdza2lsbHMnKTtcbiAgY29uc3QgY3Vyc29yRGlyID0gcGF0aC5qb2luKHByb2plY3RQYXRoLCAnLmN1cnNvcicsICdydWxlcycpO1xuICBcbiAgcmV0dXJuIHtcbiAgICBjbGF1ZGU6IGZzLmV4aXN0c1N5bmMoY2xhdWRlRGlyKSAmJiBmcy5yZWFkZGlyU3luYyhjbGF1ZGVEaXIpLmxlbmd0aCA+IDAsXG4gICAgY3Vyc29yOiBmcy5leGlzdHNTeW5jKGN1cnNvckRpcikgJiYgZnMucmVhZGRpclN5bmMoY3Vyc29yRGlyKS5zb21lKGYgPT4gZi5zdGFydHNXaXRoKCdkZXZkb2MnKSksXG4gIH07XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBhaShvcHRpb25zOiBBSU9wdGlvbnMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc29sZS5sb2coKTtcbiAgXG4gIGNvbnN0IHByb2plY3RQYXRoID0gcHJvY2Vzcy5jd2QoKTtcbiAgY29uc3QgZXhpc3RpbmcgPSBjaGVja0V4aXN0aW5nSW5zdGFsbGF0aW9uKHByb2plY3RQYXRoKTtcbiAgY29uc3QgaXNVcGRhdGUgPSBvcHRpb25zLnVwZGF0ZSB8fCBleGlzdGluZy5jbGF1ZGUgfHwgZXhpc3RpbmcuY3Vyc29yO1xuICBcbiAgaWYgKGlzVXBkYXRlKSB7XG4gICAgbG9nZ2VyLmluZm8oJ0RldkRvYyBBSSBBZ2VudCBVcGRhdGUnKTtcbiAgfSBlbHNlIHtcbiAgICBsb2dnZXIuaW5mbygnRGV2RG9jIEFJIEFnZW50IFNldHVwJyk7XG4gIH1cbiAgY29uc29sZS5sb2coKTtcblxuICAvLyBDaGVjayBpZiB0aGlzIGlzIGEgRGV2RG9jIHByb2plY3RcbiAgY29uc3QgZG9jc0pzb25QYXRoID0gcGF0aC5qb2luKHByb2plY3RQYXRoLCAnZG9jcy5qc29uJyk7XG4gIGNvbnN0IGhhc0RvY3NKc29uID0gZnMuZXhpc3RzU3luYyhkb2NzSnNvblBhdGgpO1xuICBcbiAgaWYgKCFoYXNEb2NzSnNvbikge1xuICAgIGxvZ2dlci53YXJuKCdObyBkb2NzLmpzb24gZm91bmQuIFRoaXMgbWF5IG5vdCBiZSBhIERldkRvYyBwcm9qZWN0LicpO1xuICAgIGNvbnNvbGUubG9nKCk7XG4gIH1cblxuICAvLyBHZXQgdGVtcGxhdGUgZGlyZWN0b3J5XG4gIGxldCB0ZW1wbGF0ZURpcjogc3RyaW5nO1xuICB0cnkge1xuICAgIHRlbXBsYXRlRGlyID0gZ2V0VGVtcGxhdGVEaXIoKTtcbiAgfSBjYXRjaCB7XG4gICAgbG9nZ2VyLmVycm9yKCdDb3VsZCBub3QgZmluZCBBSSBhZ2VudCB0ZW1wbGF0ZXMuIFBsZWFzZSBlbnN1cmUgRGV2RG9jIGlzIGluc3RhbGxlZCBjb3JyZWN0bHkuJyk7XG4gICAgcHJvY2Vzcy5leGl0KDEpO1xuICB9XG5cbiAgLy8gR2V0IHRvb2wgc2VsZWN0aW9uIGlmIG5vdCBwcm92aWRlZFxuICBsZXQgdG9vbDogQUlUb29sID0gb3B0aW9ucy50b29sIHx8ICdib3RoJztcbiAgXG4gIGlmICghb3B0aW9ucy50b29sKSB7XG4gICAgLy8gSWYgdXBkYXRpbmcsIGRlZmF1bHQgdG8gdXBkYXRpbmcgd2hhdCdzIGFscmVhZHkgaW5zdGFsbGVkXG4gICAgaWYgKGlzVXBkYXRlICYmIGV4aXN0aW5nLmNsYXVkZSAmJiAhZXhpc3RpbmcuY3Vyc29yKSB7XG4gICAgICB0b29sID0gJ2NsYXVkZSc7XG4gICAgfSBlbHNlIGlmIChpc1VwZGF0ZSAmJiBleGlzdGluZy5jdXJzb3IgJiYgIWV4aXN0aW5nLmNsYXVkZSkge1xuICAgICAgdG9vbCA9ICdjdXJzb3InO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCB0b29sQ2hvaWNlcyA9IFtcbiAgICAgICAgeyB2YWx1ZTogJ2JvdGgnLCBsYWJlbDogJ0JvdGggLSBDbGF1ZGUgQ29kZSBhbmQgQ3Vyc29yJyB9LFxuICAgICAgICB7IHZhbHVlOiAnY2xhdWRlJywgbGFiZWw6ICdDbGF1ZGUgQ29kZSAtIFNraWxscyBhbmQgQ0xBVURFLm1kJyB9LFxuICAgICAgICB7IHZhbHVlOiAnY3Vyc29yJywgbGFiZWw6ICdDdXJzb3IgLSBSdWxlcyAoLmN1cnNvci9ydWxlcy8pJyB9LFxuICAgICAgXTtcblxuICAgICAgdG9vbCA9IGF3YWl0IHByb21wdFNlbGVjdCgnV2hpY2ggQUkgdG9vbCBkbyB5b3UgdXNlPycsIHRvb2xDaG9pY2VzKSBhcyBBSVRvb2w7XG4gICAgfVxuICB9XG5cbiAgY29uc29sZS5sb2coKTtcbiAgaWYgKGlzVXBkYXRlKSB7XG4gICAgbG9nZ2VyLmluZm8oJ1VwZGF0aW5nIEFJIGFnZW50IGNvbmZpZ3VyYXRpb24uLi4nKTtcbiAgfSBlbHNlIHtcbiAgICBsb2dnZXIuaW5mbygnU2V0dGluZyB1cCBBSSBhZ2VudCBjb25maWd1cmF0aW9uLi4uJyk7XG4gIH1cbiAgY29uc29sZS5sb2coKTtcblxuICBsZXQgY3JlYXRlZENvdW50ID0gMDtcbiAgbGV0IHVwZGF0ZWRDb3VudCA9IDA7XG5cbiAgLy8gU2V0dXAgQ2xhdWRlIENvZGVcbiAgaWYgKHRvb2wgPT09ICdjbGF1ZGUnIHx8IHRvb2wgPT09ICdib3RoJykge1xuICAgIC8vIENvcHkgQ0xBVURFLm1kXG4gICAgY29uc3QgY2xhdWRlTWRTdGF0dXMgPSBjb3B5Q2xhdWRlTWQocHJvamVjdFBhdGgsIHRlbXBsYXRlRGlyKTtcbiAgICBpZiAoY2xhdWRlTWRTdGF0dXMgPT09ICdjcmVhdGVkJykge1xuICAgICAgbG9nZ2VyLnN1Y2Nlc3MoJ0NyZWF0ZWQgQ0xBVURFLm1kJyk7XG4gICAgICBjcmVhdGVkQ291bnQrKztcbiAgICB9IGVsc2UgaWYgKGNsYXVkZU1kU3RhdHVzID09PSAndXBkYXRlZCcpIHtcbiAgICAgIGxvZ2dlci5zdWNjZXNzKCdVcGRhdGVkIENMQVVERS5tZCcpO1xuICAgICAgdXBkYXRlZENvdW50Kys7XG4gICAgfVxuICAgIFxuICAgIC8vIENvcHkgc2tpbGxzXG4gICAgY29uc3Qgc2tpbGxSZXN1bHRzID0gY29weUNsYXVkZVNraWxscyhwcm9qZWN0UGF0aCwgdGVtcGxhdGVEaXIpO1xuICAgIGZvciAoY29uc3QgeyBza2lsbCwgc3RhdHVzIH0gb2Ygc2tpbGxSZXN1bHRzKSB7XG4gICAgICBpZiAoc3RhdHVzID09PSAnY3JlYXRlZCcpIHtcbiAgICAgICAgbG9nZ2VyLnN1Y2Nlc3MoYENyZWF0ZWQgLmNsYXVkZS9za2lsbHMvJHtza2lsbH0vU0tJTEwubWRgKTtcbiAgICAgICAgY3JlYXRlZENvdW50Kys7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsb2dnZXIuc3VjY2VzcyhgVXBkYXRlZCAuY2xhdWRlL3NraWxscy8ke3NraWxsfS9TS0lMTC5tZGApO1xuICAgICAgICB1cGRhdGVkQ291bnQrKztcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBTZXR1cCBDdXJzb3JcbiAgaWYgKHRvb2wgPT09ICdjdXJzb3InIHx8IHRvb2wgPT09ICdib3RoJykge1xuICAgIGNvbnN0IHJ1bGVSZXN1bHRzID0gY29weUN1cnNvclJ1bGVzKHByb2plY3RQYXRoLCB0ZW1wbGF0ZURpcik7XG4gICAgZm9yIChjb25zdCB7IHJ1bGUsIHN0YXR1cyB9IG9mIHJ1bGVSZXN1bHRzKSB7XG4gICAgICBpZiAoc3RhdHVzID09PSAnY3JlYXRlZCcpIHtcbiAgICAgICAgbG9nZ2VyLnN1Y2Nlc3MoYENyZWF0ZWQgLmN1cnNvci9ydWxlcy8ke3J1bGV9YCk7XG4gICAgICAgIGNyZWF0ZWRDb3VudCsrO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbG9nZ2VyLnN1Y2Nlc3MoYFVwZGF0ZWQgLmN1cnNvci9ydWxlcy8ke3J1bGV9YCk7XG4gICAgICAgIHVwZGF0ZWRDb3VudCsrO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIFN1bW1hcnlcbiAgY29uc29sZS5sb2coKTtcbiAgaWYgKHVwZGF0ZWRDb3VudCA+IDAgJiYgY3JlYXRlZENvdW50ID4gMCkge1xuICAgIGxvZ2dlci5zdWNjZXNzKGBBSSBhZ2VudCBjb25maWd1cmF0aW9uIGNvbXBsZXRlISAoJHtjcmVhdGVkQ291bnR9IGNyZWF0ZWQsICR7dXBkYXRlZENvdW50fSB1cGRhdGVkKWApO1xuICB9IGVsc2UgaWYgKHVwZGF0ZWRDb3VudCA+IDApIHtcbiAgICBsb2dnZXIuc3VjY2VzcyhgQUkgYWdlbnQgY29uZmlndXJhdGlvbiB1cGRhdGVkISAoJHt1cGRhdGVkQ291bnR9IGZpbGVzKWApO1xuICB9IGVsc2Uge1xuICAgIGxvZ2dlci5zdWNjZXNzKCdBSSBhZ2VudCBjb25maWd1cmF0aW9uIGNvbXBsZXRlIScpO1xuICB9XG4gIGNvbnNvbGUubG9nKCk7XG5cbiAgaWYgKHRvb2wgPT09ICdjbGF1ZGUnIHx8IHRvb2wgPT09ICdib3RoJykge1xuICAgIGNvbnNvbGUubG9nKCdBdmFpbGFibGUgQ2xhdWRlIENvZGUgY29tbWFuZHM6Jyk7XG4gICAgY29uc29sZS5sb2coJyAgL2Jvb3RzdHJhcC1kb2NzICAgIC0gQW5hbHl6ZSByZXBvIGFuZCBnZW5lcmF0ZSBpbml0aWFsIGRvY3VtZW50YXRpb24nKTtcbiAgICBjb25zb2xlLmxvZygnICAvbWlncmF0ZS1kb2NzICAgICAgLSBNaWdyYXRlIGZyb20gTWludGxpZnksIERvY3VzYXVydXMsIEdpdEJvb2ssIGV0Yy4nKTtcbiAgICBjb25zb2xlLmxvZygnICAvaW1wb3J0LWFwaS1zcGVjICAgLSBJbXBvcnQgT3BlbkFQSSwgR3JhcGhRTCwgb3IgQXN5bmNBUEkgc3BlY3MnKTtcbiAgICBjb25zb2xlLmxvZygnICAvc3luYy1kb2NzICAgICAgICAgLSBGaW5kIGFuZCBmaXggb3V0ZGF0ZWQgZG9jdW1lbnRhdGlvbicpO1xuICAgIGNvbnNvbGUubG9nKCcgIC9jaGVjay1kb2NzICAgICAgICAtIFF1aWNrIGhlYWx0aCBjaGVjayB3aXRob3V0IGNoYW5nZXMnKTtcbiAgICBjb25zb2xlLmxvZygnICAvY3JlYXRlLWRvYy1wYWdlICAgLSBDcmVhdGUgYSBuZXcgZG9jdW1lbnRhdGlvbiBwYWdlJyk7XG4gICAgY29uc29sZS5sb2coJyAgL3VwZGF0ZS1kb2NzLWpzb24gIC0gQWRkIHBhZ2VzIHRvIG5hdmlnYXRpb24nKTtcbiAgICBjb25zb2xlLmxvZygnICAvZ2VuZXJhdGUtYXBpLWRvY3MgLSBHZW5lcmF0ZSBBUEkgZG9jdW1lbnRhdGlvbicpO1xuICAgIGNvbnNvbGUubG9nKCcgIC9kb2NzLWZyb20tY29kZSAgICAtIEdlbmVyYXRlIGRvY3MgZnJvbSBzcGVjaWZpYyBjb2RlIGZpbGVzJyk7XG4gICAgY29uc29sZS5sb2coKTtcbiAgfVxuXG4gIGlmICh0b29sID09PSAnY3Vyc29yJyB8fCB0b29sID09PSAnYm90aCcpIHtcbiAgICBjb25zb2xlLmxvZygnQ3Vyc29yIHJ1bGVzIGNvbmZpZ3VyZWQgZm9yICoubWR4IGZpbGVzLicpO1xuICAgIGNvbnNvbGUubG9nKCk7XG4gICAgY29uc29sZS5sb2coJ1N1Z2dlc3RlZCBwcm9tcHRzIGluIEFnZW50IG1vZGU6Jyk7XG4gICAgY29uc29sZS5sb2coJyAgXCJBbmFseXplIHRoaXMgcmVwbyBhbmQgZ2VuZXJhdGUgaW5pdGlhbCBkb2N1bWVudGF0aW9uXCInKTtcbiAgICBjb25zb2xlLmxvZygnICBcIk1pZ3JhdGUgbXkgTWludGxpZnkgZG9jcyB0byBEZXZEb2MgZm9ybWF0XCInKTtcbiAgICBjb25zb2xlLmxvZygnICBcIkNoZWNrIG15IGRvY3MgZm9yIG91dGRhdGVkIGNvbnRlbnRcIicpO1xuICAgIGNvbnNvbGUubG9nKCcgIFwiQ3JlYXRlIGEgbmV3IGd1aWRlIGFib3V0IGF1dGhlbnRpY2F0aW9uXCInKTtcbiAgICBjb25zb2xlLmxvZygpO1xuICB9XG5cbiAgY29uc29sZS5sb2coJ1F1aWNrIHN0YXJ0OicpO1xuICBpZiAodG9vbCA9PT0gJ2NsYXVkZScgfHwgdG9vbCA9PT0gJ2JvdGgnKSB7XG4gICAgY29uc29sZS5sb2coJyAgQ2xhdWRlIENvZGU6IC9ib290c3RyYXAtZG9jcycpO1xuICB9XG4gIGlmICh0b29sID09PSAnY3Vyc29yJyB8fCB0b29sID09PSAnYm90aCcpIHtcbiAgICBjb25zb2xlLmxvZygnICBDdXJzb3I6IEFzayBcImdlbmVyYXRlIGluaXRpYWwgZG9jdW1lbnRhdGlvbiBmcm9tIHRoaXMgcmVwb1wiJyk7XG4gIH1cbiAgY29uc29sZS5sb2coKTtcbiAgXG4gIGlmIChpc1VwZGF0ZSkge1xuICAgIGNvbnNvbGUubG9nKCdUaXA6IFJlc3RhcnQgQ2xhdWRlIENvZGUgb3IgQ3Vyc29yIHRvIGxvYWQgdGhlIHVwZGF0ZWQgc2tpbGxzL3J1bGVzLicpO1xuICAgIGNvbnNvbGUubG9nKCk7XG4gIH1cbn1cbiJdfQ==