@jsprismarine/spawning 0.0.0 → 0.16.0-unstable-20261029140140
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 +80 -0
- package/LICENSE +373 -0
- package/README.md +207 -0
- package/dist/conditions.cjs.cjs +190 -0
- package/dist/conditions.d.ts +81 -0
- package/dist/conditions.d.ts.map +1 -0
- package/dist/conditions.es.js +186 -0
- package/dist/constants.cjs.cjs +29 -0
- package/dist/constants.d.ts +73 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.es.js +26 -0
- package/dist/despawn.cjs.cjs +25 -0
- package/dist/despawn.d.ts +33 -0
- package/dist/despawn.d.ts.map +1 -0
- package/dist/despawn.es.js +23 -0
- package/dist/engineRules.cjs.cjs +145 -0
- package/dist/engineRules.d.ts +86 -0
- package/dist/engineRules.d.ts.map +1 -0
- package/dist/engineRules.es.js +138 -0
- package/dist/index.cjs.cjs +32 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.es.js +8 -0
- package/dist/rules.cjs.cjs +282 -0
- package/dist/rules.d.ts +152 -0
- package/dist/rules.d.ts.map +1 -0
- package/dist/rules.es.js +277 -0
- package/dist/spawner.cjs.cjs +280 -0
- package/dist/spawner.d.ts +105 -0
- package/dist/spawner.d.ts.map +1 -0
- package/dist/spawner.es.js +278 -0
- package/dist/tables/spawnConstants.cjs.cjs +111 -0
- package/dist/tables/spawnConstants.d.ts +2 -0
- package/dist/tables/spawnConstants.es.js +89 -0
- package/dist/tables/spawnConstants.json.d.ts +2 -0
- package/dist/world.cjs.cjs +51 -0
- package/dist/world.d.ts +111 -0
- package/dist/world.d.ts.map +1 -0
- package/dist/world.es.js +45 -0
- package/package.json +68 -5
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const require_constants = require("./constants.cjs.cjs");
|
|
4
|
+
const require_conditions = require("./conditions.cjs.cjs");
|
|
5
|
+
const require_engineRules = require("./engineRules.cjs.cjs");
|
|
6
|
+
// src/spawner.ts
|
|
7
|
+
/** Splits `minecraft:pillager<minecraft:spawn_as_patrol_follower>` into its two halves. */
|
|
8
|
+
var splitSpawnType = (value) => {
|
|
9
|
+
const match = /^(?<identifier>[^<]+)<(?<event>[^>]+)>$/.exec(value);
|
|
10
|
+
if (match?.groups === void 0) return { identifier: value };
|
|
11
|
+
return {
|
|
12
|
+
identifier: match.groups.identifier,
|
|
13
|
+
event: match.groups.event
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
/** Draws an integer in the inclusive range, which is how every size and offset is picked. */
|
|
17
|
+
var between = (random, min, max) => max <= min ? min : min + random.nextInt(max - min + 1);
|
|
18
|
+
/**
|
|
19
|
+
* Builds the permutation each herd member spawns as.
|
|
20
|
+
*
|
|
21
|
+
* `min_guaranteed` members take their permutation before the weighted draw
|
|
22
|
+
* runs, which is what makes the pillager patrol's captain and the zombie
|
|
23
|
+
* herd's one villager certain.
|
|
24
|
+
*/
|
|
25
|
+
var permutationsFor = (permutations, size, random) => {
|
|
26
|
+
const members = [];
|
|
27
|
+
for (const permutation of permutations) for (let index = 0; index < permutation.minGuaranteed && members.length < size; index += 1) members.push(permutation);
|
|
28
|
+
const total = permutations.reduce((sum, permutation) => sum + Math.max(0, permutation.weight), 0);
|
|
29
|
+
while (members.length < size) {
|
|
30
|
+
if (total <= 0) {
|
|
31
|
+
members.push(void 0);
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
let roll = random.nextFloat() * total;
|
|
35
|
+
let chosen;
|
|
36
|
+
for (const permutation of permutations) {
|
|
37
|
+
roll -= Math.max(0, permutation.weight);
|
|
38
|
+
if (roll < 0) {
|
|
39
|
+
chosen = permutation;
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
members.push(chosen ?? permutations[permutations.length - 1]);
|
|
44
|
+
}
|
|
45
|
+
return members;
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* The event one herd member runs.
|
|
49
|
+
*
|
|
50
|
+
* `initial_event` wins for the first `initial_event_count` members, `event`
|
|
51
|
+
* takes every member past `event_skip_count`, and a permutation's `<event>`
|
|
52
|
+
* suffix or the condition's `minecraft:spawn_event` fills in for the rest.
|
|
53
|
+
*/
|
|
54
|
+
var eventForMember = (index, herd, permutationEvent, condition) => {
|
|
55
|
+
if (herd?.initialEvent !== void 0 && index < herd.initialEventCount) return herd.initialEvent;
|
|
56
|
+
if (herd?.event !== void 0 && index >= herd.eventSkipCount) return herd.event;
|
|
57
|
+
return permutationEvent ?? condition.spawnEvent;
|
|
58
|
+
};
|
|
59
|
+
/** Runs the spawn loop for one world. */
|
|
60
|
+
var Spawner = class {
|
|
61
|
+
rulesByPool = /* @__PURE__ */ new Map();
|
|
62
|
+
world;
|
|
63
|
+
random;
|
|
64
|
+
constants;
|
|
65
|
+
delays;
|
|
66
|
+
engineRules;
|
|
67
|
+
onUnanswered;
|
|
68
|
+
constructor(options) {
|
|
69
|
+
this.world = options.world;
|
|
70
|
+
this.random = options.random;
|
|
71
|
+
this.constants = options.constants ?? require_constants.SPAWN_CONSTANTS;
|
|
72
|
+
this.delays = options.delays ?? new require_conditions.SpawnDelays();
|
|
73
|
+
this.engineRules = options.engineRules ?? require_engineRules.VANILLA_ENGINE_SPAWN_RULES;
|
|
74
|
+
this.onUnanswered = options.onUnanswered;
|
|
75
|
+
for (const rule of options.rules) {
|
|
76
|
+
const pool = rule.populationControl;
|
|
77
|
+
if (pool === void 0) continue;
|
|
78
|
+
const existing = this.rulesByPool.get(pool);
|
|
79
|
+
if (existing === void 0) this.rulesByPool.set(pool, [rule]);
|
|
80
|
+
else existing.push(rule);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/** The pools the loaded rules name, which is what {@link tick} cycles. */
|
|
84
|
+
get pools() {
|
|
85
|
+
return [...this.rulesByPool.keys()];
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Runs every pool whose cadence falls on this tick.
|
|
89
|
+
*
|
|
90
|
+
* @returns Every entity to create, in the order the cycles produced them.
|
|
91
|
+
*/
|
|
92
|
+
tick(tick) {
|
|
93
|
+
const requests = [];
|
|
94
|
+
for (const pool of this.rulesByPool.keys()) {
|
|
95
|
+
const cadence = this.constants.pools[pool]?.cycleTicks;
|
|
96
|
+
if (cadence === void 0 || cadence <= 0 || tick % cadence !== 0) continue;
|
|
97
|
+
requests.push(...this.cycle(pool, tick));
|
|
98
|
+
}
|
|
99
|
+
return requests;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Runs one cycle of one pool, whatever the cadence says.
|
|
103
|
+
*
|
|
104
|
+
* @returns Every entity to create, never more than the pool's remaining cap.
|
|
105
|
+
*/
|
|
106
|
+
cycle(pool, tick) {
|
|
107
|
+
const rules = this.rulesByPool.get(pool);
|
|
108
|
+
if (rules === void 0 || rules.length === 0) return [];
|
|
109
|
+
const players = this.world.players();
|
|
110
|
+
if (players.length === 0) return [];
|
|
111
|
+
const cap = require_constants.poolCapFor(pool, players.length, this.constants);
|
|
112
|
+
let remaining = cap === void 0 ? Number.POSITIVE_INFINITY : cap - this.world.poolCount(pool);
|
|
113
|
+
if (remaining <= 0) return [];
|
|
114
|
+
const requests = [];
|
|
115
|
+
const { spawnRadiusChunks, chunksPerCycle, positionsPerChunk } = this.constants;
|
|
116
|
+
for (const player of players) {
|
|
117
|
+
const playerChunkX = Math.floor(player.position.x / 16);
|
|
118
|
+
const playerChunkZ = Math.floor(player.position.z / 16);
|
|
119
|
+
for (let sample = 0; sample < chunksPerCycle && remaining > 0; sample += 1) {
|
|
120
|
+
const chunkX = playerChunkX + between(this.random, -spawnRadiusChunks, spawnRadiusChunks);
|
|
121
|
+
const chunkZ = playerChunkZ + between(this.random, -spawnRadiusChunks, spawnRadiusChunks);
|
|
122
|
+
for (let attempt = 0; attempt < positionsPerChunk && remaining > 0; attempt += 1) for (const pass of ["surface", "underground"]) {
|
|
123
|
+
if (remaining <= 0) break;
|
|
124
|
+
const position = this.positionIn(chunkX, chunkZ, pass);
|
|
125
|
+
if (position === void 0) continue;
|
|
126
|
+
const spawned = this.attemptAt(pool, rules, position, pass, tick, remaining);
|
|
127
|
+
remaining -= spawned.length;
|
|
128
|
+
requests.push(...spawned);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return requests;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Draws one position inside a chunk for one pass.
|
|
136
|
+
*
|
|
137
|
+
* @returns The position, or undefined when the column is unloaded or the draw landed
|
|
138
|
+
* somewhere no entity fits.
|
|
139
|
+
*/
|
|
140
|
+
positionIn(chunkX, chunkZ, pass) {
|
|
141
|
+
const x = chunkX * 16 + this.random.nextInt(16);
|
|
142
|
+
const z = chunkZ * 16 + this.random.nextInt(16);
|
|
143
|
+
if (pass === "surface") return this.surfacePosition(x, z);
|
|
144
|
+
const top = this.world.surfaceY(x, z);
|
|
145
|
+
if (top === void 0) return void 0;
|
|
146
|
+
const floor = this.world.minY();
|
|
147
|
+
if (top - 1 < floor) return void 0;
|
|
148
|
+
const at = {
|
|
149
|
+
x,
|
|
150
|
+
y: between(this.random, floor, top - 1),
|
|
151
|
+
z
|
|
152
|
+
};
|
|
153
|
+
return this.fits(at) ? at : void 0;
|
|
154
|
+
}
|
|
155
|
+
/** The top spawn position in a column, using the water surface when one covers the terrain. */
|
|
156
|
+
surfacePosition(x, z) {
|
|
157
|
+
const top = this.world.surfaceY(x, z);
|
|
158
|
+
if (top === void 0) return void 0;
|
|
159
|
+
const surface = {
|
|
160
|
+
x,
|
|
161
|
+
y: top,
|
|
162
|
+
z
|
|
163
|
+
};
|
|
164
|
+
if (this.world.site("underwater", surface)) return surface;
|
|
165
|
+
const waterSurface = {
|
|
166
|
+
...surface,
|
|
167
|
+
y: top - 1
|
|
168
|
+
};
|
|
169
|
+
return this.world.site("underwater", waterSurface) ? waterSurface : surface;
|
|
170
|
+
}
|
|
171
|
+
/** Whether an entity fits at a position: its own block and the one over its head are free. */
|
|
172
|
+
fits(at) {
|
|
173
|
+
return !this.world.solid(at) && !this.world.solid({
|
|
174
|
+
...at,
|
|
175
|
+
y: at.y + 1
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Runs one attempt: collect the rules that pass here, draw one, and build
|
|
180
|
+
* its herd.
|
|
181
|
+
*
|
|
182
|
+
* A rule with an engine condition is asked that first, because a condition
|
|
183
|
+
* Bedrock keeps in code is a condition the file was never able to state.
|
|
184
|
+
* `minecraft:slime` is the rule this matters to: its file names no
|
|
185
|
+
* brightness and no height, so without the engine condition it is the only
|
|
186
|
+
* monster that passes in daylight and it fills the pool on its own.
|
|
187
|
+
*/
|
|
188
|
+
attemptAt(pool, rules, position, pass, tick, remaining) {
|
|
189
|
+
const candidates = [];
|
|
190
|
+
let totalWeight = 0;
|
|
191
|
+
for (const rule of rules) {
|
|
192
|
+
if (this.world.structureSpawnOverrideAt?.(rule.identifier, position) === false) continue;
|
|
193
|
+
const engineRule = this.engineRules.get(rule.identifier);
|
|
194
|
+
if (engineRule !== void 0 && !engineRule(position, {
|
|
195
|
+
world: this.world,
|
|
196
|
+
random: this.random
|
|
197
|
+
})) continue;
|
|
198
|
+
for (const condition of rule.conditions) {
|
|
199
|
+
if (!require_conditions.evaluateSpawnCondition(condition, position, this.contextFor(rule, tick), pass).passed) continue;
|
|
200
|
+
candidates.push({
|
|
201
|
+
rule,
|
|
202
|
+
condition
|
|
203
|
+
});
|
|
204
|
+
totalWeight += Math.max(0, condition.weight.default);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
if (candidates.length === 0 || totalWeight <= 0) return [];
|
|
208
|
+
let roll = this.random.nextFloat() * totalWeight;
|
|
209
|
+
let chosen = candidates[candidates.length - 1];
|
|
210
|
+
for (const candidate of candidates) {
|
|
211
|
+
roll -= Math.max(0, candidate.condition.weight.default);
|
|
212
|
+
if (roll < 0) {
|
|
213
|
+
chosen = candidate;
|
|
214
|
+
break;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
const { rarity } = chosen.condition.weight;
|
|
218
|
+
if (rarity > 0 && this.random.nextFloat() * rarity >= 1) return [];
|
|
219
|
+
if (chosen.condition.delay !== void 0) this.delays.scheduleFrom(chosen.condition.delay, tick, this.random);
|
|
220
|
+
return this.herdAt(pool, chosen, position, pass, remaining);
|
|
221
|
+
}
|
|
222
|
+
/** Builds one herd around an anchor position. */
|
|
223
|
+
herdAt(pool, candidate, anchor, pass, remaining) {
|
|
224
|
+
const { condition, rule } = candidate;
|
|
225
|
+
const herd = condition.herd.length === 0 ? void 0 : condition.herd[this.random.nextInt(condition.herd.length)];
|
|
226
|
+
const drawn = herd === void 0 ? 1 : between(this.random, herd.minSize, herd.maxSize);
|
|
227
|
+
const size = Math.max(0, Math.min(drawn, remaining));
|
|
228
|
+
if (size === 0) return [];
|
|
229
|
+
const permutations = condition.permutations === void 0 ? void 0 : permutationsFor(condition.permutations, size, this.random);
|
|
230
|
+
const requests = [];
|
|
231
|
+
for (let index = 0; index < size; index += 1) {
|
|
232
|
+
const permutation = permutations?.[index];
|
|
233
|
+
const swapped = permutation?.entityType === void 0 ? void 0 : splitSpawnType(permutation.entityType);
|
|
234
|
+
const position = index === 0 ? anchor : this.herdMemberPosition(anchor, pass);
|
|
235
|
+
const identifier = swapped?.identifier ?? rule.identifier;
|
|
236
|
+
if (this.world.structureSpawnOverrideAt?.(identifier, position) === false) continue;
|
|
237
|
+
const event = eventForMember(index, herd, swapped?.event, condition);
|
|
238
|
+
const request = {
|
|
239
|
+
identifier,
|
|
240
|
+
position,
|
|
241
|
+
pool,
|
|
242
|
+
rule: rule.identifier,
|
|
243
|
+
pass
|
|
244
|
+
};
|
|
245
|
+
if (event !== void 0) request.spawnEvent = event;
|
|
246
|
+
requests.push(request);
|
|
247
|
+
}
|
|
248
|
+
return requests;
|
|
249
|
+
}
|
|
250
|
+
/** Places one herd member around the anchor, following the terrain on the surface pass. */
|
|
251
|
+
herdMemberPosition(anchor, pass) {
|
|
252
|
+
const radius = this.constants.herdRadius;
|
|
253
|
+
const x = anchor.x + between(this.random, -radius, radius);
|
|
254
|
+
const z = anchor.z + between(this.random, -radius, radius);
|
|
255
|
+
if (pass !== "surface") return {
|
|
256
|
+
x,
|
|
257
|
+
y: anchor.y,
|
|
258
|
+
z
|
|
259
|
+
};
|
|
260
|
+
const position = this.surfacePosition(x, z);
|
|
261
|
+
if (position === void 0) return anchor;
|
|
262
|
+
if (this.world.site("underwater", anchor) && !this.world.site("underwater", position)) return anchor;
|
|
263
|
+
return position;
|
|
264
|
+
}
|
|
265
|
+
contextFor(rule, tick) {
|
|
266
|
+
const context = {
|
|
267
|
+
world: this.world,
|
|
268
|
+
identifier: rule.identifier,
|
|
269
|
+
random: this.random,
|
|
270
|
+
tick,
|
|
271
|
+
constants: this.constants,
|
|
272
|
+
delays: this.delays
|
|
273
|
+
};
|
|
274
|
+
if (this.onUnanswered !== void 0) context.onUnanswered = this.onUnanswered;
|
|
275
|
+
return context;
|
|
276
|
+
}
|
|
277
|
+
};
|
|
278
|
+
exports.Spawner = Spawner;
|
|
279
|
+
|
|
280
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3Bhd25lci5janMuY2pzIiwibmFtZXMiOlsiU1BBV05fQ09OU1RBTlRTIiwiU3Bhd25EZWxheXMiLCJWQU5JTExBX0VOR0lORV9TUEFXTl9SVUxFUyIsInBvb2xDYXBGb3IiLCJldmFsdWF0ZVNwYXduQ29uZGl0aW9uIl0sInNvdXJjZXMiOlsiLi4vc3JjL3NwYXduZXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgeyBFdmFsdWF0ZUZpbHRlck9wdGlvbnMgfSBmcm9tICdAanNwcmlzbWFyaW5lL2VudGl0aWVzJztcbmltcG9ydCB0eXBlIHsgUmFuZG9tU291cmNlIH0gZnJvbSAnQGpzcHJpc21hcmluZS9wcmVkaWNhdGVzJztcblxuaW1wb3J0IHR5cGUgeyBTcGF3bkNvbmRpdGlvbkNvbnRleHQgfSBmcm9tICcuL2NvbmRpdGlvbnMnO1xuaW1wb3J0IHsgU3Bhd25EZWxheXMsIGV2YWx1YXRlU3Bhd25Db25kaXRpb24gfSBmcm9tICcuL2NvbmRpdGlvbnMnO1xuaW1wb3J0IHR5cGUgeyBTcGF3bkNvbnN0YW50cyB9IGZyb20gJy4vY29uc3RhbnRzJztcbmltcG9ydCB7IFNQQVdOX0NPTlNUQU5UUywgcG9vbENhcEZvciB9IGZyb20gJy4vY29uc3RhbnRzJztcbmltcG9ydCB0eXBlIHsgRW5naW5lU3Bhd25SdWxlIH0gZnJvbSAnLi9lbmdpbmVSdWxlcyc7XG5pbXBvcnQgeyBWQU5JTExBX0VOR0lORV9TUEFXTl9SVUxFUyB9IGZyb20gJy4vZW5naW5lUnVsZXMnO1xuaW1wb3J0IHR5cGUgeyBIZXJkUnVsZSwgU3Bhd25Db25kaXRpb24sIFNwYXduUGVybXV0YXRpb24sIFNwYXduUnVsZSB9IGZyb20gJy4vcnVsZXMnO1xuaW1wb3J0IHR5cGUgeyBTcGF3blBhc3MsIFNwYXduUG9zaXRpb24sIFNwYXduV29ybGQgfSBmcm9tICcuL3dvcmxkJztcblxuLyoqXG4gKiBUaGUgc3Bhd24gbG9vcC5cbiAqXG4gKiBNb2phbmcncyBzcGF3biBjeWNsZSBkaWFncmFtIG5hbWVzIHNpeCBzdGVwcywgXCJjaGVjayBzcGF3biBjb25kaXRpb25zLCBmaW5kXG4gKiB2YWxpZCBzcGF3biBsb2NhdGlvbnMsIGNoZWNrIHBvcHVsYXRpb24gY2FwcywgZXZhbHVhdGUgc3Bhd24gd2VpZ2h0LCBzcGF3blxuICogZW50aXR5LCBhbmQgcnVuIHNwYXduIGV2ZW50XCIsIGFuZCBwdWJsaXNoZXMgbm8gbnVtYmVyIGJlaGluZCBhbnkgb2YgdGhlbS5cbiAqIFRoaXMgbG9vcCBpbXBsZW1lbnRzIHRob3NlIHNpeCBzdGVwcyBvdmVyIHRoZSBjb25zdGFudHMgaW5cbiAqIGBzcmMvdGFibGVzL3NwYXduQ29uc3RhbnRzLmpzb25gLCBhbmQgZXZlcnkgZHJhdyBnb2VzIHRocm91Z2ggYW4gaW5qZWN0ZWRcbiAqIHtAbGluayBSYW5kb21Tb3VyY2V9LCBzbyBvbmUgc2VlZCByZXByb2R1Y2VzIG9uZSBzZXQgb2Ygc3Bhd25zLlxuICpcbiAqIE9uZSBjeWNsZSBvZiBvbmUgcG9vbCBzYW1wbGVzIGBjaHVua3NQZXJDeWNsZWAgY2h1bmtzIGFyb3VuZCBlYWNoIHBsYXllcixcbiAqIHRyaWVzIGBwb3NpdGlvbnNQZXJDaHVua2AgcG9zaXRpb25zIGluIGVhY2ggY2h1bmsgZm9yIHRoZSBzdXJmYWNlIHBhc3MgYW5kXG4gKiB0aGUgc2FtZSBudW1iZXIgZm9yIHRoZSB1bmRlcmdyb3VuZCBwYXNzLCBhbmQgYXQgZWFjaCBwb3NpdGlvbiBkcmF3cyBvbmUgb2ZcbiAqIHRoZSBjb25kaXRpb25zIHRoYXQgcGFzc2VkLCB3ZWlnaHRlZCBieSBgbWluZWNyYWZ0OndlaWdodGAuXG4gKi9cblxuLyoqIE9uZSBlbnRpdHkgdGhlIHNwYXduZXIgYXNrcyB0aGUgc2VydmVyIHRvIGNyZWF0ZS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU3Bhd25SZXF1ZXN0IHtcbiAgICAvKiogVGhlIGVudGl0eSB0eXBlLCB3aXRoIGFueSBgPGV2ZW50PmAgc3VmZml4IGFscmVhZHkgc3BsaXQgb2ZmLiAqL1xuICAgIHJlYWRvbmx5IGlkZW50aWZpZXI6IHN0cmluZztcbiAgICAvKiogVGhlIGV2ZW50IHRvIHJ1biBpbnN0ZWFkIG9mIGBtaW5lY3JhZnQ6ZW50aXR5X3NwYXduZWRgLCB3aGVuIHRoZSBydWxlIG5hbWVzIG9uZS4gKi9cbiAgICByZWFkb25seSBzcGF3bkV2ZW50Pzogc3RyaW5nO1xuICAgIHJlYWRvbmx5IHBvc2l0aW9uOiBTcGF3blBvc2l0aW9uO1xuICAgIC8qKiBUaGUgcG9vbCB3aG9zZSBjYXAgdGhpcyBzcGF3biBjb3VudHMgYWdhaW5zdC4gKi9cbiAgICByZWFkb25seSBwb29sOiBzdHJpbmc7XG4gICAgLyoqIFRoZSBydWxlIHRoYXQgcHJvZHVjZWQgdGhlIHNwYXduLCB3aGljaCBpcyB0aGUgaWRlbnRpZmllciBvZiBpdHMgZmlsZS4gKi9cbiAgICByZWFkb25seSBydWxlOiBzdHJpbmc7XG4gICAgcmVhZG9ubHkgcGFzczogU3Bhd25QYXNzO1xufVxuXG4vKiogSG93IHRvIGJ1aWxkIGEge0BsaW5rIFNwYXduZXJ9LiAqL1xuZXhwb3J0IGludGVyZmFjZSBTcGF3bmVyT3B0aW9ucyB7XG4gICAgcmVhZG9ubHkgcnVsZXM6IEl0ZXJhYmxlPFNwYXduUnVsZT47XG4gICAgcmVhZG9ubHkgd29ybGQ6IFNwYXduV29ybGQ7XG4gICAgcmVhZG9ubHkgcmFuZG9tOiBSYW5kb21Tb3VyY2U7XG4gICAgcmVhZG9ubHkgY29uc3RhbnRzPzogU3Bhd25Db25zdGFudHM7XG4gICAgLyoqIFRoZSBgbWluZWNyYWZ0OmRlbGF5X2ZpbHRlcmAgY29vbGRvd25zLCBzbyBhIGNhbGxlciBjYW4gcGVyc2lzdCB0aGVtIGFjcm9zcyBhIHJlc3RhcnQuICovXG4gICAgcmVhZG9ubHkgZGVsYXlzPzogU3Bhd25EZWxheXM7XG4gICAgLyoqXG4gICAgICogVGhlIGNvbmRpdGlvbnMgQmVkcm9jayBrZWVwcyBpbiBlbmdpbmUgY29kZSwga2V5ZWQgYnkgdGhlIGVudGl0eSBlYWNoXG4gICAgICogb25lIGdhdGVzLiBEZWZhdWx0cyB0byB7QGxpbmsgVkFOSUxMQV9FTkdJTkVfU1BBV05fUlVMRVN9OyBwYXNzIGFuIGVtcHR5XG4gICAgICogbWFwIHRvIHJ1biB0aGUgSlNPTiBjb25kaXRpb25zIGFsb25lLlxuICAgICAqL1xuICAgIHJlYWRvbmx5IGVuZ2luZVJ1bGVzPzogUmVhZG9ubHlNYXA8c3RyaW5nLCBFbmdpbmVTcGF3blJ1bGU+O1xuICAgIC8qKiBSZWNlaXZlcyBldmVyeSBiaW9tZSBmaWx0ZXIgdGVzdCB0aGUgZXZhbHVhdG9yIGNvdWxkIG5vdCBhbnN3ZXIuICovXG4gICAgcmVhZG9ubHkgb25VbmFuc3dlcmVkPzogRXZhbHVhdGVGaWx0ZXJPcHRpb25zWydvblVuYW5zd2VyZWQnXTtcbn1cblxuLyoqIE9uZSBydWxlIGFuZCB0aGUgb25lIG9mIGl0cyBjb25kaXRpb25zIHRoYXQgcGFzc2VkIGF0IGEgcG9zaXRpb24uICovXG5pbnRlcmZhY2UgQ2FuZGlkYXRlIHtcbiAgICByZWFkb25seSBydWxlOiBTcGF3blJ1bGU7XG4gICAgcmVhZG9ubHkgY29uZGl0aW9uOiBTcGF3bkNvbmRpdGlvbjtcbn1cblxuLyoqIFNwbGl0cyBgbWluZWNyYWZ0OnBpbGxhZ2VyPG1pbmVjcmFmdDpzcGF3bl9hc19wYXRyb2xfZm9sbG93ZXI+YCBpbnRvIGl0cyB0d28gaGFsdmVzLiAqL1xuY29uc3Qgc3BsaXRTcGF3blR5cGUgPSAodmFsdWU6IHN0cmluZyk6IHsgcmVhZG9ubHkgaWRlbnRpZmllcjogc3RyaW5nOyByZWFkb25seSBldmVudD86IHN0cmluZyB9ID0+IHtcbiAgICBjb25zdCBtYXRjaCA9IC9eKD88aWRlbnRpZmllcj5bXjxdKyk8KD88ZXZlbnQ+W14+XSspPiQvLmV4ZWModmFsdWUpO1xuICAgIGlmIChtYXRjaD8uZ3JvdXBzID09PSB1bmRlZmluZWQpIHJldHVybiB7IGlkZW50aWZpZXI6IHZhbHVlIH07XG4gICAgcmV0dXJuIHsgaWRlbnRpZmllcjogbWF0Y2guZ3JvdXBzLmlkZW50aWZpZXIhLCBldmVudDogbWF0Y2guZ3JvdXBzLmV2ZW50ISB9O1xufTtcblxuLyoqIERyYXdzIGFuIGludGVnZXIgaW4gdGhlIGluY2x1c2l2ZSByYW5nZSwgd2hpY2ggaXMgaG93IGV2ZXJ5IHNpemUgYW5kIG9mZnNldCBpcyBwaWNrZWQuICovXG5jb25zdCBiZXR3ZWVuID0gKHJhbmRvbTogUmFuZG9tU291cmNlLCBtaW46IG51bWJlciwgbWF4OiBudW1iZXIpOiBudW1iZXIgPT5cbiAgICBtYXggPD0gbWluID8gbWluIDogbWluICsgcmFuZG9tLm5leHRJbnQobWF4IC0gbWluICsgMSk7XG5cbi8qKlxuICogQnVpbGRzIHRoZSBwZXJtdXRhdGlvbiBlYWNoIGhlcmQgbWVtYmVyIHNwYXducyBhcy5cbiAqXG4gKiBgbWluX2d1YXJhbnRlZWRgIG1lbWJlcnMgdGFrZSB0aGVpciBwZXJtdXRhdGlvbiBiZWZvcmUgdGhlIHdlaWdodGVkIGRyYXdcbiAqIHJ1bnMsIHdoaWNoIGlzIHdoYXQgbWFrZXMgdGhlIHBpbGxhZ2VyIHBhdHJvbCdzIGNhcHRhaW4gYW5kIHRoZSB6b21iaWVcbiAqIGhlcmQncyBvbmUgdmlsbGFnZXIgY2VydGFpbi5cbiAqL1xuY29uc3QgcGVybXV0YXRpb25zRm9yID0gKFxuICAgIHBlcm11dGF0aW9uczogcmVhZG9ubHkgU3Bhd25QZXJtdXRhdGlvbltdLFxuICAgIHNpemU6IG51bWJlcixcbiAgICByYW5kb206IFJhbmRvbVNvdXJjZVxuKTogcmVhZG9ubHkgKFNwYXduUGVybXV0YXRpb24gfCB1bmRlZmluZWQpW10gPT4ge1xuICAgIGNvbnN0IG1lbWJlcnM6IChTcGF3blBlcm11dGF0aW9uIHwgdW5kZWZpbmVkKVtdID0gW107XG4gICAgZm9yIChjb25zdCBwZXJtdXRhdGlvbiBvZiBwZXJtdXRhdGlvbnMpIHtcbiAgICAgICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IHBlcm11dGF0aW9uLm1pbkd1YXJhbnRlZWQgJiYgbWVtYmVycy5sZW5ndGggPCBzaXplOyBpbmRleCArPSAxKVxuICAgICAgICAgICAgbWVtYmVycy5wdXNoKHBlcm11dGF0aW9uKTtcbiAgICB9XG5cbiAgICBjb25zdCB0b3RhbCA9IHBlcm11dGF0aW9ucy5yZWR1Y2UoKHN1bSwgcGVybXV0YXRpb24pID0+IHN1bSArIE1hdGgubWF4KDAsIHBlcm11dGF0aW9uLndlaWdodCksIDApO1xuICAgIHdoaWxlIChtZW1iZXJzLmxlbmd0aCA8IHNpemUpIHtcbiAgICAgICAgaWYgKHRvdGFsIDw9IDApIHtcbiAgICAgICAgICAgIG1lbWJlcnMucHVzaCh1bmRlZmluZWQpO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHJvbGwgPSByYW5kb20ubmV4dEZsb2F0KCkgKiB0b3RhbDtcbiAgICAgICAgbGV0IGNob3NlbjogU3Bhd25QZXJtdXRhdGlvbiB8IHVuZGVmaW5lZDtcbiAgICAgICAgZm9yIChjb25zdCBwZXJtdXRhdGlvbiBvZiBwZXJtdXRhdGlvbnMpIHtcbiAgICAgICAgICAgIHJvbGwgLT0gTWF0aC5tYXgoMCwgcGVybXV0YXRpb24ud2VpZ2h0KTtcbiAgICAgICAgICAgIGlmIChyb2xsIDwgMCkge1xuICAgICAgICAgICAgICAgIGNob3NlbiA9IHBlcm11dGF0aW9uO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIG1lbWJlcnMucHVzaChjaG9zZW4gPz8gcGVybXV0YXRpb25zW3Blcm11dGF0aW9ucy5sZW5ndGggLSAxXSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG1lbWJlcnM7XG59O1xuXG4vKipcbiAqIFRoZSBldmVudCBvbmUgaGVyZCBtZW1iZXIgcnVucy5cbiAqXG4gKiBgaW5pdGlhbF9ldmVudGAgd2lucyBmb3IgdGhlIGZpcnN0IGBpbml0aWFsX2V2ZW50X2NvdW50YCBtZW1iZXJzLCBgZXZlbnRgXG4gKiB0YWtlcyBldmVyeSBtZW1iZXIgcGFzdCBgZXZlbnRfc2tpcF9jb3VudGAsIGFuZCBhIHBlcm11dGF0aW9uJ3MgYDxldmVudD5gXG4gKiBzdWZmaXggb3IgdGhlIGNvbmRpdGlvbidzIGBtaW5lY3JhZnQ6c3Bhd25fZXZlbnRgIGZpbGxzIGluIGZvciB0aGUgcmVzdC5cbiAqL1xuY29uc3QgZXZlbnRGb3JNZW1iZXIgPSAoXG4gICAgaW5kZXg6IG51bWJlcixcbiAgICBoZXJkOiBIZXJkUnVsZSB8IHVuZGVmaW5lZCxcbiAgICBwZXJtdXRhdGlvbkV2ZW50OiBzdHJpbmcgfCB1bmRlZmluZWQsXG4gICAgY29uZGl0aW9uOiBTcGF3bkNvbmRpdGlvblxuKTogc3RyaW5nIHwgdW5kZWZpbmVkID0+IHtcbiAgICBpZiAoaGVyZD8uaW5pdGlhbEV2ZW50ICE9PSB1bmRlZmluZWQgJiYgaW5kZXggPCBoZXJkLmluaXRpYWxFdmVudENvdW50KSByZXR1cm4gaGVyZC5pbml0aWFsRXZlbnQ7XG4gICAgaWYgKGhlcmQ/LmV2ZW50ICE9PSB1bmRlZmluZWQgJiYgaW5kZXggPj0gaGVyZC5ldmVudFNraXBDb3VudCkgcmV0dXJuIGhlcmQuZXZlbnQ7XG4gICAgcmV0dXJuIHBlcm11dGF0aW9uRXZlbnQgPz8gY29uZGl0aW9uLnNwYXduRXZlbnQ7XG59O1xuXG4vKiogUnVucyB0aGUgc3Bhd24gbG9vcCBmb3Igb25lIHdvcmxkLiAqL1xuZXhwb3J0IGNsYXNzIFNwYXduZXIge1xuICAgIHByaXZhdGUgcmVhZG9ubHkgcnVsZXNCeVBvb2wgPSBuZXcgTWFwPHN0cmluZywgU3Bhd25SdWxlW10+KCk7XG4gICAgcHJpdmF0ZSByZWFkb25seSB3b3JsZDogU3Bhd25Xb3JsZDtcbiAgICBwcml2YXRlIHJlYWRvbmx5IHJhbmRvbTogUmFuZG9tU291cmNlO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgY29uc3RhbnRzOiBTcGF3bkNvbnN0YW50cztcbiAgICBwcml2YXRlIHJlYWRvbmx5IGRlbGF5czogU3Bhd25EZWxheXM7XG4gICAgcHJpdmF0ZSByZWFkb25seSBlbmdpbmVSdWxlczogUmVhZG9ubHlNYXA8c3RyaW5nLCBFbmdpbmVTcGF3blJ1bGU+O1xuICAgIHByaXZhdGUgcmVhZG9ubHkgb25VbmFuc3dlcmVkOiBFdmFsdWF0ZUZpbHRlck9wdGlvbnNbJ29uVW5hbnN3ZXJlZCddIHwgdW5kZWZpbmVkO1xuXG4gICAgcHVibGljIGNvbnN0cnVjdG9yKG9wdGlvbnM6IFNwYXduZXJPcHRpb25zKSB7XG4gICAgICAgIHRoaXMud29ybGQgPSBvcHRpb25zLndvcmxkO1xuICAgICAgICB0aGlzLnJhbmRvbSA9IG9wdGlvbnMucmFuZG9tO1xuICAgICAgICB0aGlzLmNvbnN0YW50cyA9IG9wdGlvbnMuY29uc3RhbnRzID8/IFNQQVdOX0NPTlNUQU5UUztcbiAgICAgICAgdGhpcy5kZWxheXMgPSBvcHRpb25zLmRlbGF5cyA/PyBuZXcgU3Bhd25EZWxheXMoKTtcbiAgICAgICAgdGhpcy5lbmdpbmVSdWxlcyA9IG9wdGlvbnMuZW5naW5lUnVsZXMgPz8gVkFOSUxMQV9FTkdJTkVfU1BBV05fUlVMRVM7XG4gICAgICAgIHRoaXMub25VbmFuc3dlcmVkID0gb3B0aW9ucy5vblVuYW5zd2VyZWQ7XG5cbiAgICAgICAgZm9yIChjb25zdCBydWxlIG9mIG9wdGlvbnMucnVsZXMpIHtcbiAgICAgICAgICAgIGNvbnN0IHBvb2wgPSBydWxlLnBvcHVsYXRpb25Db250cm9sO1xuICAgICAgICAgICAgaWYgKHBvb2wgPT09IHVuZGVmaW5lZCkgY29udGludWU7XG4gICAgICAgICAgICBjb25zdCBleGlzdGluZyA9IHRoaXMucnVsZXNCeVBvb2wuZ2V0KHBvb2wpO1xuICAgICAgICAgICAgaWYgKGV4aXN0aW5nID09PSB1bmRlZmluZWQpIHRoaXMucnVsZXNCeVBvb2wuc2V0KHBvb2wsIFtydWxlXSk7XG4gICAgICAgICAgICBlbHNlIGV4aXN0aW5nLnB1c2gocnVsZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogVGhlIHBvb2xzIHRoZSBsb2FkZWQgcnVsZXMgbmFtZSwgd2hpY2ggaXMgd2hhdCB7QGxpbmsgdGlja30gY3ljbGVzLiAqL1xuICAgIHB1YmxpYyBnZXQgcG9vbHMoKTogcmVhZG9ubHkgc3RyaW5nW10ge1xuICAgICAgICByZXR1cm4gWy4uLnRoaXMucnVsZXNCeVBvb2wua2V5cygpXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSdW5zIGV2ZXJ5IHBvb2wgd2hvc2UgY2FkZW5jZSBmYWxscyBvbiB0aGlzIHRpY2suXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBFdmVyeSBlbnRpdHkgdG8gY3JlYXRlLCBpbiB0aGUgb3JkZXIgdGhlIGN5Y2xlcyBwcm9kdWNlZCB0aGVtLlxuICAgICAqL1xuICAgIHB1YmxpYyB0aWNrKHRpY2s6IG51bWJlcik6IHJlYWRvbmx5IFNwYXduUmVxdWVzdFtdIHtcbiAgICAgICAgY29uc3QgcmVxdWVzdHM6IFNwYXduUmVxdWVzdFtdID0gW107XG4gICAgICAgIGZvciAoY29uc3QgcG9vbCBvZiB0aGlzLnJ1bGVzQnlQb29sLmtleXMoKSkge1xuICAgICAgICAgICAgY29uc3QgY2FkZW5jZSA9IHRoaXMuY29uc3RhbnRzLnBvb2xzW3Bvb2xdPy5jeWNsZVRpY2tzO1xuICAgICAgICAgICAgaWYgKGNhZGVuY2UgPT09IHVuZGVmaW5lZCB8fCBjYWRlbmNlIDw9IDAgfHwgdGljayAlIGNhZGVuY2UgIT09IDApIGNvbnRpbnVlO1xuICAgICAgICAgICAgcmVxdWVzdHMucHVzaCguLi50aGlzLmN5Y2xlKHBvb2wsIHRpY2spKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVxdWVzdHM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUnVucyBvbmUgY3ljbGUgb2Ygb25lIHBvb2wsIHdoYXRldmVyIHRoZSBjYWRlbmNlIHNheXMuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBFdmVyeSBlbnRpdHkgdG8gY3JlYXRlLCBuZXZlciBtb3JlIHRoYW4gdGhlIHBvb2wncyByZW1haW5pbmcgY2FwLlxuICAgICAqL1xuICAgIHB1YmxpYyBjeWNsZShwb29sOiBzdHJpbmcsIHRpY2s6IG51bWJlcik6IHJlYWRvbmx5IFNwYXduUmVxdWVzdFtdIHtcbiAgICAgICAgY29uc3QgcnVsZXMgPSB0aGlzLnJ1bGVzQnlQb29sLmdldChwb29sKTtcbiAgICAgICAgaWYgKHJ1bGVzID09PSB1bmRlZmluZWQgfHwgcnVsZXMubGVuZ3RoID09PSAwKSByZXR1cm4gW107XG5cbiAgICAgICAgY29uc3QgcGxheWVycyA9IHRoaXMud29ybGQucGxheWVycygpO1xuICAgICAgICBpZiAocGxheWVycy5sZW5ndGggPT09IDApIHJldHVybiBbXTtcblxuICAgICAgICBjb25zdCBjYXAgPSBwb29sQ2FwRm9yKHBvb2wsIHBsYXllcnMubGVuZ3RoLCB0aGlzLmNvbnN0YW50cyk7XG4gICAgICAgIGxldCByZW1haW5pbmcgPSBjYXAgPT09IHVuZGVmaW5lZCA/IE51bWJlci5QT1NJVElWRV9JTkZJTklUWSA6IGNhcCAtIHRoaXMud29ybGQucG9vbENvdW50KHBvb2wpO1xuICAgICAgICBpZiAocmVtYWluaW5nIDw9IDApIHJldHVybiBbXTtcblxuICAgICAgICBjb25zdCByZXF1ZXN0czogU3Bhd25SZXF1ZXN0W10gPSBbXTtcbiAgICAgICAgY29uc3QgeyBzcGF3blJhZGl1c0NodW5rcywgY2h1bmtzUGVyQ3ljbGUsIHBvc2l0aW9uc1BlckNodW5rIH0gPSB0aGlzLmNvbnN0YW50cztcblxuICAgICAgICBmb3IgKGNvbnN0IHBsYXllciBvZiBwbGF5ZXJzKSB7XG4gICAgICAgICAgICBjb25zdCBwbGF5ZXJDaHVua1ggPSBNYXRoLmZsb29yKHBsYXllci5wb3NpdGlvbi54IC8gMTYpO1xuICAgICAgICAgICAgY29uc3QgcGxheWVyQ2h1bmtaID0gTWF0aC5mbG9vcihwbGF5ZXIucG9zaXRpb24ueiAvIDE2KTtcblxuICAgICAgICAgICAgZm9yIChsZXQgc2FtcGxlID0gMDsgc2FtcGxlIDwgY2h1bmtzUGVyQ3ljbGUgJiYgcmVtYWluaW5nID4gMDsgc2FtcGxlICs9IDEpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjaHVua1ggPSBwbGF5ZXJDaHVua1ggKyBiZXR3ZWVuKHRoaXMucmFuZG9tLCAtc3Bhd25SYWRpdXNDaHVua3MsIHNwYXduUmFkaXVzQ2h1bmtzKTtcbiAgICAgICAgICAgICAgICBjb25zdCBjaHVua1ogPSBwbGF5ZXJDaHVua1ogKyBiZXR3ZWVuKHRoaXMucmFuZG9tLCAtc3Bhd25SYWRpdXNDaHVua3MsIHNwYXduUmFkaXVzQ2h1bmtzKTtcblxuICAgICAgICAgICAgICAgIGZvciAobGV0IGF0dGVtcHQgPSAwOyBhdHRlbXB0IDwgcG9zaXRpb25zUGVyQ2h1bmsgJiYgcmVtYWluaW5nID4gMDsgYXR0ZW1wdCArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgcGFzcyBvZiBbJ3N1cmZhY2UnLCAndW5kZXJncm91bmQnXSBhcyBjb25zdCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlbWFpbmluZyA8PSAwKSBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHBvc2l0aW9uID0gdGhpcy5wb3NpdGlvbkluKGNodW5rWCwgY2h1bmtaLCBwYXNzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwb3NpdGlvbiA9PT0gdW5kZWZpbmVkKSBjb250aW51ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHNwYXduZWQgPSB0aGlzLmF0dGVtcHRBdChwb29sLCBydWxlcywgcG9zaXRpb24sIHBhc3MsIHRpY2ssIHJlbWFpbmluZyk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZW1haW5pbmcgLT0gc3Bhd25lZC5sZW5ndGg7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0cy5wdXNoKC4uLnNwYXduZWQpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlcXVlc3RzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIERyYXdzIG9uZSBwb3NpdGlvbiBpbnNpZGUgYSBjaHVuayBmb3Igb25lIHBhc3MuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBUaGUgcG9zaXRpb24sIG9yIHVuZGVmaW5lZCB3aGVuIHRoZSBjb2x1bW4gaXMgdW5sb2FkZWQgb3IgdGhlIGRyYXcgbGFuZGVkXG4gICAgICogICBzb21ld2hlcmUgbm8gZW50aXR5IGZpdHMuXG4gICAgICovXG4gICAgcHJpdmF0ZSBwb3NpdGlvbkluKGNodW5rWDogbnVtYmVyLCBjaHVua1o6IG51bWJlciwgcGFzczogU3Bhd25QYXNzKTogU3Bhd25Qb3NpdGlvbiB8IHVuZGVmaW5lZCB7XG4gICAgICAgIGNvbnN0IHggPSBjaHVua1ggKiAxNiArIHRoaXMucmFuZG9tLm5leHRJbnQoMTYpO1xuICAgICAgICBjb25zdCB6ID0gY2h1bmtaICogMTYgKyB0aGlzLnJhbmRvbS5uZXh0SW50KDE2KTtcbiAgICAgICAgaWYgKHBhc3MgPT09ICdzdXJmYWNlJykgcmV0dXJuIHRoaXMuc3VyZmFjZVBvc2l0aW9uKHgsIHopO1xuXG4gICAgICAgIGNvbnN0IHRvcCA9IHRoaXMud29ybGQuc3VyZmFjZVkoeCwgeik7XG4gICAgICAgIGlmICh0b3AgPT09IHVuZGVmaW5lZCkgcmV0dXJuIHVuZGVmaW5lZDtcblxuICAgICAgICBjb25zdCBmbG9vciA9IHRoaXMud29ybGQubWluWSgpO1xuICAgICAgICBpZiAodG9wIC0gMSA8IGZsb29yKSByZXR1cm4gdW5kZWZpbmVkO1xuXG4gICAgICAgIC8vIFRoZSBkcmF3IGlzIHVuaWZvcm0gb3ZlciB0aGUgY29sdW1uLCBzbyBpbiBhIHdvcmxkIHdpdGggZmV3IGNhdmVzIG1vc3Qgb2YgaXQgaXNcbiAgICAgICAgLy8gaW5zaWRlIHJvY2suIE9uZSBhdHRlbXB0LCBvbmUgZHJhdywgdGhlIHdheSBKYXZhJ3MgYE5hdHVyYWxTcGF3bmVyYCByZWplY3RzIGFcbiAgICAgICAgLy8gcG9zaXRpb24gcmF0aGVyIHRoYW4gc2VhcmNoaW5nIGZvciBhIGJldHRlciBvbmU6IGEgc3Bhd24gaW5zaWRlIGEgYmxvY2sgaXMgYSBtb2JcbiAgICAgICAgLy8gdGhhdCBjYW4gcGF0aCBub3doZXJlLCBuZXZlciBkZXNwYXducyBhbmQgZmlsbHMgdGhlIHBvb2wgc28gbm90aGluZyBlbHNlIGNhbiBzcGF3bi5cbiAgICAgICAgY29uc3QgYXQgPSB7IHgsIHk6IGJldHdlZW4odGhpcy5yYW5kb20sIGZsb29yLCB0b3AgLSAxKSwgeiB9O1xuICAgICAgICByZXR1cm4gdGhpcy5maXRzKGF0KSA/IGF0IDogdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIC8qKiBUaGUgdG9wIHNwYXduIHBvc2l0aW9uIGluIGEgY29sdW1uLCB1c2luZyB0aGUgd2F0ZXIgc3VyZmFjZSB3aGVuIG9uZSBjb3ZlcnMgdGhlIHRlcnJhaW4uICovXG4gICAgcHJpdmF0ZSBzdXJmYWNlUG9zaXRpb24oeDogbnVtYmVyLCB6OiBudW1iZXIpOiBTcGF3blBvc2l0aW9uIHwgdW5kZWZpbmVkIHtcbiAgICAgICAgY29uc3QgdG9wID0gdGhpcy53b3JsZC5zdXJmYWNlWSh4LCB6KTtcbiAgICAgICAgaWYgKHRvcCA9PT0gdW5kZWZpbmVkKSByZXR1cm4gdW5kZWZpbmVkO1xuXG4gICAgICAgIGNvbnN0IHN1cmZhY2UgPSB7IHgsIHk6IHRvcCwgeiB9O1xuICAgICAgICBpZiAodGhpcy53b3JsZC5zaXRlKCd1bmRlcndhdGVyJywgc3VyZmFjZSkpIHJldHVybiBzdXJmYWNlO1xuXG4gICAgICAgIC8vIEEgaGVpZ2h0IG1hcCB0aGF0IGNvdW50cyB3YXRlciBwdXRzIGl0cyBzdXJmYWNlIG9uZSBibG9jayBhYm92ZSB0aGUgZmx1aWQuIEZpc2ggcnVsZXNcbiAgICAgICAgLy8gYXNrIGZvciBib3RoIHRoZSBzdXJmYWNlIHBhc3MgYW5kIGFuIHVuZGVyd2F0ZXIgcG9zaXRpb24sIHNvIHNhbXBsZSB0aGUgdG9wIHdhdGVyXG4gICAgICAgIC8vIGJsb2NrIGluc3RlYWQgb2YgdGhlIGFpciBhYm92ZSBpdC5cbiAgICAgICAgY29uc3Qgd2F0ZXJTdXJmYWNlID0geyAuLi5zdXJmYWNlLCB5OiB0b3AgLSAxIH07XG4gICAgICAgIHJldHVybiB0aGlzLndvcmxkLnNpdGUoJ3VuZGVyd2F0ZXInLCB3YXRlclN1cmZhY2UpID8gd2F0ZXJTdXJmYWNlIDogc3VyZmFjZTtcbiAgICB9XG5cbiAgICAvKiogV2hldGhlciBhbiBlbnRpdHkgZml0cyBhdCBhIHBvc2l0aW9uOiBpdHMgb3duIGJsb2NrIGFuZCB0aGUgb25lIG92ZXIgaXRzIGhlYWQgYXJlIGZyZWUuICovXG4gICAgcHJpdmF0ZSBmaXRzKGF0OiBTcGF3blBvc2l0aW9uKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiAhdGhpcy53b3JsZC5zb2xpZChhdCkgJiYgIXRoaXMud29ybGQuc29saWQoeyAuLi5hdCwgeTogYXQueSArIDEgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUnVucyBvbmUgYXR0ZW1wdDogY29sbGVjdCB0aGUgcnVsZXMgdGhhdCBwYXNzIGhlcmUsIGRyYXcgb25lLCBhbmQgYnVpbGRcbiAgICAgKiBpdHMgaGVyZC5cbiAgICAgKlxuICAgICAqIEEgcnVsZSB3aXRoIGFuIGVuZ2luZSBjb25kaXRpb24gaXMgYXNrZWQgdGhhdCBmaXJzdCwgYmVjYXVzZSBhIGNvbmRpdGlvblxuICAgICAqIEJlZHJvY2sga2VlcHMgaW4gY29kZSBpcyBhIGNvbmRpdGlvbiB0aGUgZmlsZSB3YXMgbmV2ZXIgYWJsZSB0byBzdGF0ZS5cbiAgICAgKiBgbWluZWNyYWZ0OnNsaW1lYCBpcyB0aGUgcnVsZSB0aGlzIG1hdHRlcnMgdG86IGl0cyBmaWxlIG5hbWVzIG5vXG4gICAgICogYnJpZ2h0bmVzcyBhbmQgbm8gaGVpZ2h0LCBzbyB3aXRob3V0IHRoZSBlbmdpbmUgY29uZGl0aW9uIGl0IGlzIHRoZSBvbmx5XG4gICAgICogbW9uc3RlciB0aGF0IHBhc3NlcyBpbiBkYXlsaWdodCBhbmQgaXQgZmlsbHMgdGhlIHBvb2wgb24gaXRzIG93bi5cbiAgICAgKi9cbiAgICBwcml2YXRlIGF0dGVtcHRBdChcbiAgICAgICAgcG9vbDogc3RyaW5nLFxuICAgICAgICBydWxlczogcmVhZG9ubHkgU3Bhd25SdWxlW10sXG4gICAgICAgIHBvc2l0aW9uOiBTcGF3blBvc2l0aW9uLFxuICAgICAgICBwYXNzOiBTcGF3blBhc3MsXG4gICAgICAgIHRpY2s6IG51bWJlcixcbiAgICAgICAgcmVtYWluaW5nOiBudW1iZXJcbiAgICApOiByZWFkb25seSBTcGF3blJlcXVlc3RbXSB7XG4gICAgICAgIGNvbnN0IGNhbmRpZGF0ZXM6IENhbmRpZGF0ZVtdID0gW107XG4gICAgICAgIGxldCB0b3RhbFdlaWdodCA9IDA7XG5cbiAgICAgICAgZm9yIChjb25zdCBydWxlIG9mIHJ1bGVzKSB7XG4gICAgICAgICAgICBpZiAodGhpcy53b3JsZC5zdHJ1Y3R1cmVTcGF3bk92ZXJyaWRlQXQ/LihydWxlLmlkZW50aWZpZXIsIHBvc2l0aW9uKSA9PT0gZmFsc2UpIGNvbnRpbnVlO1xuXG4gICAgICAgICAgICBjb25zdCBlbmdpbmVSdWxlID0gdGhpcy5lbmdpbmVSdWxlcy5nZXQocnVsZS5pZGVudGlmaWVyKTtcbiAgICAgICAgICAgIGlmIChlbmdpbmVSdWxlICE9PSB1bmRlZmluZWQgJiYgIWVuZ2luZVJ1bGUocG9zaXRpb24sIHsgd29ybGQ6IHRoaXMud29ybGQsIHJhbmRvbTogdGhpcy5yYW5kb20gfSkpIGNvbnRpbnVlO1xuXG4gICAgICAgICAgICBmb3IgKGNvbnN0IGNvbmRpdGlvbiBvZiBydWxlLmNvbmRpdGlvbnMpIHtcbiAgICAgICAgICAgICAgICBpZiAoIWV2YWx1YXRlU3Bhd25Db25kaXRpb24oY29uZGl0aW9uLCBwb3NpdGlvbiwgdGhpcy5jb250ZXh0Rm9yKHJ1bGUsIHRpY2spLCBwYXNzKS5wYXNzZWQpIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIGNhbmRpZGF0ZXMucHVzaCh7IHJ1bGUsIGNvbmRpdGlvbiB9KTtcbiAgICAgICAgICAgICAgICB0b3RhbFdlaWdodCArPSBNYXRoLm1heCgwLCBjb25kaXRpb24ud2VpZ2h0LmRlZmF1bHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGNhbmRpZGF0ZXMubGVuZ3RoID09PSAwIHx8IHRvdGFsV2VpZ2h0IDw9IDApIHJldHVybiBbXTtcblxuICAgICAgICBsZXQgcm9sbCA9IHRoaXMucmFuZG9tLm5leHRGbG9hdCgpICogdG90YWxXZWlnaHQ7XG4gICAgICAgIGxldCBjaG9zZW4gPSBjYW5kaWRhdGVzW2NhbmRpZGF0ZXMubGVuZ3RoIC0gMV0hO1xuICAgICAgICBmb3IgKGNvbnN0IGNhbmRpZGF0ZSBvZiBjYW5kaWRhdGVzKSB7XG4gICAgICAgICAgICByb2xsIC09IE1hdGgubWF4KDAsIGNhbmRpZGF0ZS5jb25kaXRpb24ud2VpZ2h0LmRlZmF1bHQpO1xuICAgICAgICAgICAgaWYgKHJvbGwgPCAwKSB7XG4gICAgICAgICAgICAgICAgY2hvc2VuID0gY2FuZGlkYXRlO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gYHJhcml0eWAgaXMgZG9jdW1lbnRlZCBieSBuYW1lIG9ubHkuIFRoaXMgcHJvamVjdCByZWFkcyBpdCBhcyBhXG4gICAgICAgIC8vIG9uZS1pbi1OIHJvbGwgb24gdG9wIG9mIHRoZSB3ZWlnaHQsIHdoaWNoIGlzIHRoZSBvbmx5IHJlYWRpbmcgdGhhdFxuICAgICAgICAvLyBtYWtlcyBhIHJhcml0eSBvZiAyIG9yIDMgcmFyZXIgcmF0aGVyIHRoYW4gbW9yZSBjb21tb24uXG4gICAgICAgIGNvbnN0IHsgcmFyaXR5IH0gPSBjaG9zZW4uY29uZGl0aW9uLndlaWdodDtcbiAgICAgICAgaWYgKHJhcml0eSA+IDAgJiYgdGhpcy5yYW5kb20ubmV4dEZsb2F0KCkgKiByYXJpdHkgPj0gMSkgcmV0dXJuIFtdO1xuXG4gICAgICAgIGlmIChjaG9zZW4uY29uZGl0aW9uLmRlbGF5ICE9PSB1bmRlZmluZWQpIHRoaXMuZGVsYXlzLnNjaGVkdWxlRnJvbShjaG9zZW4uY29uZGl0aW9uLmRlbGF5LCB0aWNrLCB0aGlzLnJhbmRvbSk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuaGVyZEF0KHBvb2wsIGNob3NlbiwgcG9zaXRpb24sIHBhc3MsIHJlbWFpbmluZyk7XG4gICAgfVxuXG4gICAgLyoqIEJ1aWxkcyBvbmUgaGVyZCBhcm91bmQgYW4gYW5jaG9yIHBvc2l0aW9uLiAqL1xuICAgIHByaXZhdGUgaGVyZEF0KFxuICAgICAgICBwb29sOiBzdHJpbmcsXG4gICAgICAgIGNhbmRpZGF0ZTogQ2FuZGlkYXRlLFxuICAgICAgICBhbmNob3I6IFNwYXduUG9zaXRpb24sXG4gICAgICAgIHBhc3M6IFNwYXduUGFzcyxcbiAgICAgICAgcmVtYWluaW5nOiBudW1iZXJcbiAgICApOiByZWFkb25seSBTcGF3blJlcXVlc3RbXSB7XG4gICAgICAgIGNvbnN0IHsgY29uZGl0aW9uLCBydWxlIH0gPSBjYW5kaWRhdGU7XG4gICAgICAgIGNvbnN0IGhlcmQgPVxuICAgICAgICAgICAgY29uZGl0aW9uLmhlcmQubGVuZ3RoID09PSAwID8gdW5kZWZpbmVkIDogY29uZGl0aW9uLmhlcmRbdGhpcy5yYW5kb20ubmV4dEludChjb25kaXRpb24uaGVyZC5sZW5ndGgpXTtcbiAgICAgICAgY29uc3QgZHJhd24gPSBoZXJkID09PSB1bmRlZmluZWQgPyAxIDogYmV0d2Vlbih0aGlzLnJhbmRvbSwgaGVyZC5taW5TaXplLCBoZXJkLm1heFNpemUpO1xuICAgICAgICBjb25zdCBzaXplID0gTWF0aC5tYXgoMCwgTWF0aC5taW4oZHJhd24sIHJlbWFpbmluZykpO1xuICAgICAgICBpZiAoc2l6ZSA9PT0gMCkgcmV0dXJuIFtdO1xuXG4gICAgICAgIGNvbnN0IHBlcm11dGF0aW9ucyA9XG4gICAgICAgICAgICBjb25kaXRpb24ucGVybXV0YXRpb25zID09PSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICA/IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgIDogcGVybXV0YXRpb25zRm9yKGNvbmRpdGlvbi5wZXJtdXRhdGlvbnMsIHNpemUsIHRoaXMucmFuZG9tKTtcblxuICAgICAgICBjb25zdCByZXF1ZXN0czogU3Bhd25SZXF1ZXN0W10gPSBbXTtcbiAgICAgICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IHNpemU7IGluZGV4ICs9IDEpIHtcbiAgICAgICAgICAgIGNvbnN0IHBlcm11dGF0aW9uID0gcGVybXV0YXRpb25zPy5baW5kZXhdO1xuICAgICAgICAgICAgY29uc3Qgc3dhcHBlZCA9IHBlcm11dGF0aW9uPy5lbnRpdHlUeXBlID09PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiBzcGxpdFNwYXduVHlwZShwZXJtdXRhdGlvbi5lbnRpdHlUeXBlKTtcbiAgICAgICAgICAgIGNvbnN0IHBvc2l0aW9uID0gaW5kZXggPT09IDAgPyBhbmNob3IgOiB0aGlzLmhlcmRNZW1iZXJQb3NpdGlvbihhbmNob3IsIHBhc3MpO1xuICAgICAgICAgICAgY29uc3QgaWRlbnRpZmllciA9IHN3YXBwZWQ/LmlkZW50aWZpZXIgPz8gcnVsZS5pZGVudGlmaWVyO1xuICAgICAgICAgICAgaWYgKHRoaXMud29ybGQuc3RydWN0dXJlU3Bhd25PdmVycmlkZUF0Py4oaWRlbnRpZmllciwgcG9zaXRpb24pID09PSBmYWxzZSkgY29udGludWU7XG4gICAgICAgICAgICBjb25zdCBldmVudCA9IGV2ZW50Rm9yTWVtYmVyKGluZGV4LCBoZXJkLCBzd2FwcGVkPy5ldmVudCwgY29uZGl0aW9uKTtcblxuICAgICAgICAgICAgY29uc3QgcmVxdWVzdDogeyAtcmVhZG9ubHkgW0tleSBpbiBrZXlvZiBTcGF3blJlcXVlc3RdOiBTcGF3blJlcXVlc3RbS2V5XSB9ID0ge1xuICAgICAgICAgICAgICAgIGlkZW50aWZpZXIsXG4gICAgICAgICAgICAgICAgcG9zaXRpb24sXG4gICAgICAgICAgICAgICAgcG9vbCxcbiAgICAgICAgICAgICAgICBydWxlOiBydWxlLmlkZW50aWZpZXIsXG4gICAgICAgICAgICAgICAgcGFzc1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGlmIChldmVudCAhPT0gdW5kZWZpbmVkKSByZXF1ZXN0LnNwYXduRXZlbnQgPSBldmVudDtcbiAgICAgICAgICAgIHJlcXVlc3RzLnB1c2gocmVxdWVzdCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmVxdWVzdHM7XG4gICAgfVxuXG4gICAgLyoqIFBsYWNlcyBvbmUgaGVyZCBtZW1iZXIgYXJvdW5kIHRoZSBhbmNob3IsIGZvbGxvd2luZyB0aGUgdGVycmFpbiBvbiB0aGUgc3VyZmFjZSBwYXNzLiAqL1xuICAgIHByaXZhdGUgaGVyZE1lbWJlclBvc2l0aW9uKGFuY2hvcjogU3Bhd25Qb3NpdGlvbiwgcGFzczogU3Bhd25QYXNzKTogU3Bhd25Qb3NpdGlvbiB7XG4gICAgICAgIGNvbnN0IHJhZGl1cyA9IHRoaXMuY29uc3RhbnRzLmhlcmRSYWRpdXM7XG4gICAgICAgIGNvbnN0IHggPSBhbmNob3IueCArIGJldHdlZW4odGhpcy5yYW5kb20sIC1yYWRpdXMsIHJhZGl1cyk7XG4gICAgICAgIGNvbnN0IHogPSBhbmNob3IueiArIGJldHdlZW4odGhpcy5yYW5kb20sIC1yYWRpdXMsIHJhZGl1cyk7XG4gICAgICAgIGlmIChwYXNzICE9PSAnc3VyZmFjZScpIHJldHVybiB7IHgsIHk6IGFuY2hvci55LCB6IH07XG5cbiAgICAgICAgY29uc3QgcG9zaXRpb24gPSB0aGlzLnN1cmZhY2VQb3NpdGlvbih4LCB6KTtcbiAgICAgICAgaWYgKHBvc2l0aW9uID09PSB1bmRlZmluZWQpIHJldHVybiBhbmNob3I7XG4gICAgICAgIGlmICh0aGlzLndvcmxkLnNpdGUoJ3VuZGVyd2F0ZXInLCBhbmNob3IpICYmICF0aGlzLndvcmxkLnNpdGUoJ3VuZGVyd2F0ZXInLCBwb3NpdGlvbikpIHJldHVybiBhbmNob3I7XG4gICAgICAgIHJldHVybiBwb3NpdGlvbjtcbiAgICB9XG5cbiAgICBwcml2YXRlIGNvbnRleHRGb3IocnVsZTogU3Bhd25SdWxlLCB0aWNrOiBudW1iZXIpOiBTcGF3bkNvbmRpdGlvbkNvbnRleHQge1xuICAgICAgICBjb25zdCBjb250ZXh0OiB7IC1yZWFkb25seSBbS2V5IGluIGtleW9mIFNwYXduQ29uZGl0aW9uQ29udGV4dF06IFNwYXduQ29uZGl0aW9uQ29udGV4dFtLZXldIH0gPSB7XG4gICAgICAgICAgICB3b3JsZDogdGhpcy53b3JsZCxcbiAgICAgICAgICAgIGlkZW50aWZpZXI6IHJ1bGUuaWRlbnRpZmllcixcbiAgICAgICAgICAgIHJhbmRvbTogdGhpcy5yYW5kb20sXG4gICAgICAgICAgICB0aWNrLFxuICAgICAgICAgICAgY29uc3RhbnRzOiB0aGlzLmNvbnN0YW50cyxcbiAgICAgICAgICAgIGRlbGF5czogdGhpcy5kZWxheXNcbiAgICAgICAgfTtcbiAgICAgICAgaWYgKHRoaXMub25VbmFuc3dlcmVkICE9PSB1bmRlZmluZWQpIGNvbnRleHQub25VbmFuc3dlcmVkID0gdGhpcy5vblVuYW5zd2VyZWQ7XG4gICAgICAgIHJldHVybiBjb250ZXh0O1xuICAgIH1cbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQW1FQSxJQUFNLGtCQUFrQixVQUE0RTtDQUNoRyxNQUFNLFFBQVEsMENBQTBDLEtBQUssS0FBSztDQUNsRSxJQUFJLE9BQU8sV0FBVyxLQUFBLEdBQVcsT0FBTyxFQUFFLFlBQVksTUFBTTtDQUM1RCxPQUFPO0VBQUUsWUFBWSxNQUFNLE9BQU87RUFBYSxPQUFPLE1BQU0sT0FBTztDQUFPO0FBQzlFOztBQUdBLElBQU0sV0FBVyxRQUFzQixLQUFhLFFBQ2hELE9BQU8sTUFBTSxNQUFNLE1BQU0sT0FBTyxRQUFRLE1BQU0sTUFBTSxDQUFDOzs7Ozs7OztBQVN6RCxJQUFNLG1CQUNGLGNBQ0EsTUFDQSxXQUM0QztDQUM1QyxNQUFNLFVBQTRDLENBQUM7Q0FDbkQsS0FBSyxNQUFNLGVBQWUsY0FDdEIsS0FBSyxJQUFJLFFBQVEsR0FBRyxRQUFRLFlBQVksaUJBQWlCLFFBQVEsU0FBUyxNQUFNLFNBQVMsR0FDckYsUUFBUSxLQUFLLFdBQVc7Q0FHaEMsTUFBTSxRQUFRLGFBQWEsUUFBUSxLQUFLLGdCQUFnQixNQUFNLEtBQUssSUFBSSxHQUFHLFlBQVksTUFBTSxHQUFHLENBQUM7Q0FDaEcsT0FBTyxRQUFRLFNBQVMsTUFBTTtFQUMxQixJQUFJLFNBQVMsR0FBRztHQUNaLFFBQVEsS0FBSyxLQUFBLENBQVM7R0FDdEI7RUFDSjtFQUNBLElBQUksT0FBTyxPQUFPLFVBQVUsSUFBSTtFQUNoQyxJQUFJO0VBQ0osS0FBSyxNQUFNLGVBQWUsY0FBYztHQUNwQyxRQUFRLEtBQUssSUFBSSxHQUFHLFlBQVksTUFBTTtHQUN0QyxJQUFJLE9BQU8sR0FBRztJQUNWLFNBQVM7SUFDVDtHQUNKO0VBQ0o7RUFDQSxRQUFRLEtBQUssVUFBVSxhQUFhLGFBQWEsU0FBUyxFQUFFO0NBQ2hFO0NBRUEsT0FBTztBQUNYOzs7Ozs7OztBQVNBLElBQU0sa0JBQ0YsT0FDQSxNQUNBLGtCQUNBLGNBQ3FCO0NBQ3JCLElBQUksTUFBTSxpQkFBaUIsS0FBQSxLQUFhLFFBQVEsS0FBSyxtQkFBbUIsT0FBTyxLQUFLO0NBQ3BGLElBQUksTUFBTSxVQUFVLEtBQUEsS0FBYSxTQUFTLEtBQUssZ0JBQWdCLE9BQU8sS0FBSztDQUMzRSxPQUFPLG9CQUFvQixVQUFVO0FBQ3pDOztBQUdBLElBQWEsVUFBYixNQUFxQjtDQUNqQiw4QkFBK0IsSUFBSSxJQUF5QjtDQUM1RDtDQUNBO0NBQ0E7Q0FDQTtDQUNBO0NBQ0E7Q0FFQSxZQUFtQixTQUF5QjtFQUN4QyxLQUFLLFFBQVEsUUFBUTtFQUNyQixLQUFLLFNBQVMsUUFBUTtFQUN0QixLQUFLLFlBQVksUUFBUSxhQUFhQSxrQkFBQUE7RUFDdEMsS0FBSyxTQUFTLFFBQVEsVUFBVSxJQUFJQyxtQkFBQUEsWUFBWTtFQUNoRCxLQUFLLGNBQWMsUUFBUSxlQUFlQyxvQkFBQUE7RUFDMUMsS0FBSyxlQUFlLFFBQVE7RUFFNUIsS0FBSyxNQUFNLFFBQVEsUUFBUSxPQUFPO0dBQzlCLE1BQU0sT0FBTyxLQUFLO0dBQ2xCLElBQUksU0FBUyxLQUFBLEdBQVc7R0FDeEIsTUFBTSxXQUFXLEtBQUssWUFBWSxJQUFJLElBQUk7R0FDMUMsSUFBSSxhQUFhLEtBQUEsR0FBVyxLQUFLLFlBQVksSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDO1FBQ3hELFNBQVMsS0FBSyxJQUFJO0VBQzNCO0NBQ0o7O0NBR0EsSUFBVyxRQUEyQjtFQUNsQyxPQUFPLENBQUMsR0FBRyxLQUFLLFlBQVksS0FBSyxDQUFDO0NBQ3RDOzs7Ozs7Q0FPQSxLQUFZLE1BQXVDO0VBQy9DLE1BQU0sV0FBMkIsQ0FBQztFQUNsQyxLQUFLLE1BQU0sUUFBUSxLQUFLLFlBQVksS0FBSyxHQUFHO0dBQ3hDLE1BQU0sVUFBVSxLQUFLLFVBQVUsTUFBTSxLQUFLLEVBQUU7R0FDNUMsSUFBSSxZQUFZLEtBQUEsS0FBYSxXQUFXLEtBQUssT0FBTyxZQUFZLEdBQUc7R0FDbkUsU0FBUyxLQUFLLEdBQUcsS0FBSyxNQUFNLE1BQU0sSUFBSSxDQUFDO0VBQzNDO0VBQ0EsT0FBTztDQUNYOzs7Ozs7Q0FPQSxNQUFhLE1BQWMsTUFBdUM7RUFDOUQsTUFBTSxRQUFRLEtBQUssWUFBWSxJQUFJLElBQUk7RUFDdkMsSUFBSSxVQUFVLEtBQUEsS0FBYSxNQUFNLFdBQVcsR0FBRyxPQUFPLENBQUM7RUFFdkQsTUFBTSxVQUFVLEtBQUssTUFBTSxRQUFRO0VBQ25DLElBQUksUUFBUSxXQUFXLEdBQUcsT0FBTyxDQUFDO0VBRWxDLE1BQU0sTUFBTUMsa0JBQUFBLFdBQVcsTUFBTSxRQUFRLFFBQVEsS0FBSyxTQUFTO0VBQzNELElBQUksWUFBWSxRQUFRLEtBQUEsSUFBWSxPQUFPLG9CQUFvQixNQUFNLEtBQUssTUFBTSxVQUFVLElBQUk7RUFDOUYsSUFBSSxhQUFhLEdBQUcsT0FBTyxDQUFDO0VBRTVCLE1BQU0sV0FBMkIsQ0FBQztFQUNsQyxNQUFNLEVBQUUsbUJBQW1CLGdCQUFnQixzQkFBc0IsS0FBSztFQUV0RSxLQUFLLE1BQU0sVUFBVSxTQUFTO0dBQzFCLE1BQU0sZUFBZSxLQUFLLE1BQU0sT0FBTyxTQUFTLElBQUksRUFBRTtHQUN0RCxNQUFNLGVBQWUsS0FBSyxNQUFNLE9BQU8sU0FBUyxJQUFJLEVBQUU7R0FFdEQsS0FBSyxJQUFJLFNBQVMsR0FBRyxTQUFTLGtCQUFrQixZQUFZLEdBQUcsVUFBVSxHQUFHO0lBQ3hFLE1BQU0sU0FBUyxlQUFlLFFBQVEsS0FBSyxRQUFRLENBQUMsbUJBQW1CLGlCQUFpQjtJQUN4RixNQUFNLFNBQVMsZUFBZSxRQUFRLEtBQUssUUFBUSxDQUFDLG1CQUFtQixpQkFBaUI7SUFFeEYsS0FBSyxJQUFJLFVBQVUsR0FBRyxVQUFVLHFCQUFxQixZQUFZLEdBQUcsV0FBVyxHQUMzRSxLQUFLLE1BQU0sUUFBUSxDQUFDLFdBQVcsYUFBYSxHQUFZO0tBQ3BELElBQUksYUFBYSxHQUFHO0tBQ3BCLE1BQU0sV0FBVyxLQUFLLFdBQVcsUUFBUSxRQUFRLElBQUk7S0FDckQsSUFBSSxhQUFhLEtBQUEsR0FBVztLQUM1QixNQUFNLFVBQVUsS0FBSyxVQUFVLE1BQU0sT0FBTyxVQUFVLE1BQU0sTUFBTSxTQUFTO0tBQzNFLGFBQWEsUUFBUTtLQUNyQixTQUFTLEtBQUssR0FBRyxPQUFPO0lBQzVCO0dBRVI7RUFDSjtFQUVBLE9BQU87Q0FDWDs7Ozs7OztDQVFBLFdBQW1CLFFBQWdCLFFBQWdCLE1BQTRDO0VBQzNGLE1BQU0sSUFBSSxTQUFTLEtBQUssS0FBSyxPQUFPLFFBQVEsRUFBRTtFQUM5QyxNQUFNLElBQUksU0FBUyxLQUFLLEtBQUssT0FBTyxRQUFRLEVBQUU7RUFDOUMsSUFBSSxTQUFTLFdBQVcsT0FBTyxLQUFLLGdCQUFnQixHQUFHLENBQUM7RUFFeEQsTUFBTSxNQUFNLEtBQUssTUFBTSxTQUFTLEdBQUcsQ0FBQztFQUNwQyxJQUFJLFFBQVEsS0FBQSxHQUFXLE9BQU8sS0FBQTtFQUU5QixNQUFNLFFBQVEsS0FBSyxNQUFNLEtBQUs7RUFDOUIsSUFBSSxNQUFNLElBQUksT0FBTyxPQUFPLEtBQUE7RUFNNUIsTUFBTSxLQUFLO0dBQUU7R0FBRyxHQUFHLFFBQVEsS0FBSyxRQUFRLE9BQU8sTUFBTSxDQUFDO0dBQUc7RUFBRTtFQUMzRCxPQUFPLEtBQUssS0FBSyxFQUFFLElBQUksS0FBSyxLQUFBO0NBQ2hDOztDQUdBLGdCQUF3QixHQUFXLEdBQXNDO0VBQ3JFLE1BQU0sTUFBTSxLQUFLLE1BQU0sU0FBUyxHQUFHLENBQUM7RUFDcEMsSUFBSSxRQUFRLEtBQUEsR0FBVyxPQUFPLEtBQUE7RUFFOUIsTUFBTSxVQUFVO0dBQUU7R0FBRyxHQUFHO0dBQUs7RUFBRTtFQUMvQixJQUFJLEtBQUssTUFBTSxLQUFLLGNBQWMsT0FBTyxHQUFHLE9BQU87RUFLbkQsTUFBTSxlQUFlO0dBQUUsR0FBRztHQUFTLEdBQUcsTUFBTTtFQUFFO0VBQzlDLE9BQU8sS0FBSyxNQUFNLEtBQUssY0FBYyxZQUFZLElBQUksZUFBZTtDQUN4RTs7Q0FHQSxLQUFhLElBQTRCO0VBQ3JDLE9BQU8sQ0FBQyxLQUFLLE1BQU0sTUFBTSxFQUFFLEtBQUssQ0FBQyxLQUFLLE1BQU0sTUFBTTtHQUFFLEdBQUc7R0FBSSxHQUFHLEdBQUcsSUFBSTtFQUFFLENBQUM7Q0FDNUU7Ozs7Ozs7Ozs7O0NBWUEsVUFDSSxNQUNBLE9BQ0EsVUFDQSxNQUNBLE1BQ0EsV0FDdUI7RUFDdkIsTUFBTSxhQUEwQixDQUFDO0VBQ2pDLElBQUksY0FBYztFQUVsQixLQUFLLE1BQU0sUUFBUSxPQUFPO0dBQ3RCLElBQUksS0FBSyxNQUFNLDJCQUEyQixLQUFLLFlBQVksUUFBUSxNQUFNLE9BQU87R0FFaEYsTUFBTSxhQUFhLEtBQUssWUFBWSxJQUFJLEtBQUssVUFBVTtHQUN2RCxJQUFJLGVBQWUsS0FBQSxLQUFhLENBQUMsV0FBVyxVQUFVO0lBQUUsT0FBTyxLQUFLO0lBQU8sUUFBUSxLQUFLO0dBQU8sQ0FBQyxHQUFHO0dBRW5HLEtBQUssTUFBTSxhQUFhLEtBQUssWUFBWTtJQUNyQyxJQUFJLENBQUNDLG1CQUFBQSx1QkFBdUIsV0FBVyxVQUFVLEtBQUssV0FBVyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsQ0FBQyxRQUFRO0lBQzVGLFdBQVcsS0FBSztLQUFFO0tBQU07SUFBVSxDQUFDO0lBQ25DLGVBQWUsS0FBSyxJQUFJLEdBQUcsVUFBVSxPQUFPLE9BQU87R0FDdkQ7RUFDSjtFQUVBLElBQUksV0FBVyxXQUFXLEtBQUssZUFBZSxHQUFHLE9BQU8sQ0FBQztFQUV6RCxJQUFJLE9BQU8sS0FBSyxPQUFPLFVBQVUsSUFBSTtFQUNyQyxJQUFJLFNBQVMsV0FBVyxXQUFXLFNBQVM7RUFDNUMsS0FBSyxNQUFNLGFBQWEsWUFBWTtHQUNoQyxRQUFRLEtBQUssSUFBSSxHQUFHLFVBQVUsVUFBVSxPQUFPLE9BQU87R0FDdEQsSUFBSSxPQUFPLEdBQUc7SUFDVixTQUFTO0lBQ1Q7R0FDSjtFQUNKO0VBS0EsTUFBTSxFQUFFLFdBQVcsT0FBTyxVQUFVO0VBQ3BDLElBQUksU0FBUyxLQUFLLEtBQUssT0FBTyxVQUFVLElBQUksVUFBVSxHQUFHLE9BQU8sQ0FBQztFQUVqRSxJQUFJLE9BQU8sVUFBVSxVQUFVLEtBQUEsR0FBVyxLQUFLLE9BQU8sYUFBYSxPQUFPLFVBQVUsT0FBTyxNQUFNLEtBQUssTUFBTTtFQUU1RyxPQUFPLEtBQUssT0FBTyxNQUFNLFFBQVEsVUFBVSxNQUFNLFNBQVM7Q0FDOUQ7O0NBR0EsT0FDSSxNQUNBLFdBQ0EsUUFDQSxNQUNBLFdBQ3VCO0VBQ3ZCLE1BQU0sRUFBRSxXQUFXLFNBQVM7RUFDNUIsTUFBTSxPQUNGLFVBQVUsS0FBSyxXQUFXLElBQUksS0FBQSxJQUFZLFVBQVUsS0FBSyxLQUFLLE9BQU8sUUFBUSxVQUFVLEtBQUssTUFBTTtFQUN0RyxNQUFNLFFBQVEsU0FBUyxLQUFBLElBQVksSUFBSSxRQUFRLEtBQUssUUFBUSxLQUFLLFNBQVMsS0FBSyxPQUFPO0VBQ3RGLE1BQU0sT0FBTyxLQUFLLElBQUksR0FBRyxLQUFLLElBQUksT0FBTyxTQUFTLENBQUM7RUFDbkQsSUFBSSxTQUFTLEdBQUcsT0FBTyxDQUFDO0VBRXhCLE1BQU0sZUFDRixVQUFVLGlCQUFpQixLQUFBLElBQ3JCLEtBQUEsSUFDQSxnQkFBZ0IsVUFBVSxjQUFjLE1BQU0sS0FBSyxNQUFNO0VBRW5FLE1BQU0sV0FBMkIsQ0FBQztFQUNsQyxLQUFLLElBQUksUUFBUSxHQUFHLFFBQVEsTUFBTSxTQUFTLEdBQUc7R0FDMUMsTUFBTSxjQUFjLGVBQWU7R0FDbkMsTUFBTSxVQUFVLGFBQWEsZUFBZSxLQUFBLElBQVksS0FBQSxJQUFZLGVBQWUsWUFBWSxVQUFVO0dBQ3pHLE1BQU0sV0FBVyxVQUFVLElBQUksU0FBUyxLQUFLLG1CQUFtQixRQUFRLElBQUk7R0FDNUUsTUFBTSxhQUFhLFNBQVMsY0FBYyxLQUFLO0dBQy9DLElBQUksS0FBSyxNQUFNLDJCQUEyQixZQUFZLFFBQVEsTUFBTSxPQUFPO0dBQzNFLE1BQU0sUUFBUSxlQUFlLE9BQU8sTUFBTSxTQUFTLE9BQU8sU0FBUztHQUVuRSxNQUFNLFVBQXdFO0lBQzFFO0lBQ0E7SUFDQTtJQUNBLE1BQU0sS0FBSztJQUNYO0dBQ0o7R0FDQSxJQUFJLFVBQVUsS0FBQSxHQUFXLFFBQVEsYUFBYTtHQUM5QyxTQUFTLEtBQUssT0FBTztFQUN6QjtFQUVBLE9BQU87Q0FDWDs7Q0FHQSxtQkFBMkIsUUFBdUIsTUFBZ0M7RUFDOUUsTUFBTSxTQUFTLEtBQUssVUFBVTtFQUM5QixNQUFNLElBQUksT0FBTyxJQUFJLFFBQVEsS0FBSyxRQUFRLENBQUMsUUFBUSxNQUFNO0VBQ3pELE1BQU0sSUFBSSxPQUFPLElBQUksUUFBUSxLQUFLLFFBQVEsQ0FBQyxRQUFRLE1BQU07RUFDekQsSUFBSSxTQUFTLFdBQVcsT0FBTztHQUFFO0dBQUcsR0FBRyxPQUFPO0dBQUc7RUFBRTtFQUVuRCxNQUFNLFdBQVcsS0FBSyxnQkFBZ0IsR0FBRyxDQUFDO0VBQzFDLElBQUksYUFBYSxLQUFBLEdBQVcsT0FBTztFQUNuQyxJQUFJLEtBQUssTUFBTSxLQUFLLGNBQWMsTUFBTSxLQUFLLENBQUMsS0FBSyxNQUFNLEtBQUssY0FBYyxRQUFRLEdBQUcsT0FBTztFQUM5RixPQUFPO0NBQ1g7Q0FFQSxXQUFtQixNQUFpQixNQUFxQztFQUNyRSxNQUFNLFVBQTBGO0dBQzVGLE9BQU8sS0FBSztHQUNaLFlBQVksS0FBSztHQUNqQixRQUFRLEtBQUs7R0FDYjtHQUNBLFdBQVcsS0FBSztHQUNoQixRQUFRLEtBQUs7RUFDakI7RUFDQSxJQUFJLEtBQUssaUJBQWlCLEtBQUEsR0FBVyxRQUFRLGVBQWUsS0FBSztFQUNqRSxPQUFPO0NBQ1g7QUFDSiJ9
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import type { EvaluateFilterOptions } from '@jsprismarine/entities';
|
|
2
|
+
import type { RandomSource } from '@jsprismarine/predicates';
|
|
3
|
+
import { SpawnDelays } from './conditions';
|
|
4
|
+
import type { SpawnConstants } from './constants';
|
|
5
|
+
import type { EngineSpawnRule } from './engineRules';
|
|
6
|
+
import type { SpawnRule } from './rules';
|
|
7
|
+
import type { SpawnPass, SpawnPosition, SpawnWorld } from './world';
|
|
8
|
+
/**
|
|
9
|
+
* The spawn loop.
|
|
10
|
+
*
|
|
11
|
+
* Mojang's spawn cycle diagram names six steps, "check spawn conditions, find
|
|
12
|
+
* valid spawn locations, check population caps, evaluate spawn weight, spawn
|
|
13
|
+
* entity, and run spawn event", and publishes no number behind any of them.
|
|
14
|
+
* This loop implements those six steps over the constants in
|
|
15
|
+
* `src/tables/spawnConstants.json`, and every draw goes through an injected
|
|
16
|
+
* {@link RandomSource}, so one seed reproduces one set of spawns.
|
|
17
|
+
*
|
|
18
|
+
* One cycle of one pool samples `chunksPerCycle` chunks around each player,
|
|
19
|
+
* tries `positionsPerChunk` positions in each chunk for the surface pass and
|
|
20
|
+
* the same number for the underground pass, and at each position draws one of
|
|
21
|
+
* the conditions that passed, weighted by `minecraft:weight`.
|
|
22
|
+
*/
|
|
23
|
+
/** One entity the spawner asks the server to create. */
|
|
24
|
+
export interface SpawnRequest {
|
|
25
|
+
/** The entity type, with any `<event>` suffix already split off. */
|
|
26
|
+
readonly identifier: string;
|
|
27
|
+
/** The event to run instead of `minecraft:entity_spawned`, when the rule names one. */
|
|
28
|
+
readonly spawnEvent?: string;
|
|
29
|
+
readonly position: SpawnPosition;
|
|
30
|
+
/** The pool whose cap this spawn counts against. */
|
|
31
|
+
readonly pool: string;
|
|
32
|
+
/** The rule that produced the spawn, which is the identifier of its file. */
|
|
33
|
+
readonly rule: string;
|
|
34
|
+
readonly pass: SpawnPass;
|
|
35
|
+
}
|
|
36
|
+
/** How to build a {@link Spawner}. */
|
|
37
|
+
export interface SpawnerOptions {
|
|
38
|
+
readonly rules: Iterable<SpawnRule>;
|
|
39
|
+
readonly world: SpawnWorld;
|
|
40
|
+
readonly random: RandomSource;
|
|
41
|
+
readonly constants?: SpawnConstants;
|
|
42
|
+
/** The `minecraft:delay_filter` cooldowns, so a caller can persist them across a restart. */
|
|
43
|
+
readonly delays?: SpawnDelays;
|
|
44
|
+
/**
|
|
45
|
+
* The conditions Bedrock keeps in engine code, keyed by the entity each
|
|
46
|
+
* one gates. Defaults to {@link VANILLA_ENGINE_SPAWN_RULES}; pass an empty
|
|
47
|
+
* map to run the JSON conditions alone.
|
|
48
|
+
*/
|
|
49
|
+
readonly engineRules?: ReadonlyMap<string, EngineSpawnRule>;
|
|
50
|
+
/** Receives every biome filter test the evaluator could not answer. */
|
|
51
|
+
readonly onUnanswered?: EvaluateFilterOptions['onUnanswered'];
|
|
52
|
+
}
|
|
53
|
+
/** Runs the spawn loop for one world. */
|
|
54
|
+
export declare class Spawner {
|
|
55
|
+
private readonly rulesByPool;
|
|
56
|
+
private readonly world;
|
|
57
|
+
private readonly random;
|
|
58
|
+
private readonly constants;
|
|
59
|
+
private readonly delays;
|
|
60
|
+
private readonly engineRules;
|
|
61
|
+
private readonly onUnanswered;
|
|
62
|
+
constructor(options: SpawnerOptions);
|
|
63
|
+
/** The pools the loaded rules name, which is what {@link tick} cycles. */
|
|
64
|
+
get pools(): readonly string[];
|
|
65
|
+
/**
|
|
66
|
+
* Runs every pool whose cadence falls on this tick.
|
|
67
|
+
*
|
|
68
|
+
* @returns Every entity to create, in the order the cycles produced them.
|
|
69
|
+
*/
|
|
70
|
+
tick(tick: number): readonly SpawnRequest[];
|
|
71
|
+
/**
|
|
72
|
+
* Runs one cycle of one pool, whatever the cadence says.
|
|
73
|
+
*
|
|
74
|
+
* @returns Every entity to create, never more than the pool's remaining cap.
|
|
75
|
+
*/
|
|
76
|
+
cycle(pool: string, tick: number): readonly SpawnRequest[];
|
|
77
|
+
/**
|
|
78
|
+
* Draws one position inside a chunk for one pass.
|
|
79
|
+
*
|
|
80
|
+
* @returns The position, or undefined when the column is unloaded or the draw landed
|
|
81
|
+
* somewhere no entity fits.
|
|
82
|
+
*/
|
|
83
|
+
private positionIn;
|
|
84
|
+
/** The top spawn position in a column, using the water surface when one covers the terrain. */
|
|
85
|
+
private surfacePosition;
|
|
86
|
+
/** Whether an entity fits at a position: its own block and the one over its head are free. */
|
|
87
|
+
private fits;
|
|
88
|
+
/**
|
|
89
|
+
* Runs one attempt: collect the rules that pass here, draw one, and build
|
|
90
|
+
* its herd.
|
|
91
|
+
*
|
|
92
|
+
* A rule with an engine condition is asked that first, because a condition
|
|
93
|
+
* Bedrock keeps in code is a condition the file was never able to state.
|
|
94
|
+
* `minecraft:slime` is the rule this matters to: its file names no
|
|
95
|
+
* brightness and no height, so without the engine condition it is the only
|
|
96
|
+
* monster that passes in daylight and it fills the pool on its own.
|
|
97
|
+
*/
|
|
98
|
+
private attemptAt;
|
|
99
|
+
/** Builds one herd around an anchor position. */
|
|
100
|
+
private herdAt;
|
|
101
|
+
/** Places one herd member around the anchor, following the terrain on the surface pass. */
|
|
102
|
+
private herdMemberPosition;
|
|
103
|
+
private contextFor;
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=spawner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spawner.d.ts","sourceRoot":"","sources":["../src/spawner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AACpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAG7D,OAAO,EAAE,WAAW,EAA0B,MAAM,cAAc,CAAC;AACnE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAErD,OAAO,KAAK,EAA8C,SAAS,EAAE,MAAM,SAAS,CAAC;AACrF,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAEpE;;;;;;;;;;;;;;GAcG;AAEH,wDAAwD;AACxD,MAAM,WAAW,YAAY;IACzB,oEAAoE;IACpE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,uFAAuF;IACvF,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC,oDAAoD;IACpD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,6EAA6E;IAC7E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;CAC5B;AAED,sCAAsC;AACtC,MAAM,WAAW,cAAc;IAC3B,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC;IACpC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,SAAS,CAAC,EAAE,cAAc,CAAC;IACpC,6FAA6F;IAC7F,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAC9B;;;;OAIG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC5D,uEAAuE;IACvE,QAAQ,CAAC,YAAY,CAAC,EAAE,qBAAqB,CAAC,cAAc,CAAC,CAAC;CACjE;AA4ED,yCAAyC;AACzC,qBAAa,OAAO;IAChB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAkC;IAC9D,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAa;IACnC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;IACtC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAiB;IAC3C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;IACrC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAuC;IACnE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAoD;IAEjF,YAAmB,OAAO,EAAE,cAAc,EAezC;IAED,0EAA0E;IAC1E,IAAW,KAAK,IAAI,SAAS,MAAM,EAAE,CAEpC;IAED;;;;OAIG;IACI,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,YAAY,EAAE,CAQjD;IAED;;;;OAIG;IACI,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,YAAY,EAAE,CAoChE;IAED;;;;;OAKG;IACH,OAAO,CAAC,UAAU;IAmBlB,+FAA+F;IAC/F,OAAO,CAAC,eAAe;IAcvB,8FAA8F;IAC9F,OAAO,CAAC,IAAI;IAIZ;;;;;;;;;OASG;IACH,OAAO,CAAC,SAAS;IA+CjB,iDAAiD;IACjD,OAAO,CAAC,MAAM;IA0Cd,2FAA2F;IAC3F,OAAO,CAAC,kBAAkB;IAY1B,OAAO,CAAC,UAAU;CAYrB"}
|