velocious 1.0.552 → 1.0.555
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/README.md +2 -0
- package/build/background-jobs/status-reporter.js +15 -2
- package/build/background-jobs/worker.js +5 -1
- package/build/frontend-models/base.js +105 -47
- package/build/frontend-models/transport-deadline.js +66 -0
- package/build/src/background-jobs/status-reporter.d.ts +3 -1
- package/build/src/background-jobs/status-reporter.d.ts.map +1 -1
- package/build/src/background-jobs/status-reporter.js +16 -3
- package/build/src/background-jobs/worker.d.ts.map +1 -1
- package/build/src/background-jobs/worker.js +6 -2
- package/build/src/frontend-models/base.d.ts +10 -1
- package/build/src/frontend-models/base.d.ts.map +1 -1
- package/build/src/frontend-models/base.js +71 -26
- package/build/src/frontend-models/transport-deadline.d.ts +26 -0
- package/build/src/frontend-models/transport-deadline.d.ts.map +1 -0
- package/build/src/frontend-models/transport-deadline.js +61 -0
- package/build/src/testing/factory/association-declaration.d.ts +37 -0
- package/build/src/testing/factory/association-declaration.d.ts.map +1 -0
- package/build/src/testing/factory/association-declaration.js +41 -0
- package/build/src/testing/factory/declarations.d.ts +190 -0
- package/build/src/testing/factory/declarations.d.ts.map +1 -0
- package/build/src/testing/factory/declarations.js +98 -0
- package/build/src/testing/factory/definition-builder.d.ts +132 -0
- package/build/src/testing/factory/definition-builder.d.ts.map +1 -0
- package/build/src/testing/factory/definition-builder.js +417 -0
- package/build/src/testing/factory/errors.d.ts +62 -0
- package/build/src/testing/factory/errors.d.ts.map +1 -0
- package/build/src/testing/factory/errors.js +67 -0
- package/build/src/testing/factory/evaluation-context.d.ts +95 -0
- package/build/src/testing/factory/evaluation-context.d.ts.map +1 -0
- package/build/src/testing/factory/evaluation-context.js +175 -0
- package/build/src/testing/factory/events.d.ts +21 -0
- package/build/src/testing/factory/events.d.ts.map +1 -0
- package/build/src/testing/factory/events.js +26 -0
- package/build/src/testing/factory/factory-definition.d.ts +39 -0
- package/build/src/testing/factory/factory-definition.d.ts.map +1 -0
- package/build/src/testing/factory/factory-definition.js +35 -0
- package/build/src/testing/factory/factory-registry.d.ts +263 -0
- package/build/src/testing/factory/factory-registry.d.ts.map +1 -0
- package/build/src/testing/factory/factory-registry.js +438 -0
- package/build/src/testing/factory/factory-runner.d.ts +179 -0
- package/build/src/testing/factory/factory-runner.d.ts.map +1 -0
- package/build/src/testing/factory/factory-runner.js +266 -0
- package/build/src/testing/factory/index.d.ts +18 -0
- package/build/src/testing/factory/index.d.ts.map +1 -0
- package/build/src/testing/factory/index.js +21 -0
- package/build/src/testing/factory/linter.d.ts +55 -0
- package/build/src/testing/factory/linter.d.ts.map +1 -0
- package/build/src/testing/factory/linter.js +106 -0
- package/build/src/testing/factory/model-contract.d.ts +11 -0
- package/build/src/testing/factory/model-contract.d.ts.map +1 -0
- package/build/src/testing/factory/model-contract.js +26 -0
- package/build/src/testing/factory/node/load-definitions.d.ts +24 -0
- package/build/src/testing/factory/node/load-definitions.d.ts.map +1 -0
- package/build/src/testing/factory/node/load-definitions.js +87 -0
- package/build/src/testing/factory/sequence.d.ts +73 -0
- package/build/src/testing/factory/sequence.d.ts.map +1 -0
- package/build/src/testing/factory/sequence.js +78 -0
- package/build/src/testing/factory/strategies/attributes-for.d.ts +21 -0
- package/build/src/testing/factory/strategies/attributes-for.d.ts.map +1 -0
- package/build/src/testing/factory/strategies/attributes-for.js +22 -0
- package/build/src/testing/factory/strategies/base.d.ts +101 -0
- package/build/src/testing/factory/strategies/base.d.ts.map +1 -0
- package/build/src/testing/factory/strategies/base.js +191 -0
- package/build/src/testing/factory/strategies/build.d.ts +20 -0
- package/build/src/testing/factory/strategies/build.d.ts.map +1 -0
- package/build/src/testing/factory/strategies/build.js +34 -0
- package/build/src/testing/factory/strategies/create.d.ts +32 -0
- package/build/src/testing/factory/strategies/create.d.ts.map +1 -0
- package/build/src/testing/factory/strategies/create.js +57 -0
- package/build/src/testing/factory/trait-definition.d.ts +22 -0
- package/build/src/testing/factory/trait-definition.d.ts.map +1 -0
- package/build/src/testing/factory/trait-definition.js +22 -0
- package/build/testing/factory/association-declaration.js +50 -0
- package/build/testing/factory/declarations.js +110 -0
- package/build/testing/factory/definition-builder.js +476 -0
- package/build/testing/factory/errors.js +79 -0
- package/build/testing/factory/evaluation-context.js +199 -0
- package/build/testing/factory/events.js +30 -0
- package/build/testing/factory/factory-definition.js +41 -0
- package/build/testing/factory/factory-registry.js +501 -0
- package/build/testing/factory/factory-runner.js +296 -0
- package/build/testing/factory/index.js +24 -0
- package/build/testing/factory/linter.js +119 -0
- package/build/testing/factory/model-contract.js +31 -0
- package/build/testing/factory/node/load-definitions.js +103 -0
- package/build/testing/factory/sequence.js +91 -0
- package/build/testing/factory/strategies/attributes-for.js +24 -0
- package/build/testing/factory/strategies/base.js +209 -0
- package/build/testing/factory/strategies/build.js +42 -0
- package/build/testing/factory/strategies/create.js +68 -0
- package/build/testing/factory/trait-definition.js +24 -0
- package/build/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/background-jobs/status-reporter.js +15 -2
- package/src/background-jobs/worker.js +5 -1
- package/src/frontend-models/base.js +105 -47
- package/src/frontend-models/transport-deadline.js +66 -0
- package/src/testing/factory/association-declaration.js +50 -0
- package/src/testing/factory/declarations.js +110 -0
- package/src/testing/factory/definition-builder.js +476 -0
- package/src/testing/factory/errors.js +79 -0
- package/src/testing/factory/evaluation-context.js +199 -0
- package/src/testing/factory/events.js +30 -0
- package/src/testing/factory/factory-definition.js +41 -0
- package/src/testing/factory/factory-registry.js +501 -0
- package/src/testing/factory/factory-runner.js +296 -0
- package/src/testing/factory/index.js +24 -0
- package/src/testing/factory/linter.js +119 -0
- package/src/testing/factory/model-contract.js +31 -0
- package/src/testing/factory/node/load-definitions.js +103 -0
- package/src/testing/factory/sequence.js +91 -0
- package/src/testing/factory/strategies/attributes-for.js +24 -0
- package/src/testing/factory/strategies/base.js +209 -0
- package/src/testing/factory/strategies/build.js +42 -0
- package/src/testing/factory/strategies/create.js +68 -0
- package/src/testing/factory/trait-definition.js +24 -0
|
@@ -0,0 +1,438 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
import { DuplicateDefinitionError, RegistryBusyError, UndefinedSequenceError } from "./errors.js";
|
|
3
|
+
import AttributesForStrategy from "./strategies/attributes-for.js";
|
|
4
|
+
import BuildStrategy from "./strategies/build.js";
|
|
5
|
+
import CreateStrategy from "./strategies/create.js";
|
|
6
|
+
import DefinitionSession from "./definition-builder.js";
|
|
7
|
+
import FactoryEventEmitter from "./events.js";
|
|
8
|
+
import FactoryLinter from "./linter.js";
|
|
9
|
+
import FactoryRunner from "./factory-runner.js";
|
|
10
|
+
import { isPlainObject } from "is-plain-object";
|
|
11
|
+
/**
|
|
12
|
+
* Normalizes a strategy invocation's variadic tail into ordered trait names plus
|
|
13
|
+
* a single final overrides object (`strategy(name, ...traits, overrides?)`).
|
|
14
|
+
* @param {Array<?>} args - Arguments after the factory name (and count for lists).
|
|
15
|
+
* @returns {{traits: string[], overrides: Record<string, ?>}} - Normalized invocation.
|
|
16
|
+
*/
|
|
17
|
+
function normalizeInvocationArgs(args) {
|
|
18
|
+
/** @type {string[]} */
|
|
19
|
+
const traits = [];
|
|
20
|
+
/** @type {Record<string, ?>} */
|
|
21
|
+
let overrides = {};
|
|
22
|
+
let sawOverrides = false;
|
|
23
|
+
for (const arg of args) {
|
|
24
|
+
if (typeof arg === "string" && !sawOverrides) {
|
|
25
|
+
traits.push(arg);
|
|
26
|
+
}
|
|
27
|
+
else if (isPlainObject(arg) && !sawOverrides) {
|
|
28
|
+
overrides = arg;
|
|
29
|
+
sawOverrides = true;
|
|
30
|
+
}
|
|
31
|
+
else if (arg !== undefined) {
|
|
32
|
+
throw new TypeError(`Invalid factory invocation argument: ${String(arg)}. Expected trait names then a single final overrides object.`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return { traits, overrides };
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Owns all factories, traits, sequences, callbacks and construction defaults for
|
|
39
|
+
* one isolated scope, and exposes the strategy entry points. Registry mutation is
|
|
40
|
+
* setup-time only and is rejected while evaluations are active.
|
|
41
|
+
*/
|
|
42
|
+
export default class FactoryRegistry {
|
|
43
|
+
/** Builds an empty registry with the built-in strategies installed. */
|
|
44
|
+
constructor() {
|
|
45
|
+
/** @type {Map<string, import("./factory-definition.js").default>} - Factories and aliases. */
|
|
46
|
+
this._factories = new Map();
|
|
47
|
+
/** @type {Map<string, import("./trait-definition.js").default>} - Global traits. */
|
|
48
|
+
this._globalTraits = new Map();
|
|
49
|
+
/** @type {Map<string, import("./sequence.js").default>} - Global sequences and aliases. */
|
|
50
|
+
this._sequences = new Map();
|
|
51
|
+
/** @type {Map<string, Map<string, import("./sequence.js").default>>} - Factory-scoped sequences. */
|
|
52
|
+
this._factorySequences = new Map();
|
|
53
|
+
/** @type {import("./declarations.js").Declaration[]} - Registry-level default declarations. */
|
|
54
|
+
this._globalDeclarations = [];
|
|
55
|
+
/** @type {number} - In-flight evaluation count (mutation guard). */
|
|
56
|
+
this._activeEvaluations = 0;
|
|
57
|
+
/** @type {FactoryRunner} - Plan compiler. */
|
|
58
|
+
this._runner = new FactoryRunner(this);
|
|
59
|
+
/** @type {FactoryEventEmitter} - Debug/performance event emitter. */
|
|
60
|
+
this._events = new FactoryEventEmitter();
|
|
61
|
+
/** @type {{attributesFor: AttributesForStrategy, build: BuildStrategy, create: CreateStrategy}} - Installed strategies. */
|
|
62
|
+
this._strategies = {
|
|
63
|
+
attributesFor: new AttributesForStrategy(),
|
|
64
|
+
build: new BuildStrategy(),
|
|
65
|
+
create: new CreateStrategy()
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Registers factories/traits/sequences/callbacks via a builder callback.
|
|
70
|
+
* @param {(builder: object) => void} callback - The definition callback.
|
|
71
|
+
* @returns {this} - This registry (for chaining).
|
|
72
|
+
*/
|
|
73
|
+
define(callback) {
|
|
74
|
+
this._assertNotEvaluating("define");
|
|
75
|
+
new DefinitionSession(this).run(callback);
|
|
76
|
+
return this;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Reopens existing factories to append/override declarations, recompiling each
|
|
80
|
+
* into a fresh immutable definition. Rejected while evaluations are active.
|
|
81
|
+
* @param {(builder: object) => void} callback - The modify callback.
|
|
82
|
+
* @returns {this} - This registry (for chaining).
|
|
83
|
+
*/
|
|
84
|
+
modify(callback) {
|
|
85
|
+
this._assertNotEvaluating("modify");
|
|
86
|
+
new DefinitionSession(this).runModify(callback);
|
|
87
|
+
return this;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Lints factories/traits, aggregating every failure. Create-strategy cases roll
|
|
91
|
+
* back their database writes.
|
|
92
|
+
* @param {object} [options] - Lint options (factories, traits, strategy).
|
|
93
|
+
* @returns {Promise<void>} - Resolves when all cases pass; rejects with an aggregate otherwise.
|
|
94
|
+
*/
|
|
95
|
+
async lint(options) {
|
|
96
|
+
return await new FactoryLinter(this).lint(options);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Subscribes to factory debug events (`start`, `success`, `failure`).
|
|
100
|
+
* @param {string} event - Event name.
|
|
101
|
+
* @param {(payload: {invocationId: string, factory: string, strategy: string, traits: string[], durationMs?: number, error?: ?}) => void} handler - Event handler.
|
|
102
|
+
* @returns {this} - This registry (for chaining).
|
|
103
|
+
*/
|
|
104
|
+
on(event, handler) {
|
|
105
|
+
this._events.on(event, handler);
|
|
106
|
+
return this;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Unsubscribes a previously-registered event handler.
|
|
110
|
+
* @param {string} event - Event name.
|
|
111
|
+
* @param {(payload: ?) => void} handler - Event handler to remove.
|
|
112
|
+
* @returns {this} - This registry (for chaining).
|
|
113
|
+
*/
|
|
114
|
+
off(event, handler) {
|
|
115
|
+
this._events.off(event, handler);
|
|
116
|
+
return this;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Resolves attributes without constructing a model or building associations.
|
|
120
|
+
* @param {string} factoryName - Factory name.
|
|
121
|
+
* @param {Array<?>} args - Trait names then an optional overrides object.
|
|
122
|
+
* @returns {Promise<Record<string, ?>>} - The resolved attributes.
|
|
123
|
+
*/
|
|
124
|
+
async attributesFor(factoryName, ...args) {
|
|
125
|
+
const { traits, overrides } = normalizeInvocationArgs(args);
|
|
126
|
+
return await this._runFactory({ factoryName, traits, overrides, strategy: "attributesFor" });
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Builds an unsaved record graph.
|
|
130
|
+
* @param {string} factoryName - Factory name.
|
|
131
|
+
* @param {Array<?>} args - Trait names then an optional overrides object.
|
|
132
|
+
* @returns {Promise<?>} - The built record.
|
|
133
|
+
*/
|
|
134
|
+
async build(factoryName, ...args) {
|
|
135
|
+
const { traits, overrides } = normalizeInvocationArgs(args);
|
|
136
|
+
return await this._runFactory({ factoryName, traits, overrides, strategy: "build" });
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Builds and persists a record graph.
|
|
140
|
+
* @param {string} factoryName - Factory name.
|
|
141
|
+
* @param {Array<?>} args - Trait names then an optional overrides object.
|
|
142
|
+
* @returns {Promise<?>} - The persisted record.
|
|
143
|
+
*/
|
|
144
|
+
async create(factoryName, ...args) {
|
|
145
|
+
const { traits, overrides } = normalizeInvocationArgs(args);
|
|
146
|
+
return await this._runFactory({ factoryName, traits, overrides, strategy: "create" });
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Resolves attributes for a list of records sequentially.
|
|
150
|
+
* @param {string} factoryName - Factory name.
|
|
151
|
+
* @param {number} count - Number of entries.
|
|
152
|
+
* @param {Array<?>} args - Trait names then an optional overrides object.
|
|
153
|
+
* @returns {Promise<Array<Record<string, ?>>>} - The resolved attribute objects.
|
|
154
|
+
*/
|
|
155
|
+
async attributesForList(factoryName, count, ...args) {
|
|
156
|
+
return await this._runList("attributesFor", factoryName, count, args);
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Builds a list of unsaved records sequentially.
|
|
160
|
+
* @param {string} factoryName - Factory name.
|
|
161
|
+
* @param {number} count - Number of records.
|
|
162
|
+
* @param {Array<?>} args - Trait names then an optional overrides object.
|
|
163
|
+
* @returns {Promise<Array<?>>} - The built records.
|
|
164
|
+
*/
|
|
165
|
+
async buildList(factoryName, count, ...args) {
|
|
166
|
+
return await this._runList("build", factoryName, count, args);
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Creates a list of persisted records sequentially.
|
|
170
|
+
* @param {string} factoryName - Factory name.
|
|
171
|
+
* @param {number} count - Number of records.
|
|
172
|
+
* @param {Array<?>} args - Trait names then an optional overrides object.
|
|
173
|
+
* @returns {Promise<Array<?>>} - The persisted records.
|
|
174
|
+
*/
|
|
175
|
+
async createList(factoryName, count, ...args) {
|
|
176
|
+
return await this._runList("create", factoryName, count, args);
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Resolves attributes for exactly two records.
|
|
180
|
+
* @param {string} factoryName - Factory name.
|
|
181
|
+
* @param {Array<?>} args - Trait names then an optional overrides object.
|
|
182
|
+
* @returns {Promise<Array<Record<string, ?>>>} - The two resolved attribute objects.
|
|
183
|
+
*/
|
|
184
|
+
async attributesForPair(factoryName, ...args) {
|
|
185
|
+
return await this._runList("attributesFor", factoryName, 2, args);
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Builds exactly two unsaved records.
|
|
189
|
+
* @param {string} factoryName - Factory name.
|
|
190
|
+
* @param {Array<?>} args - Trait names then an optional overrides object.
|
|
191
|
+
* @returns {Promise<Array<?>>} - The two built records.
|
|
192
|
+
*/
|
|
193
|
+
async buildPair(factoryName, ...args) {
|
|
194
|
+
return await this._runList("build", factoryName, 2, args);
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Creates exactly two persisted records.
|
|
198
|
+
* @param {string} factoryName - Factory name.
|
|
199
|
+
* @param {Array<?>} args - Trait names then an optional overrides object.
|
|
200
|
+
* @returns {Promise<Array<?>>} - The two persisted records.
|
|
201
|
+
*/
|
|
202
|
+
async createPair(factoryName, ...args) {
|
|
203
|
+
return await this._runList("create", factoryName, 2, args);
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Advances a sequence and returns its formatted value.
|
|
207
|
+
* @param {string} sequenceName - Sequence name.
|
|
208
|
+
* @returns {Promise<?>} - The formatted value.
|
|
209
|
+
*/
|
|
210
|
+
async generate(sequenceName) {
|
|
211
|
+
return await this._generateScoped(sequenceName, []);
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Advances a sequence `count` times and returns the formatted values.
|
|
215
|
+
* @param {string} sequenceName - Sequence name.
|
|
216
|
+
* @param {number} count - Number of values.
|
|
217
|
+
* @returns {Promise<Array<?>>} - The formatted values.
|
|
218
|
+
*/
|
|
219
|
+
async generateList(sequenceName, count) {
|
|
220
|
+
/** @type {Array<?>} */
|
|
221
|
+
const values = [];
|
|
222
|
+
for (let index = 0; index < count; index++) {
|
|
223
|
+
values.push(await this._generateScoped(sequenceName, []));
|
|
224
|
+
}
|
|
225
|
+
return values;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Returns the next raw value a global sequence would allocate without consuming it.
|
|
229
|
+
* @param {string} sequenceName - Sequence name.
|
|
230
|
+
* @returns {number} - The upcoming raw value.
|
|
231
|
+
*/
|
|
232
|
+
peekSequence(sequenceName) {
|
|
233
|
+
return this._resolveGlobalSequence(sequenceName).peek();
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Sets the next value a global sequence will allocate.
|
|
237
|
+
* @param {string} sequenceName - Sequence name.
|
|
238
|
+
* @param {number} value - Next raw value.
|
|
239
|
+
* @returns {void}
|
|
240
|
+
*/
|
|
241
|
+
setSequence(sequenceName, value) {
|
|
242
|
+
this._assertNotEvaluating("setSequence");
|
|
243
|
+
this._resolveGlobalSequence(sequenceName).set(value);
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Rewinds a single global sequence to its initial value.
|
|
247
|
+
* @param {string} sequenceName - Sequence name.
|
|
248
|
+
* @returns {void}
|
|
249
|
+
*/
|
|
250
|
+
rewindSequence(sequenceName) {
|
|
251
|
+
this._assertNotEvaluating("rewindSequence");
|
|
252
|
+
this._resolveGlobalSequence(sequenceName).rewind();
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Rewinds every global and factory-scoped sequence to its initial value while
|
|
256
|
+
* leaving all definitions intact.
|
|
257
|
+
* @returns {void}
|
|
258
|
+
*/
|
|
259
|
+
rewindSequences() {
|
|
260
|
+
this._assertNotEvaluating("rewindSequences");
|
|
261
|
+
for (const sequence of new Set(this._sequences.values()))
|
|
262
|
+
sequence.rewind();
|
|
263
|
+
for (const scope of this._factorySequences.values()) {
|
|
264
|
+
for (const sequence of new Set(scope.values()))
|
|
265
|
+
sequence.rewind();
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Clears all definitions, traits, sequences and registry defaults, restoring an
|
|
270
|
+
* empty registry with the built-in strategies.
|
|
271
|
+
* @returns {void}
|
|
272
|
+
*/
|
|
273
|
+
reset() {
|
|
274
|
+
this._assertNotEvaluating("reset");
|
|
275
|
+
this._factories.clear();
|
|
276
|
+
this._globalTraits.clear();
|
|
277
|
+
this._sequences.clear();
|
|
278
|
+
this._factorySequences.clear();
|
|
279
|
+
this._globalDeclarations = [];
|
|
280
|
+
this._events = new FactoryEventEmitter();
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Runs `count` sequential strategy invocations.
|
|
284
|
+
* @param {"attributesFor" | "build" | "create"} strategy - Strategy name.
|
|
285
|
+
* @param {string} factoryName - Factory name.
|
|
286
|
+
* @param {number} count - Number of entries.
|
|
287
|
+
* @param {Array<?>} args - Trait names then an optional overrides object.
|
|
288
|
+
* @returns {Promise<Array<?>>} - The results.
|
|
289
|
+
*/
|
|
290
|
+
async _runList(strategy, factoryName, count, args) {
|
|
291
|
+
const { traits, overrides } = normalizeInvocationArgs(args);
|
|
292
|
+
/** @type {Array<?>} */
|
|
293
|
+
const results = [];
|
|
294
|
+
for (let index = 0; index < count; index++) {
|
|
295
|
+
results.push(await this._runFactory({ factoryName, traits, overrides, strategy }));
|
|
296
|
+
}
|
|
297
|
+
return results;
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Compiles and runs a factory invocation under a strategy, tracking active
|
|
301
|
+
* evaluations for the mutation guard.
|
|
302
|
+
* @param {object} args - Options.
|
|
303
|
+
* @param {string} args.factoryName - Factory name.
|
|
304
|
+
* @param {string[]} args.traits - Ordered traits.
|
|
305
|
+
* @param {Record<string, ?>} args.overrides - Overrides.
|
|
306
|
+
* @param {"attributesFor" | "build" | "create"} args.strategy - Strategy name.
|
|
307
|
+
* @returns {Promise<?>} - The strategy result.
|
|
308
|
+
*/
|
|
309
|
+
async _runFactory({ factoryName, traits, overrides, strategy }) {
|
|
310
|
+
this._activeEvaluations += 1;
|
|
311
|
+
const invocationId = this._events.nextInvocationId();
|
|
312
|
+
const startedAt = Date.now();
|
|
313
|
+
try {
|
|
314
|
+
this._events.emit("start", { invocationId, factory: factoryName, strategy, traits });
|
|
315
|
+
const plan = this._runner.compile(factoryName, traits, overrides);
|
|
316
|
+
const result = await this._strategies[strategy].run({ registry: this, plan });
|
|
317
|
+
this._events.emit("success", { invocationId, factory: factoryName, strategy, traits, durationMs: Date.now() - startedAt });
|
|
318
|
+
return result;
|
|
319
|
+
}
|
|
320
|
+
catch (error) {
|
|
321
|
+
this._events.emit("failure", { invocationId, factory: factoryName, strategy, traits, durationMs: Date.now() - startedAt, error });
|
|
322
|
+
throw error;
|
|
323
|
+
}
|
|
324
|
+
finally {
|
|
325
|
+
this._activeEvaluations -= 1;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* Registers an immutable factory definition and its aliases.
|
|
330
|
+
* @param {import("./factory-definition.js").default} definition - Compiled factory.
|
|
331
|
+
* @returns {void}
|
|
332
|
+
*/
|
|
333
|
+
_registerFactoryDefinition(definition) {
|
|
334
|
+
for (const name of [definition.name, ...definition.aliases]) {
|
|
335
|
+
if (this._factories.has(name)) {
|
|
336
|
+
throw new DuplicateDefinitionError(`Factory "${name}" is already registered`);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
for (const name of [definition.name, ...definition.aliases]) {
|
|
340
|
+
this._factories.set(name, definition);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* Replaces an existing factory definition (and its aliases) with a recompiled
|
|
345
|
+
* one. Used by `modify`; no duplicate check because it intentionally overwrites.
|
|
346
|
+
* @param {import("./factory-definition.js").default} definition - Recompiled factory.
|
|
347
|
+
* @returns {void}
|
|
348
|
+
*/
|
|
349
|
+
_replaceFactoryDefinition(definition) {
|
|
350
|
+
for (const name of [definition.name, ...definition.aliases]) {
|
|
351
|
+
this._factories.set(name, definition);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Registers a global trait.
|
|
356
|
+
* @param {import("./trait-definition.js").default} trait - Compiled trait.
|
|
357
|
+
* @returns {void}
|
|
358
|
+
*/
|
|
359
|
+
_registerGlobalTrait(trait) {
|
|
360
|
+
if (this._globalTraits.has(trait.name)) {
|
|
361
|
+
throw new DuplicateDefinitionError(`Trait "${trait.name}" is already registered`);
|
|
362
|
+
}
|
|
363
|
+
this._globalTraits.set(trait.name, trait);
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* Registers a sequence (and its aliases) either globally or under a factory scope.
|
|
367
|
+
* @param {import("./sequence.js").default} sequence - Sequence instance.
|
|
368
|
+
* @param {string | null} factoryScope - Factory name to scope under, or null for global.
|
|
369
|
+
* @returns {void}
|
|
370
|
+
*/
|
|
371
|
+
_registerSequence(sequence, factoryScope) {
|
|
372
|
+
/** @type {Map<string, import("./sequence.js").default>} */
|
|
373
|
+
let target;
|
|
374
|
+
if (factoryScope) {
|
|
375
|
+
if (!this._factorySequences.has(factoryScope))
|
|
376
|
+
this._factorySequences.set(factoryScope, new Map());
|
|
377
|
+
target = /** @type {Map<string, import("./sequence.js").default>} */ (this._factorySequences.get(factoryScope));
|
|
378
|
+
}
|
|
379
|
+
else {
|
|
380
|
+
target = this._sequences;
|
|
381
|
+
}
|
|
382
|
+
for (const name of [sequence.name, ...sequence.aliases]) {
|
|
383
|
+
if (target.has(name)) {
|
|
384
|
+
throw new DuplicateDefinitionError(`Sequence "${name}" is already registered${factoryScope ? ` for factory "${factoryScope}"` : ""}`);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
for (const name of [sequence.name, ...sequence.aliases]) {
|
|
388
|
+
target.set(name, sequence);
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Appends a registry-level default declaration (callbacks/construction defaults).
|
|
393
|
+
* @param {import("./declarations.js").Declaration} declaration - Declaration to add.
|
|
394
|
+
* @returns {void}
|
|
395
|
+
*/
|
|
396
|
+
_addGlobalDeclaration(declaration) {
|
|
397
|
+
this._globalDeclarations.push(declaration);
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* Resolves a sequence name against a factory scope chain (child first) then the
|
|
401
|
+
* global scope and advances it.
|
|
402
|
+
* @param {string} sequenceName - Sequence name.
|
|
403
|
+
* @param {string[]} chainNames - Inheritance chain names (child last).
|
|
404
|
+
* @returns {Promise<?>} - The formatted value.
|
|
405
|
+
*/
|
|
406
|
+
async _generateScoped(sequenceName, chainNames) {
|
|
407
|
+
for (let index = chainNames.length - 1; index >= 0; index--) {
|
|
408
|
+
const scope = this._factorySequences.get(chainNames[index]);
|
|
409
|
+
if (scope && scope.has(sequenceName)) {
|
|
410
|
+
return await /** @type {import("./sequence.js").default} */ (scope.get(sequenceName)).next();
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
return await this._resolveGlobalSequence(sequenceName).next();
|
|
414
|
+
}
|
|
415
|
+
/**
|
|
416
|
+
* Resolves a global sequence by name.
|
|
417
|
+
* @param {string} sequenceName - Sequence name.
|
|
418
|
+
* @returns {import("./sequence.js").default} - The sequence.
|
|
419
|
+
*/
|
|
420
|
+
_resolveGlobalSequence(sequenceName) {
|
|
421
|
+
const sequence = this._sequences.get(sequenceName);
|
|
422
|
+
if (!sequence) {
|
|
423
|
+
throw new UndefinedSequenceError(`No sequence registered called "${sequenceName}"`);
|
|
424
|
+
}
|
|
425
|
+
return sequence;
|
|
426
|
+
}
|
|
427
|
+
/**
|
|
428
|
+
* Rejects setup-time mutation while evaluations are active.
|
|
429
|
+
* @param {string} operation - Operation name, for the error message.
|
|
430
|
+
* @returns {void}
|
|
431
|
+
*/
|
|
432
|
+
_assertNotEvaluating(operation) {
|
|
433
|
+
if (this._activeEvaluations > 0) {
|
|
434
|
+
throw new RegistryBusyError(`Cannot ${operation} while factory evaluations are active. Registry mutation is setup-time only.`);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFjdG9yeS1yZWdpc3RyeS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy90ZXN0aW5nL2ZhY3RvcnkvZmFjdG9yeS1yZWdpc3RyeS5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxZQUFZO0FBRVosT0FBTyxFQUFDLHdCQUF3QixFQUFFLGlCQUFpQixFQUFFLHNCQUFzQixFQUFDLE1BQU0sYUFBYSxDQUFBO0FBQy9GLE9BQU8scUJBQXFCLE1BQU0sZ0NBQWdDLENBQUE7QUFDbEUsT0FBTyxhQUFhLE1BQU0sdUJBQXVCLENBQUE7QUFDakQsT0FBTyxjQUFjLE1BQU0sd0JBQXdCLENBQUE7QUFDbkQsT0FBTyxpQkFBaUIsTUFBTSx5QkFBeUIsQ0FBQTtBQUN2RCxPQUFPLG1CQUFtQixNQUFNLGFBQWEsQ0FBQTtBQUM3QyxPQUFPLGFBQWEsTUFBTSxhQUFhLENBQUE7QUFDdkMsT0FBTyxhQUFhLE1BQU0scUJBQXFCLENBQUE7QUFDL0MsT0FBTyxFQUFDLGFBQWEsRUFBQyxNQUFNLGlCQUFpQixDQUFBO0FBRTdDOzs7OztHQUtHO0FBQ0gsU0FBUyx1QkFBdUIsQ0FBQyxJQUFJO0lBQ25DLHVCQUF1QjtJQUN2QixNQUFNLE1BQU0sR0FBRyxFQUFFLENBQUE7SUFDakIsZ0NBQWdDO0lBQ2hDLElBQUksU0FBUyxHQUFHLEVBQUUsQ0FBQTtJQUNsQixJQUFJLFlBQVksR0FBRyxLQUFLLENBQUE7SUFFeEIsS0FBSyxNQUFNLEdBQUcsSUFBSSxJQUFJLEVBQUUsQ0FBQztRQUN2QixJQUFJLE9BQU8sR0FBRyxLQUFLLFFBQVEsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1lBQzdDLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUE7UUFDbEIsQ0FBQzthQUFNLElBQUksYUFBYSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7WUFDL0MsU0FBUyxHQUFHLEdBQUcsQ0FBQTtZQUNmLFlBQVks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aXRpb25FcnJvciwgUmVnaXN0cnlCdXN5RXJyb3IsIFVuZGVmaW5lZFNlcXVlbmNlRXJyb3J9IGZyb20gXCIuL2Vycm9ycy5qc1wiXG5pbXBvcnQgQXR0cmlidXRlc0ZvclN0cmF0ZWd5IGZyb20gXCIuL3N0cmF0ZWdpZXMvYXR0cmlidXRlcy1mb3IuanNcIlxuaW1wb3J0IEJ1aWxkU3RyYXRlZ3kgZnJvbSBcIi4vc3RyYXRlZ2llcy9idWlsZC5qc1wiXG5pbXBvcnQgQ3JlYXRlU3RyYXRlZ3kgZnJvbSBcIi4vc3RyYXRlZ2llcy9jcmVhdGUuanNcIlxuaW1wb3J0IERlZmluaXRpb25TZXNzaW9uIGZyb20gXCIuL2RlZmluaXRpb24tYnVpbGRlci5qc1wiXG5pbXBvcnQgRmFjdG9yeUV2ZW50RW1pdHRlciBmcm9tIFwiLi9ldmVudHMuanNcIlxuaW1wb3J0IEZhY3RvcnlMaW50ZXIgZnJvbSBcIi4vbGludGVyLmpzXCJcbmltcG9ydCBGYWN0b3J5UnVubmVyIGZyb20gXCIuL2ZhY3RvcnktcnVubmVyLmpzXCJcbmltcG9ydCB7aXNQbGFpbk9iamVjdH0gZnJvbSBcImlzLXBsYWluLW9iamVjdFwiXG5cbi8qKlxuICogTm9ybWFsaXplcyBhIHN0cmF0ZWd5IGludm9jYXRpb24ncyB2YXJpYWRpYyB0YWlsIGludG8gb3JkZXJlZCB0cmFpdCBuYW1lcyBwbHVzXG4gKiBhIHNpbmdsZSBmaW5hbCBvdmVycmlkZXMgb2JqZWN0IChgc3RyYXRlZ3kobmFtZSwgLi4udHJhaXRzLCBvdmVycmlkZXM/KWApLlxuICogQHBhcmFtIHtBcnJheTw/Pn0gYXJncyAtIEFyZ3VtZW50cyBhZnRlciB0aGUgZmFjdG9yeSBuYW1lIChhbmQgY291bnQgZm9yIGxpc3RzKS5cbiAqIEByZXR1cm5zIHt7dHJhaXRzOiBzdHJpbmdbXSwgb3ZlcnJpZGVzOiBSZWNvcmQ8c3RyaW5nLCA/Pn19IC0gTm9ybWFsaXplZCBpbnZvY2F0aW9uLlxuICovXG5mdW5jdGlvbiBub3JtYWxpemVJbnZvY2F0aW9uQXJncyhhcmdzKSB7XG4gIC8qKiBAdHlwZSB7c3RyaW5nW119ICovXG4gIGNvbnN0IHRyYWl0cyA9IFtdXG4gIC8qKiBAdHlwZSB7UmVjb3JkPHN0cmluZywgPz59ICovXG4gIGxldCBvdmVycmlkZXMgPSB7fVxuICBsZXQgc2F3T3ZlcnJpZGVzID0gZmFsc2VcblxuICBmb3IgKGNvbnN0IGFyZyBvZiBhcmdzKSB7XG4gICAgaWYgKHR5cGVvZiBhcmcgPT09IFwic3RyaW5nXCIgJiYgIXNhd092ZXJyaWRlcykge1xuICAgICAgdHJhaXRzLnB1c2goYXJnKVxuICAgIH0gZWxzZSBpZiAoaXNQbGFpbk9iamVjdChhcmcpICYmICFzYXdPdmVycmlkZXMpIHtcbiAgICAgIG92ZXJyaWRlcyA9IGFyZ1xuICAgICAgc2F3T3ZlcnJpZGVzID0gdHJ1ZVxuICAgIH0gZWxzZSBpZiAoYXJnICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYEludmFsaWQgZmFjdG9yeSBpbnZvY2F0aW9uIGFyZ3VtZW50OiAke1N0cmluZyhhcmcpfS4gRXhwZWN0ZWQgdHJhaXQgbmFtZXMgdGhlbiBhIHNpbmdsZSBmaW5hbCBvdmVycmlkZXMgb2JqZWN0LmApXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHt0cmFpdHMsIG92ZXJyaWRlc31cbn1cblxuLyoqXG4gKiBPd25zIGFsbCBmYWN0b3JpZXMsIHRyYWl0cywgc2VxdWVuY2VzLCBjYWxsYmFja3MgYW5kIGNvbnN0cnVjdGlvbiBkZWZhdWx0cyBmb3JcbiAqIG9uZSBpc29sYXRlZCBzY29wZSwgYW5kIGV4cG9zZXMgdGhlIHN0cmF0ZWd5IGVudHJ5IHBvaW50cy4gUmVnaXN0cnkgbXV0YXRpb24gaXNcbiAqIHNldHVwLXRpbWUgb25seSBhbmQgaXMgcmVqZWN0ZWQgd2hpbGUgZXZhbHVhdGlvbnMgYXJlIGFjdGl2ZS5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgRmFjdG9yeVJlZ2lzdHJ5IHtcbiAgLyoqIEJ1aWxkcyBhbiBlbXB0eSByZWdpc3RyeSB3aXRoIHRoZSBidWlsdC1pbiBzdHJhdGVnaWVzIGluc3RhbGxlZC4gKi9cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgLyoqIEB0eXBlIHtNYXA8c3RyaW5nLCBpbXBvcnQoXCIuL2ZhY3RvcnktZGVmaW5pdGlvbi5qc1wiKS5kZWZhdWx0Pn0gLSBGYWN0b3JpZXMgYW5kIGFsaWFzZXMuICovXG4gICAgdGhpcy5fZmFjdG9yaWVzID0gbmV3IE1hcCgpXG5cbiAgICAvKiogQHR5cGUge01hcDxzdHJpbmcsIGltcG9ydChcIi4vdHJhaXQtZGVmaW5pdGlvbi5qc1wiKS5kZWZhdWx0Pn0gLSBHbG9iYWwgdHJhaXRzLiAqL1xuICAgIHRoaXMuX2dsb2JhbFRyYWl0cyA9IG5ldyBNYXAoKVxuXG4gICAgLyoqIEB0eXBlIHtNYXA8c3RyaW5nLCBpbXBvcnQoXCIuL3NlcXVlbmNlLmpzXCIpLmRlZmF1bHQ+fSAtIEdsb2JhbCBzZXF1ZW5jZXMgYW5kIGFsaWFzZXMuICovXG4gICAgdGhpcy5fc2VxdWVuY2VzID0gbmV3IE1hcCgpXG5cbiAgICAvKiogQHR5cGUge01hcDxzdHJpbmcsIE1hcDxzdHJpbmcsIGltcG9ydChcIi4vc2VxdWVuY2UuanNcIikuZGVmYXVsdD4+fSAtIEZhY3Rvcnktc2NvcGVkIHNlcXVlbmNlcy4gKi9cbiAgICB0aGlzLl9mYWN0b3J5U2VxdWVuY2VzID0gbmV3IE1hcCgpXG5cbiAgICAvKiogQHR5cGUge2ltcG9ydChcIi4vZGVjbGFyYXRpb25zLmpzXCIpLkRlY2xhcmF0aW9uW119IC0gUmVnaXN0cnktbGV2ZWwgZGVmYXVsdCBkZWNsYXJhdGlvbnMuICovXG4gICAgdGhpcy5fZ2xvYmFsRGVjbGFyYXRpb25zID0gW11cblxuICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAtIEluLWZsaWdodCBldmFsdWF0aW9uIGNvdW50IChtdXRhdGlvbiBndWFyZCkuICovXG4gICAgdGhpcy5fYWN0aXZlRXZhbHVhdGlvbnMgPSAwXG5cbiAgICAvKiogQHR5cGUge0ZhY3RvcnlSdW5uZXJ9IC0gUGxhbiBjb21waWxlci4gKi9cbiAgICB0aGlzLl9ydW5uZXIgPSBuZXcgRmFjdG9yeVJ1bm5lcih0aGlzKVxuXG4gICAgLyoqIEB0eXBlIHtGYWN0b3J5RXZlbnRFbWl0dGVyfSAtIERlYnVnL3BlcmZvcm1hbmNlIGV2ZW50IGVtaXR0ZXIuICovXG4gICAgdGhpcy5fZXZlbnRzID0gbmV3IEZhY3RvcnlFdmVudEVtaXR0ZXIoKVxuXG4gICAgLyoqIEB0eXBlIHt7YXR0cmlidXRlc0ZvcjogQXR0cmlidXRlc0ZvclN0cmF0ZWd5LCBidWlsZDogQnVpbGRTdHJhdGVneSwgY3JlYXRlOiBDcmVhdGVTdHJhdGVneX19IC0gSW5zdGFsbGVkIHN0cmF0ZWdpZXMuICovXG4gICAgdGhpcy5fc3RyYXRlZ2llcyA9IHtcbiAgICAgIGF0dHJpYnV0ZXNGb3I6IG5ldyBBdHRyaWJ1dGVzRm9yU3RyYXRlZ3koKSxcbiAgICAgIGJ1aWxkOiBuZXcgQnVpbGRTdHJhdGVneSgpLFxuICAgICAgY3JlYXRlOiBuZXcgQ3JlYXRlU3RyYXRlZ3koKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZWdpc3RlcnMgZmFjdG9yaWVzL3RyYWl0cy9zZXF1ZW5jZXMvY2FsbGJhY2tzIHZpYSBhIGJ1aWxkZXIgY2FsbGJhY2suXG4gICAqIEBwYXJhbSB7KGJ1aWxkZXI6IG9iamVjdCkgPT4gdm9pZH0gY2FsbGJhY2sgLSBUaGUgZGVmaW5pdGlvbiBjYWxsYmFjay5cbiAgICogQHJldHVybnMge3RoaXN9IC0gVGhpcyByZWdpc3RyeSAoZm9yIGNoYWluaW5nKS5cbiAgICovXG4gIGRlZmluZShjYWxsYmFjaykge1xuICAgIHRoaXMuX2Fzc2VydE5vdEV2YWx1YXRpbmcoXCJkZWZpbmVcIilcbiAgICBuZXcgRGVmaW5pdGlvblNlc3Npb24odGhpcykucnVuKGNhbGxiYWNrKVxuXG4gICAgcmV0dXJuIHRoaXNcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW9wZW5zIGV4aXN0aW5nIGZhY3RvcmllcyB0byBhcHBlbmQvb3ZlcnJpZGUgZGVjbGFyYXRpb25zLCByZWNvbXBpbGluZyBlYWNoXG4gICAqIGludG8gYSBmcmVzaCBpbW11dGFibGUgZGVmaW5pdGlvbi4gUmVqZWN0ZWQgd2hpbGUgZXZhbHVhdGlvbnMgYXJlIGFjdGl2ZS5cbiAgICogQHBhcmFtIHsoYnVpbGRlcjogb2JqZWN0KSA9PiB2b2lkfSBjYWxsYmFjayAtIFRoZSBtb2RpZnkgY2FsbGJhY2suXG4gICAqIEByZXR1cm5zIHt0aGlzfSAtIFRoaXMgcmVnaXN0cnkgKGZvciBjaGFpbmluZykuXG4gICAqL1xuICBtb2RpZnkoY2FsbGJhY2spIHtcbiAgICB0aGlzLl9hc3NlcnROb3RFdmFsdWF0aW5nKFwibW9kaWZ5XCIpXG4gICAgbmV3IERlZmluaXRpb25TZXNzaW9uKHRoaXMpLnJ1bk1vZGlmeShjYWxsYmFjaylcblxuICAgIHJldHVybiB0aGlzXG4gIH1cblxuICAvKipcbiAgICogTGludHMgZmFjdG9yaWVzL3RyYWl0cywgYWdncmVnYXRpbmcgZXZlcnkgZmFpbHVyZS4gQ3JlYXRlLXN0cmF0ZWd5IGNhc2VzIHJvbGxcbiAgICogYmFjayB0aGVpciBkYXRhYmFzZSB3cml0ZXMuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBbb3B0aW9uc10gLSBMaW50IG9wdGlvbnMgKGZhY3RvcmllcywgdHJhaXRzLCBzdHJhdGVneSkuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gYWxsIGNhc2VzIHBhc3M7IHJlamVjdHMgd2l0aCBhbiBhZ2dyZWdhdGUgb3RoZXJ3aXNlLlxuICAgKi9cbiAgYXN5bmMgbGludChvcHRpb25zKSB7XG4gICAgcmV0dXJuIGF3YWl0IG5ldyBGYWN0b3J5TGludGVyKHRoaXMpLmxpbnQob3B0aW9ucylcbiAgfVxuXG4gIC8qKlxuICAgKiBTdWJzY3JpYmVzIHRvIGZhY3RvcnkgZGVidWcgZXZlbnRzIChgc3RhcnRgLCBgc3VjY2Vzc2AsIGBmYWlsdXJlYCkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBldmVudCAtIEV2ZW50IG5hbWUuXG4gICAqIEBwYXJhbSB7KHBheWxvYWQ6IHtpbnZvY2F0aW9uSWQ6IHN0cmluZywgZmFjdG9yeTogc3RyaW5nLCBzdHJhdGVneTogc3RyaW5nLCB0cmFpdHM6IHN0cmluZ1tdLCBkdXJhdGlvbk1zPzogbnVtYmVyLCBlcnJvcj86ID99KSA9PiB2b2lkfSBoYW5kbGVyIC0gRXZlbnQgaGFuZGxlci5cbiAgICogQHJldHVybnMge3RoaXN9IC0gVGhpcyByZWdpc3RyeSAoZm9yIGNoYWluaW5nKS5cbiAgICovXG4gIG9uKGV2ZW50LCBoYW5kbGVyKSB7XG4gICAgdGhpcy5fZXZlbnRzLm9uKGV2ZW50LCBoYW5kbGVyKVxuXG4gICAgcmV0dXJuIHRoaXNcbiAgfVxuXG4gIC8qKlxuICAgKiBVbnN1YnNjcmliZXMgYSBwcmV2aW91c2x5LXJlZ2lzdGVyZWQgZXZlbnQgaGFuZGxlci5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50IC0gRXZlbnQgbmFtZS5cbiAgICogQHBhcmFtIHsocGF5bG9hZDogPykgPT4gdm9pZH0gaGFuZGxlciAtIEV2ZW50IGhhbmRsZXIgdG8gcmVtb3ZlLlxuICAgKiBAcmV0dXJucyB7dGhpc30gLSBUaGlzIHJlZ2lzdHJ5IChmb3IgY2hhaW5pbmcpLlxuICAgKi9cbiAgb2ZmKGV2ZW50LCBoYW5kbGVyKSB7XG4gICAgdGhpcy5fZXZlbnRzLm9mZihldmVudCwgaGFuZGxlcilcblxuICAgIHJldHVybiB0aGlzXG4gIH1cblxuICAvKipcbiAgICogUmVzb2x2ZXMgYXR0cmlidXRlcyB3aXRob3V0IGNvbnN0cnVjdGluZyBhIG1vZGVsIG9yIGJ1aWxkaW5nIGFzc29jaWF0aW9ucy5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGZhY3RvcnlOYW1lIC0gRmFjdG9yeSBuYW1lLlxuICAgKiBAcGFyYW0ge0FycmF5PD8+fSBhcmdzIC0gVHJhaXQgbmFtZXMgdGhlbiBhbiBvcHRpb25hbCBvdmVycmlkZXMgb2JqZWN0LlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCA/Pj59IC0gVGhlIHJlc29sdmVkIGF0dHJpYnV0ZXMuXG4gICAqL1xuICBhc3luYyBhdHRyaWJ1dGVzRm9yKGZhY3RvcnlOYW1lLCAuLi5hcmdzKSB7XG4gICAgY29uc3Qge3RyYWl0cywgb3ZlcnJpZGVzfSA9IG5vcm1hbGl6ZUludm9jYXRpb25BcmdzKGFyZ3MpXG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5fcnVuRmFjdG9yeSh7ZmFjdG9yeU5hbWUsIHRyYWl0cywgb3ZlcnJpZGVzLCBzdHJhdGVneTogXCJhdHRyaWJ1dGVzRm9yXCJ9KVxuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkcyBhbiB1bnNhdmVkIHJlY29yZCBncmFwaC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGZhY3RvcnlOYW1lIC0gRmFjdG9yeSBuYW1lLlxuICAgKiBAcGFyYW0ge0FycmF5PD8+fSBhcmdzIC0gVHJhaXQgbmFtZXMgdGhlbiBhbiBvcHRpb25hbCBvdmVycmlkZXMgb2JqZWN0LlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTw/Pn0gLSBUaGUgYnVpbHQgcmVjb3JkLlxuICAgKi9cbiAgYXN5bmMgYnVpbGQoZmFjdG9yeU5hbWUsIC4uLmFyZ3MpIHtcbiAgICBjb25zdCB7dHJhaXRzLCBvdmVycmlkZXN9ID0gbm9ybWFsaXplSW52b2NhdGlvbkFyZ3MoYXJncylcblxuICAgIHJldHVybiBhd2FpdCB0aGlzLl9ydW5GYWN0b3J5KHtmYWN0b3J5TmFtZSwgdHJhaXRzLCBvdmVycmlkZXMsIHN0cmF0ZWd5OiBcImJ1aWxkXCJ9KVxuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkcyBhbmQgcGVyc2lzdHMgYSByZWNvcmQgZ3JhcGguXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBmYWN0b3J5TmFtZSAtIEZhY3RvcnkgbmFtZS5cbiAgICogQHBhcmFtIHtBcnJheTw/Pn0gYXJncyAtIFRyYWl0IG5hbWVzIHRoZW4gYW4gb3B0aW9uYWwgb3ZlcnJpZGVzIG9iamVjdC5cbiAgICogQHJldHVybnMge1Byb21pc2U8Pz59IC0gVGhlIHBlcnNpc3RlZCByZWNvcmQuXG4gICAqL1xuICBhc3luYyBjcmVhdGUoZmFjdG9yeU5hbWUsIC4uLmFyZ3MpIHtcbiAgICBjb25zdCB7dHJhaXRzLCBvdmVycmlkZXN9ID0gbm9ybWFsaXplSW52b2NhdGlvbkFyZ3MoYXJncylcblxuICAgIHJldHVybiBhd2FpdCB0aGlzLl9ydW5GYWN0b3J5KHtmYWN0b3J5TmFtZSwgdHJhaXRzLCBvdmVycmlkZXMsIHN0cmF0ZWd5OiBcImNyZWF0ZVwifSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNvbHZlcyBhdHRyaWJ1dGVzIGZvciBhIGxpc3Qgb2YgcmVjb3JkcyBzZXF1ZW50aWFsbHkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBmYWN0b3J5TmFtZSAtIEZhY3RvcnkgbmFtZS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGNvdW50IC0gTnVtYmVyIG9mIGVudHJpZXMuXG4gICAqIEBwYXJhbSB7QXJyYXk8Pz59IGFyZ3MgLSBUcmFpdCBuYW1lcyB0aGVuIGFuIG9wdGlvbmFsIG92ZXJyaWRlcyBvYmplY3QuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPEFycmF5PFJlY29yZDxzdHJpbmcsID8+Pj59IC0gVGhlIHJlc29sdmVkIGF0dHJpYnV0ZSBvYmplY3RzLlxuICAgKi9cbiAgYXN5bmMgYXR0cmlidXRlc0Zvckxpc3QoZmFjdG9yeU5hbWUsIGNvdW50LCAuLi5hcmdzKSB7XG4gICAgcmV0dXJuIGF3YWl0IHRoaXMuX3J1bkxpc3QoXCJhdHRyaWJ1dGVzRm9yXCIsIGZhY3RvcnlOYW1lLCBjb3VudCwgYXJncylcbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZHMgYSBsaXN0IG9mIHVuc2F2ZWQgcmVjb3JkcyBzZXF1ZW50aWFsbHkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBmYWN0b3J5TmFtZSAtIEZhY3RvcnkgbmFtZS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGNvdW50IC0gTnVtYmVyIG9mIHJlY29yZHMuXG4gICAqIEBwYXJhbSB7QXJyYXk8Pz59IGFyZ3MgLSBUcmFpdCBuYW1lcyB0aGVuIGFuIG9wdGlvbmFsIG92ZXJyaWRlcyBvYmplY3QuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPEFycmF5PD8+Pn0gLSBUaGUgYnVpbHQgcmVjb3Jkcy5cbiAgICovXG4gIGFzeW5jIGJ1aWxkTGlzdChmYWN0b3J5TmFtZSwgY291bnQsIC4uLmFyZ3MpIHtcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5fcnVuTGlzdChcImJ1aWxkXCIsIGZhY3RvcnlOYW1lLCBjb3VudCwgYXJncylcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgbGlzdCBvZiBwZXJzaXN0ZWQgcmVjb3JkcyBzZXF1ZW50aWFsbHkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBmYWN0b3J5TmFtZSAtIEZhY3RvcnkgbmFtZS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGNvdW50IC0gTnVtYmVyIG9mIHJlY29yZHMuXG4gICAqIEBwYXJhbSB7QXJyYXk8Pz59IGFyZ3MgLSBUcmFpdCBuYW1lcyB0aGVuIGFuIG9wdGlvbmFsIG92ZXJyaWRlcyBvYmplY3QuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPEFycmF5PD8+Pn0gLSBUaGUgcGVyc2lzdGVkIHJlY29yZHMuXG4gICAqL1xuICBhc3luYyBjcmVhdGVMaXN0KGZhY3RvcnlOYW1lLCBjb3VudCwgLi4uYXJncykge1xuICAgIHJldHVybiBhd2FpdCB0aGlzLl9ydW5MaXN0KFwiY3JlYXRlXCIsIGZhY3RvcnlOYW1lLCBjb3VudCwgYXJncylcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNvbHZlcyBhdHRyaWJ1dGVzIGZvciBleGFjdGx5IHR3byByZWNvcmRzLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZmFjdG9yeU5hbWUgLSBGYWN0b3J5IG5hbWUuXG4gICAqIEBwYXJhbSB7QXJyYXk8Pz59IGFyZ3MgLSBUcmFpdCBuYW1lcyB0aGVuIGFuIG9wdGlvbmFsIG92ZXJyaWRlcyBvYmplY3QuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPEFycmF5PFJlY29yZDxzdHJpbmcsID8+Pj59IC0gVGhlIHR3byByZXNvbHZlZCBhdHRyaWJ1dGUgb2JqZWN0cy5cbiAgICovXG4gIGFzeW5jIGF0dHJpYnV0ZXNGb3JQYWlyKGZhY3RvcnlOYW1lLCAuLi5hcmdzKSB7XG4gICAgcmV0dXJuIGF3YWl0IHRoaXMuX3J1bkxpc3QoXCJhdHRyaWJ1dGVzRm9yXCIsIGZhY3RvcnlOYW1lLCAyLCBhcmdzKVxuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkcyBleGFjdGx5IHR3byB1bnNhdmVkIHJlY29yZHMuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBmYWN0b3J5TmFtZSAtIEZhY3RvcnkgbmFtZS5cbiAgICogQHBhcmFtIHtBcnJheTw/Pn0gYXJncyAtIFRyYWl0IG5hbWVzIHRoZW4gYW4gb3B0aW9uYWwgb3ZlcnJpZGVzIG9iamVjdC5cbiAgICogQHJldHVybnMge1Byb21pc2U8QXJyYXk8Pz4+fSAtIFRoZSB0d28gYnVpbHQgcmVjb3Jkcy5cbiAgICovXG4gIGFzeW5jIGJ1aWxkUGFpcihmYWN0b3J5TmFtZSwgLi4uYXJncykge1xuICAgIHJldHVybiBhd2FpdCB0aGlzLl9ydW5MaXN0KFwiYnVpbGRcIiwgZmFjdG9yeU5hbWUsIDIsIGFyZ3MpXG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyBleGFjdGx5IHR3byBwZXJzaXN0ZWQgcmVjb3Jkcy5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGZhY3RvcnlOYW1lIC0gRmFjdG9yeSBuYW1lLlxuICAgKiBAcGFyYW0ge0FycmF5PD8+fSBhcmdzIC0gVHJhaXQgbmFtZXMgdGhlbiBhbiBvcHRpb25hbCBvdmVycmlkZXMgb2JqZWN0LlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxBcnJheTw/Pj59IC0gVGhlIHR3byBwZXJzaXN0ZWQgcmVjb3Jkcy5cbiAgICovXG4gIGFzeW5jIGNyZWF0ZVBhaXIoZmFjdG9yeU5hbWUsIC4uLmFyZ3MpIHtcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5fcnVuTGlzdChcImNyZWF0ZVwiLCBmYWN0b3J5TmFtZSwgMiwgYXJncylcbiAgfVxuXG4gIC8qKlxuICAgKiBBZHZhbmNlcyBhIHNlcXVlbmNlIGFuZCByZXR1cm5zIGl0cyBmb3JtYXR0ZWQgdmFsdWUuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBzZXF1ZW5jZU5hbWUgLSBTZXF1ZW5jZSBuYW1lLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTw/Pn0gLSBUaGUgZm9ybWF0dGVkIHZhbHVlLlxuICAgKi9cbiAgYXN5bmMgZ2VuZXJhdGUoc2VxdWVuY2VOYW1lKSB7XG4gICAgcmV0dXJuIGF3YWl0IHRoaXMuX2dlbmVyYXRlU2NvcGVkKHNlcXVlbmNlTmFtZSwgW10pXG4gIH1cblxuICAvKipcbiAgICogQWR2YW5jZXMgYSBzZXF1ZW5jZSBgY291bnRgIHRpbWVzIGFuZCByZXR1cm5zIHRoZSBmb3JtYXR0ZWQgdmFsdWVzLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gc2VxdWVuY2VOYW1lIC0gU2VxdWVuY2UgbmFtZS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGNvdW50IC0gTnVtYmVyIG9mIHZhbHVlcy5cbiAgICogQHJldHVybnMge1Byb21pc2U8QXJyYXk8Pz4+fSAtIFRoZSBmb3JtYXR0ZWQgdmFsdWVzLlxuICAgKi9cbiAgYXN5bmMgZ2VuZXJhdGVMaXN0KHNlcXVlbmNlTmFtZSwgY291bnQpIHtcbiAgICAvKiogQHR5cGUge0FycmF5PD8+fSAqL1xuICAgIGNvbnN0IHZhbHVlcyA9IFtdXG5cbiAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgY291bnQ7IGluZGV4KyspIHtcbiAgICAgIHZhbHVlcy5wdXNoKGF3YWl0IHRoaXMuX2dlbmVyYXRlU2NvcGVkKHNlcXVlbmNlTmFtZSwgW10pKVxuICAgIH1cblxuICAgIHJldHVybiB2YWx1ZXNcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBuZXh0IHJhdyB2YWx1ZSBhIGdsb2JhbCBzZXF1ZW5jZSB3b3VsZCBhbGxvY2F0ZSB3aXRob3V0IGNvbnN1bWluZyBpdC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHNlcXVlbmNlTmFtZSAtIFNlcXVlbmNlIG5hbWUuXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IC0gVGhlIHVwY29taW5nIHJhdyB2YWx1ZS5cbiAgICovXG4gIHBlZWtTZXF1ZW5jZShzZXF1ZW5jZU5hbWUpIHtcbiAgICByZXR1cm4gdGhpcy5fcmVzb2x2ZUdsb2JhbFNlcXVlbmNlKHNlcXVlbmNlTmFtZSkucGVlaygpXG4gIH1cblxuICAvKipcbiAgICogU2V0cyB0aGUgbmV4dCB2YWx1ZSBhIGdsb2JhbCBzZXF1ZW5jZSB3aWxsIGFsbG9jYXRlLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gc2VxdWVuY2VOYW1lIC0gU2VxdWVuY2UgbmFtZS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIC0gTmV4dCByYXcgdmFsdWUuXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgc2V0U2VxdWVuY2Uoc2VxdWVuY2VOYW1lLCB2YWx1ZSkge1xuICAgIHRoaXMuX2Fzc2VydE5vdEV2YWx1YXRpbmcoXCJzZXRTZXF1ZW5jZVwiKVxuICAgIHRoaXMuX3Jlc29sdmVHbG9iYWxTZXF1ZW5jZShzZXF1ZW5jZU5hbWUpLnNldCh2YWx1ZSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXdpbmRzIGEgc2luZ2xlIGdsb2JhbCBzZXF1ZW5jZSB0byBpdHMgaW5pdGlhbCB2YWx1ZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHNlcXVlbmNlTmFtZSAtIFNlcXVlbmNlIG5hbWUuXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgcmV3aW5kU2VxdWVuY2Uoc2VxdWVuY2VOYW1lKSB7XG4gICAgdGhpcy5fYXNzZXJ0Tm90RXZhbHVhdGluZyhcInJld2luZFNlcXVlbmNlXCIpXG4gICAgdGhpcy5fcmVzb2x2ZUdsb2JhbFNlcXVlbmNlKHNlcXVlbmNlTmFtZSkucmV3aW5kKClcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXdpbmRzIGV2ZXJ5IGdsb2JhbCBhbmQgZmFjdG9yeS1zY29wZWQgc2VxdWVuY2UgdG8gaXRzIGluaXRpYWwgdmFsdWUgd2hpbGVcbiAgICogbGVhdmluZyBhbGwgZGVmaW5pdGlvbnMgaW50YWN0LlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIHJld2luZFNlcXVlbmNlcygpIHtcbiAgICB0aGlzLl9hc3NlcnROb3RFdmFsdWF0aW5nKFwicmV3aW5kU2VxdWVuY2VzXCIpXG5cbiAgICBmb3IgKGNvbnN0IHNlcXVlbmNlIG9mIG5ldyBTZXQodGhpcy5fc2VxdWVuY2VzLnZhbHVlcygpKSkgc2VxdWVuY2UucmV3aW5kKClcblxuICAgIGZvciAoY29uc3Qgc2NvcGUgb2YgdGhpcy5fZmFjdG9yeVNlcXVlbmNlcy52YWx1ZXMoKSkge1xuICAgICAgZm9yIChjb25zdCBzZXF1ZW5jZSBvZiBuZXcgU2V0KHNjb3BlLnZhbHVlcygpKSkgc2VxdWVuY2UucmV3aW5kKClcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ2xlYXJzIGFsbCBkZWZpbml0aW9ucywgdHJhaXRzLCBzZXF1ZW5jZXMgYW5kIHJlZ2lzdHJ5IGRlZmF1bHRzLCByZXN0b3JpbmcgYW5cbiAgICogZW1wdHkgcmVnaXN0cnkgd2l0aCB0aGUgYnVpbHQtaW4gc3RyYXRlZ2llcy5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICByZXNldCgpIHtcbiAgICB0aGlzLl9hc3NlcnROb3RFdmFsdWF0aW5nKFwicmVzZXRcIilcbiAgICB0aGlzLl9mYWN0b3JpZXMuY2xlYXIoKVxuICAgIHRoaXMuX2dsb2JhbFRyYWl0cy5jbGVhcigpXG4gICAgdGhpcy5fc2VxdWVuY2VzLmNsZWFyKClcbiAgICB0aGlzLl9mYWN0b3J5U2VxdWVuY2VzLmNsZWFyKClcbiAgICB0aGlzLl9nbG9iYWxEZWNsYXJhdGlvbnMgPSBbXVxuICAgIHRoaXMuX2V2ZW50cyA9IG5ldyBGYWN0b3J5RXZlbnRFbWl0dGVyKClcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGBjb3VudGAgc2VxdWVudGlhbCBzdHJhdGVneSBpbnZvY2F0aW9ucy5cbiAgICogQHBhcmFtIHtcImF0dHJpYnV0ZXNGb3JcIiB8IFwiYnVpbGRcIiB8IFwiY3JlYXRlXCJ9IHN0cmF0ZWd5IC0gU3RyYXRlZ3kgbmFtZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGZhY3RvcnlOYW1lIC0gRmFjdG9yeSBuYW1lLlxuICAgKiBAcGFyYW0ge251bWJlcn0gY291bnQgLSBOdW1iZXIgb2YgZW50cmllcy5cbiAgICogQHBhcmFtIHtBcnJheTw/Pn0gYXJncyAtIFRyYWl0IG5hbWVzIHRoZW4gYW4gb3B0aW9uYWwgb3ZlcnJpZGVzIG9iamVjdC5cbiAgICogQHJldHVybnMge1Byb21pc2U8QXJyYXk8Pz4+fSAtIFRoZSByZXN1bHRzLlxuICAgKi9cbiAgYXN5bmMgX3J1bkxpc3Qoc3RyYXRlZ3ksIGZhY3RvcnlOYW1lLCBjb3VudCwgYXJncykge1xuICAgIGNvbnN0IHt0cmFpdHMsIG92ZXJyaWRlc30gPSBub3JtYWxpemVJbnZvY2F0aW9uQXJncyhhcmdzKVxuICAgIC8qKiBAdHlwZSB7QXJyYXk8Pz59ICovXG4gICAgY29uc3QgcmVzdWx0cyA9IFtdXG5cbiAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgY291bnQ7IGluZGV4KyspIHtcbiAgICAgIHJlc3VsdHMucHVzaChhd2FpdCB0aGlzLl9ydW5GYWN0b3J5KHtmYWN0b3J5TmFtZSwgdHJhaXRzLCBvdmVycmlkZXMsIHN0cmF0ZWd5fSkpXG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdHNcbiAgfVxuXG4gIC8qKlxuICAgKiBDb21waWxlcyBhbmQgcnVucyBhIGZhY3RvcnkgaW52b2NhdGlvbiB1bmRlciBhIHN0cmF0ZWd5LCB0cmFja2luZyBhY3RpdmVcbiAgICogZXZhbHVhdGlvbnMgZm9yIHRoZSBtdXRhdGlvbiBndWFyZC5cbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBPcHRpb25zLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYXJncy5mYWN0b3J5TmFtZSAtIEZhY3RvcnkgbmFtZS5cbiAgICogQHBhcmFtIHtzdHJpbmdbXX0gYXJncy50cmFpdHMgLSBPcmRlcmVkIHRyYWl0cy5cbiAgICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gYXJncy5vdmVycmlkZXMgLSBPdmVycmlkZXMuXG4gICAqIEBwYXJhbSB7XCJhdHRyaWJ1dGVzRm9yXCIgfCBcImJ1aWxkXCIgfCBcImNyZWF0ZVwifSBhcmdzLnN0cmF0ZWd5IC0gU3RyYXRlZ3kgbmFtZS5cbiAgICogQHJldHVybnMge1Byb21pc2U8Pz59IC0gVGhlIHN0cmF0ZWd5IHJlc3VsdC5cbiAgICovXG4gIGFzeW5jIF9ydW5GYWN0b3J5KHtmYWN0b3J5TmFtZSwgdHJhaXRzLCBvdmVycmlkZXMsIHN0cmF0ZWd5fSkge1xuICAgIHRoaXMuX2FjdGl2ZUV2YWx1YXRpb25zICs9IDFcblxuICAgIGNvbnN0IGludm9jYXRpb25JZCA9IHRoaXMuX2V2ZW50cy5uZXh0SW52b2NhdGlvbklkKClcbiAgICBjb25zdCBzdGFydGVkQXQgPSBEYXRlLm5vdygpXG5cbiAgICB0cnkge1xuICAgICAgdGhpcy5fZXZlbnRzLmVtaXQoXCJzdGFydFwiLCB7aW52b2NhdGlvbklkLCBmYWN0b3J5OiBmYWN0b3J5TmFtZSwgc3RyYXRlZ3ksIHRyYWl0c30pXG5cbiAgICAgIGNvbnN0IHBsYW4gPSB0aGlzLl9ydW5uZXIuY29tcGlsZShmYWN0b3J5TmFtZSwgdHJhaXRzLCBvdmVycmlkZXMpXG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLl9zdHJhdGVnaWVzW3N0cmF0ZWd5XS5ydW4oe3JlZ2lzdHJ5OiB0aGlzLCBwbGFufSlcblxuICAgICAgdGhpcy5fZXZlbnRzLmVtaXQoXCJzdWNjZXNzXCIsIHtpbnZvY2F0aW9uSWQsIGZhY3Rvcnk6IGZhY3RvcnlOYW1lLCBzdHJhdGVneSwgdHJhaXRzLCBkdXJhdGlvbk1zOiBEYXRlLm5vdygpIC0gc3RhcnRlZEF0fSlcblxuICAgICAgcmV0dXJuIHJlc3VsdFxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aGlzLl9ldmVudHMuZW1pdChcImZhaWx1cmVcIiwge2ludm9jYXRpb25JZCwgZmFjdG9yeTogZmFjdG9yeU5hbWUsIHN0cmF0ZWd5LCB0cmFpdHMsIGR1cmF0aW9uTXM6IERhdGUubm93KCkgLSBzdGFydGVkQXQsIGVycm9yfSlcblxuICAgICAgdGhyb3cgZXJyb3JcbiAgICB9IGZpbmFsbHkge1xuICAgICAgdGhpcy5fYWN0aXZlRXZhbHVhdGlvbnMgLT0gMVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZWdpc3RlcnMgYW4gaW1tdXRhYmxlIGZhY3RvcnkgZGVmaW5pdGlvbiBhbmQgaXRzIGFsaWFzZXMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9mYWN0b3J5LWRlZmluaXRpb24uanNcIikuZGVmYXVsdH0gZGVmaW5pdGlvbiAtIENvbXBpbGVkIGZhY3RvcnkuXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgX3JlZ2lzdGVyRmFjdG9yeURlZmluaXRpb24oZGVmaW5pdGlvbikge1xuICAgIGZvciAoY29uc3QgbmFtZSBvZiBbZGVmaW5pdGlvbi5uYW1lLCAuLi5kZWZpbml0aW9uLmFsaWFzZXNdKSB7XG4gICAgICBpZiAodGhpcy5fZmFjdG9yaWVzLmhhcyhuYW1lKSkge1xuICAgICAgICB0aHJvdyBuZXcgRHVwbGljYXRlRGVmaW5pdGlvbkVycm9yKGBGYWN0b3J5IFwiJHtuYW1lfVwiIGlzIGFscmVhZHkgcmVnaXN0ZXJlZGApXG4gICAgICB9XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBuYW1lIG9mIFtkZWZpbml0aW9uLm5hbWUsIC4uLmRlZmluaXRpb24uYWxpYXNlc10pIHtcbiAgICAgIHRoaXMuX2ZhY3Rvcmllcy5zZXQobmFtZSwgZGVmaW5pdGlvbilcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmVwbGFjZXMgYW4gZXhpc3RpbmcgZmFjdG9yeSBkZWZpbml0aW9uIChhbmQgaXRzIGFsaWFzZXMpIHdpdGggYSByZWNvbXBpbGVkXG4gICAqIG9uZS4gVXNlZCBieSBgbW9kaWZ5YDsgbm8gZHVwbGljYXRlIGNoZWNrIGJlY2F1c2UgaXQgaW50ZW50aW9uYWxseSBvdmVyd3JpdGVzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vZmFjdG9yeS1kZWZpbml0aW9uLmpzXCIpLmRlZmF1bHR9IGRlZmluaXRpb24gLSBSZWNvbXBpbGVkIGZhY3RvcnkuXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgX3JlcGxhY2VGYWN0b3J5RGVmaW5pdGlvbihkZWZpbml0aW9uKSB7XG4gICAgZm9yIChjb25zdCBuYW1lIG9mIFtkZWZpbml0aW9uLm5hbWUsIC4uLmRlZmluaXRpb24uYWxpYXNlc10pIHtcbiAgICAgIHRoaXMuX2ZhY3Rvcmllcy5zZXQobmFtZSwgZGVmaW5pdGlvbilcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmVnaXN0ZXJzIGEgZ2xvYmFsIHRyYWl0LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vdHJhaXQtZGVmaW5pdGlvbi5qc1wiKS5kZWZhdWx0fSB0cmFpdCAtIENvbXBpbGVkIHRyYWl0LlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIF9yZWdpc3Rlckdsb2JhbFRyYWl0KHRyYWl0KSB7XG4gICAgaWYgKHRoaXMuX2dsb2JhbFRyYWl0cy5oYXModHJhaXQubmFtZSkpIHtcbiAgICAgIHRocm93IG5ldyBEdXBsaWNhdGVEZWZpbml0aW9uRXJyb3IoYFRyYWl0IFwiJHt0cmFpdC5uYW1lfVwiIGlzIGFscmVhZHkgcmVnaXN0ZXJlZGApXG4gICAgfVxuXG4gICAgdGhpcy5fZ2xvYmFsVHJhaXRzLnNldCh0cmFpdC5uYW1lLCB0cmFpdClcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWdpc3RlcnMgYSBzZXF1ZW5jZSAoYW5kIGl0cyBhbGlhc2VzKSBlaXRoZXIgZ2xvYmFsbHkgb3IgdW5kZXIgYSBmYWN0b3J5IHNjb3BlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vc2VxdWVuY2UuanNcIikuZGVmYXVsdH0gc2VxdWVuY2UgLSBTZXF1ZW5jZSBpbnN0YW5jZS5cbiAgICogQHBhcmFtIHtzdHJpbmcgfCBudWxsfSBmYWN0b3J5U2NvcGUgLSBGYWN0b3J5IG5hbWUgdG8gc2NvcGUgdW5kZXIsIG9yIG51bGwgZm9yIGdsb2JhbC5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICBfcmVnaXN0ZXJTZXF1ZW5jZShzZXF1ZW5jZSwgZmFjdG9yeVNjb3BlKSB7XG4gICAgLyoqIEB0eXBlIHtNYXA8c3RyaW5nLCBpbXBvcnQoXCIuL3NlcXVlbmNlLmpzXCIpLmRlZmF1bHQ+fSAqL1xuICAgIGxldCB0YXJnZXRcblxuICAgIGlmIChmYWN0b3J5U2NvcGUpIHtcbiAgICAgIGlmICghdGhpcy5fZmFjdG9yeVNlcXVlbmNlcy5oYXMoZmFjdG9yeVNjb3BlKSkgdGhpcy5fZmFjdG9yeVNlcXVlbmNlcy5zZXQoZmFjdG9yeVNjb3BlLCBuZXcgTWFwKCkpXG4gICAgICB0YXJnZXQgPSAvKiogQHR5cGUge01hcDxzdHJpbmcsIGltcG9ydChcIi4vc2VxdWVuY2UuanNcIikuZGVmYXVsdD59ICovICh0aGlzLl9mYWN0b3J5U2VxdWVuY2VzLmdldChmYWN0b3J5U2NvcGUpKVxuICAgIH0gZWxzZSB7XG4gICAgICB0YXJnZXQgPSB0aGlzLl9zZXF1ZW5jZXNcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IG5hbWUgb2YgW3NlcXVlbmNlLm5hbWUsIC4uLnNlcXVlbmNlLmFsaWFzZXNdKSB7XG4gICAgICBpZiAodGFyZ2V0LmhhcyhuYW1lKSkge1xuICAgICAgICB0aHJvdyBuZXcgRHVwbGljYXRlRGVmaW5pdGlvbkVycm9yKGBTZXF1ZW5jZSBcIiR7bmFtZX1cIiBpcyBhbHJlYWR5IHJlZ2lzdGVyZWQke2ZhY3RvcnlTY29wZSA/IGAgZm9yIGZhY3RvcnkgXCIke2ZhY3RvcnlTY29wZX1cImAgOiBcIlwifWApXG4gICAgICB9XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBuYW1lIG9mIFtzZXF1ZW5jZS5uYW1lLCAuLi5zZXF1ZW5jZS5hbGlhc2VzXSkge1xuICAgICAgdGFyZ2V0LnNldChuYW1lLCBzZXF1ZW5jZSlcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQXBwZW5kcyBhIHJlZ2lzdHJ5LWxldmVsIGRlZmF1bHQgZGVjbGFyYXRpb24gKGNhbGxiYWNrcy9jb25zdHJ1Y3Rpb24gZGVmYXVsdHMpLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vZGVjbGFyYXRpb25zLmpzXCIpLkRlY2xhcmF0aW9ufSBkZWNsYXJhdGlvbiAtIERlY2xhcmF0aW9uIHRvIGFkZC5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICBfYWRkR2xvYmFsRGVjbGFyYXRpb24oZGVjbGFyYXRpb24pIHtcbiAgICB0aGlzLl9nbG9iYWxEZWNsYXJhdGlvbnMucHVzaChkZWNsYXJhdGlvbilcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNvbHZlcyBhIHNlcXVlbmNlIG5hbWUgYWdhaW5zdCBhIGZhY3Rvcnkgc2NvcGUgY2hhaW4gKGNoaWxkIGZpcnN0KSB0aGVuIHRoZVxuICAgKiBnbG9iYWwgc2NvcGUgYW5kIGFkdmFuY2VzIGl0LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gc2VxdWVuY2VOYW1lIC0gU2VxdWVuY2UgbmFtZS5cbiAgICogQHBhcmFtIHtzdHJpbmdbXX0gY2hhaW5OYW1lcyAtIEluaGVyaXRhbmNlIGNoYWluIG5hbWVzIChjaGlsZCBsYXN0KS5cbiAgICogQHJldHVybnMge1Byb21pc2U8Pz59IC0gVGhlIGZvcm1hdHRlZCB2YWx1ZS5cbiAgICovXG4gIGFzeW5jIF9nZW5lcmF0ZVNjb3BlZChzZXF1ZW5jZU5hbWUsIGNoYWluTmFtZXMpIHtcbiAgICBmb3IgKGxldCBpbmRleCA9IGNoYWluTmFtZXMubGVuZ3RoIC0gMTsgaW5kZXggPj0gMDsgaW5kZXgtLSkge1xuICAgICAgY29uc3Qgc2NvcGUgPSB0aGlzLl9mYWN0b3J5U2VxdWVuY2VzLmdldChjaGFpbk5hbWVzW2luZGV4XSlcblxuICAgICAgaWYgKHNjb3BlICYmIHNjb3BlLmhhcyhzZXF1ZW5jZU5hbWUpKSB7XG4gICAgICAgIHJldHVybiBhd2FpdCAvKiogQHR5cGUge2ltcG9ydChcIi4vc2VxdWVuY2UuanNcIikuZGVmYXVsdH0gKi8gKHNjb3BlLmdldChzZXF1ZW5jZU5hbWUpKS5uZXh0KClcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5fcmVzb2x2ZUdsb2JhbFNlcXVlbmNlKHNlcXVlbmNlTmFtZSkubmV4dCgpXG4gIH1cblxuICAvKipcbiAgICogUmVzb2x2ZXMgYSBnbG9iYWwgc2VxdWVuY2UgYnkgbmFtZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHNlcXVlbmNlTmFtZSAtIFNlcXVlbmNlIG5hbWUuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuL3NlcXVlbmNlLmpzXCIpLmRlZmF1bHR9IC0gVGhlIHNlcXVlbmNlLlxuICAgKi9cbiAgX3Jlc29sdmVHbG9iYWxTZXF1ZW5jZShzZXF1ZW5jZU5hbWUpIHtcbiAgICBjb25zdCBzZXF1ZW5jZSA9IHRoaXMuX3NlcXVlbmNlcy5nZXQoc2VxdWVuY2VOYW1lKVxuXG4gICAgaWYgKCFzZXF1ZW5jZSkge1xuICAgICAgdGhyb3cgbmV3IFVuZGVmaW5lZFNlcXVlbmNlRXJyb3IoYE5vIHNlcXVlbmNlIHJlZ2lzdGVyZWQgY2FsbGVkIFwiJHtzZXF1ZW5jZU5hbWV9XCJgKVxuICAgIH1cblxuICAgIHJldHVybiBzZXF1ZW5jZVxuICB9XG5cbiAgLyoqXG4gICAqIFJlamVjdHMgc2V0dXAtdGltZSBtdXRhdGlvbiB3aGlsZSBldmFsdWF0aW9ucyBhcmUgYWN0aXZlLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gb3BlcmF0aW9uIC0gT3BlcmF0aW9uIG5hbWUsIGZvciB0aGUgZXJyb3IgbWVzc2FnZS5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICBfYXNzZXJ0Tm90RXZhbHVhdGluZyhvcGVyYXRpb24pIHtcbiAgICBpZiAodGhpcy5fYWN0aXZlRXZhbHVhdGlvbnMgPiAwKSB7XG4gICAgICB0aHJvdyBuZXcgUmVnaXN0cnlCdXN5RXJyb3IoYENhbm5vdCAke29wZXJhdGlvbn0gd2hpbGUgZmFjdG9yeSBldmFsdWF0aW9ucyBhcmUgYWN0aXZlLiBSZWdpc3RyeSBtdXRhdGlvbiBpcyBzZXR1cC10aW1lIG9ubHkuYClcbiAgICB9XG4gIH1cbn1cbiJdfQ==
|