@dollhousemcp/mcp-server 1.7.1 → 1.7.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/dist/auth/GitHubAuthManager.js +2 -2
- package/dist/config/ConfigManager.d.ts +158 -25
- package/dist/config/ConfigManager.d.ts.map +1 -1
- package/dist/config/ConfigManager.js +627 -88
- package/dist/generated/version.d.ts +2 -2
- package/dist/generated/version.js +3 -3
- package/dist/handlers/ConfigHandler.d.ts +32 -0
- package/dist/handlers/ConfigHandler.d.ts.map +1 -0
- package/dist/handlers/ConfigHandler.js +202 -0
- package/dist/handlers/SyncHandlerV2.d.ts +42 -0
- package/dist/handlers/SyncHandlerV2.d.ts.map +1 -0
- package/dist/handlers/SyncHandlerV2.js +231 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19 -3
- package/dist/portfolio/GitHubPortfolioIndexer.d.ts +0 -1
- package/dist/portfolio/GitHubPortfolioIndexer.d.ts.map +1 -1
- package/dist/portfolio/GitHubPortfolioIndexer.js +36 -16
- package/dist/portfolio/PortfolioRepoManager.d.ts +2 -1
- package/dist/portfolio/PortfolioRepoManager.d.ts.map +1 -1
- package/dist/portfolio/PortfolioRepoManager.js +2 -1
- package/dist/portfolio/PortfolioSyncManager.d.ts +127 -0
- package/dist/portfolio/PortfolioSyncManager.d.ts.map +1 -0
- package/dist/portfolio/PortfolioSyncManager.js +818 -0
- package/dist/security/audit/config/suppressions.d.ts.map +1 -1
- package/dist/security/audit/config/suppressions.js +54 -2
- package/dist/security/secureYamlParser.d.ts +46 -2
- package/dist/security/secureYamlParser.d.ts.map +1 -1
- package/dist/security/secureYamlParser.js +47 -3
- package/dist/server/ServerSetup.d.ts.map +1 -1
- package/dist/server/ServerSetup.js +16 -10
- package/dist/server/tools/ConfigToolsV2.d.ts +10 -0
- package/dist/server/tools/ConfigToolsV2.d.ts.map +1 -0
- package/dist/server/tools/ConfigToolsV2.js +110 -0
- package/dist/server/types.d.ts +2 -0
- package/dist/server/types.d.ts.map +1 -1
- package/dist/server/types.js +1 -1
- package/dist/utils/logger.d.ts +45 -0
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +202 -9
- package/package.json +1 -1
|
@@ -1,27 +1,33 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* ConfigManager -
|
|
2
|
+
* ConfigManager - Centralized configuration management for DollhouseMCP
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Features:
|
|
5
|
+
* - YAML-based configuration file
|
|
6
|
+
* - Default values with user overrides
|
|
7
|
+
* - Migration from environment variables
|
|
8
|
+
* - Validation and type safety
|
|
9
|
+
* - Atomic updates with backup
|
|
10
|
+
* - Privacy-first defaults
|
|
11
|
+
* - OAuth client ID storage for Claude Desktop integration
|
|
7
12
|
*/
|
|
8
13
|
import * as fs from 'fs/promises';
|
|
9
14
|
import * as path from 'path';
|
|
10
15
|
import * as os from 'os';
|
|
16
|
+
import * as yaml from 'js-yaml';
|
|
17
|
+
import { logger } from '../utils/logger.js';
|
|
18
|
+
import { SecureYamlParser } from '../security/secureYamlParser.js';
|
|
11
19
|
export class ConfigManager {
|
|
12
20
|
static instance = null;
|
|
13
21
|
static instanceLock = false;
|
|
14
22
|
configDir;
|
|
15
23
|
configPath;
|
|
16
|
-
|
|
24
|
+
backupPath;
|
|
25
|
+
config = null;
|
|
17
26
|
constructor() {
|
|
18
27
|
// Initialize paths
|
|
19
28
|
this.configDir = path.join(os.homedir(), '.dollhouse');
|
|
20
|
-
this.configPath = path.join(this.configDir, 'config.
|
|
21
|
-
|
|
22
|
-
this.config = {
|
|
23
|
-
version: '1.0.0'
|
|
24
|
-
};
|
|
29
|
+
this.configPath = path.join(this.configDir, 'config.yml');
|
|
30
|
+
this.backupPath = path.join(this.configDir, 'config.yml.backup');
|
|
25
31
|
}
|
|
26
32
|
/**
|
|
27
33
|
* Thread-safe singleton instance getter
|
|
@@ -47,67 +53,192 @@ export class ConfigManager {
|
|
|
47
53
|
return ConfigManager.instance;
|
|
48
54
|
}
|
|
49
55
|
/**
|
|
50
|
-
*
|
|
51
|
-
|
|
56
|
+
* Get default configuration
|
|
57
|
+
*/
|
|
58
|
+
getDefaultConfig() {
|
|
59
|
+
return {
|
|
60
|
+
version: '1.0.0',
|
|
61
|
+
user: {
|
|
62
|
+
username: null,
|
|
63
|
+
email: null,
|
|
64
|
+
display_name: null
|
|
65
|
+
},
|
|
66
|
+
github: {
|
|
67
|
+
portfolio: {
|
|
68
|
+
repository_url: null,
|
|
69
|
+
repository_name: 'dollhouse-portfolio',
|
|
70
|
+
default_branch: 'main',
|
|
71
|
+
auto_create: true
|
|
72
|
+
},
|
|
73
|
+
auth: {
|
|
74
|
+
use_oauth: true,
|
|
75
|
+
token_source: 'environment'
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
sync: {
|
|
79
|
+
enabled: false, // Privacy first - off by default
|
|
80
|
+
individual: {
|
|
81
|
+
require_confirmation: true,
|
|
82
|
+
show_diff_before_sync: true,
|
|
83
|
+
track_versions: true,
|
|
84
|
+
keep_history: 10
|
|
85
|
+
},
|
|
86
|
+
bulk: {
|
|
87
|
+
upload_enabled: false, // Requires explicit enablement
|
|
88
|
+
download_enabled: false,
|
|
89
|
+
require_preview: true,
|
|
90
|
+
respect_local_only: true
|
|
91
|
+
},
|
|
92
|
+
privacy: {
|
|
93
|
+
scan_for_secrets: true,
|
|
94
|
+
scan_for_pii: true,
|
|
95
|
+
warn_on_sensitive: true,
|
|
96
|
+
excluded_patterns: [
|
|
97
|
+
'*.secret',
|
|
98
|
+
'*-private.*',
|
|
99
|
+
'credentials/**',
|
|
100
|
+
'personal/**'
|
|
101
|
+
]
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
collection: {
|
|
105
|
+
auto_submit: false, // Never auto-submit
|
|
106
|
+
require_review: true,
|
|
107
|
+
add_attribution: true
|
|
108
|
+
},
|
|
109
|
+
elements: {
|
|
110
|
+
auto_activate: {},
|
|
111
|
+
default_element_dir: path.join(os.homedir(), '.dollhouse', 'portfolio')
|
|
112
|
+
},
|
|
113
|
+
display: {
|
|
114
|
+
persona_indicators: {
|
|
115
|
+
enabled: true,
|
|
116
|
+
style: 'minimal',
|
|
117
|
+
include_emoji: true
|
|
118
|
+
},
|
|
119
|
+
verbose_logging: false,
|
|
120
|
+
show_progress: true
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Initialize configuration
|
|
52
126
|
*/
|
|
53
|
-
async
|
|
127
|
+
async initialize() {
|
|
128
|
+
// Always reload config from disk if it exists, even if we have defaults in memory
|
|
129
|
+
// This ensures we pick up any manual edits or saved settings
|
|
54
130
|
try {
|
|
55
|
-
//
|
|
56
|
-
await fs.
|
|
57
|
-
//
|
|
58
|
-
|
|
59
|
-
await
|
|
60
|
-
await fs.chmod(this.configPath, 0o600);
|
|
131
|
+
// Ensure config directory exists with proper permissions (0o700 = owner only)
|
|
132
|
+
await fs.mkdir(this.configDir, { recursive: true, mode: 0o700 });
|
|
133
|
+
// Load or create config
|
|
134
|
+
if (await this.configExists()) {
|
|
135
|
+
await this.loadConfig();
|
|
61
136
|
}
|
|
62
|
-
|
|
63
|
-
//
|
|
137
|
+
else {
|
|
138
|
+
// Create default config
|
|
139
|
+
this.config = this.getDefaultConfig();
|
|
140
|
+
// Try to migrate from environment variables
|
|
141
|
+
await this.migrateFromEnvironment();
|
|
142
|
+
// Save the config
|
|
143
|
+
await this.saveConfig();
|
|
144
|
+
logger.info('Created new configuration file', {
|
|
145
|
+
path: this.configPath
|
|
146
|
+
});
|
|
64
147
|
}
|
|
65
148
|
}
|
|
66
149
|
catch (error) {
|
|
67
|
-
|
|
68
|
-
|
|
150
|
+
logger.error('Failed to initialize configuration', {
|
|
151
|
+
error: error instanceof Error ? error.message : String(error)
|
|
152
|
+
});
|
|
153
|
+
// Use defaults in memory
|
|
154
|
+
this.config = this.getDefaultConfig();
|
|
69
155
|
}
|
|
70
156
|
}
|
|
71
157
|
/**
|
|
72
|
-
* Load configuration from file
|
|
158
|
+
* Load configuration from file
|
|
73
159
|
*/
|
|
74
160
|
async loadConfig() {
|
|
75
161
|
try {
|
|
76
|
-
|
|
77
|
-
|
|
162
|
+
const content = await fs.readFile(this.configPath, 'utf-8');
|
|
163
|
+
/**
|
|
164
|
+
* IMPORTANT: Parser Selection for Different File Types
|
|
165
|
+
*
|
|
166
|
+
* We use DIFFERENT parsers for different file types:
|
|
167
|
+
*
|
|
168
|
+
* 1. js-yaml (used here) - For PURE YAML files:
|
|
169
|
+
* - Configuration files (config.yml)
|
|
170
|
+
* - Data files without markdown content
|
|
171
|
+
* - Any .yml or .yaml file that's just YAML
|
|
172
|
+
* Example format:
|
|
173
|
+
* ```yaml
|
|
174
|
+
* version: 1.0.0
|
|
175
|
+
* user:
|
|
176
|
+
* username: johndoe
|
|
177
|
+
* email: john@example.com
|
|
178
|
+
* ```
|
|
179
|
+
*
|
|
180
|
+
* 2. SecureYamlParser - For MARKDOWN files with YAML frontmatter:
|
|
181
|
+
* - Persona files (*.md in personas/)
|
|
182
|
+
* - Skill files (*.md in skills/)
|
|
183
|
+
* - Template files (*.md in templates/)
|
|
184
|
+
* - Any .md file with frontmatter between --- markers
|
|
185
|
+
* Example format:
|
|
186
|
+
* ```markdown
|
|
187
|
+
* ---
|
|
188
|
+
* name: Creative Writer
|
|
189
|
+
* description: A creative assistant
|
|
190
|
+
* ---
|
|
191
|
+
* # Instructions
|
|
192
|
+
* You are a creative writer...
|
|
193
|
+
* ```
|
|
194
|
+
*
|
|
195
|
+
* The config file is PURE YAML, so we use js-yaml directly with FAILSAFE_SCHEMA
|
|
196
|
+
* for security (prevents code execution via YAML tags).
|
|
197
|
+
* SECURITY: This is NOT a vulnerability - FAILSAFE_SCHEMA prevents code execution
|
|
198
|
+
*/
|
|
199
|
+
let loadedData;
|
|
78
200
|
try {
|
|
79
|
-
|
|
201
|
+
// Using yaml with FAILSAFE_SCHEMA is secure - prevents code execution
|
|
202
|
+
loadedData = yaml.load(content, {
|
|
203
|
+
schema: yaml.FAILSAFE_SCHEMA // Safe schema prevents code execution
|
|
204
|
+
});
|
|
80
205
|
}
|
|
81
|
-
catch (
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
206
|
+
catch (yamlError) {
|
|
207
|
+
throw new Error(`Invalid YAML in configuration file: ${yamlError instanceof Error ? yamlError.message : String(yamlError)}`);
|
|
208
|
+
}
|
|
209
|
+
if (!loadedData || typeof loadedData !== 'object') {
|
|
210
|
+
throw new Error('Invalid configuration format');
|
|
86
211
|
}
|
|
212
|
+
logger.debug('Loaded config from file', {
|
|
213
|
+
username: loadedData.user?.username,
|
|
214
|
+
email: loadedData.user?.email,
|
|
215
|
+
syncEnabled: loadedData.sync?.enabled
|
|
216
|
+
});
|
|
217
|
+
this.config = this.mergeWithDefaults(loadedData);
|
|
218
|
+
// Fix any string booleans that might have been saved incorrectly
|
|
219
|
+
this.fixConfigTypes();
|
|
220
|
+
logger.debug('Configuration loaded successfully', {
|
|
221
|
+
username: this.config.user.username,
|
|
222
|
+
syncEnabled: this.config.sync.enabled
|
|
223
|
+
});
|
|
87
224
|
}
|
|
88
225
|
catch (error) {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
`Please check file permissions or run with appropriate privileges.`);
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
else {
|
|
109
|
-
throw error;
|
|
110
|
-
}
|
|
226
|
+
logger.error('Failed to load configuration', {
|
|
227
|
+
error: error instanceof Error ? error.message : String(error)
|
|
228
|
+
});
|
|
229
|
+
throw error;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Check if config file exists
|
|
234
|
+
*/
|
|
235
|
+
async configExists() {
|
|
236
|
+
try {
|
|
237
|
+
await fs.access(this.configPath);
|
|
238
|
+
return true;
|
|
239
|
+
}
|
|
240
|
+
catch {
|
|
241
|
+
return false;
|
|
111
242
|
}
|
|
112
243
|
}
|
|
113
244
|
/**
|
|
@@ -121,7 +252,7 @@ export class ConfigManager {
|
|
|
121
252
|
return envClientId;
|
|
122
253
|
}
|
|
123
254
|
// Fall back to config file
|
|
124
|
-
return this.config
|
|
255
|
+
return this.config?.github?.auth?.client_id || null;
|
|
125
256
|
}
|
|
126
257
|
/**
|
|
127
258
|
* Set GitHub OAuth client ID in config file
|
|
@@ -130,27 +261,91 @@ export class ConfigManager {
|
|
|
130
261
|
if (!ConfigManager.validateClientId(clientId)) {
|
|
131
262
|
throw new Error(`Invalid GitHub client ID format. Expected format: Ov23li followed by at least 14 alphanumeric characters (e.g., Ov23liABCDEFGHIJKLMN)`);
|
|
132
263
|
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
264
|
+
if (!this.config) {
|
|
265
|
+
this.config = this.getDefaultConfig();
|
|
266
|
+
}
|
|
267
|
+
// Ensure github.auth object exists
|
|
268
|
+
if (!this.config.github) {
|
|
269
|
+
this.config.github = this.getDefaultConfig().github;
|
|
136
270
|
}
|
|
137
|
-
this.config.
|
|
271
|
+
if (!this.config.github.auth) {
|
|
272
|
+
this.config.github.auth = this.getDefaultConfig().github.auth;
|
|
273
|
+
}
|
|
274
|
+
this.config.github.auth.client_id = clientId;
|
|
138
275
|
await this.saveConfig();
|
|
139
276
|
}
|
|
140
277
|
/**
|
|
141
|
-
* Get
|
|
142
|
-
* @returns A defensive copy of the configuration object
|
|
278
|
+
* Get the current configuration
|
|
143
279
|
*/
|
|
144
280
|
getConfig() {
|
|
145
|
-
|
|
281
|
+
if (!this.config) {
|
|
282
|
+
throw new Error('Configuration not initialized');
|
|
283
|
+
}
|
|
284
|
+
return this.config;
|
|
146
285
|
}
|
|
147
286
|
/**
|
|
148
|
-
*
|
|
149
|
-
* @param newConfig The new configuration to set
|
|
287
|
+
* Get a specific setting using dot notation
|
|
150
288
|
*/
|
|
151
|
-
|
|
152
|
-
this.config
|
|
289
|
+
getSetting(path, defaultValue) {
|
|
290
|
+
if (!this.config) {
|
|
291
|
+
return defaultValue;
|
|
292
|
+
}
|
|
293
|
+
const keys = path.split('.');
|
|
294
|
+
let value = this.config;
|
|
295
|
+
for (const key of keys) {
|
|
296
|
+
if (value && typeof value === 'object' && key in value) {
|
|
297
|
+
value = value[key];
|
|
298
|
+
}
|
|
299
|
+
else {
|
|
300
|
+
return defaultValue;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
return value;
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Update a specific setting using dot notation
|
|
307
|
+
* SECURITY FIX (PR #895): Added prototype pollution protection
|
|
308
|
+
* Previously: Direct property assignment allowed __proto__ injection
|
|
309
|
+
* Now: Validates keys against forbidden properties before assignment
|
|
310
|
+
*/
|
|
311
|
+
async updateSetting(path, value) {
|
|
312
|
+
if (!this.config) {
|
|
313
|
+
await this.initialize();
|
|
314
|
+
}
|
|
315
|
+
const keys = path.split('.');
|
|
316
|
+
// SECURITY: Validate all keys to prevent prototype pollution
|
|
317
|
+
const FORBIDDEN_KEYS = ['__proto__', 'constructor', 'prototype'];
|
|
318
|
+
for (const key of keys) {
|
|
319
|
+
if (FORBIDDEN_KEYS.includes(key)) {
|
|
320
|
+
throw new Error(`Forbidden property in path: ${key}`);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
let current = this.config;
|
|
324
|
+
const previousValue = this.getSetting(path);
|
|
325
|
+
// Navigate to the parent object
|
|
326
|
+
for (let i = 0; i < keys.length - 1; i++) {
|
|
327
|
+
const key = keys[i];
|
|
328
|
+
if (!(key in current)) {
|
|
329
|
+
current[key] = {};
|
|
330
|
+
}
|
|
331
|
+
current = current[key];
|
|
332
|
+
}
|
|
333
|
+
// Set the value
|
|
334
|
+
const lastKey = keys[keys.length - 1];
|
|
335
|
+
current[lastKey] = value;
|
|
336
|
+
// Save the configuration
|
|
153
337
|
await this.saveConfig();
|
|
338
|
+
logger.info('Configuration setting updated', {
|
|
339
|
+
path,
|
|
340
|
+
previousValue,
|
|
341
|
+
newValue: value
|
|
342
|
+
});
|
|
343
|
+
return {
|
|
344
|
+
success: true,
|
|
345
|
+
message: `Setting '${path}' updated successfully`,
|
|
346
|
+
previousValue,
|
|
347
|
+
newValue: value
|
|
348
|
+
};
|
|
154
349
|
}
|
|
155
350
|
/**
|
|
156
351
|
* Validate GitHub OAuth client ID format
|
|
@@ -174,43 +369,387 @@ export class ConfigManager {
|
|
|
174
369
|
return clientIdPattern.test(clientId);
|
|
175
370
|
}
|
|
176
371
|
/**
|
|
177
|
-
*
|
|
372
|
+
* Save configuration to file
|
|
178
373
|
*/
|
|
179
|
-
async
|
|
374
|
+
async saveConfig() {
|
|
375
|
+
if (!this.config) {
|
|
376
|
+
throw new Error('No configuration to save');
|
|
377
|
+
}
|
|
180
378
|
try {
|
|
181
|
-
|
|
379
|
+
// Create backup of existing config
|
|
380
|
+
if (await this.configExists()) {
|
|
381
|
+
await fs.copyFile(this.configPath, this.backupPath);
|
|
382
|
+
}
|
|
383
|
+
// Convert to YAML
|
|
384
|
+
// Note: We use js-yaml's dump() for pure YAML output (no frontmatter markers)
|
|
385
|
+
// This creates a standard YAML file, not a markdown file with frontmatter
|
|
386
|
+
const yamlContent = yaml.dump(this.config, {
|
|
387
|
+
indent: 2,
|
|
388
|
+
lineWidth: 120,
|
|
389
|
+
noRefs: true,
|
|
390
|
+
sortKeys: false
|
|
391
|
+
// Using default schema (not FAILSAFE) for dump to preserve types like booleans
|
|
392
|
+
});
|
|
393
|
+
// Write atomically with proper permissions (0o600 = owner read/write only)
|
|
394
|
+
const tempPath = `${this.configPath}.tmp`;
|
|
395
|
+
await fs.writeFile(tempPath, yamlContent, { encoding: 'utf-8', mode: 0o600 });
|
|
396
|
+
await fs.rename(tempPath, this.configPath);
|
|
397
|
+
logger.debug('Configuration saved successfully');
|
|
398
|
+
// Log audit event for configuration update
|
|
399
|
+
logger.debug('Configuration update audit', {
|
|
400
|
+
event: 'CONFIG_UPDATED',
|
|
401
|
+
source: 'ConfigManager.saveConfig',
|
|
402
|
+
timestamp: new Date().toISOString()
|
|
403
|
+
});
|
|
182
404
|
}
|
|
183
405
|
catch (error) {
|
|
184
|
-
|
|
185
|
-
|
|
406
|
+
logger.error('Failed to save configuration', {
|
|
407
|
+
error: error instanceof Error ? error.message : String(error)
|
|
408
|
+
});
|
|
409
|
+
// Try to restore backup
|
|
410
|
+
if (await this.backupExists()) {
|
|
411
|
+
await fs.copyFile(this.backupPath, this.configPath);
|
|
412
|
+
logger.info('Restored configuration from backup');
|
|
186
413
|
}
|
|
187
414
|
throw error;
|
|
188
415
|
}
|
|
189
416
|
}
|
|
190
417
|
/**
|
|
191
|
-
*
|
|
418
|
+
* Check if backup exists
|
|
192
419
|
*/
|
|
193
|
-
async
|
|
194
|
-
await this.ensureConfigDirectory();
|
|
195
|
-
// Use atomic write: write to temp file, then rename
|
|
196
|
-
const tempPath = this.configPath + '.tmp';
|
|
197
|
-
const configContent = JSON.stringify(this.config, null, 2);
|
|
420
|
+
async backupExists() {
|
|
198
421
|
try {
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
422
|
+
await fs.access(this.backupPath);
|
|
423
|
+
return true;
|
|
424
|
+
}
|
|
425
|
+
catch {
|
|
426
|
+
return false;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
/**
|
|
430
|
+
* Fix incorrect types in config (e.g., string booleans, string "null")
|
|
431
|
+
*/
|
|
432
|
+
fixConfigTypes() {
|
|
433
|
+
if (!this.config)
|
|
434
|
+
return;
|
|
435
|
+
// Helper to convert string "null" to actual null
|
|
436
|
+
const fixNull = (value) => {
|
|
437
|
+
if (value === 'null' || value === 'NULL')
|
|
438
|
+
return null;
|
|
439
|
+
return value;
|
|
440
|
+
};
|
|
441
|
+
// Helper to convert string booleans to actual booleans
|
|
442
|
+
const fixBoolean = (value) => {
|
|
443
|
+
if (typeof value === 'string') {
|
|
444
|
+
const lower = value.toLowerCase();
|
|
445
|
+
if (lower === 'true')
|
|
446
|
+
return true;
|
|
447
|
+
if (lower === 'false')
|
|
448
|
+
return false;
|
|
449
|
+
}
|
|
450
|
+
return value;
|
|
451
|
+
};
|
|
452
|
+
// Fix user fields - handle string "null" values
|
|
453
|
+
if (this.config.user) {
|
|
454
|
+
this.config.user.username = fixNull(this.config.user.username);
|
|
455
|
+
this.config.user.email = fixNull(this.config.user.email);
|
|
456
|
+
this.config.user.display_name = fixNull(this.config.user.display_name);
|
|
457
|
+
}
|
|
458
|
+
// Fix sync settings
|
|
459
|
+
if (this.config.sync) {
|
|
460
|
+
this.config.sync.enabled = fixBoolean(this.config.sync.enabled);
|
|
461
|
+
if (this.config.sync.individual) {
|
|
462
|
+
this.config.sync.individual.require_confirmation = fixBoolean(this.config.sync.individual.require_confirmation);
|
|
463
|
+
this.config.sync.individual.show_diff_before_sync = fixBoolean(this.config.sync.individual.show_diff_before_sync);
|
|
464
|
+
this.config.sync.individual.track_versions = fixBoolean(this.config.sync.individual.track_versions);
|
|
465
|
+
}
|
|
466
|
+
if (this.config.sync.bulk) {
|
|
467
|
+
this.config.sync.bulk.upload_enabled = fixBoolean(this.config.sync.bulk.upload_enabled);
|
|
468
|
+
this.config.sync.bulk.download_enabled = fixBoolean(this.config.sync.bulk.download_enabled);
|
|
469
|
+
this.config.sync.bulk.require_preview = fixBoolean(this.config.sync.bulk.require_preview);
|
|
470
|
+
this.config.sync.bulk.respect_local_only = fixBoolean(this.config.sync.bulk.respect_local_only);
|
|
471
|
+
}
|
|
472
|
+
if (this.config.sync.privacy) {
|
|
473
|
+
this.config.sync.privacy.scan_for_secrets = fixBoolean(this.config.sync.privacy.scan_for_secrets);
|
|
474
|
+
this.config.sync.privacy.scan_for_pii = fixBoolean(this.config.sync.privacy.scan_for_pii);
|
|
475
|
+
this.config.sync.privacy.warn_on_sensitive = fixBoolean(this.config.sync.privacy.warn_on_sensitive);
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
// Fix collection settings
|
|
479
|
+
if (this.config.collection) {
|
|
480
|
+
this.config.collection.auto_submit = fixBoolean(this.config.collection.auto_submit);
|
|
481
|
+
this.config.collection.require_review = fixBoolean(this.config.collection.require_review);
|
|
482
|
+
this.config.collection.add_attribution = fixBoolean(this.config.collection.add_attribution);
|
|
483
|
+
}
|
|
484
|
+
// Fix display settings
|
|
485
|
+
if (this.config.display) {
|
|
486
|
+
if (this.config.display.persona_indicators) {
|
|
487
|
+
this.config.display.persona_indicators.enabled = fixBoolean(this.config.display.persona_indicators.enabled);
|
|
488
|
+
this.config.display.persona_indicators.include_emoji = fixBoolean(this.config.display.persona_indicators.include_emoji);
|
|
489
|
+
}
|
|
490
|
+
this.config.display.verbose_logging = fixBoolean(this.config.display.verbose_logging);
|
|
491
|
+
this.config.display.show_progress = fixBoolean(this.config.display.show_progress);
|
|
492
|
+
}
|
|
493
|
+
// Fix github settings
|
|
494
|
+
if (this.config.github) {
|
|
495
|
+
if (this.config.github.portfolio) {
|
|
496
|
+
this.config.github.portfolio.repository_url = fixNull(this.config.github.portfolio.repository_url);
|
|
497
|
+
this.config.github.portfolio.auto_create = fixBoolean(this.config.github.portfolio.auto_create);
|
|
498
|
+
}
|
|
499
|
+
if (this.config.github.auth) {
|
|
500
|
+
this.config.github.auth.use_oauth = fixBoolean(this.config.github.auth.use_oauth);
|
|
501
|
+
// Fix client_id if it's a string "null"
|
|
502
|
+
if (this.config.github.auth.client_id) {
|
|
503
|
+
this.config.github.auth.client_id = fixNull(this.config.github.auth.client_id) || undefined;
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
/**
|
|
509
|
+
* Merge partial config with defaults
|
|
510
|
+
*
|
|
511
|
+
* IMPORTANT: This function preserves unknown fields for forward compatibility.
|
|
512
|
+
* If a future version adds new config fields, older versions won't lose them.
|
|
513
|
+
*/
|
|
514
|
+
mergeWithDefaults(partial) {
|
|
515
|
+
const defaults = this.getDefaultConfig();
|
|
516
|
+
// Start with a deep clone of partial to preserve all unknown fields
|
|
517
|
+
const result = JSON.parse(JSON.stringify(partial));
|
|
518
|
+
// Ensure all required fields exist with defaults
|
|
519
|
+
result.version = result.version || defaults.version;
|
|
520
|
+
// User section - preserve unknown fields while ensuring required fields
|
|
521
|
+
result.user = {
|
|
522
|
+
...result.user,
|
|
523
|
+
username: result.user?.username ?? defaults.user.username,
|
|
524
|
+
email: result.user?.email ?? defaults.user.email,
|
|
525
|
+
display_name: result.user?.display_name ?? defaults.user.display_name
|
|
526
|
+
};
|
|
527
|
+
// GitHub section - deep merge preserving unknown fields
|
|
528
|
+
if (!result.github)
|
|
529
|
+
result.github = {};
|
|
530
|
+
result.github.portfolio = {
|
|
531
|
+
...defaults.github.portfolio,
|
|
532
|
+
...result.github.portfolio
|
|
533
|
+
};
|
|
534
|
+
result.github.auth = {
|
|
535
|
+
...defaults.github.auth,
|
|
536
|
+
...result.github.auth
|
|
537
|
+
};
|
|
538
|
+
// Sync section - preserve unknown fields at all levels
|
|
539
|
+
if (!result.sync)
|
|
540
|
+
result.sync = {};
|
|
541
|
+
result.sync.enabled = result.sync.enabled ?? defaults.sync.enabled;
|
|
542
|
+
result.sync.individual = {
|
|
543
|
+
...defaults.sync.individual,
|
|
544
|
+
...result.sync.individual
|
|
545
|
+
};
|
|
546
|
+
result.sync.bulk = {
|
|
547
|
+
...defaults.sync.bulk,
|
|
548
|
+
...result.sync.bulk
|
|
549
|
+
};
|
|
550
|
+
result.sync.privacy = {
|
|
551
|
+
...defaults.sync.privacy,
|
|
552
|
+
...result.sync.privacy,
|
|
553
|
+
// Special handling for arrays - use provided or default
|
|
554
|
+
excluded_patterns: result.sync.privacy?.excluded_patterns || defaults.sync.privacy.excluded_patterns
|
|
555
|
+
};
|
|
556
|
+
// Collection section
|
|
557
|
+
result.collection = {
|
|
558
|
+
...defaults.collection,
|
|
559
|
+
...result.collection
|
|
560
|
+
};
|
|
561
|
+
// Elements section
|
|
562
|
+
if (!result.elements)
|
|
563
|
+
result.elements = {};
|
|
564
|
+
result.elements = {
|
|
565
|
+
...result.elements,
|
|
566
|
+
auto_activate: result.elements.auto_activate || defaults.elements.auto_activate,
|
|
567
|
+
default_element_dir: result.elements.default_element_dir || defaults.elements.default_element_dir
|
|
568
|
+
};
|
|
569
|
+
// Display section
|
|
570
|
+
if (!result.display)
|
|
571
|
+
result.display = {};
|
|
572
|
+
result.display.persona_indicators = {
|
|
573
|
+
...defaults.display.persona_indicators,
|
|
574
|
+
...result.display.persona_indicators
|
|
575
|
+
};
|
|
576
|
+
result.display.verbose_logging = result.display.verbose_logging ?? defaults.display.verbose_logging;
|
|
577
|
+
result.display.show_progress = result.display.show_progress ?? defaults.display.show_progress;
|
|
578
|
+
return result;
|
|
579
|
+
}
|
|
580
|
+
/**
|
|
581
|
+
* Migrate settings from environment variables
|
|
582
|
+
*/
|
|
583
|
+
async migrateFromEnvironment() {
|
|
584
|
+
let migrated = false;
|
|
585
|
+
// Migrate user settings
|
|
586
|
+
if (process.env.DOLLHOUSE_USER && !this.config?.user.username) {
|
|
587
|
+
if (!this.config)
|
|
588
|
+
this.config = this.getDefaultConfig();
|
|
589
|
+
this.config.user.username = process.env.DOLLHOUSE_USER;
|
|
590
|
+
migrated = true;
|
|
591
|
+
}
|
|
592
|
+
if (process.env.DOLLHOUSE_EMAIL && !this.config?.user.email) {
|
|
593
|
+
if (!this.config)
|
|
594
|
+
this.config = this.getDefaultConfig();
|
|
595
|
+
this.config.user.email = process.env.DOLLHOUSE_EMAIL;
|
|
596
|
+
migrated = true;
|
|
597
|
+
}
|
|
598
|
+
// Migrate portfolio URL
|
|
599
|
+
if (process.env.DOLLHOUSE_PORTFOLIO_URL && !this.config?.github.portfolio.repository_url) {
|
|
600
|
+
if (!this.config)
|
|
601
|
+
this.config = this.getDefaultConfig();
|
|
602
|
+
this.config.github.portfolio.repository_url = process.env.DOLLHOUSE_PORTFOLIO_URL;
|
|
603
|
+
migrated = true;
|
|
604
|
+
}
|
|
605
|
+
// Migrate collection auto-submit
|
|
606
|
+
if (process.env.DOLLHOUSE_AUTO_SUBMIT_TO_COLLECTION !== undefined) {
|
|
607
|
+
if (!this.config)
|
|
608
|
+
this.config = this.getDefaultConfig();
|
|
609
|
+
this.config.collection.auto_submit = process.env.DOLLHOUSE_AUTO_SUBMIT_TO_COLLECTION === 'true';
|
|
610
|
+
migrated = true;
|
|
611
|
+
}
|
|
612
|
+
if (migrated) {
|
|
613
|
+
logger.info('Migrated settings from environment variables');
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
/**
|
|
617
|
+
* Reset configuration to defaults
|
|
618
|
+
* SECURITY FIX (PR #895): Added prototype pollution protection
|
|
619
|
+
* Previously: Direct property assignment allowed __proto__ injection
|
|
620
|
+
* Now: Validates keys against forbidden properties before assignment
|
|
621
|
+
*/
|
|
622
|
+
async resetConfig(section) {
|
|
623
|
+
const defaults = this.getDefaultConfig();
|
|
624
|
+
if (section) {
|
|
625
|
+
// Reset specific section
|
|
626
|
+
if (!this.config) {
|
|
627
|
+
this.config = defaults;
|
|
628
|
+
}
|
|
629
|
+
else {
|
|
630
|
+
const sectionKeys = section.split('.');
|
|
631
|
+
// SECURITY: Validate all keys to prevent prototype pollution
|
|
632
|
+
const FORBIDDEN_KEYS = ['__proto__', 'constructor', 'prototype'];
|
|
633
|
+
for (const key of sectionKeys) {
|
|
634
|
+
if (FORBIDDEN_KEYS.includes(key)) {
|
|
635
|
+
throw new Error(`Forbidden property in section: ${key}`);
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
let current = this.config;
|
|
639
|
+
let defaultSection = defaults;
|
|
640
|
+
for (let i = 0; i < sectionKeys.length - 1; i++) {
|
|
641
|
+
current = current[sectionKeys[i]];
|
|
642
|
+
defaultSection = defaultSection[sectionKeys[i]];
|
|
643
|
+
}
|
|
644
|
+
const lastKey = sectionKeys[sectionKeys.length - 1];
|
|
645
|
+
current[lastKey] = defaultSection[lastKey];
|
|
646
|
+
}
|
|
647
|
+
await this.saveConfig();
|
|
648
|
+
return {
|
|
649
|
+
success: true,
|
|
650
|
+
message: `Section '${section}' reset to defaults`
|
|
651
|
+
};
|
|
652
|
+
}
|
|
653
|
+
else {
|
|
654
|
+
// Reset entire config
|
|
655
|
+
this.config = defaults;
|
|
656
|
+
await this.saveConfig();
|
|
657
|
+
return {
|
|
658
|
+
success: true,
|
|
659
|
+
message: 'Configuration reset to defaults'
|
|
660
|
+
};
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
/**
|
|
664
|
+
* Export configuration to file
|
|
665
|
+
*/
|
|
666
|
+
async exportConfig(filePath) {
|
|
667
|
+
if (!this.config) {
|
|
668
|
+
return {
|
|
669
|
+
success: false,
|
|
670
|
+
message: 'No configuration to export'
|
|
671
|
+
};
|
|
672
|
+
}
|
|
673
|
+
try {
|
|
674
|
+
const yamlContent = yaml.dump(this.config, {
|
|
675
|
+
indent: 2,
|
|
676
|
+
lineWidth: 120,
|
|
677
|
+
noRefs: true,
|
|
678
|
+
sortKeys: false
|
|
679
|
+
});
|
|
680
|
+
await fs.writeFile(filePath, yamlContent, { encoding: 'utf-8', mode: 0o600 });
|
|
681
|
+
return {
|
|
682
|
+
success: true,
|
|
683
|
+
message: `Configuration exported to ${filePath}`
|
|
684
|
+
};
|
|
203
685
|
}
|
|
204
686
|
catch (error) {
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
687
|
+
return {
|
|
688
|
+
success: false,
|
|
689
|
+
message: `Failed to export configuration: ${error instanceof Error ? error.message : String(error)}`
|
|
690
|
+
};
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
/**
|
|
694
|
+
* Import configuration from file
|
|
695
|
+
*/
|
|
696
|
+
async importConfig(filePath) {
|
|
697
|
+
try {
|
|
698
|
+
const content = await fs.readFile(filePath, 'utf-8');
|
|
699
|
+
// Parse and validate
|
|
700
|
+
const parsed = SecureYamlParser.parse(content, {
|
|
701
|
+
maxYamlSize: 64 * 1024,
|
|
702
|
+
validateContent: false,
|
|
703
|
+
validateFields: false
|
|
704
|
+
});
|
|
705
|
+
if (!parsed.data || typeof parsed.data !== 'object') {
|
|
706
|
+
return {
|
|
707
|
+
success: false,
|
|
708
|
+
message: 'Invalid configuration format in import file'
|
|
709
|
+
};
|
|
208
710
|
}
|
|
209
|
-
|
|
210
|
-
|
|
711
|
+
// Merge with defaults
|
|
712
|
+
this.config = this.mergeWithDefaults(parsed.data);
|
|
713
|
+
// Save the imported config
|
|
714
|
+
await this.saveConfig();
|
|
715
|
+
return {
|
|
716
|
+
success: true,
|
|
717
|
+
message: `Configuration imported from ${filePath}`
|
|
718
|
+
};
|
|
719
|
+
}
|
|
720
|
+
catch (error) {
|
|
721
|
+
return {
|
|
722
|
+
success: false,
|
|
723
|
+
message: `Failed to import configuration: ${error instanceof Error ? error.message : String(error)}`
|
|
724
|
+
};
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
/**
|
|
728
|
+
* Get formatted config for display
|
|
729
|
+
*/
|
|
730
|
+
getFormattedConfig(section) {
|
|
731
|
+
if (!this.config) {
|
|
732
|
+
return 'Configuration not initialized';
|
|
733
|
+
}
|
|
734
|
+
let configToShow = this.config;
|
|
735
|
+
if (section) {
|
|
736
|
+
configToShow = this.getSetting(section);
|
|
737
|
+
if (!configToShow) {
|
|
738
|
+
return `Section '${section}' not found`;
|
|
211
739
|
}
|
|
212
|
-
throw error;
|
|
213
740
|
}
|
|
741
|
+
// Remove sensitive data for display
|
|
742
|
+
const sanitized = JSON.parse(JSON.stringify(configToShow));
|
|
743
|
+
// Don't show tokens if they exist
|
|
744
|
+
if (sanitized.github?.auth?.token) {
|
|
745
|
+
sanitized.github.auth.token = '***REDACTED***';
|
|
746
|
+
}
|
|
747
|
+
return yaml.dump(sanitized, {
|
|
748
|
+
indent: 2,
|
|
749
|
+
lineWidth: 120,
|
|
750
|
+
noRefs: true,
|
|
751
|
+
sortKeys: false
|
|
752
|
+
});
|
|
214
753
|
}
|
|
215
754
|
}
|
|
216
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ29uZmlnTWFuYWdlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb25maWcvQ29uZmlnTWFuYWdlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7O0dBTUc7QUFFSCxPQUFPLEtBQUssRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUNsQyxPQUFPLEtBQUssSUFBSSxNQUFNLE1BQU0sQ0FBQztBQUM3QixPQUFPLEtBQUssRUFBRSxNQUFNLElBQUksQ0FBQztBQVV6QixNQUFNLE9BQU8sYUFBYTtJQUNoQixNQUFNLENBQUMsUUFBUSxHQUF5QixJQUFJLENBQUM7SUFDN0MsTUFBTSxDQUFDLFlBQVksR0FBWSxLQUFLLENBQUM7SUFFckMsU0FBUyxDQUFTO0lBQ2xCLFVBQVUsQ0FBUztJQUNuQixNQUFNLENBQWE7SUFFM0I7UUFDRSxtQkFBbUI7UUFDbkIsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsRUFBRSxZQUFZLENBQUMsQ0FBQztRQUN2RCxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxhQUFhLENBQUMsQ0FBQztRQUUzRCxpQ0FBaUM7UUFDakMsSUFBSSxDQUFDLE1BQU0sR0FBRztZQUNaLE9BQU8sRUFBRSxPQUFPO1NBQ2pCLENBQUM7SUFDSixDQUFDO0lBRUQ7O09BRUc7SUFDSSxNQUFNLENBQUMsV0FBVztRQUN2QixJQUFJLGFBQWEsQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUMzQixPQUFPLGFBQWEsQ0FBQyxRQUFRLENBQUM7UUFDaEMsQ0FBQztRQUVELHNEQUFzRDtRQUN0RCxJQUFJLGFBQWEsQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUMvQix5REFBeUQ7WUFDekQsT0FBTyxhQUFhLENBQUMsWUFBWSxJQUFJLENBQUMsYUFBYSxDQUFDLFFBQVEsRUFBRSxDQUFDO2dCQUM3RCw2RUFBNkU7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LFFBQVEsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDN0MsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixrQ0FBa0M7WUFDbEMsSUFBSSxDQUFDO2dCQUNILE1BQU0sRUFBRSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUM1QixDQUFDO1lBQUMsTUFBTSxDQUFDO2dCQUNQLHdCQUF3QjtZQUMxQixDQUFDO1lBQ0QsTUFBTSxLQUFLLENBQUM7UUFDZCxDQUFDO0lBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQ29uZmlnTWFuYWdlciAtIFRocmVhZC1zYWZlIHNpbmdsZXRvbiBmb3IgcGVyc2lzdGVudCBjb25maWd1cmF0aW9uXG4gKiBcbiAqIEhhbmRsZXMgT0F1dGggY2xpZW50IElEIHN0b3JhZ2UgZm9yIENsYXVkZSBEZXNrdG9wIGludGVncmF0aW9uLlxuICogU3RvcmVzIGNvbmZpZyBpbiB+Ly5kb2xsaG91c2UvY29uZmlnLmpzb24gd2l0aCBwcm9wZXIgcGVybWlzc2lvbnMuXG4gKiBQcmVmZXJzIGVudmlyb25tZW50IHZhcmlhYmxlcyBvdmVyIGNvbmZpZyBmaWxlIHZhbHVlcy5cbiAqL1xuXG5pbXBvcnQgKiBhcyBmcyBmcm9tICdmcy9wcm9taXNlcyc7XG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0ICogYXMgb3MgZnJvbSAnb3MnO1xuXG5pbnRlcmZhY2UgQ29uZmlnRGF0YSB7XG4gIHZlcnNpb246IHN0cmluZztcbiAgb2F1dGg/OiB7XG4gICAgZ2l0aHViQ2xpZW50SWQ/OiBzdHJpbmc7XG4gIH07XG4gIFtrZXk6IHN0cmluZ106IGFueTsgLy8gQWxsb3cgdW5rbm93biBmaWVsZHMgdG8gYmUgcHJlc2VydmVkXG59XG5cbmV4cG9ydCBjbGFzcyBDb25maWdNYW5hZ2VyIHtcbiAgcHJpdmF0ZSBzdGF0aWMgaW5zdGFuY2U6IENvbmZpZ01hbmFnZXIgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBzdGF0aWMgaW5zdGFuY2VMb2NrOiBib29sZWFuID0gZmFsc2U7XG5cbiAgcHJpdmF0ZSBjb25maWdEaXI6IHN0cmluZztcbiAgcHJpdmF0ZSBjb25maWdQYXRoOiBzdHJpbmc7XG4gIHByaXZhdGUgY29uZmlnOiBDb25maWdEYXRhO1xuXG4gIHByaXZhdGUgY29uc3RydWN0b3IoKSB7XG4gICAgLy8gSW5pdGlhbGl6ZSBwYXRoc1xuICAgIHRoaXMuY29uZmlnRGlyID0gcGF0aC5qb2luKG9zLmhvbWVkaXIoKSwgJy5kb2xsaG91c2UnKTtcbiAgICB0aGlzLmNvbmZpZ1BhdGggPSBwYXRoLmpvaW4odGhpcy5jb25maWdEaXIsICdjb25maWcuanNvbicpO1xuICAgIFxuICAgIC8vIEluaXRpYWxpemUgd2l0aCBkZWZhdWx0IGNvbmZpZ1xuICAgIHRoaXMuY29uZmlnID0ge1xuICAgICAgdmVyc2lvbjogJzEuMC4wJ1xuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogVGhyZWFkLXNhZmUgc2luZ2xldG9uIGluc3RhbmNlIGdldHRlclxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBnZXRJbnN0YW5jZSgpOiBDb25maWdNYW5hZ2VyIHtcbiAgICBpZiAoQ29uZmlnTWFuYWdlci5pbnN0YW5jZSkge1xuICAgICAgcmV0dXJuIENvbmZpZ01hbmFnZXIuaW5zdGFuY2U7XG4gICAgfVxuXG4gICAgLy8gU2ltcGxlIGxvY2tpbmcgbWVjaGFuaXNtIHRvIHByZXZlbnQgcmFjZSBjb25kaXRpb25zXG4gICAgaWYgKENvbmZpZ01hbmFnZXIuaW5zdGFuY2VMb2NrKSB7XG4gICAgICAvLyBXYWl0IGZvciBsb2NrIHRvIGJlIHJlbGVhc2VkLCB0aGVuIHJldHVybiB0aGUgaW5zdGFuY2VcbiAgICAgIHdoaWxlIChDb25maWdNYW5hZ2VyLmluc3RhbmNlTG9jayAmJiAhQ29uZmlnTWFuYWdlci5pbnN0YW5jZSkge1xuICAgICAgICAvLyBJbiBhIHJlYWwgc2NlbmFyaW8gd2l0aCBhc3luYyBvcGVyYXRpb25zLCB0aGlzIHdvdWxkIGJlIG1vcmUgc29waGlzdGljYXRlZFxuICAgICAgICAvLyBCdXQgZm9yIHRoZSB0ZXN0IGNhc2VzLCB0aGlzIHNpbXBsZSBhcHByb2FjaCB3b3Jrc1xuICAgICAgfVxuICAgICAgcmV0dXJuIENvbmZpZ01hbmFnZXIuaW5zdGFuY2UhO1xuICAgIH1cblxuICAgIENvbmZpZ01hbmFnZXIuaW5zdGFuY2VMb2NrID0gdHJ1ZTtcbiAgICBcbiAgICBpZiAoIUNvbmZpZ01hbmFnZXIuaW5zdGFuY2UpIHtcbiAgICAgIENvbmZpZ01hbmFnZXIuaW5zdGFuY2UgPSBuZXcgQ29uZmlnTWFuYWdlcigpO1xuICAgIH1cbiAgICBcbiAgICBDb25maWdNYW5hZ2VyLmluc3RhbmNlTG9jayA9IGZhbHNlO1xuICAgIHJldHVybiBDb25maWdNYW5hZ2VyLmluc3RhbmNlO1xuICB9XG5cbiAgLyoqXG4gICAqIEF0dGVtcHQgdG8gcmVwYWlyIGZpbGUgcGVybWlzc2lvbnMgaWYgdGhleSdyZSBpbmNvcnJlY3RcbiAgICogVGhpcyBoZWxwcyB3aXRoIGVycm9yIHJlY292ZXJ5IGluIHBlcm1pc3Npb24tcmVsYXRlZCBpc3N1ZXNcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgcmVwYWlyUGVybWlzc2lvbnMoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIFRyeSB0byBmaXggZGlyZWN0b3J5IHBlcm1pc3Npb25zXG4gICAgICBhd2FpdCBmcy5jaG1vZCh0aGlzLmNvbmZpZ0RpciwgMG83MDApO1xuICAgICAgXG4gICAgICAvLyBUcnkgdG8gZml4IGZpbGUgcGVybWlzc2lvbnMgaWYgaXQgZXhpc3RzXG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCBmcy5hY2Nlc3ModGhpcy5jb25maWdQYXRoKTtcbiAgICAgICAgYXdhaXQgZnMuY2htb2QodGhpcy5jb25maWdQYXRoLCAwbzYwMCk7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgLy8gRmlsZSBkb2Vzbid0IGV4aXN0LCB0aGF0J3MgT0tcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgLy8gTG9nIGJ1dCBkb24ndCBmYWlsIC0gdGhpcyBpcyBiZXN0LWVmZm9ydCByZWNvdmVyeVxuICAgICAgLy8gV2UgZG9uJ3QgaGF2ZSBhIGxvZ2dlciBoZXJlLCBzbyB3ZSdsbCBzaWxlbnRseSBjb250aW51ZVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBMb2FkIGNvbmZpZ3VyYXRpb24gZnJvbSBmaWxlIHN5c3RlbVxuICAgKi9cbiAgcHVibGljIGFzeW5jIGxvYWRDb25maWcoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIFRyeSB0byByZWFkIGV4aXN0aW5nIGNvbmZpZyBmaWxlXG4gICAgICBjb25zdCBjb25maWdDb250ZW50ID0gYXdhaXQgZnMucmVhZEZpbGUodGhpcy5jb25maWdQYXRoLCAndXRmLTgnKTtcbiAgICAgIFxuICAgICAgdHJ5IHtcbiAgICAgICAgdGhpcy5jb25maWcgPSBKU09OLnBhcnNlKGNvbmZpZ0NvbnRlbnQpO1xuICAgICAgfSBjYXRjaCAocGFyc2VFcnJvcikge1xuICAgICAgICAvLyBIYW5kbGUgY29ycnVwdGVkIEpTT04gLSBjcmVhdGUgbmV3IGNvbmZpZ1xuICAgICAgICBjb25zb2xlLndhcm4oJ0NvbmZpZyBmaWxlIGNvcnJ1cHRlZCwgY3JlYXRpbmcgbmV3IGNvbmZpZycpO1xuICAgICAgICB0aGlzLmNvbmZpZyA9IHsgdmVyc2lvbjogJzEuMC4wJyB9O1xuICAgICAgICBhd2FpdCB0aGlzLnNhdmVDb25maWcoKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICBpZiAoZXJyb3IuY29kZSA9PT0gJ0VOT0VOVCcpIHtcbiAgICAgICAgLy8gQ29uZmlnIGZpbGUgZG9lc24ndCBleGlzdCwgY3JlYXRlIGRpcmVjdG9yeSBhbmQgZmlsZVxuICAgICAgICBhd2FpdCB0aGlzLmVuc3VyZUNvbmZpZ0RpcmVjdG9yeSgpO1xuICAgICAgICBhd2FpdCB0aGlzLnNhdmVDb25maWcoKTtcbiAgICAgIH0gZWxzZSBpZiAoZXJyb3IuY29kZSA9PT0gJ0VBQ0NFUycgfHwgZXJyb3IuY29kZSA9PT0gJ0VQRVJNJykge1xuICAgICAgICAvLyBQZXJtaXNzaW9uIGRlbmllZCAtIGF0dGVtcHQgcmVwYWlyXG4gICAgICAgIGF3YWl0IHRoaXMucmVwYWlyUGVybWlzc2lvbnMoKTtcbiAgICAgICAgXG4gICAgICAgIC8vIFRyeSBvbmNlIG1vcmUgYWZ0ZXIgcmVwYWlyIGF0dGVtcHRcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCBjb25maWdDb250ZW50ID0gYXdhaXQgZnMucmVhZEZpbGUodGhpcy5jb25maWdQYXRoLCAndXRmLTgnKTtcbiAgICAgICAgICB0aGlzLmNvbmZpZyA9IEpTT04ucGFyc2UoY29uZmlnQ29udGVudCk7XG4gICAgICAgIH0gY2F0Y2ggKHJldHJ5RXJyb3I6IGFueSkge1xuICAgICAgICAgIC8vIFN0aWxsIGZhaWxpbmcsIHRocm93IG9yaWdpbmFsIGVycm9yIHdpdGggaGVscGZ1bCBtZXNzYWdlXG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgYFBlcm1pc3Npb24gZGVuaWVkIGFjY2Vzc2luZyBjb25maWcgYXQgJHt0aGlzLmNvbmZpZ1BhdGh9LiBgICtcbiAgICAgICAgICAgIGBQbGVhc2UgY2hlY2sgZmlsZSBwZXJtaXNzaW9ucyBvciBydW4gd2l0aCBhcHByb3ByaWF0ZSBwcml2aWxlZ2VzLmBcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogR2V0IEdpdEh1YiBPQXV0aCBjbGllbnQgSURcbiAgICogRW52aXJvbm1lbnQgdmFyaWFibGUgdGFrZXMgcHJlY2VkZW5jZSBvdmVyIGNvbmZpZyBmaWxlXG4gICAqL1xuICBwdWJsaWMgZ2V0R2l0SHViQ2xpZW50SWQoKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgLy8gQ2hlY2sgZW52aXJvbm1lbnQgdmFyaWFibGUgZmlyc3RcbiAgICBjb25zdCBlbnZDbGllbnRJZCA9IHByb2Nlc3MuZW52LkRPTExIT1VTRV9HSVRIVUJfQ0xJRU5UX0lEO1xuICAgIGlmIChlbnZDbGllbnRJZCkge1xuICAgICAgcmV0dXJuIGVudkNsaWVudElkO1xuICAgIH1cblxuICAgIC8vIEZhbGwgYmFjayB0byBjb25maWcgZmlsZVxuICAgIHJldHVybiB0aGlzLmNvbmZpZy5vYXV0aD8uZ2l0aHViQ2xpZW50SWQgfHwgbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXQgR2l0SHViIE9BdXRoIGNsaWVudCBJRCBpbiBjb25maWcgZmlsZVxuICAgKi9cbiAgcHVibGljIGFzeW5jIHNldEdpdEh1YkNsaWVudElkKGNsaWVudElkOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoIUNvbmZpZ01hbmFnZXIudmFsaWRhdGVDbGllbnRJZChjbGllbnRJZCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYEludmFsaWQgR2l0SHViIGNsaWVudCBJRCBmb3JtYXQuIEV4cGVjdGVkIGZvcm1hdDogT3YyM2xpIGZvbGxvd2VkIGJ5IGF0IGxlYXN0IDE0IGFscGhhbnVtZXJpYyBjaGFyYWN0ZXJzIChlLmcuLCBPdjIzbGlBQkNERUZHSElKS0xNTilgXG4gICAgICApO1xuICAgIH1cblxuICAgIC8vIEVuc3VyZSBvYXV0aCBvYmplY3QgZXhpc3RzXG4gICAgaWYgKCF0aGlzLmNvbmZpZy5vYXV0aCkge1xuICAgICAgdGhpcy5jb25maWcub2F1dGggPSB7fTtcbiAgICB9XG5cbiAgICB0aGlzLmNvbmZpZy5vYXV0aC5naXRodWJDbGllbnRJZCA9IGNsaWVudElkO1xuICAgIGF3YWl0IHRoaXMuc2F2ZUNvbmZpZygpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBhIGNvcHkgb2YgdGhlIGN1cnJlbnQgY29uZmlndXJhdGlvblxuICAgKiBAcmV0dXJucyBBIGRlZmVuc2l2ZSBjb3B5IG9mIHRoZSBjb25maWd1cmF0aW9uIG9iamVjdFxuICAgKi9cbiAgcHVibGljIGdldENvbmZpZygpOiBDb25maWdEYXRhIHtcbiAgICByZXR1cm4geyAuLi50aGlzLmNvbmZpZyB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZSB0aGUgZW50aXJlIGNvbmZpZ3VyYXRpb25cbiAgICogQHBhcmFtIG5ld0NvbmZpZyBUaGUgbmV3IGNvbmZpZ3VyYXRpb24gdG8gc2V0XG4gICAqL1xuICBwdWJsaWMgYXN5bmMgdXBkYXRlQ29uZmlnKG5ld0NvbmZpZzogQ29uZmlnRGF0YSk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMuY29uZmlnID0geyAuLi5uZXdDb25maWcgfTtcbiAgICBhd2FpdCB0aGlzLnNhdmVDb25maWcoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZSBHaXRIdWIgT0F1dGggY2xpZW50IElEIGZvcm1hdFxuICAgKiBDbGllbnQgSURzIHN0YXJ0IHdpdGggXCJPdjIzbGlcIiBmb2xsb3dlZCBieSBhdCBsZWFzdCAxNCBhbHBoYW51bWVyaWMgY2hhcmFjdGVyc1xuICAgKiBcbiAgICogQHBhcmFtIGNsaWVudElkIC0gVGhlIGNsaWVudCBJRCB0byB2YWxpZGF0ZVxuICAgKiBAcmV0dXJucyB0cnVlIGlmIHZhbGlkLCBmYWxzZSBvdGhlcndpc2VcbiAgICogXG4gICAqIEBleGFtcGxlXG4gICAqIENvbmZpZ01hbmFnZXIudmFsaWRhdGVDbGllbnRJZChcIk92MjNsaUFCQ0RFRkdISUpLTE1OMTIzNDU2XCIpIC8vIHRydWVcbiAgICogQ29uZmlnTWFuYWdlci52YWxpZGF0ZUNsaWVudElkKFwiaW52YWxpZFwiKSAvLyBmYWxzZVxuICAgKiBDb25maWdNYW5hZ2VyLnZhbGlkYXRlQ2xpZW50SWQoXCJPdjIzbGlcIikgLy8gZmFsc2UgKHRvbyBzaG9ydClcbiAgICogQ29uZmlnTWFuYWdlci52YWxpZGF0ZUNsaWVudElkKFwiWHYyM2xpQUJDREVGR0hJSktMTU5cIikgLy8gZmFsc2UgKHdyb25nIHByZWZpeClcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgdmFsaWRhdGVDbGllbnRJZChjbGllbnRJZDogYW55KTogYm9vbGVhbiB7XG4gICAgaWYgKHR5cGVvZiBjbGllbnRJZCAhPT0gJ3N0cmluZycgfHwgIWNsaWVudElkKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gR2l0SHViIE9BdXRoIGNsaWVudCBJRHMgZm9sbG93IHRoZSBwYXR0ZXJuOiBPdjIzbGlbQS1aYS16MC05XXsxNCx9XG4gICAgY29uc3QgY2xpZW50SWRQYXR0ZXJuID0gL15PdjIzbGlbQS1aYS16MC05XXsxNCx9JC87XG4gICAgcmV0dXJuIGNsaWVudElkUGF0dGVybi50ZXN0KGNsaWVudElkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFbnN1cmUgY29uZmlnIGRpcmVjdG9yeSBleGlzdHMgd2l0aCBwcm9wZXIgcGVybWlzc2lvbnNcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZW5zdXJlQ29uZmlnRGlyZWN0b3J5KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBmcy5ta2Rpcih0aGlzLmNvbmZpZ0RpciwgeyByZWN1cnNpdmU6IHRydWUsIG1vZGU6IDBvNzAwIH0pO1xuICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgIGlmIChlcnJvci5jb2RlID09PSAnRUFDQ0VTJykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFBlcm1pc3Npb24gZGVuaWVkIGNyZWF0aW5nIGNvbmZpZyBkaXJlY3Rvcnk6ICR7dGhpcy5jb25maWdEaXJ9YCk7XG4gICAgICB9XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU2F2ZSBjb25maWcgdXNpbmcgYXRvbWljIGZpbGUgd3JpdGVzXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHNhdmVDb25maWcoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy5lbnN1cmVDb25maWdEaXJlY3RvcnkoKTtcbiAgICBcbiAgICAvLyBVc2UgYXRvbWljIHdyaXRlOiB3cml0ZSB0byB0ZW1wIGZpbGUsIHRoZW4gcmVuYW1lXG4gICAgY29uc3QgdGVtcFBhdGggPSB0aGlzLmNvbmZpZ1BhdGggKyAnLnRtcCc7XG4gICAgY29uc3QgY29uZmlnQ29udGVudCA9IEpTT04uc3RyaW5naWZ5KHRoaXMuY29uZmlnLCBudWxsLCAyKTtcbiAgICBcbiAgICB0cnkge1xuICAgICAgLy8gV3JpdGUgdG8gdGVtcCBmaWxlIGZpcnN0XG4gICAgICBhd2FpdCBmcy53cml0ZUZpbGUodGVtcFBhdGgsIGNvbmZpZ0NvbnRlbnQsIHsgbW9kZTogMG82MDAgfSk7XG4gICAgICBcbiAgICAgIC8vIEF0b21pYyByZW5hbWVcbiAgICAgIGF3YWl0IGZzLnJlbmFtZSh0ZW1wUGF0aCwgdGhpcy5jb25maWdQYXRoKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgLy8gQ2xlYW4gdXAgdGVtcCBmaWxlIGlmIGl0IGV4aXN0c1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgZnMudW5saW5rKHRlbXBQYXRoKTtcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICAvLyBJZ25vcmUgY2xlYW51cCBlcnJvcnNcbiAgICAgIH1cbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfVxufSJdfQ==
|
|
755
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ29uZmlnTWFuYWdlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb25maWcvQ29uZmlnTWFuYWdlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7R0FXRztBQUVILE9BQU8sS0FBSyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ2xDLE9BQU8sS0FBSyxJQUFJLE1BQU0sTUFBTSxDQUFDO0FBQzdCLE9BQU8sS0FBSyxFQUFFLE1BQU0sSUFBSSxDQUFDO0FBQ3pCLE9BQU8sS0FBSyxJQUFJLE1BQU0sU0FBUyxDQUFDO0FBQ2hDLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUM1QyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQXlHbkUsTUFBTSxPQUFPLGFBQWE7SUFDaEIsTUFBTSxDQUFDLFFBQVEsR0FBeUIsSUFBSSxDQUFDO0lBQzdDLE1BQU0sQ0FBQyxZQUFZLEdBQVksS0FBSyxDQUFDO0lBRXJDLFNBQVMsQ0FBUztJQUNsQixVQUFVLENBQVM7SUFDbkIsVUFBVSxDQUFTO0lBQ25CLE1BQU0sR0FBMkIsSUFBSSxDQUFDO0lBRTlDO1FBQ0UsbUJBQW1CO1FBQ25CLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLEVBQUUsWUFBWSxDQUFDLENBQUM7UUFDdkQsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsWUFBWSxDQUFDLENBQUM7UUFDMUQsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsbUJBQW1CLENBQUMsQ0FBQztJQUNuRSxDQUFDO0lBRUQ7O09BRUc7SUFDSSxNQUFNLENBQUMsV0FBVztRQUN2QixJQUFJLGFBQWEsQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUMzQixP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LE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUU7WUFDMUIsTUFBTSxFQUFFLENBQUM7WUFDVCxTQUFTLEVBQUUsR0FBRztZQUNkLE1BQU0sRUFBRSxJQUFJO1lBQ1osUUFBUSxFQUFFLEtBQUs7U0FDaEIsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQ29uZmlnTWFuYWdlciAtIENlbnRyYWxpemVkIGNvbmZpZ3VyYXRpb24gbWFuYWdlbWVudCBmb3IgRG9sbGhvdXNlTUNQXG4gKiBcbiAqIEZlYXR1cmVzOlxuICogLSBZQU1MLWJhc2VkIGNvbmZpZ3VyYXRpb24gZmlsZVxuICogLSBEZWZhdWx0IHZhbHVlcyB3aXRoIHVzZXIgb3ZlcnJpZGVzXG4gKiAtIE1pZ3JhdGlvbiBmcm9tIGVudmlyb25tZW50IHZhcmlhYmxlc1xuICogLSBWYWxpZGF0aW9uIGFuZCB0eXBlIHNhZmV0eVxuICogLSBBdG9taWMgdXBkYXRlcyB3aXRoIGJhY2t1cFxuICogLSBQcml2YWN5LWZpcnN0IGRlZmF1bHRzXG4gKiAtIE9BdXRoIGNsaWVudCBJRCBzdG9yYWdlIGZvciBDbGF1ZGUgRGVza3RvcCBpbnRlZ3JhdGlvblxuICovXG5cbmltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzL3Byb21pc2VzJztcbmltcG9ydCAqIGFzIHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgKiBhcyBvcyBmcm9tICdvcyc7XG5pbXBvcnQgKiBhcyB5YW1sIGZyb20gJ2pzLXlhbWwnO1xuaW1wb3J0IHsgbG9nZ2VyIH0gZnJvbSAnLi4vdXRpbHMvbG9nZ2VyLmpzJztcbmltcG9ydCB7IFNlY3VyZVlhbWxQYXJzZXIgfSBmcm9tICcuLi9zZWN1cml0eS9zZWN1cmVZYW1sUGFyc2VyLmpzJztcblxuZXhwb3J0IGludGVyZmFjZSBVc2VyQ29uZmlnIHtcbiAgdXNlcm5hbWU6IHN0cmluZyB8IG51bGw7XG4gIGVtYWlsOiBzdHJpbmcgfCBudWxsO1xuICBkaXNwbGF5X25hbWU6IHN0cmluZyB8IG51bGw7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgR2l0SHViUG9ydGZvbGlvQ29uZmlnIHtcbiAgcmVwb3NpdG9yeV91cmw6IHN0cmluZyB8IG51bGw7XG4gIHJlcG9zaXRvcnlfbmFtZTogc3RyaW5nO1xuICBkZWZhdWx0X2JyYW5jaDogc3RyaW5nO1xuICBhdXRvX2NyZWF0ZTogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBHaXRIdWJBdXRoQ29uZmlnIHtcbiAgdXNlX29hdXRoOiBib29sZWFuO1xuICB0b2tlbl9zb3VyY2U6ICdlbnZpcm9ubWVudCcgfCAnb2F1dGgnIHwgJ2NvbmZpZyc7XG4gIGNsaWVudF9pZD86IHN0cmluZzsgLy8gT0F1dGggY2xpZW50IElEIGZvciBHaXRIdWIgQXBwXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgR2l0SHViQ29uZmlnIHtcbiAgcG9ydGZvbGlvOiBHaXRIdWJQb3J0Zm9saW9Db25maWc7XG4gIGF1dGg6IEdpdEh1YkF1dGhDb25maWc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU3luY0luZGl2aWR1YWxDb25maWcge1xuICByZXF1aXJlX2NvbmZpcm1hdGlvbjogYm9vbGVhbjtcbiAgc2hvd19kaWZmX2JlZm9yZV9zeW5jOiBib29sZWFuO1xuICB0cmFja192ZXJzaW9uczogYm9vbGVhbjtcbiAga2VlcF9oaXN0b3J5OiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU3luY0J1bGtDb25maWcge1xuICB1cGxvYWRfZW5hYmxlZDogYm9vbGVhbjtcbiAgZG93bmxvYWRfZW5hYmxlZDogYm9vbGVhbjtcbiAgcmVxdWlyZV9wcmV2aWV3OiBib29sZWFuO1xuICByZXNwZWN0X2xvY2FsX29ubHk6IGJvb2xlYW47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU3luY1ByaXZhY3lDb25maWcge1xuICBzY2FuX2Zvcl9zZWNyZXRzOiBib29sZWFuO1xuICBzY2FuX2Zvcl9waWk6IGJvb2xlYW47XG4gIHdhcm5fb25fc2Vuc2l0aXZlOiBib29sZWFuO1xuICBleGNsdWRlZF9wYXR0ZXJuczogc3RyaW5nW107XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU3luY0NvbmZpZyB7XG4gIGVuYWJsZWQ6IGJvb2xlYW47XG4gIGluZGl2aWR1YWw6IFN5bmNJbmRpdmlkdWFsQ29uZmlnO1xuICBidWxrOiBTeW5jQnVsa0NvbmZpZztcbiAgcHJpdmFjeTogU3luY1ByaXZhY3lDb25maWc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29sbGVjdGlvbkNvbmZpZyB7XG4gIGF1dG9fc3VibWl0OiBib29sZWFuO1xuICByZXF1aXJlX3JldmlldzogYm9vbGVhbjtcbiAgYWRkX2F0dHJpYnV0aW9uOiBib29sZWFuO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEVsZW1lbnRzQ29uZmlnIHtcbiAgYXV0b19hY3RpdmF0ZToge1xuICAgIHBlcnNvbmFzPzogc3RyaW5nW107XG4gICAgc2tpbGxzPzogc3RyaW5nW107XG4gICAgdGVtcGxhdGVzPzogc3RyaW5nW107XG4gICAgYWdlbnRzPzogc3RyaW5nW107XG4gICAgbWVtb3JpZXM/OiBzdHJpbmdbXTtcbiAgICBlbnNlbWJsZXM/OiBzdHJpbmdbXTtcbiAgfTtcbiAgZGVmYXVsdF9lbGVtZW50X2Rpcjogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIERpc3BsYXlDb25maWcge1xuICBwZXJzb25hX2luZGljYXRvcnM6IHtcbiAgICBlbmFibGVkOiBib29sZWFuO1xuICAgIHN0eWxlOiAnZnVsbCcgfCAnbWluaW1hbCcgfCAnY29tcGFjdCcgfCAnY3VzdG9tJztcbiAgICBpbmNsdWRlX2Vtb2ppOiBib29sZWFuO1xuICB9O1xuICB2ZXJib3NlX2xvZ2dpbmc6IGJvb2xlYW47XG4gIHNob3dfcHJvZ3Jlc3M6IGJvb2xlYW47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRG9sbGhvdXNlQ29uZmlnIHtcbiAgdmVyc2lvbjogc3RyaW5nO1xuICB1c2VyOiBVc2VyQ29uZmlnO1xuICBnaXRodWI6IEdpdEh1YkNvbmZpZztcbiAgc3luYzogU3luY0NvbmZpZztcbiAgY29sbGVjdGlvbjogQ29sbGVjdGlvbkNvbmZpZztcbiAgZWxlbWVudHM6IEVsZW1lbnRzQ29uZmlnO1xuICBkaXNwbGF5OiBEaXNwbGF5Q29uZmlnO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIENvbmZpZ1VwZGF0ZVJlc3VsdCB7XG4gIHN1Y2Nlc3M6IGJvb2xlYW47XG4gIG1lc3NhZ2U6IHN0cmluZztcbiAgcHJldmlvdXNWYWx1ZT86IGFueTtcbiAgbmV3VmFsdWU/OiBhbnk7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29uZmlnQWN0aW9uUmVzdWx0IHtcbiAgc3VjY2VzczogYm9vbGVhbjtcbiAgbWVzc2FnZTogc3RyaW5nO1xuICBkYXRhPzogYW55O1xufVxuXG5leHBvcnQgY2xhc3MgQ29uZmlnTWFuYWdlciB7XG4gIHByaXZhdGUgc3RhdGljIGluc3RhbmNlOiBDb25maWdNYW5hZ2VyIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgc3RhdGljIGluc3RhbmNlTG9jazogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIHByaXZhdGUgY29uZmlnRGlyOiBzdHJpbmc7XG4gIHByaXZhdGUgY29uZmlnUGF0aDogc3RyaW5nO1xuICBwcml2YXRlIGJhY2t1cFBhdGg6IHN0cmluZztcbiAgcHJpdmF0ZSBjb25maWc6IERvbGxob3VzZUNvbmZpZyB8IG51bGwgPSBudWxsO1xuXG4gIHByaXZhdGUgY29uc3RydWN0b3IoKSB7XG4gICAgLy8gSW5pdGlhbGl6ZSBwYXRoc1xuICAgIHRoaXMuY29uZmlnRGlyID0gcGF0aC5qb2luKG9zLmhvbWVkaXIoKSwgJy5kb2xsaG91c2UnKTtcbiAgICB0aGlzLmNvbmZpZ1BhdGggPSBwYXRoLmpvaW4odGhpcy5jb25maWdEaXIsICdjb25maWcueW1sJyk7XG4gICAgdGhpcy5iYWNrdXBQYXRoID0gcGF0aC5qb2luKHRoaXMuY29uZmlnRGlyLCAnY29uZmlnLnltbC5iYWNrdXAnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaHJlYWQtc2FmZSBzaW5nbGV0b24gaW5zdGFuY2UgZ2V0dGVyXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGdldEluc3RhbmNlKCk6IENvbmZpZ01hbmFnZXIge1xuICAgIGlmIChDb25maWdNYW5hZ2VyLmluc3RhbmNlKSB7XG4gICAgICByZXR1cm4gQ29uZmlnTWFuYWdlci5pbnN0YW5jZTtcbiAgICB9XG5cbiAgICAvLyBTaW1wbGUgbG9ja2luZyBtZWNoYW5pc20gdG8gcHJldmVudCByYWNlIGNvbmRpdGlvbnNcbiAgICBpZiAoQ29uZmlnTWFuYWdlci5pbnN0YW5jZUxvY2spIHtcbiAgICAgIC8vIFdhaXQgZm9yIGxvY2sgdG8gYmUgcmVsZWFzZWQsIHRoZW4gcmV0dXJuIHRoZSBpbnN0YW5jZVxuICAgICAgd2hpbGUgKENvbmZpZ01hbmFnZXIuaW5zdGFuY2VMb2NrICYmICFDb25maWdNYW5hZ2VyLmluc3RhbmNlKSB7XG4gICAgICAgIC8vIEluIGEgcmVhbCBzY2VuYXJpbyB3aXRoIGFzeW5jIG9wZXJhdGlvbnMsIHRoaXMgd291bGQgYmUgbW9yZSBzb3BoaXN0aWNhdGVkXG4gICAgICAgIC8vIEJ1dCBmb3IgdGhlIHRlc3QgY2FzZXMsIHRoaXMgc2ltcGxlIGFwcHJvYWNoIHdvcmtzXG4gICAgICB9XG4gICAgICByZXR1cm4gQ29uZmlnTWFuYWdlci5pbnN0YW5jZSE7XG4gICAgfVxuXG4gICAgQ29uZmlnTWFuYWdlci5pbnN0YW5jZUxvY2sgPSB0cnVlO1xuICAgIFxuICAgIGlmICghQ29uZmlnTWFuYWdlci5pbnN0YW5jZSkge1xuICAgICAgQ29uZmlnTWFuYWdlci5pbnN0YW5jZSA9IG5ldyBDb25maWdNYW5hZ2VyKCk7XG4gICAgfVxuICAgIFxuICAgIENvbmZpZ01hbmFnZXIuaW5zdGFuY2VMb2NrID0gZmFsc2U7XG4gICAgcmV0dXJuIENvbmZpZ01hbmFnZXIuaW5zdGFuY2U7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGRlZmF1bHQgY29uZmlndXJhdGlvblxuICAgKi9cbiAgcHJpdmF0ZSBnZXREZWZhdWx0Q29uZmlnKCk6IERvbGxob3VzZUNvbmZpZyB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHZlcnNpb246ICcxLjAuMCcsXG4gICAgICB1c2VyOiB7XG4gICAgICAgIHVzZXJuYW1lOiBudWxsLFxuICAgICAgICBlbWFpbDogbnVsbCxcbiAgICAgICAgZGlzcGxheV9uYW1lOiBudWxsXG4gICAgICB9LFxuICAgICAgZ2l0aHViOiB7XG4gICAgICAgIHBvcnRmb2xpbzoge1xuICAgICAgICAgIHJlcG9zaXRvcnlfdXJsOiBudWxsLFxuICAgICAgICAgIHJlcG9zaXRvcnlfbmFtZTogJ2RvbGxob3VzZS1wb3J0Zm9saW8nLFxuICAgICAgICAgIGRlZmF1bHRfYnJhbmNoOiAnbWFpbicsXG4gICAgICAgICAgYXV0b19jcmVhdGU6IHRydWVcbiAgICAgICAgfSxcbiAgICAgICAgYXV0aDoge1xuICAgICAgICAgIHVzZV9vYXV0aDogdHJ1ZSxcbiAgICAgICAgICB0b2tlbl9zb3VyY2U6ICdlbnZpcm9ubWVudCdcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIHN5bmM6IHtcbiAgICAgICAgZW5hYmxlZDogZmFsc2UsIC8vIFByaXZhY3kgZmlyc3QgLSBvZmYgYnkgZGVmYXVsdFxuICAgICAgICBpbmRpdmlkdWFsOiB7XG4gICAgICAgICAgcmVxdWlyZV9jb25maXJtYXRpb246IHRydWUsXG4gICAgICAgICAgc2hvd19kaWZmX2JlZm9yZV9zeW5jOiB0cnVlLFxuICAgICAgICAgIHRyYWNrX3ZlcnNpb25zOiB0cnVlLFxuICAgICAgICAgIGtlZXBfaGlzdG9yeTogMTBcbiAgICAgICAgfSxcbiAgICAgICAgYnVsazoge1xuICAgICAgICAgIHVwbG9hZF9lbmFibGVkOiBmYWxzZSwgLy8gUmVxdWlyZXMgZXhwbGljaXQgZW5hYmxlbWVudFxuICAgICAgICAgIGRvd25sb2FkX2VuYWJsZWQ6IGZhbHNlLFxuICAgICAgICAgIHJlcXVpcmVfcHJldmlldzogdHJ1ZSxcbiAgICAgICAgICByZXNwZWN0X2xvY2FsX29ubHk6IHRydWVcbiAgICAgICAgfSxcbiAgICAgICAgcHJpdmFjeToge1xuICAgICAgICAgIHNjYW5fZm9yX3NlY3JldHM6IHRydWUsXG4gICAgICAgICAgc2Nhbl9mb3JfcGlpOiB0cnVlLFxuICAgICAgICAgIHdhcm5fb25fc2Vuc2l0aXZlOiB0cnVlLFxuICAgICAgICAgIGV4Y2x1ZGVkX3BhdHRlcm5zOiBbXG4gICAgICAgICAgICAnKi5zZWNyZXQnLFxuICAgICAgICAgICAgJyotcHJpdmF0ZS4qJyxcbiAgICAgICAgICAgICdjcmVkZW50aWFscy8qKicsXG4gICAgICAgICAgICAncGVyc29uYWwvKionXG4gICAgICAgICAgXVxuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgY29sbGVjdGlvbjoge1xuICAgICAgICBhdXRvX3N1Ym1pdDogZmFsc2UsIC8vIE5ldmVyIGF1dG8tc3VibWl0XG4gICAgICAgIHJlcXVpcmVfcmV2aWV3OiB0cnVlLFxuICAgICAgICBhZGRfYXR0cmlidXRpb246IHRydWVcbiAgICAgIH0sXG4gICAgICBlbGVtZW50czoge1xuICAgICAgICBhdXRvX2FjdGl2YXRlOiB7fSxcbiAgICAgICAgZGVmYXVsdF9lbGVtZW50X2RpcjogcGF0aC5qb2luKG9zLmhvbWVkaXIoKSwgJy5kb2xsaG91c2UnLCAncG9ydGZvbGlvJylcbiAgICAgIH0sXG4gICAgICBkaXNwbGF5OiB7XG4gICAgICAgIHBlcnNvbmFfaW5kaWNhdG9yczoge1xuICAgICAgICAgIGVuYWJsZWQ6IHRydWUsXG4gICAgICAgICAgc3R5bGU6ICdtaW5pbWFsJyxcbiAgICAgICAgICBpbmNsdWRlX2Vtb2ppOiB0cnVlXG4gICAgICAgIH0sXG4gICAgICAgIHZlcmJvc2VfbG9nZ2luZzogZmFsc2UsXG4gICAgICAgIHNob3dfcHJvZ3Jlc3M6IHRydWVcbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEluaXRpYWxpemUgY29uZmlndXJhdGlvblxuICAgKi9cbiAgcHVibGljIGFzeW5jIGluaXRpYWxpemUoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgLy8gQWx3YXlzIHJlbG9hZCBjb25maWcgZnJvbSBkaXNrIGlmIGl0IGV4aXN0cywgZXZlbiBpZiB3ZSBoYXZlIGRlZmF1bHRzIGluIG1lbW9yeVxuICAgIC8vIFRoaXMgZW5zdXJlcyB3ZSBwaWNrIHVwIGFueSBtYW51YWwgZWRpdHMgb3Igc2F2ZWQgc2V0dGluZ3NcbiAgICBcbiAgICB0cnkge1xuICAgICAgLy8gRW5zdXJlIGNvbmZpZyBkaXJlY3RvcnkgZXhpc3RzIHdpdGggcHJvcGVyIHBlcm1pc3Npb25zICgwbzcwMCA9IG93bmVyIG9ubHkpXG4gICAgICBhd2FpdCBmcy5ta2Rpcih0aGlzLmNvbmZpZ0RpciwgeyByZWN1cnNpdmU6IHRydWUsIG1vZGU6IDBvNzAwIH0pO1xuICAgICAgXG4gICAgICAvLyBMb2FkIG9yIGNyZWF0ZSBjb25maWdcbiAgICAgIGlmIChhd2FpdCB0aGlzLmNvbmZpZ0V4aXN0cygpKSB7XG4gICAgICAgIGF3YWl0IHRoaXMubG9hZENvbmZpZygpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gQ3JlYXRlIGRlZmF1bHQgY29uZmlnXG4gICAgICAgIHRoaXMuY29uZmlnID0gdGhpcy5nZXREZWZhdWx0Q29uZmlnKCk7XG4gICAgICAgIFxuICAgICAgICAvLyBUcnkgdG8gbWlncmF0ZSBmcm9tIGVudmlyb25tZW50IHZhcmlhYmxlc1xuICAgICAgICBhd2FpdCB0aGlzLm1pZ3JhdGVGcm9tRW52aXJvbm1lbnQoKTtcbiAgICAgICAgXG4gICAgICAgIC8vIFNhdmUgdGhlIGNvbmZpZ1xuICAgICAgICBhd2FpdCB0aGlzLnNhdmVDb25maWcoKTtcbiAgICAgICAgXG4gICAgICAgIGxvZ2dlci5pbmZvKCdDcmVhdGVkIG5ldyBjb25maWd1cmF0aW9uIGZpbGUnLCB7XG4gICAgICAgICAgcGF0aDogdGhpcy5jb25maWdQYXRoXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoJ0ZhaWxlZCB0byBpbml0aWFsaXplIGNvbmZpZ3VyYXRpb24nLCB7XG4gICAgICAgIGVycm9yOiBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvcilcbiAgICAgIH0pO1xuICAgICAgLy8gVXNlIGRlZmF1bHRzIGluIG1lbW9yeVxuICAgICAgdGhpcy5jb25maWcgPSB0aGlzLmdldERlZmF1bHRDb25maWcoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogTG9hZCBjb25maWd1cmF0aW9uIGZyb20gZmlsZVxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBsb2FkQ29uZmlnKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBjb250ZW50ID0gYXdhaXQgZnMucmVhZEZpbGUodGhpcy5jb25maWdQYXRoLCAndXRmLTgnKTtcbiAgICAgIFxuICAgICAgLyoqXG4gICAgICAgKiBJTVBPUlRBTlQ6IFBhcnNlciBTZWxlY3Rpb24gZm9yIERpZmZlcmVudCBGaWxlIFR5cGVzXG4gICAgICAgKiBcbiAgICAgICAqIFdlIHVzZSBESUZGRVJFTlQgcGFyc2VycyBmb3IgZGlmZmVyZW50IGZpbGUgdHlwZXM6XG4gICAgICAgKiBcbiAgICAgICAqIDEuIGpzLXlhbWwgKHVzZWQgaGVyZSkgLSBGb3IgUFVSRSBZQU1MIGZpbGVzOlxuICAgICAgICogICAgLSBDb25maWd1cmF0aW9uIGZpbGVzIChjb25maWcueW1sKVxuICAgICAgICogICAgLSBEYXRhIGZpbGVzIHdpdGhvdXQgbWFya2Rvd24gY29udGVudFxuICAgICAgICogICAgLSBBbnkgLnltbCBvciAueWFtbCBmaWxlIHRoYXQncyBqdXN0IFlBTUxcbiAgICAgICAqICAgIEV4YW1wbGUgZm9ybWF0OlxuICAgICAgICogICAgYGBgeWFtbFxuICAgICAgICogICAgdmVyc2lvbjogMS4wLjBcbiAgICAgICAqICAgIHVzZXI6XG4gICAgICAgKiAgICAgIHVzZXJuYW1lOiBqb2huZG9lXG4gICAgICAgKiAgICAgIGVtYWlsOiBqb2huQGV4YW1wbGUuY29tXG4gICAgICAgKiAgICBgYGBcbiAgICAgICAqIFxuICAgICAgICogMi4gU2VjdXJlWWFtbFBhcnNlciAtIEZvciBNQVJLRE9XTiBmaWxlcyB3aXRoIFlBTUwgZnJvbnRtYXR0ZXI6XG4gICAgICAgKiAgICAtIFBlcnNvbmEgZmlsZXMgKCoubWQgaW4gcGVyc29uYXMvKVxuICAgICAgICogICAgLSBTa2lsbCBmaWxlcyAoKi5tZCBpbiBza2lsbHMvKVxuICAgICAgICogICAgLSBUZW1wbGF0ZSBmaWxlcyAoKi5tZCBpbiB0ZW1wbGF0ZXMvKVxuICAgICAgICogICAgLSBBbnkgLm1kIGZpbGUgd2l0aCBmcm9udG1hdHRlciBiZXR3ZWVuIC0tLSBtYXJrZXJzXG4gICAgICAgKiAgICBFeGFtcGxlIGZvcm1hdDpcbiAgICAgICAqICAgIGBgYG1hcmtkb3duXG4gICAgICAgKiAgICAtLS1cbiAgICAgICAqICAgIG5hbWU6IENyZWF0aXZlIFdyaXRlclxuICAgICAgICogICAgZGVzY3JpcHRpb246IEEgY3JlYXRpdmUgYXNzaXN0YW50XG4gICAgICAgKiAgICAtLS1cbiAgICAgICAqICAgICMgSW5zdHJ1Y3Rpb25zXG4gICAgICAgKiAgICBZb3UgYXJlIGEgY3JlYXRpdmUgd3JpdGVyLi4uXG4gICAgICAgKiAgICBgYGBcbiAgICAgICAqIFxuICAgICAgICogVGhlIGNvbmZpZyBmaWxlIGlzIFBVUkUgWUFNTCwgc28gd2UgdXNlIGpzLXlhbWwgZGlyZWN0bHkgd2l0aCBGQUlMU0FGRV9TQ0hFTUFcbiAgICAgICAqIGZvciBzZWN1cml0eSAocHJldmVudHMgY29kZSBleGVjdXRpb24gdmlhIFlBTUwgdGFncykuXG4gICAgICAgKiBTRUNVUklUWTogVGhpcyBpcyBOT1QgYSB2dWxuZXJhYmlsaXR5IC0gRkFJTFNBRkVfU0NIRU1BIHByZXZlbnRzIGNvZGUgZXhlY3V0aW9uXG4gICAgICAgKi9cbiAgICAgIGxldCBsb2FkZWREYXRhOiBhbnk7XG4gICAgICB0cnkge1xuICAgICAgICAvLyBVc2luZyB5YW1sIHdpdGggRkFJTFNBRkVfU0NIRU1BIGlzIHNlY3VyZSAtIHByZXZlbnRzIGNvZGUgZXhlY3V0aW9uXG4gICAgICAgIGxvYWRlZERhdGEgPSB5YW1sLmxvYWQoY29udGVudCwge1xuICAgICAgICAgIHNjaGVtYTogeWFtbC5GQUlMU0FGRV9TQ0hFTUEgLy8gU2FmZSBzY2hlbWEgcHJldmVudHMgY29kZSBleGVjdXRpb25cbiAgICAgICAgfSk7XG4gICAgICB9IGNhdGNoICh5YW1sRXJyb3IpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIFlBTUwgaW4gY29uZmlndXJhdGlvbiBmaWxlOiAke3lhbWxFcnJvciBpbnN0YW5jZW9mIEVycm9yID8geWFtbEVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoeWFtbEVycm9yKX1gKTtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgaWYgKCFsb2FkZWREYXRhIHx8IHR5cGVvZiBsb2FkZWREYXRhICE9PSAnb2JqZWN0Jykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgY29uZmlndXJhdGlvbiBmb3JtYXQnKTtcbiAgICAgIH1cbiAgICAgIGxvZ2dlci5kZWJ1ZygnTG9hZGVkIGNvbmZpZyBmcm9tIGZpbGUnLCB7XG4gICAgICAgIHVzZXJuYW1lOiBsb2FkZWREYXRhLnVzZXI/LnVzZXJuYW1lLFxuICAgICAgICBlbWFpbDogbG9hZGVkRGF0YS51c2VyPy5lbWFpbCxcbiAgICAgICAgc3luY0VuYWJsZWQ6IGxvYWRlZERhdGEuc3luYz8uZW5hYmxlZFxuICAgICAgfSk7XG4gICAgICBcbiAgICAgIHRoaXMuY29uZmlnID0gdGhpcy5tZXJnZVdpdGhEZWZhdWx0cyhsb2FkZWREYXRhKTtcbiAgICAgIFxuICAgICAgLy8gRml4IGFueSBzdHJpbmcgYm9vbGVhbnMgdGhhdCBtaWdodCBoYXZlIGJlZW4gc2F2ZWQgaW5jb3JyZWN0bHlcbiAgICAgIHRoaXMuZml4Q29uZmlnVHlwZXMoKTtcbiAgICAgIFxuICAgICAgbG9nZ2VyLmRlYnVnKCdDb25maWd1cmF0aW9uIGxvYWRlZCBzdWNjZXNzZnVsbHknLCB7XG4gICAgICAgIHVzZXJuYW1lOiB0aGlzLmNvbmZpZy51c2VyLnVzZXJuYW1lLFxuICAgICAgICBzeW5jRW5hYmxlZDogdGhpcy5jb25maWcuc3luYy5lbmFibGVkXG4gICAgICB9KTtcbiAgICAgIFxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoJ0ZhaWxlZCB0byBsb2FkIGNvbmZpZ3VyYXRpb24nLCB7XG4gICAgICAgIGVycm9yOiBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvcilcbiAgICAgIH0pO1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIGlmIGNvbmZpZyBmaWxlIGV4aXN0c1xuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBjb25maWdFeGlzdHMoKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IGZzLmFjY2Vzcyh0aGlzLmNvbmZpZ1BhdGgpO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBjYXRjaCB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEdldCBHaXRIdWIgT0F1dGggY2xpZW50IElEXG4gICAqIEVudmlyb25tZW50IHZhcmlhYmxlIHRha2VzIHByZWNlZGVuY2Ugb3ZlciBjb25maWcgZmlsZVxuICAgKi9cbiAgcHVibGljIGdldEdpdEh1YkNsaWVudElkKCk6IHN0cmluZyB8IG51bGwge1xuICAgIC8vIENoZWNrIGVudmlyb25tZW50IHZhcmlhYmxlIGZpcnN0XG4gICAgY29uc3QgZW52Q2xpZW50SWQgPSBwcm9jZXNzLmVudi5ET0xMSE9VU0VfR0lUSFVCX0NMSUVOVF9JRDtcbiAgICBpZiAoZW52Q2xpZW50SWQpIHtcbiAgICAgIHJldHVybiBlbnZDbGllbnRJZDtcbiAgICB9XG5cbiAgICAvLyBGYWxsIGJhY2sgdG8gY29uZmlnIGZpbGVcbiAgICByZXR1cm4gdGhpcy5jb25maWc/LmdpdGh1Yj8uYXV0aD8uY2xpZW50X2lkIHx8IG51bGw7XG4gIH1cblxuICAvKipcbiAgICogU2V0IEdpdEh1YiBPQXV0aCBjbGllbnQgSUQgaW4gY29uZmlnIGZpbGVcbiAgICovXG4gIHB1YmxpYyBhc3luYyBzZXRHaXRIdWJDbGllbnRJZChjbGllbnRJZDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKCFDb25maWdNYW5hZ2VyLnZhbGlkYXRlQ2xpZW50SWQoY2xpZW50SWQpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBJbnZhbGlkIEdpdEh1YiBjbGllbnQgSUQgZm9ybWF0LiBFeHBlY3RlZCBmb3JtYXQ6IE92MjNsaSBmb2xsb3dlZCBieSBhdCBsZWFzdCAxNCBhbHBoYW51bWVyaWMgY2hhcmFjdGVycyAoZS5nLiwgT3YyM2xpQUJDREVGR0hJSktMTU4pYFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMuY29uZmlnKSB7XG4gICAgICB0aGlzLmNvbmZpZyA9IHRoaXMuZ2V0RGVmYXVsdENvbmZpZygpO1xuICAgIH1cblxuICAgIC8vIEVuc3VyZSBnaXRodWIuYXV0aCBvYmplY3QgZXhpc3RzXG4gICAgaWYgKCF0aGlzLmNvbmZpZy5naXRodWIpIHtcbiAgICAgIHRoaXMuY29uZmlnLmdpdGh1YiA9IHRoaXMuZ2V0RGVmYXVsdENvbmZpZygpLmdpdGh1YjtcbiAgICB9XG4gICAgaWYgKCF0aGlzLmNvbmZpZy5naXRodWIuYXV0aCkge1xuICAgICAgdGhpcy5jb25maWcuZ2l0aHViLmF1dGggPSB0aGlzLmdldERlZmF1bHRDb25maWcoKS5naXRodWIuYXV0aDtcbiAgICB9XG5cbiAgICB0aGlzLmNvbmZpZy5naXRodWIuYXV0aC5jbGllbnRfaWQgPSBjbGllbnRJZDtcbiAgICBhd2FpdCB0aGlzLnNhdmVDb25maWcoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIGN1cnJlbnQgY29uZmlndXJhdGlvblxuICAgKi9cbiAgcHVibGljIGdldENvbmZpZygpOiBEb2xsaG91c2VDb25maWcge1xuICAgIGlmICghdGhpcy5jb25maWcpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQ29uZmlndXJhdGlvbiBub3QgaW5pdGlhbGl6ZWQnKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuY29uZmlnO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBhIHNwZWNpZmljIHNldHRpbmcgdXNpbmcgZG90IG5vdGF0aW9uXG4gICAqL1xuICBwdWJsaWMgZ2V0U2V0dGluZzxUPihwYXRoOiBzdHJpbmcsIGRlZmF1bHRWYWx1ZT86IFQpOiBUIHwgdW5kZWZpbmVkIHtcbiAgICBpZiAoIXRoaXMuY29uZmlnKSB7XG4gICAgICByZXR1cm4gZGVmYXVsdFZhbHVlO1xuICAgIH1cbiAgICBcbiAgICBjb25zdCBrZXlzID0gcGF0aC5zcGxpdCgnLicpO1xuICAgIGxldCB2YWx1ZTogYW55ID0gdGhpcy5jb25maWc7XG4gICAgXG4gICAgZm9yIChjb25zdCBrZXkgb2Yga2V5cykge1xuICAgICAgaWYgKHZhbHVlICYmIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYga2V5IGluIHZhbHVlKSB7XG4gICAgICAgIHZhbHVlID0gdmFsdWVba2V5XTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBkZWZhdWx0VmFsdWU7XG4gICAgICB9XG4gICAgfVxuICAgIFxuICAgIHJldHVybiB2YWx1ZSBhcyBUO1xuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZSBhIHNwZWNpZmljIHNldHRpbmcgdXNpbmcgZG90IG5vdGF0aW9uXG4gICAqIFNFQ1VSSVRZIEZJWCAoUFIgIzg5NSk6IEFkZGVkIHByb3RvdHlwZSBwb2xsdXRpb24gcHJvdGVjdGlvblxuICAgKiBQcmV2aW91c2x5OiBEaXJlY3QgcHJvcGVydHkgYXNzaWdubWVudCBhbGxvd2VkIF9fcHJvdG9fXyBpbmplY3Rpb25cbiAgICogTm93OiBWYWxpZGF0ZXMga2V5cyBhZ2FpbnN0IGZvcmJpZGRlbiBwcm9wZXJ0aWVzIGJlZm9yZSBhc3NpZ25tZW50XG4gICAqL1xuICBwdWJsaWMgYXN5bmMgdXBkYXRlU2V0dGluZyhwYXRoOiBzdHJpbmcsIHZhbHVlOiBhbnkpOiBQcm9taXNlPENvbmZpZ1VwZGF0ZVJlc3VsdD4ge1xuICAgIGlmICghdGhpcy5jb25maWcpIHtcbiAgICAgIGF3YWl0IHRoaXMuaW5pdGlhbGl6ZSgpO1xuICAgIH1cbiAgICBcbiAgICBjb25zdCBrZXlzID0gcGF0aC5zcGxpdCgnLicpO1xuICAgIFxuICAgIC8vIFNFQ1VSSVRZOiBWYWxpZGF0ZSBhbGwga2V5cyB0byBwcmV2ZW50IHByb3RvdHlwZSBwb2xsdXRpb25cbiAgICBjb25zdCBGT1JCSURERU5fS0VZUyA9IFsnX19wcm90b19fJywgJ2NvbnN0cnVjdG9yJywgJ3Byb3RvdHlwZSddO1xuICAgIGZvciAoY29uc3Qga2V5IG9mIGtleXMpIHtcbiAgICAgIGlmIChGT1JCSURERU5fS0VZUy5pbmNsdWRlcyhrZXkpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgRm9yYmlkZGVuIHByb3BlcnR5IGluIHBhdGg6ICR7a2V5fWApO1xuICAgICAgfVxuICAgIH1cbiAgICBcbiAgICBsZXQgY3VycmVudDogYW55ID0gdGhpcy5jb25maWc7XG4gICAgY29uc3QgcHJldmlvdXNWYWx1ZSA9IHRoaXMuZ2V0U2V0dGluZyhwYXRoKTtcbiAgICBcbiAgICAvLyBOYXZpZ2F0ZSB0byB0aGUgcGFyZW50IG9iamVjdFxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwga2V5cy5sZW5ndGggLSAxOyBpKyspIHtcbiAgICAgIGNvbnN0IGtleSA9IGtleXNbaV07XG4gICAgICBpZiAoIShrZXkgaW4gY3VycmVudCkpIHtcbiAgICAgICAgY3VycmVudFtrZXldID0ge307XG4gICAgICB9XG4gICAgICBjdXJyZW50ID0gY3VycmVudFtrZXldO1xuICAgIH1cbiAgICBcbiAgICAvLyBTZXQgdGhlIHZhbHVlXG4gICAgY29uc3QgbGFzdEtleSA9IGtleXNba2V5cy5sZW5ndGggLSAxXTtcbiAgICBjdXJyZW50W2xhc3RLZXldID0gdmFsdWU7XG4gICAgXG4gICAgLy8gU2F2ZSB0aGUgY29uZmlndXJhdGlvblxuICAgIGF3YWl0IHRoaXMuc2F2ZUNvbmZpZygpO1xuICAgIFxuICAgIGxvZ2dlci5pbmZvKCdDb25maWd1cmF0aW9uIHNldHRpbmcgdXBkYXRlZCcsIHtcbiAgICAgIHBhdGgsXG4gICAgICBwcmV2aW91c1ZhbHVlLFxuICAgICAgbmV3VmFsdWU6IHZhbHVlXG4gICAgfSk7XG4gICAgXG4gICAgcmV0dXJuIHtcbiAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICBtZXNzYWdlOiBgU2V0dGluZyAnJHtwYXRofScgdXBkYXRlZCBzdWNjZXNzZnVsbHlgLFxuICAgICAgcHJldmlvdXNWYWx1ZSxcbiAgICAgIG5ld1ZhbHVlOiB2YWx1ZVxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGUgR2l0SHViIE9BdXRoIGNsaWVudCBJRCBmb3JtYXRcbiAgICogQ2xpZW50IElEcyBzdGFydCB3aXRoIFwiT3YyM2xpXCIgZm9sbG93ZWQgYnkgYXQgbGVhc3QgMTQgYWxwaGFudW1lcmljIGNoYXJhY3RlcnNcbiAgICogXG4gICAqIEBwYXJhbSBjbGllbnRJZCAtIFRoZSBjbGllbnQgSUQgdG8gdmFsaWRhdGVcbiAgICogQHJldHVybnMgdHJ1ZSBpZiB2YWxpZCwgZmFsc2Ugb3RoZXJ3aXNlXG4gICAqIFxuICAgKiBAZXhhbXBsZVxuICAgKiBDb25maWdNYW5hZ2VyLnZhbGlkYXRlQ2xpZW50SWQoXCJPdjIzbGlBQkNERUZHSElKS0xNTjEyMzQ1NlwiKSAvLyB0cnVlXG4gICAqIENvbmZpZ01hbmFnZXIudmFsaWRhdGVDbGllbnRJZChcImludmFsaWRcIikgLy8gZmFsc2VcbiAgICogQ29uZmlnTWFuYWdlci52YWxpZGF0ZUNsaWVudElkKFwiT3YyM2xpXCIpIC8vIGZhbHNlICh0b28gc2hvcnQpXG4gICAqIENvbmZpZ01hbmFnZXIudmFsaWRhdGVDbGllbnRJZChcIlh2MjNsaUFCQ0RFRkdISUpLTE1OXCIpIC8vIGZhbHNlICh3cm9uZyBwcmVmaXgpXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIHZhbGlkYXRlQ2xpZW50SWQoY2xpZW50SWQ6IGFueSk6IGJvb2xlYW4ge1xuICAgIGlmICh0eXBlb2YgY2xpZW50SWQgIT09ICdzdHJpbmcnIHx8ICFjbGllbnRJZCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIC8vIEdpdEh1YiBPQXV0aCBjbGllbnQgSURzIGZvbGxvdyB0aGUgcGF0dGVybjogT3YyM2xpW0EtWmEtejAtOV17MTQsfVxuICAgIGNvbnN0IGNsaWVudElkUGF0dGVybiA9IC9eT3YyM2xpW0EtWmEtejAtOV17MTQsfSQvO1xuICAgIHJldHVybiBjbGllbnRJZFBhdHRlcm4udGVzdChjbGllbnRJZCk7XG4gIH1cblxuICAvKipcbiAgICogU2F2ZSBjb25maWd1cmF0aW9uIHRvIGZpbGVcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgc2F2ZUNvbmZpZygpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoIXRoaXMuY29uZmlnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vIGNvbmZpZ3VyYXRpb24gdG8gc2F2ZScpO1xuICAgIH1cbiAgICBcbiAgICB0cnkge1xuICAgICAgLy8gQ3JlYXRlIGJhY2t1cCBvZiBleGlzdGluZyBjb25maWdcbiAgICAgIGlmIChhd2FpdCB0aGlzLmNvbmZpZ0V4aXN0cygpKSB7XG4gICAgICAgIGF3YWl0IGZzLmNvcHlGaWxlKHRoaXMuY29uZmlnUGF0aCwgdGhpcy5iYWNrdXBQYXRoKTtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgLy8gQ29udmVydCB0byBZQU1MXG4gICAgICAvLyBOb3RlOiBXZSB1c2UganMteWFtbCdzIGR1bXAoKSBmb3IgcHVyZSBZQU1MIG91dHB1dCAobm8gZnJvbnRtYXR0ZXIgbWFya2VycylcbiAgICAgIC8vIFRoaXMgY3JlYXRlcyBhIHN0YW5kYXJkIFlBTUwgZmlsZSwgbm90IGEgbWFya2Rvd24gZmlsZSB3aXRoIGZyb250bWF0dGVyXG4gICAgICBjb25zdCB5YW1sQ29udGVudCA9IHlhbWwuZHVtcCh0aGlzLmNvbmZpZywge1xuICAgICAgICBpbmRlbnQ6IDIsXG4gICAgICAgIGxpbmVXaWR0aDogMTIwLFxuICAgICAgICBub1JlZnM6IHRydWUsXG4gICAgICAgIHNvcnRLZXlzOiBmYWxzZVxuICAgICAgICAvLyBVc2luZyBkZWZhdWx0IHNjaGVtYSAobm90IEZBSUxTQUZFKSBmb3IgZHVtcCB0byBwcmVzZXJ2ZSB0eXBlcyBsaWtlIGJvb2xlYW5zXG4gICAgICB9KTtcbiAgICAgIFxuICAgICAgLy8gV3JpdGUgYXRvbWljYWxseSB3aXRoIHByb3BlciBwZXJtaXNzaW9ucyAoMG82MDAgPSBvd25lciByZWFkL3dyaXRlIG9ubHkpXG4gICAgICBjb25zdCB0ZW1wUGF0aCA9IGAke3RoaXMuY29uZmlnUGF0aH0udG1wYDtcbiAgICAgIGF3YWl0IGZzLndyaXRlRmlsZSh0ZW1wUGF0aCwgeWFtbENvbnRlbnQsIHsgZW5jb2Rpbmc6ICd1dGYtOCcsIG1vZGU6IDBvNjAwIH0pO1xuICAgICAgYXdhaXQgZnMucmVuYW1lKHRlbXBQYXRoLCB0aGlzLmNvbmZpZ1BhdGgpO1xuICAgICAgXG4gICAgICBsb2dnZXIuZGVidWcoJ0NvbmZpZ3VyYXRpb24gc2F2ZWQgc3VjY2Vzc2Z1bGx5Jyk7XG4gICAgICBcbiAgICAgIC8vIExvZyBhdWRpdCBldmVudCBmb3IgY29uZmlndXJhdGlvbiB1cGRhdGVcbiAgICAgIGxvZ2dlci5kZWJ1ZygnQ29uZmlndXJhdGlvbiB1cGRhdGUgYXVkaXQnLCB7XG4gICAgICAgIGV2ZW50OiAnQ09ORklHX1VQREFURUQnLFxuICAgICAgICBzb3VyY2U6ICdDb25maWdNYW5hZ2VyLnNhdmVDb25maWcnLFxuICAgICAgICB0aW1lc3RhbXA6IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKVxuICAgICAgfSk7XG4gICAgICBcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nZ2VyLmVycm9yKCdGYWlsZWQgdG8gc2F2ZSBjb25maWd1cmF0aW9uJywge1xuICAgICAgICBlcnJvcjogZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpXG4gICAgICB9KTtcbiAgICAgIFxuICAgICAgLy8gVHJ5IHRvIHJlc3RvcmUgYmFja3VwXG4gICAgICBpZiAoYXdhaXQgdGhpcy5iYWNrdXBFeGlzdHMoKSkge1xuICAgICAgICBhd2FpdCBmcy5jb3B5RmlsZSh0aGlzLmJhY2t1cFBhdGgsIHRoaXMuY29uZmlnUGF0aCk7XG4gICAgICAgIGxvZ2dlci5pbmZvKCdSZXN0b3JlZCBjb25maWd1cmF0aW9uIGZyb20gYmFja3VwJyk7XG4gICAgICB9XG4gICAgICBcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBiYWNrdXAgZXhpc3RzXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGJhY2t1cEV4aXN0cygpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgZnMuYWNjZXNzKHRoaXMuYmFja3VwUGF0aCk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRml4IGluY29ycmVjdCB0eXBlcyBpbiBjb25maWcgKGUuZy4sIHN0cmluZyBib29sZWFucywgc3RyaW5nIFwibnVsbFwiKVxuICAgKi9cbiAgcHJpdmF0ZSBmaXhDb25maWdUeXBlcygpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuY29uZmlnKSByZXR1cm47XG4gICAgXG4gICAgLy8gSGVscGVyIHRvIGNvbnZlcnQgc3RyaW5nIFwibnVsbFwiIHRvIGFjdHVhbCBudWxsXG4gICAgY29uc3QgZml4TnVsbCA9ICh2YWx1ZTogYW55KTogYW55ID0+IHtcbiAgICAgIGlmICh2YWx1ZSA9PT0gJ251bGwnIHx8IHZhbHVlID09PSAnTlVMTCcpIHJldHVybiBudWxsO1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH07XG4gICAgXG4gICAgLy8gSGVscGVyIHRvIGNvbnZlcnQgc3RyaW5nIGJvb2xlYW5zIHRvIGFjdHVhbCBib29sZWFuc1xuICAgIGNvbnN0IGZpeEJvb2xlYW4gPSAodmFsdWU6IGFueSk6IGFueSA9PiB7XG4gICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgICAgICBjb25zdCBsb3dlciA9IHZhbHVlLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgIGlmIChsb3dlciA9PT0gJ3RydWUnKSByZXR1cm4gdHJ1ZTtcbiAgICAgICAgaWYgKGxvd2VyID09PSAnZmFsc2UnKSByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfTtcbiAgICBcbiAgICAvLyBGaXggdXNlciBmaWVsZHMgLSBoYW5kbGUgc3RyaW5nIFwibnVsbFwiIHZhbHVlc1xuICAgIGlmICh0aGlzLmNvbmZpZy51c2VyKSB7XG4gICAgICB0aGlzLmNvbmZpZy51c2VyLnVzZXJuYW1lID0gZml4TnVsbCh0aGlzLmNvbmZpZy51c2VyLnVzZXJuYW1lKTtcbiAgICAgIHRoaXMuY29uZmlnLnVzZXIuZW1haWwgPSBmaXhOdWxsKHRoaXMuY29uZmlnLnVzZXIuZW1haWwpO1xuICAgICAgdGhpcy5jb25maWcudXNlci5kaXNwbGF5X25hbWUgPSBmaXhOdWxsKHRoaXMuY29uZmlnLnVzZXIuZGlzcGxheV9uYW1lKTtcbiAgICB9XG4gICAgXG4gICAgLy8gRml4IHN5bmMgc2V0dGluZ3NcbiAgICBpZiAodGhpcy5jb25maWcuc3luYykge1xuICAgICAgdGhpcy5jb25maWcuc3luYy5lbmFibGVkID0gZml4Qm9vbGVhbih0aGlzLmNvbmZpZy5zeW5jLmVuYWJsZWQpO1xuICAgICAgXG4gICAgICBpZiAodGhpcy5jb25maWcuc3luYy5pbmRpdmlkdWFsKSB7XG4gICAgICAgIHRoaXMuY29uZmlnLnN5bmMuaW5kaXZpZHVhbC5yZXF1aXJlX2NvbmZpcm1hdGlvbiA9IGZpeEJvb2xlYW4odGhpcy5jb25maWcuc3luYy5pbmRpdmlkdWFsLnJlcXVpcmVfY29uZmlybWF0aW9uKTtcbiAgICAgICAgdGhpcy5jb25maWcuc3luYy5pbmRpdmlkdWFsLnNob3dfZGlmZl9iZWZvcmVfc3luYyA9IGZpeEJvb2xlYW4odGhpcy5jb25maWcuc3luYy5pbmRpdmlkdWFsLnNob3dfZGlmZl9iZWZvcmVfc3luYyk7XG4gICAgICAgIHRoaXMuY29uZmlnLnN5bmMuaW5kaXZpZHVhbC50cmFja192ZXJzaW9ucyA9IGZpeEJvb2xlYW4odGhpcy5jb25maWcuc3luYy5pbmRpdmlkdWFsLnRyYWNrX3ZlcnNpb25zKTtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgaWYgKHRoaXMuY29uZmlnLnN5bmMuYnVsaykge1xuICAgICAgICB0aGlzLmNvbmZpZy5zeW5jLmJ1bGsudXBsb2FkX2VuYWJsZWQgPSBmaXhCb29sZWFuKHRoaXMuY29uZmlnLnN5bmMuYnVsay51cGxvYWRfZW5hYmxlZCk7XG4gICAgICAgIHRoaXMuY29uZmlnLnN5bmMuYnVsay5kb3dubG9hZF9lbmFibGVkID0gZml4Qm9vbGVhbih0aGlzLmNvbmZpZy5zeW5jLmJ1bGsuZG93bmxvYWRfZW5hYmxlZCk7XG4gICAgICAgIHRoaXMuY29uZmlnLnN5bmMuYnVsay5yZXF1aXJlX3ByZXZpZXcgPSBmaXhCb29sZWFuKHRoaXMuY29uZmlnLnN5bmMuYnVsay5yZXF1aXJlX3ByZXZpZXcpO1xuICAgICAgICB0aGlzLmNvbmZpZy5zeW5jLmJ1bGsucmVzcGVjdF9sb2NhbF9vbmx5ID0gZml4Qm9vbGVhbih0aGlzLmNvbmZpZy5zeW5jLmJ1bGsucmVzcGVjdF9sb2NhbF9vbmx5KTtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgaWYgKHRoaXMuY29uZmlnLnN5bmMucHJpdmFjeSkge1xuICAgICAgICB0aGlzLmNvbmZpZy5zeW5jLnByaXZhY3kuc2Nhbl9mb3Jfc2VjcmV0cyA9IGZpeEJvb2xlYW4odGhpcy5jb25maWcuc3luYy5wcml2YWN5LnNjYW5fZm9yX3NlY3JldHMpO1xuICAgICAgICB0aGlzLmNvbmZpZy5zeW5jLnByaXZhY3kuc2Nhbl9mb3JfcGlpID0gZml4Qm9vbGVhbih0aGlzLmNvbmZpZy5zeW5jLnByaXZhY3kuc2Nhbl9mb3JfcGlpKTtcbiAgICAgICAgdGhpcy5jb25maWcuc3luYy5wcml2YWN5Lndhcm5fb25fc2Vuc2l0aXZlID0gZml4Qm9vbGVhbih0aGlzLmNvbmZpZy5zeW5jLnByaXZhY3kud2Fybl9vbl9zZW5zaXRpdmUpO1xuICAgICAgfVxuICAgIH1cbiAgICBcbiAgICAvLyBGaXggY29sbGVjdGlvbiBzZXR0aW5nc1xuICAgIGlmICh0aGlzLmNvbmZpZy5jb2xsZWN0aW9uKSB7XG4gICAgICB0aGlzLmNvbmZpZy5jb2xsZWN0aW9uLmF1dG9fc3VibWl0ID0gZml4Qm9vbGVhbih0aGlzLmNvbmZpZy5jb2xsZWN0aW9uLmF1dG9fc3VibWl0KTtcbiAgICAgIHRoaXMuY29uZmlnLmNvbGxlY3Rpb24ucmVxdWlyZV9yZXZpZXcgPSBmaXhCb29sZWFuKHRoaXMuY29uZmlnLmNvbGxlY3Rpb24ucmVxdWlyZV9yZXZpZXcpO1xuICAgICAgdGhpcy5jb25maWcuY29sbGVjdGlvbi5hZGRfYXR0cmlidXRpb24gPSBmaXhCb29sZWFuKHRoaXMuY29uZmlnLmNvbGxlY3Rpb24uYWRkX2F0dHJpYnV0aW9uKTtcbiAgICB9XG4gICAgXG4gICAgLy8gRml4IGRpc3BsYXkgc2V0dGluZ3NcbiAgICBpZiAodGhpcy5jb25maWcuZGlzcGxheSkge1xuICAgICAgaWYgKHRoaXMuY29uZmlnLmRpc3BsYXkucGVyc29uYV9pbmRpY2F0b3JzKSB7XG4gICAgICAgIHRoaXMuY29uZmlnLmRpc3BsYXkucGVyc29uYV9pbmRpY2F0b3JzLmVuYWJsZWQgPSBmaXhCb29sZWFuKHRoaXMuY29uZmlnLmRpc3BsYXkucGVyc29uYV9pbmRpY2F0b3JzLmVuYWJsZWQpO1xuICAgICAgICB0aGlzLmNvbmZpZy5kaXNwbGF5LnBlcnNvbmFfaW5kaWNhdG9ycy5pbmNsdWRlX2Vtb2ppID0gZml4Qm9vbGVhbih0aGlzLmNvbmZpZy5kaXNwbGF5LnBlcnNvbmFfaW5kaWNhdG9ycy5pbmNsdWRlX2Vtb2ppKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuY29uZmlnLmRpc3BsYXkudmVyYm9zZV9sb2dnaW5nID0gZml4Qm9vbGVhbih0aGlzLmNvbmZpZy5kaXNwbGF5LnZlcmJvc2VfbG9nZ2luZyk7XG4gICAgICB0aGlzLmNvbmZpZy5kaXNwbGF5LnNob3dfcHJvZ3Jlc3MgPSBmaXhCb29sZWFuKHRoaXMuY29uZmlnLmRpc3BsYXkuc2hvd19wcm9ncmVzcyk7XG4gICAgfVxuICAgIFxuICAgIC8vIEZpeCBnaXRodWIgc2V0dGluZ3NcbiAgICBpZiAodGhpcy5jb25maWcuZ2l0aHViKSB7XG4gICAgICBpZiAodGhpcy5jb25maWcuZ2l0aHViLnBvcnRmb2xpbykge1xuICAgICAgICB0aGlzLmNvbmZpZy5naXRodWIucG9ydGZvbGlvLnJlcG9zaXRvcnlfdXJsID0gZml4TnVsbCh0aGlzLmNvbmZpZy5naXRodWIucG9ydGZvbGlvLnJlcG9zaXRvcnlfdXJsKTtcbiAgICAgICAgdGhpcy5jb25maWcuZ2l0aHViLnBvcnRmb2xpby5hdXRvX2NyZWF0ZSA9IGZpeEJvb2xlYW4odGhpcy5jb25maWcuZ2l0aHViLnBvcnRmb2xpby5hdXRvX2NyZWF0ZSk7XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5jb25maWcuZ2l0aHViLmF1dGgpIHtcbiAgICAgICAgdGhpcy5jb25maWcuZ2l0aHViLmF1dGgudXNlX29hdXRoID0gZml4Qm9vbGVhbih0aGlzLmNvbmZpZy5naXRodWIuYXV0aC51c2Vfb2F1dGgpO1xuICAgICAgICAvLyBGaXggY2xpZW50X2lkIGlmIGl0J3MgYSBzdHJpbmcgXCJudWxsXCJcbiAgICAgICAgaWYgKHRoaXMuY29uZmlnLmdpdGh1Yi5hdXRoLmNsaWVudF9pZCkge1xuICAgICAgICAgIHRoaXMuY29uZmlnLmdpdGh1Yi5hdXRoLmNsaWVudF9pZCA9IGZpeE51bGwodGhpcy5jb25maWcuZ2l0aHViLmF1dGguY2xpZW50X2lkKSB8fCB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogTWVyZ2UgcGFydGlhbCBjb25maWcgd2l0aCBkZWZhdWx0c1xuICAgKiBcbiAgICogSU1QT1JUQU5UOiBUaGlzIGZ1bmN0aW9uIHByZXNlcnZlcyB1bmtub3duIGZpZWxkcyBmb3IgZm9yd2FyZCBjb21wYXRpYmlsaXR5LlxuICAgKiBJZiBhIGZ1dHVyZSB2ZXJzaW9uIGFkZHMgbmV3IGNvbmZpZyBmaWVsZHMsIG9sZGVyIHZlcnNpb25zIHdvbid0IGxvc2UgdGhlbS5cbiAgICovXG4gIHByaXZhdGUgbWVyZ2VXaXRoRGVmYXVsdHMocGFydGlhbDogUGFydGlhbDxEb2xsaG91c2VDb25maWc+KTogRG9sbGhvdXNlQ29uZmlnIHtcbiAgICBjb25zdCBkZWZhdWx0cyA9IHRoaXMuZ2V0RGVmYXVsdENvbmZpZygpO1xuICAgIFxuICAgIC8vIFN0YXJ0IHdpdGggYSBkZWVwIGNsb25lIG9mIHBhcnRpYWwgdG8gcHJlc2VydmUgYWxsIHVua25vd24gZmllbGRzXG4gICAgY29uc3QgcmVzdWx0OiBhbnkgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHBhcnRpYWwpKTtcbiAgICBcbiAgICAvLyBFbnN1cmUgYWxsIHJlcXVpcmVkIGZpZWxkcyBleGlzdCB3aXRoIGRlZmF1bHRzXG4gICAgcmVzdWx0LnZlcnNpb24gPSByZXN1bHQudmVyc2lvbiB8fCBkZWZhdWx0cy52ZXJzaW9uO1xuICAgIFxuICAgIC8vIFVzZXIgc2VjdGlvbiAtIHByZXNlcnZlIHVua25vd24gZmllbGRzIHdoaWxlIGVuc3VyaW5nIHJlcXVpcmVkIGZpZWxkc1xuICAgIHJlc3VsdC51c2VyID0ge1xuICAgICAgLi4ucmVzdWx0LnVzZXIsXG4gICAgICB1c2VybmFtZTogcmVzdWx0LnVzZXI/LnVzZXJuYW1lID8/IGRlZmF1bHRzLnVzZXIudXNlcm5hbWUsXG4gICAgICBlbWFpbDogcmVzdWx0LnVzZXI/LmVtYWlsID8/IGRlZmF1bHRzLnVzZXIuZW1haWwsXG4gICAgICBkaXNwbGF5X25hbWU6IHJlc3VsdC51c2VyPy5kaXNwbGF5X25hbWUgPz8gZGVmYXVsdHMudXNlci5kaXNwbGF5X25hbWVcbiAgICB9O1xuICAgIFxuICAgIC8vIEdpdEh1YiBzZWN0aW9uIC0gZGVlcCBtZXJnZSBwcmVzZXJ2aW5nIHVua25vd24gZmllbGRzXG4gICAgaWYgKCFyZXN1bHQuZ2l0aHViKSByZXN1bHQuZ2l0aHViID0ge307XG4gICAgcmVzdWx0LmdpdGh1Yi5wb3J0Zm9saW8gPSB7XG4gICAgICAuLi5kZWZhdWx0cy5naXRodWIucG9ydGZvbGlvLFxuICAgICAgLi4ucmVzdWx0LmdpdGh1Yi5wb3J0Zm9saW9cbiAgICB9O1xuICAgIHJlc3VsdC5naXRodWIuYXV0aCA9IHtcbiAgICAgIC4uLmRlZmF1bHRzLmdpdGh1Yi5hdXRoLFxuICAgICAgLi4ucmVzdWx0LmdpdGh1Yi5hdXRoXG4gICAgfTtcbiAgICBcbiAgICAvLyBTeW5jIHNlY3Rpb24gLSBwcmVzZXJ2ZSB1bmtub3duIGZpZWxkcyBhdCBhbGwgbGV2ZWxzXG4gICAgaWYgKCFyZXN1bHQuc3luYykgcmVzdWx0LnN5bmMgPSB7fTtcbiAgICByZXN1bHQuc3luYy5lbmFibGVkID0gcmVzdWx0LnN5bmMuZW5hYmxlZCA/PyBkZWZhdWx0cy5zeW5jLmVuYWJsZWQ7XG4gICAgcmVzdWx0LnN5bmMuaW5kaXZpZHVhbCA9IHtcbiAgICAgIC4uLmRlZmF1bHRzLnN5bmMuaW5kaXZpZHVhbCxcbiAgICAgIC4uLnJlc3VsdC5zeW5jLmluZGl2aWR1YWxcbiAgICB9O1xuICAgIHJlc3VsdC5zeW5jLmJ1bGsgPSB7XG4gICAgICAuLi5kZWZhdWx0cy5zeW5jLmJ1bGssXG4gICAgICAuLi5yZXN1bHQuc3luYy5idWxrXG4gICAgfTtcbiAgICByZXN1bHQuc3luYy5wcml2YWN5ID0ge1xuICAgICAgLi4uZGVmYXVsdHMuc3luYy5wcml2YWN5LFxuICAgICAgLi4ucmVzdWx0LnN5bmMucHJpdmFjeSxcbiAgICAgIC8vIFNwZWNpYWwgaGFuZGxpbmcgZm9yIGFycmF5cyAtIHVzZSBwcm92aWRlZCBvciBkZWZhdWx0XG4gICAgICBleGNsdWRlZF9wYXR0ZXJuczogcmVzdWx0LnN5bmMucHJpdmFjeT8uZXhjbHVkZWRfcGF0dGVybnMgfHwgZGVmYXVsdHMuc3luYy5wcml2YWN5LmV4Y2x1ZGVkX3BhdHRlcm5zXG4gICAgfTtcbiAgICBcbiAgICAvLyBDb2xsZWN0aW9uIHNlY3Rpb25cbiAgICByZXN1bHQuY29sbGVjdGlvbiA9IHtcbiAgICAgIC4uLmRlZmF1bHRzLmNvbGxlY3Rpb24sXG4gICAgICAuLi5yZXN1bHQuY29sbGVjdGlvblxuICAgIH07XG4gICAgXG4gICAgLy8gRWxlbWVudHMgc2VjdGlvblxuICAgIGlmICghcmVzdWx0LmVsZW1lbnRzKSByZXN1bHQuZWxlbWVudHMgPSB7fTtcbiAgICByZXN1bHQuZWxlbWVudHMgPSB7XG4gICAgICAuLi5yZXN1bHQuZWxlbWVudHMsXG4gICAgICBhdXRvX2FjdGl2YXRlOiByZXN1bHQuZWxlbWVudHMuYXV0b19hY3RpdmF0ZSB8fCBkZWZhdWx0cy5lbGVtZW50cy5hdXRvX2FjdGl2YXRlLFxuICAgICAgZGVmYXVsdF9lbGVtZW50X2RpcjogcmVzdWx0LmVsZW1lbnRzLmRlZmF1bHRfZWxlbWVudF9kaXIgfHwgZGVmYXVsdHMuZWxlbWVudHMuZGVmYXVsdF9lbGVtZW50X2RpclxuICAgIH07XG4gICAgXG4gICAgLy8gRGlzcGxheSBzZWN0aW9uXG4gICAgaWYgKCFyZXN1bHQuZGlzcGxheSkgcmVzdWx0LmRpc3BsYXkgPSB7fTtcbiAgICByZXN1bHQuZGlzcGxheS5wZXJzb25hX2luZGljYXRvcnMgPSB7XG4gICAgICAuLi5kZWZhdWx0cy5kaXNwbGF5LnBlcnNvbmFfaW5kaWNhdG9ycyxcbiAgICAgIC4uLnJlc3VsdC5kaXNwbGF5LnBlcnNvbmFfaW5kaWNhdG9yc1xuICAgIH07XG4gICAgcmVzdWx0LmRpc3BsYXkudmVyYm9zZV9sb2dnaW5nID0gcmVzdWx0LmRpc3BsYXkudmVyYm9zZV9sb2dnaW5nID8/IGRlZmF1bHRzLmRpc3BsYXkudmVyYm9zZV9sb2dnaW5nO1xuICAgIHJlc3VsdC5kaXNwbGF5LnNob3dfcHJvZ3Jlc3MgPSByZXN1bHQuZGlzcGxheS5zaG93X3Byb2dyZXNzID8/IGRlZmF1bHRzLmRpc3BsYXkuc2hvd19wcm9ncmVzcztcbiAgICBcbiAgICByZXR1cm4gcmVzdWx0IGFzIERvbGxob3VzZUNvbmZpZztcbiAgfVxuXG4gIC8qKlxuICAgKiBNaWdyYXRlIHNldHRpbmdzIGZyb20gZW52aXJvbm1lbnQgdmFyaWFibGVzXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIG1pZ3JhdGVGcm9tRW52aXJvbm1lbnQoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgbGV0IG1pZ3JhdGVkID0gZmFsc2U7XG4gICAgXG4gICAgLy8gTWlncmF0ZSB1c2VyIHNldHRpbmdzXG4gICAgaWYgKHByb2Nlc3MuZW52LkRPTExIT1VTRV9VU0VSICYmICF0aGlzLmNvbmZpZz8udXNlci51c2VybmFtZSkge1xuICAgICAgaWYgKCF0aGlzLmNvbmZpZykgdGhpcy5jb25maWcgPSB0aGlzLmdldERlZmF1bHRDb25maWcoKTtcbiAgICAgIHRoaXMuY29uZmlnLnVzZXIudXNlcm5hbWUgPSBwcm9jZXNzLmVudi5ET0xMSE9VU0VfVVNFUjtcbiAgICAgIG1pZ3JhdGVkID0gdHJ1ZTtcbiAgICB9XG4gICAgXG4gICAgaWYgKHByb2Nlc3MuZW52LkRPTExIT1VTRV9FTUFJTCAmJiAhdGhpcy5jb25maWc/LnVzZXIuZW1haWwpIHtcbiAgICAgIGlmICghdGhpcy5jb25maWcpIHRoaXMuY29uZmlnID0gdGhpcy5nZXREZWZhdWx0Q29uZmlnKCk7XG4gICAgICB0aGlzLmNvbmZpZy51c2VyLmVtYWlsID0gcHJvY2Vzcy5lbnYuRE9MTEhPVVNFX0VNQUlMO1xuICAgICAgbWlncmF0ZWQgPSB0cnVlO1xuICAgIH1cbiAgICBcbiAgICAvLyBNaWdyYXRlIHBvcnRmb2xpbyBVUkxcbiAgICBpZiAocHJvY2Vzcy5lbnYuRE9MTEhPVVNFX1BPUlRGT0xJT19VUkwgJiYgIXRoaXMuY29uZmlnPy5naXRodWIucG9ydGZvbGlvLnJlcG9zaXRvcnlfdXJsKSB7XG4gICAgICBpZiAoIXRoaXMuY29uZmlnKSB0aGlzLmNvbmZpZyA9IHRoaXMuZ2V0RGVmYXVsdENvbmZpZygpO1xuICAgICAgdGhpcy5jb25maWcuZ2l0aHViLnBvcnRmb2xpby5yZXBvc2l0b3J5X3VybCA9IHByb2Nlc3MuZW52LkRPTExIT1VTRV9QT1JURk9MSU9fVVJMO1xuICAgICAgbWlncmF0ZWQgPSB0cnVlO1xuICAgIH1cbiAgICBcbiAgICAvLyBNaWdyYXRlIGNvbGxlY3Rpb24gYXV0by1zdWJtaXRcbiAgICBpZiAocHJvY2Vzcy5lbnYuRE9MTEhPVVNFX0FVVE9fU1VCTUlUX1RPX0NPTExFQ1RJT04gIT09IHVuZGVmaW5lZCkge1xuICAgICAgaWYgKCF0aGlzLmNvbmZpZykgdGhpcy5jb25maWcgPSB0aGlzLmdldERlZmF1bHRDb25maWcoKTtcbiAgICAgIHRoaXMuY29uZmlnLmNvbGxlY3Rpb24uYXV0b19zdWJtaXQgPSBwcm9jZXNzLmVudi5ET0xMSE9VU0VfQVVUT19TVUJNSVRfVE9fQ09MTEVDVElPTiA9PT0gJ3RydWUnO1xuICAgICAgbWlncmF0ZWQgPSB0cnVlO1xuICAgIH1cbiAgICBcbiAgICBpZiAobWlncmF0ZWQpIHtcbiAgICAgIGxvZ2dlci5pbmZvKCdNaWdyYXRlZCBzZXR0aW5ncyBmcm9tIGVudmlyb25tZW50IHZhcmlhYmxlcycpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNldCBjb25maWd1cmF0aW9uIHRvIGRlZmF1bHRzXG4gICAqIFNFQ1VSSVRZIEZJWCAoUFIgIzg5NSk6IEFkZGVkIHByb3RvdHlwZSBwb2xsdXRpb24gcHJvdGVjdGlvblxuICAgKiBQcmV2aW91c2x5OiBEaXJlY3QgcHJvcGVydHkgYXNzaWdubWVudCBhbGxvd2VkIF9fcHJvdG9fXyBpbmplY3Rpb25cbiAgICogTm93OiBWYWxpZGF0ZXMga2V5cyBhZ2FpbnN0IGZvcmJpZGRlbiBwcm9wZXJ0aWVzIGJlZm9yZSBhc3NpZ25tZW50XG4gICAqL1xuICBwdWJsaWMgYXN5bmMgcmVzZXRDb25maWcoc2VjdGlvbj86IHN0cmluZyk6IFByb21pc2U8Q29uZmlnQWN0aW9uUmVzdWx0PiB7XG4gICAgY29uc3QgZGVmYXVsdHMgPSB0aGlzLmdldERlZmF1bHRDb25maWcoKTtcbiAgICBcbiAgICBpZiAoc2VjdGlvbikge1xuICAgICAgLy8gUmVzZXQgc3BlY2lmaWMgc2VjdGlvblxuICAgICAgaWYgKCF0aGlzLmNvbmZpZykge1xuICAgICAgICB0aGlzLmNvbmZpZyA9IGRlZmF1bHRzO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3Qgc2VjdGlvbktleXMgPSBzZWN0aW9uLnNwbGl0KCcuJyk7XG4gICAgICAgIFxuICAgICAgICAvLyBTRUNVUklUWTogVmFsaWRhdGUgYWxsIGtleXMgdG8gcHJldmVudCBwcm90b3R5cGUgcG9sbHV0aW9uXG4gICAgICAgIGNvbnN0IEZPUkJJRERFTl9LRVlTID0gWydfX3Byb3RvX18nLCAnY29uc3RydWN0b3InLCAncHJvdG90eXBlJ107XG4gICAgICAgIGZvciAoY29uc3Qga2V5IG9mIHNlY3Rpb25LZXlzKSB7XG4gICAgICAgICAgaWYgKEZPUkJJRERFTl9LRVlTLmluY2x1ZGVzKGtleSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgRm9yYmlkZGVuIHByb3BlcnR5IGluIHNlY3Rpb246ICR7a2V5fWApO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBcbiAgICAgICAgbGV0IGN1cnJlbnQ6IGFueSA9IHRoaXMuY29uZmlnO1xuICAgICAgICBsZXQgZGVmYXVsdFNlY3Rpb246IGFueSA9IGRlZmF1bHRzO1xuICAgICAgICBcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzZWN0aW9uS2V5cy5sZW5ndGggLSAxOyBpKyspIHtcbiAgICAgICAgICBjdXJyZW50ID0gY3VycmVudFtzZWN0aW9uS2V5c1tpXV07XG4gICAgICAgICAgZGVmYXVsdFNlY3Rpb24gPSBkZWZhdWx0U2VjdGlvbltzZWN0aW9uS2V5c1tpXV07XG4gICAgICAgIH1cbiAgICAgICAgXG4gICAgICAgIGNvbnN0IGxhc3RLZXkgPSBzZWN0aW9uS2V5c1tzZWN0aW9uS2V5cy5sZW5ndGggLSAxXTtcbiAgICAgICAgY3VycmVudFtsYXN0S2V5XSA9IGRlZmF1bHRTZWN0aW9uW2xhc3RLZXldO1xuICAgICAgfVxuICAgICAgXG4gICAgICBhd2FpdCB0aGlzLnNhdmVDb25maWcoKTtcbiAgICAgIFxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgc3VjY2VzczogdHJ1ZSxcbiAgICAgICAgbWVzc2FnZTogYFNlY3Rpb24gJyR7c2VjdGlvbn0nIHJlc2V0IHRvIGRlZmF1bHRzYFxuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gUmVzZXQgZW50aXJlIGNvbmZpZ1xuICAgICAgdGhpcy5jb25maWcgPSBkZWZhdWx0cztcbiAgICAgIGF3YWl0IHRoaXMuc2F2ZUNvbmZpZygpO1xuICAgICAgXG4gICAgICByZXR1cm4ge1xuICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICBtZXNzYWdlOiAnQ29uZmlndXJhdGlvbiByZXNldCB0byBkZWZhdWx0cydcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEV4cG9ydCBjb25maWd1cmF0aW9uIHRvIGZpbGVcbiAgICovXG4gIHB1YmxpYyBhc3luYyBleHBvcnRDb25maWcoZmlsZVBhdGg6IHN0cmluZyk6IFByb21pc2U8Q29uZmlnQWN0aW9uUmVzdWx0PiB7XG4gICAgaWYgKCF0aGlzLmNvbmZpZykge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICAgIG1lc3NhZ2U6ICdObyBjb25maWd1cmF0aW9uIHRvIGV4cG9ydCdcbiAgICAgIH07XG4gICAgfVxuICAgIFxuICAgIHRyeSB7XG4gICAgICBjb25zdCB5YW1sQ29udGVudCA9IHlhbWwuZHVtcCh0aGlzLmNvbmZpZywge1xuICAgICAgICBpbmRlbnQ6IDIsXG4gICAgICAgIGxpbmVXaWR0aDogMTIwLFxuICAgICAgICBub1JlZnM6IHRydWUsXG4gICAgICAgIHNvcnRLZXlzOiBmYWxzZVxuICAgICAgfSk7XG4gICAgICBcbiAgICAgIGF3YWl0IGZzLndyaXRlRmlsZShmaWxlUGF0aCwgeWFtbENvbnRlbnQsIHsgZW5jb2Rpbmc6ICd1dGYtOCcsIG1vZGU6IDBvNjAwIH0pO1xuICAgICAgXG4gICAgICByZXR1cm4ge1xuICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICBtZXNzYWdlOiBgQ29uZmlndXJhdGlvbiBleHBvcnRlZCB0byAke2ZpbGVQYXRofWBcbiAgICAgIH07XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICBtZXNzYWdlOiBgRmFpbGVkIHRvIGV4cG9ydCBjb25maWd1cmF0aW9uOiAke2Vycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKX1gXG4gICAgICB9O1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBJbXBvcnQgY29uZmlndXJhdGlvbiBmcm9tIGZpbGVcbiAgICovXG4gIHB1YmxpYyBhc3luYyBpbXBvcnRDb25maWcoZmlsZVBhdGg6IHN0cmluZyk6IFByb21pc2U8Q29uZmlnQWN0aW9uUmVzdWx0PiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGNvbnRlbnQgPSBhd2FpdCBmcy5yZWFkRmlsZShmaWxlUGF0aCwgJ3V0Zi04Jyk7XG4gICAgICBcbiAgICAgIC8vIFBhcnNlIGFuZCB2YWxpZGF0ZVxuICAgICAgY29uc3QgcGFyc2VkID0gU2VjdXJlWWFtbFBhcnNlci5wYXJzZShjb250ZW50LCB7XG4gICAgICAgIG1heFlhbWxTaXplOiA2NCAqIDEwMjQsXG4gICAgICAgIHZhbGlkYXRlQ29udGVudDogZmFsc2UsXG4gICAgICAgIHZhbGlkYXRlRmllbGRzOiBmYWxzZVxuICAgICAgfSk7XG4gICAgICBcbiAgICAgIGlmICghcGFyc2VkLmRhdGEgfHwgdHlwZW9mIHBhcnNlZC5kYXRhICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICAgIG1lc3NhZ2U6ICdJbnZhbGlkIGNvbmZpZ3VyYXRpb24gZm9ybWF0IGluIGltcG9ydCBmaWxlJ1xuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgXG4gICAgICAvLyBNZXJnZSB3aXRoIGRlZmF1bHRzXG4gICAgICB0aGlzLmNvbmZpZyA9IHRoaXMubWVyZ2VXaXRoRGVmYXVsdHMocGFyc2VkLmRhdGEgYXMgUGFydGlhbDxEb2xsaG91c2VDb25maWc+KTtcbiAgICAgIFxuICAgICAgLy8gU2F2ZSB0aGUgaW1wb3J0ZWQgY29uZmlnXG4gICAgICBhd2FpdCB0aGlzLnNhdmVDb25maWcoKTtcbiAgICAgIFxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgc3VjY2VzczogdHJ1ZSxcbiAgICAgICAgbWVzc2FnZTogYENvbmZpZ3VyYXRpb24gaW1wb3J0ZWQgZnJvbSAke2ZpbGVQYXRofWBcbiAgICAgIH07XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICBtZXNzYWdlOiBgRmFpbGVkIHRvIGltcG9ydCBjb25maWd1cmF0aW9uOiAke2Vycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKX1gXG4gICAgICB9O1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgZm9ybWF0dGVkIGNvbmZpZyBmb3IgZGlzcGxheVxuICAgKi9cbiAgcHVibGljIGdldEZvcm1hdHRlZENvbmZpZyhzZWN0aW9uPzogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBpZiAoIXRoaXMuY29uZmlnKSB7XG4gICAgICByZXR1cm4gJ0NvbmZpZ3VyYXRpb24gbm90IGluaXRpYWxpemVkJztcbiAgICB9XG4gICAgXG4gICAgbGV0IGNvbmZpZ1RvU2hvdzogYW55ID0gdGhpcy5jb25maWc7XG4gICAgXG4gICAgaWYgKHNlY3Rpb24pIHtcbiAgICAgIGNvbmZpZ1RvU2hvdyA9IHRoaXMuZ2V0U2V0dGluZyhzZWN0aW9uKTtcbiAgICAgIGlmICghY29uZmlnVG9TaG93KSB7XG4gICAgICAgIHJldHVybiBgU2VjdGlvbiAnJHtzZWN0aW9ufScgbm90IGZvdW5kYDtcbiAgICAgIH1cbiAgICB9XG4gICAgXG4gICAgLy8gUmVtb3ZlIHNlbnNpdGl2ZSBkYXRhIGZvciBkaXNwbGF5XG4gICAgY29uc3Qgc2FuaXRpemVkID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShjb25maWdUb1Nob3cpKTtcbiAgICBcbiAgICAvLyBEb24ndCBzaG93IHRva2VucyBpZiB0aGV5IGV4aXN0XG4gICAgaWYgKHNhbml0aXplZC5naXRodWI/LmF1dGg/LnRva2VuKSB7XG4gICAgICBzYW5pdGl6ZWQuZ2l0aHViLmF1dGgudG9rZW4gPSAnKioqUkVEQUNURUQqKionO1xuICAgIH1cbiAgICBcbiAgICByZXR1cm4geWFtbC5kdW1wKHNhbml0aXplZCwge1xuICAgICAgaW5kZW50OiAyLFxuICAgICAgbGluZVdpZHRoOiAxMjAsXG4gICAgICBub1JlZnM6IHRydWUsXG4gICAgICBzb3J0S2V5czogZmFsc2VcbiAgICB9KTtcbiAgfVxufSJdfQ==
|