@firestone-hs/replay-parser
Version:
This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 8.2.9.
438 lines • 73.5 kB
JavaScript
import { GameTag, MetaTags, Mulligan, Step } from '@firestone-hs/reference-data';
import { Map } from 'immutable';
import { SaxesParser } from 'saxes';
import { ActionHistoryItem } from '../models/history/action-history-item';
import { ChangeEntityHistoryItem } from '../models/history/change-entity-history-item';
import { ChoicesHistoryItem } from '../models/history/choices-history-item';
import { ChosenEntityHistoryItem } from '../models/history/chosen-entities-history-item';
import { FullEntityHistoryItem } from '../models/history/full-entity-history-item';
import { GameHistoryItem } from '../models/history/game-history-item';
import { HideEntityHistoryItem } from '../models/history/hide-entity-history-item';
import { MetadataHistoryItem } from '../models/history/metadata-history-item';
import { OptionsHistoryItem } from '../models/history/options-history-item';
import { PlayerHistoryItem } from '../models/history/player-history-item';
import { ShowEntityHistoryItem } from '../models/history/show-entity-history-item';
import { TagChangeHistoryItem } from '../models/history/tag-change-history-item';
// Don't inject it, because of the global state
export class XmlParserService {
constructor() { }
*parseXml(xmlAsString) {
this.reset();
if (!xmlAsString) {
console.error('[game-parser] [xml-parser] no xmlAsString provided');
return null;
}
// console.debug('[game-parser] [xml-parser] parsing', xmlAsString);
const saxesParser = new SaxesParser({
// fragment: true,
});
saxesParser.on('opentag', tag => this.onOpenTag(tag));
saxesParser.on('closetag', tag => this.onCloseTag());
// saxesParser.on('end', () => console.debug('parsing over'));
// saxesParser.on('error', error => console.error('Error while parsing xml', error));
// We want to have:
// - a chunk with pre-mulligan stuff, to setup the board
// - one chunk with both mulligans
// - one chunk for each turn
const mulliganSplits = xmlAsString.split(new RegExp(`(?=<TagChange.*tag="${GameTag.MULLIGAN_STATE}" value="${Mulligan.INPUT}".*/>)`));
// We isolate the pre-mulligan stuff
const [setupChunk, ...gameChunks] = mulliganSplits;
// console.debug('[game-parser] [xml-parser] setupChunk', setupChunk, gameChunks.length);
// Then the other chunks are handled only on a turn-by-turn basis
// This logic is here to handle the case where there is no mulligan info. It should usually not happen,
// but I've seen it at least once
const gameXml = gameChunks && gameChunks.length > 0 ? gameChunks.join('') : setupChunk;
// console.log('[game-parser] [xml-parser] gameXml', gameXml);
// https://stackoverflow.com/questions/12001953/javascript-and-regex-split-string-and-keep-the-separator
const chunks = gameXml.split(new RegExp(`(?=<TagChange.*tag="${GameTag.STEP}" value="${Step.MAIN_READY}".*/>)`));
// console.log('[game-parser] [xml-parser] chunks', chunks.length);
const splitChunks = gameChunks && gameChunks.length > 0 ? [setupChunk, ...chunks] : [...chunks];
for (const chunk of splitChunks) {
// console.log('[game-parser] [xml-parser] writing chunk', chunk.length);
saxesParser.write(chunk);
yield this.history;
this.history = [];
}
// console.log('[game-parser] [xml-parser] parsing over');
saxesParser.close();
return null;
}
onOpenTag(tag) {
this.stack.push(tag);
if (this[`${this.state[this.state.length - 1]}State`]) {
this[`${this.state[this.state.length - 1]}State`](tag);
}
}
onCloseTag() {
const tag = this.stack.pop();
if (this[`${this.state[this.state.length - 1]}StateClose`]) {
this[`${this.state[this.state.length - 1]}StateClose`](tag);
}
}
rootState(node) {
node.index = this.index++;
let name;
let ts;
switch (node.name) {
case 'Game':
this.initialTimestamp = this.tsToSeconds(node.attributes.ts);
this.timestamp = 0;
this.buildNumber = parseInt(node.attributes.buildNumber);
this.gameType = parseInt(node.attributes.gameType);
this.formatType = parseInt(node.attributes.formatType);
this.scenarioID = parseInt(node.attributes.scenarioID);
break;
case 'Action':
case 'Block':
ts = this.tsToSeconds(node.attributes.ts);
const item = new ActionHistoryItem(node, this.buildTimestamp(ts), node.index);
this.enqueueHistoryItem(item);
this.state.push('action');
break;
case 'ShowEntity':
let showEntities = this.stack[this.stack.length - 2].showEntities || [];
showEntities.push(this.entityDefinition);
this.stack[this.stack.length - 2].showEntities = showEntities;
/* falls through */
case 'Player':
// Remove the battle tag, if present
name =
node.attributes.name && node.attributes.name.indexOf('#') !== -1
? node.attributes.name.split('#')[0]
: node.attributes.name;
this.accountHi = node.attributes.accountHi;
this.accountLo = node.attributes.accountLo;
this.isMainPlayer = node.attributes.isMainPlayer;
/* falls through */
case 'GameEntity':
case 'FullEntity':
case 'ChangeEntity':
name = name || node.attributes.name;
this.state.push('entity');
const attributes = Object.assign({}, this.entityDefinition.attributes, {
ts: this.tsToSeconds(node.attributes.ts),
});
const newAttributes = {
id: parseInt(node.attributes.entity || node.attributes.id),
attributes,
index: this.index++,
cardID: node.attributes.cardID,
name,
tags: this.entityDefinition.tags,
playerID: parseInt(node.attributes.playerID),
};
Object.assign(this.entityDefinition, newAttributes);
break;
case 'TagChange':
const tag = {
index: this.index++,
entity: parseInt(node.attributes.entity),
tag: parseInt(node.attributes.tag),
value: parseInt(node.attributes.value),
parentIndex: this.stack[this.stack.length - 2].index,
};
let parentTags = this.stack[this.stack.length - 2].tags || [];
parentTags.push(tag);
this.stack[this.stack.length - 2].tags = parentTags;
const tagItem = new TagChangeHistoryItem(tag, this.buildTimestamp(ts), node.index);
this.enqueueHistoryItem(tagItem);
break;
case 'Options':
this.state.push('options');
break;
case 'ChosenEntities':
this.chosen = {
entity: parseInt(node.attributes.entity),
playerID: parseInt(node.attributes.playerID),
ts: this.tsToSeconds(node.attributes.ts),
cards: [],
index: this.index++,
};
this.state.push('chosenEntities');
break;
}
}
actionState(node) {
node.index = this.index++;
const ts = node.attributes.ts ? this.tsToSeconds(node.attributes.ts) : null;
switch (node.name) {
case 'ShowEntity':
case 'FullEntity':
case 'ChangeEntity':
this.state.push('entity');
const attributes = Object.assign({}, this.entityDefinition.attributes, {
ts: this.tsToSeconds(node.attributes.ts),
triggerKeyword: parseInt(node.attributes.triggerKeyword) || 0,
});
const newAttributes = {
id: parseInt(node.attributes.entity || node.attributes.id),
index: this.index++,
attributes,
cardID: node.attributes.cardID,
name: node.attributes.name,
tags: this.entityDefinition.tags,
playerID: parseInt(node.attributes.playerID),
parentIndex: this.stack[this.stack.length - 2].index,
};
Object.assign(this.entityDefinition, newAttributes);
if (node.name === 'ShowEntity') {
let showEntities = this.stack[this.stack.length - 2].showEntities || [];
showEntities.push(this.entityDefinition);
this.stack[this.stack.length - 2].showEntities = showEntities;
}
else if (node.name === 'FullEntity') {
let fullEntities = this.stack[this.stack.length - 2].fullEntities || [];
fullEntities.push(this.entityDefinition);
this.stack[this.stack.length - 2].fullEntities = fullEntities;
}
break;
case 'HideEntity':
const hideEntityHistoryItem = Object.assign(new HideEntityHistoryItem(this.index++, this.buildTimestamp(ts)), {
entity: parseInt(node.attributes.entity),
zone: parseInt(node.attributes.zone),
});
this.enqueueHistoryItem(hideEntityHistoryItem);
break;
case 'TagChange':
const tag = {
index: this.index++,
entity: parseInt(node.attributes.entity),
tag: parseInt(node.attributes.tag),
value: parseInt(node.attributes.value),
parentIndex: this.stack[this.stack.length - 2].index,
};
let parentTags = this.stack[this.stack.length - 2].tags || [];
parentTags.push(tag);
this.stack[this.stack.length - 2].tags = parentTags;
const tagItem = new TagChangeHistoryItem(tag, this.buildTimestamp(ts), node.index);
this.enqueueHistoryItem(tagItem);
break;
case 'MetaData':
this.metaData = {
meta: MetaTags[parseInt(node.attributes.meta || node.attributes.entity)],
data: parseInt(node.attributes.data),
parentIndex: this.stack[this.stack.length - 2].index,
ts,
info: [],
index: this.index++,
};
const metaItem = new MetadataHistoryItem(this.metaData, this.buildTimestamp(ts), node.index);
this.enqueueHistoryItem(metaItem);
let parentMeta = this.stack[this.stack.length - 2].meta || [];
parentMeta.push(this.metaData);
this.stack[this.stack.length - 2].meta = parentMeta;
this.state.push('metaData');
break;
case 'Action':
case 'Block':
node.parentIndex = this.stack[this.stack.length - 2].index;
this.state.push('action');
const item = new ActionHistoryItem(node, this.buildTimestamp(ts), node.index);
this.enqueueHistoryItem(item);
break;
case 'Choices':
this.choices = {
entity: parseInt(node.attributes.entity),
max: parseInt(node.attributes.max),
min: parseInt(node.attributes.min),
playerID: parseInt(node.attributes.playerID),
source: parseInt(node.attributes.source),
type: parseInt(node.attributes.type),
ts: this.tsToSeconds(node.attributes.ts),
index: this.index++,
cards: [],
};
this.state.push('choices');
break;
case 'ChosenEntities':
this.chosen = {
entity: parseInt(node.attributes.entity),
playerID: parseInt(node.attributes.playerID),
ts: this.tsToSeconds(node.attributes.ts),
cards: [],
index: this.index++,
};
this.state.push('chosenEntities');
break;
}
}
actionStateClose(node) {
switch (node.name) {
case 'Action':
case 'Block':
this.state.pop();
}
}
blockState(node) {
node.index = this.index++;
this.actionState(node);
}
blockStateClose(node) {
this.actionStateClose(node);
}
metaDataState(node) {
node.index = this.index++;
switch (node.name) {
case 'Info':
const info = {
entity: parseInt(node.attributes.id || node.attributes.entity),
parent: this.metaData,
};
let infos = this.metaData.info;
infos.push(info);
Object.assign(this.metaData, { info: infos });
break;
}
}
metaDataStateClose(node) {
switch (node.name) {
case 'MetaData':
this.state.pop();
}
}
chosenEntitiesState(node) {
node.index = this.index++;
switch (node.name) {
case 'Choice':
let cards = this.chosen.cards;
cards.push(parseInt(node.attributes.entity));
Object.assign(this.chosen, { cards });
}
}
chosenEntitiesStateClose(node) {
switch (node.name) {
case 'ChosenEntities':
this.state.pop();
const item = new ChosenEntityHistoryItem(this.chosen, this.buildTimestamp(this.chosen.ts), node.index);
this.enqueueHistoryItem(item);
}
}
optionsState(node) {
node.index = this.index++;
switch (node.name) {
case 'Option':
const option = {
entity: parseInt(node.attributes.entity),
optionIndex: parseInt(node.attributes.index),
error: parseInt(node.attributes.error),
type: parseInt(node.attributes.type),
parentIndex: this.stack[this.stack.length - 2].index,
index: this.index++,
};
let options = this.stack[this.stack.length - 2].options || [];
options.push(option);
this.stack[this.stack.length - 2].options = options;
}
}
optionsStateClose(node) {
switch (node.name) {
case 'Options':
this.state.pop();
const ts = this.tsToSeconds(node.attributes.ts);
const item = new OptionsHistoryItem(node, this.buildTimestamp(ts), node.index);
this.enqueueHistoryItem(item);
}
}
entityState(node) {
node.index = this.index++;
switch (node.name) {
case 'Tag':
const newTags = this.entityDefinition.tags.set(GameTag[parseInt(node.attributes.tag)], parseInt(node.attributes.value));
Object.assign(this.entityDefinition, { tags: newTags });
}
}
entityStateClose(node) {
const ts = node.attributes.ts ? this.tsToSeconds(node.attributes.ts) : null;
switch (node.name) {
case 'GameEntity':
this.state.pop();
const gameItem = Object.assign(new GameHistoryItem(this.entityDefinition, this.buildTimestamp(ts), node.index), {
buildNumber: this.buildNumber,
formatType: this.formatType,
gameType: this.gameType,
scenarioID: this.scenarioID,
});
this.enqueueHistoryItem(gameItem);
this.entityDefinition = { tags: Map([]) };
break;
case 'Player':
this.state.pop();
const playerItem = new PlayerHistoryItem(this.entityDefinition, this.accountHi, this.accountLo, this.isMainPlayer, this.buildTimestamp(ts), node.index);
this.enqueueHistoryItem(playerItem);
this.entityDefinition = { tags: Map([]) };
break;
case 'FullEntity':
this.state.pop();
const fullEntityItem = new FullEntityHistoryItem(this.entityDefinition, this.buildTimestamp(ts), node.index);
this.enqueueHistoryItem(fullEntityItem);
this.entityDefinition = { tags: Map([]) };
break;
case 'ShowEntity':
this.state.pop();
const showEntityItem = new ShowEntityHistoryItem(this.entityDefinition, this.buildTimestamp(ts), node.index);
this.enqueueHistoryItem(showEntityItem);
this.entityDefinition = { tags: Map([]) };
break;
case 'ChangeEntity':
this.state.pop();
const changeEntityItem = new ChangeEntityHistoryItem(this.entityDefinition, this.buildTimestamp(ts), node.index);
this.enqueueHistoryItem(changeEntityItem);
this.entityDefinition = { tags: Map([]) };
break;
}
}
choicesState(node) {
node.index = this.index++;
switch (node.name) {
case 'Choice':
let cards = this.choices.cards || [];
cards.push(parseInt(node.attributes.entity));
Object.assign(this.choices, { cards });
}
}
choicesStateClose(node) {
switch (node.name) {
case 'Choices':
this.state.pop();
const choicesItem = new ChoicesHistoryItem(this.choices, this.buildTimestamp(this.choices.ts), node.index);
this.enqueueHistoryItem(choicesItem);
}
}
buildTimestamp(ts) {
ts = ts || this.timestamp;
this.timestamp = ts;
return this.timestamp;
}
enqueueHistoryItem(item) {
if (item.timestamp === undefined) {
console.error("History item doesn't have timestamp", item);
throw new Error("History item doesn't have timestamp" + item);
}
this.history.push(item);
}
reset() {
this.stack = [];
this.state = ['root'];
this.index = 0;
this.initialTimestamp = undefined;
this.history = [];
this.entityDefinition = {
tags: Map([]),
};
this.choices = undefined;
this.chosen = undefined;
this.metaData = undefined;
this.timestamp = undefined;
}
tsToSeconds(ts) {
if (!ts) {
return undefined;
}
// Format of timestamp is HH:mm:ss.SSSSSSSSS
const tsWithoutMillis = ts.split('.')[0];
const split = tsWithoutMillis.split(':');
const tsInSeconds = parseInt(split[2]) + 60 * parseInt(split[1]) + 3600 * parseInt(split[0]);
return tsInSeconds - (this.initialTimestamp || 0);
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoieG1sLXBhcnNlci5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvcmVwbGF5LXBhcnNlci9zcmMvbGliL3NlcnZpY2VzL3htbC1wYXJzZXIuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFRLE1BQU0sOEJBQThCLENBQUM7QUFDdkYsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUNoQyxPQUFPLEVBQUUsV0FBVyxFQUFpQixNQUFNLE9BQU8sQ0FBQztBQUNuRCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx1Q0FBdUMsQ0FBQztBQUMxRSxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSw4Q0FBOEMsQ0FBQztBQUN2RixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSx3Q0FBd0MsQ0FBQztBQUM1RSxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSxnREFBZ0QsQ0FBQztBQUN6RixPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSw0Q0FBNEMsQ0FBQztBQUNuRixPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDdEUsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sNENBQTRDLENBQUM7QUFFbkYsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0seUNBQXlDLENBQUM7QUFDOUUsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sd0NBQXdDLENBQUM7QUFDNUUsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sdUNBQXVDLENBQUM7QUFDMUUsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sNENBQTRDLENBQUM7QUFDbkYsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sMkNBQTJDLENBQUM7QUFXakYsK0NBQStDO0FBQy9DLE1BQU0sT0FBTyxnQkFB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LEVBQVU7UUFDN0IsSUFBSSxDQUFDLEVBQUUsRUFBRTtZQUNSLE9BQU8sU0FBUyxDQUFDO1NBQ2pCO1FBQ0QsNENBQTRDO1FBQzVDLE1BQU0sZUFBZSxHQUFHLEVBQUUsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDekMsTUFBTSxLQUFLLEdBQUcsZUFBZSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUN6QyxNQUFNLFdBQVcsR0FBVyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3JHLE9BQU8sV0FBVyxHQUFHLENBQUMsSUFBSSxDQUFDLGdCQUFnQixJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQ25ELENBQUM7Q0FDRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEdhbWVUYWcsIE1ldGFUYWdzLCBNdWxsaWdhbiwgU3RlcCwgWm9uZSB9IGZyb20gJ0BmaXJlc3RvbmUtaHMvcmVmZXJlbmNlLWRhdGEnO1xyXG5pbXBvcnQgeyBNYXAgfSBmcm9tICdpbW11dGFibGUnO1xyXG5pbXBvcnQgeyBTYXhlc1BhcnNlciwgU2F4ZXNUYWdQbGFpbiB9IGZyb20gJ3NheGVzJztcclxuaW1wb3J0IHsgQWN0aW9uSGlzdG9yeUl0ZW0gfSBmcm9tICcuLi9tb2RlbHMvaGlzdG9yeS9hY3Rpb24taGlzdG9yeS1pdGVtJztcclxuaW1wb3J0IHsgQ2hhbmdlRW50aXR5SGlzdG9yeUl0ZW0gfSBmcm9tICcuLi9tb2RlbHMvaGlzdG9yeS9jaGFuZ2UtZW50aXR5LWhpc3RvcnktaXRlbSc7XHJcbmltcG9ydCB7IENob2ljZXNIaXN0b3J5SXRlbSB9IGZyb20gJy4uL21vZGVscy9oaXN0b3J5L2Nob2ljZXMtaGlzdG9yeS1pdGVtJztcclxuaW1wb3J0IHsgQ2hvc2VuRW50aXR5SGlzdG9yeUl0ZW0gfSBmcm9tICcuLi9tb2RlbHMvaGlzdG9yeS9jaG9zZW4tZW50aXRpZXMtaGlzdG9yeS1pdGVtJztcclxuaW1wb3J0IHsgRnVsbEVudGl0eUhpc3RvcnlJdGVtIH0gZnJvbSAnLi4vbW9kZWxzL2hpc3RvcnkvZnVsbC1lbnRpdHktaGlzdG9yeS1pdGVtJztcclxuaW1wb3J0IHsgR2FtZUhpc3RvcnlJdGVtIH0gZnJvbSAnLi4vbW9kZWxzL2hpc3RvcnkvZ2FtZS1oaXN0b3J5LWl0ZW0nO1xyXG5pbXBvcnQgeyBIaWRlRW50aXR5SGlzdG9yeUl0ZW0gfSBmcm9tICcuLi9tb2RlbHMvaGlzdG9yeS9oaWRlLWVudGl0eS1oaXN0b3J5LWl0ZW0nO1xyXG5pbXBvcnQgeyBIaXN0b3J5SXRlbSB9IGZyb20gJy4uL21vZGVscy9oaXN0b3J5L2hpc3RvcnktaXRlbSc7XHJcbmltcG9ydCB7IE1ldGFkYXRhSGlzdG9yeUl0ZW0gfSBmcm9tICcuLi9tb2RlbHMvaGlzdG9yeS9tZXRhZGF0YS1oaXN0b3J5LWl0ZW0nO1xyXG5pbXBvcnQgeyBPcHRpb25zSGlzdG9yeUl0ZW0gfSBmcm9tICcuLi9tb2RlbHMvaGlzdG9yeS9vcHRpb25zLWhpc3RvcnktaXRlbSc7XHJcbmltcG9ydCB7IFBsYXllckhpc3RvcnlJdGVtIH0gZnJvbSAnLi4vbW9kZWxzL2hpc3RvcnkvcGxheWVyLWhpc3RvcnktaXRlbSc7XHJcbmltcG9ydCB7IFNob3dFbnRpdHlIaXN0b3J5SXRlbSB9IGZyb20gJy4uL21vZGVscy9oaXN0b3J5L3Nob3ctZW50aXR5LWhpc3RvcnktaXRlbSc7XHJcbmltcG9ydCB7IFRhZ0NoYW5nZUhpc3RvcnlJdGVtIH0gZnJvbSAnLi4vbW9kZWxzL2hpc3RvcnkvdGFnLWNoYW5nZS1oaXN0b3J5LWl0ZW0nO1xyXG5pbXBvcnQgeyBDaG9pY2VzIH0gZnJvbSAnLi4vbW9kZWxzL3BhcnNlci9jaG9pY2VzJztcclxuaW1wb3J0IHsgQ2hvc2VuVGFnIH0gZnJvbSAnLi4vbW9kZWxzL3BhcnNlci9jaG9zZW4tdGFnJztcclxuaW1wb3J0IHsgRW5yaWNoZWRUYWcgfSBmcm9tICcuLi9tb2RlbHMvcGFyc2VyL2VucmljaGVkLXRhZyc7XHJcbmltcG9ydCB7IEVudGl0eURlZmluaXRpb24gfSBmcm9tICcuLi9tb2RlbHMvcGFyc2VyL2VudGl0eS1kZWZpbml0aW9uJztcclxuaW1wb3J0IHsgRW50aXR5RGVmaW5pdGlvbkF0dHJpYnV0ZSB9IGZyb20gJy4uL21vZGVscy9wYXJzZXIvZW50aXR5LWRlZmluaXRpb24tYXR0cmlidXRlJztcclxuaW1wb3J0IHsgRW50aXR5VGFnIH0gZnJvbSAnLi4vbW9kZWxzL3BhcnNlci9lbnRpdHktdGFnJztcclxuaW1wb3J0IHsgSW5mbyB9IGZyb20gJy4uL21vZGVscy9wYXJzZXIvaW5mbyc7XHJcbmltcG9ydCB7IE1ldGFEYXRhIH0gZnJvbSAnLi4vbW9kZWxzL3BhcnNlci9tZXRhZGF0YSc7XHJcbmltcG9ydCB7IE9wdGlvbiB9IGZyb20gJy4uL21vZGVscy9wYXJzZXIvb3B0aW9uJztcclxuXHJcbi8vIERvbid0IGluamVjdCBpdCwgYmVjYXVzZSBvZiB0aGUgZ2xvYmFsIHN0YXRlXHJcbmV4cG9ydCBjbGFzcyBYbWxQYXJzZXJTZXJ2aWNlIHtcclxuXHRwcml2YXRlIHN0YWNrOiBFbnJpY2hlZFRhZ1tdO1xyXG5cdHByaXZhdGUgc3RhdGU6IHN0cmluZ1tdO1xyXG5cdHByaXZhdGUgaW5kZXg6IG51bWJlcjtcclxuXHRwcml2YXRlIGluaXRpYWxUaW1lc3RhbXA6IG51bWJlcjtcclxuXHRwcml2YXRlIGhpc3Rvcnk6IEhpc3RvcnlJdGVtW107XHJcblx0cHJpdmF0ZSBlbnRpdHlEZWZpbml0aW9uOiBFbnRpdHlEZWZpbml0aW9uO1xyXG5cdHByaXZhdGUgYWNjb3VudEhpOiBzdHJpbmc7XHJcblx0cHJpdmF0ZSBhY2NvdW50TG86IHN0cmluZztcclxuXHRwcml2YXRlIGlzTWFpblBsYXllcjogc3RyaW5nO1xyXG5cdHByaXZhdGUgY2hvaWNlczogQ2hvaWNlcztcclxuXHRwcml2YXRlIGNob3NlbjogQ2hvc2VuVGFnO1xyXG5cdHByaXZhdGUgbWV0YURhdGE6IE1ldGFEYXRhO1xyXG5cdHByaXZhdGUgdGltZXN0YW1wOiBudW1iZXI7XHJcblxyXG5cdHByaXZhdGUgYnVpbGROdW1iZXI6IG51bWJlcjtcclxuXHRwcml2YXRlIGdhbWVUeXBlOiBudW1iZXI7XHJcblx0cHJpdmF0ZSBmb3JtYXRUeXBlOiBudW1iZXI7XHJcblx0cHJpdmF0ZSBzY2VuYXJpb0lEOiBudW1iZXI7XHJcblxyXG5cdGNvbnN0cnVjdG9yKCkge31cclxuXHJcblx0cHVibGljICpwYXJzZVhtbCh4bWxBc1N0cmluZzogc3RyaW5nKTogSXRlcmFibGVJdGVyYXRvcjxyZWFkb25seSBIaXN0b3J5SXRlbVtdPiB7XHJcblx0XHR0aGlzLnJlc2V0KCk7XHJcblx0XHRpZiAoIXhtbEFzU3RyaW5nKSB7XHJcblx0XHRcdGNvbnNvbGUuZXJyb3IoJ1tnYW1lLXBhcnNlcl0gW3htbC1wYXJzZXJdIG5vIHhtbEFzU3RyaW5nIHByb3ZpZGVkJyk7XHJcblx0XHRcdHJldHVybiBudWxsO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIGNvbnNvbGUuZGVidWcoJ1tnYW1lLXBhcnNlcl0gW3htbC1wYXJzZXJdIHBhcnNpbmcnLCB4bWxBc1N0cmluZyk7XHJcblx0XHRjb25zdCBzYXhlc1BhcnNlciA9IG5ldyBTYXhlc1BhcnNlcih7XHJcblx0XHRcdC8vIGZyYWdtZW50OiB0cnVlLFxyXG5cdFx0fSk7XHJcblx0XHRzYXhlc1BhcnNlci5vbignb3BlbnRhZycsIHRhZyA9PiB0aGlzLm9uT3BlblRhZyh0YWcpKTtcclxuXHRcdHNheGVzUGFyc2VyLm9uKCdjbG9zZXRhZycsIHRhZyA9PiB0aGlzLm9uQ2xvc2VUYWcoKSk7XHJcblx0XHQvLyBzYXhlc1BhcnNlci5vbignZW5kJywgKCkgPT4gY29uc29sZS5kZWJ1ZygncGFyc2luZyBvdmVyJykpO1xyXG5cdFx0Ly8gc2F4ZXNQYXJzZXIub24oJ2Vycm9yJywgZXJyb3IgPT4gY29uc29sZS5lcnJvcignRXJyb3Igd2hpbGUgcGFyc2luZyB4bWwnLCBlcnJvcikpO1xyXG5cclxuXHRcdC8vIFdlIHdhbnQgdG8gaGF2ZTpcclxuXHRcdC8vIC0gYSBjaHVuayB3aXRoIHByZS1tdWxsaWdhbiBzdHVmZiwgdG8gc2V0dXAgdGhlIGJvYXJkXHJcblx0XHQvLyAtIG9uZSBjaHVuayB3aXRoIGJvdGggbXVsbGlnYW5zXHJcblx0XHQvLyAtIG9uZSBjaHVuayBmb3IgZWFjaCB0dXJuXHJcblx0XHRjb25zdCBtdWxsaWdhblNwbGl0cyA9IHhtbEFzU3RyaW5nLnNwbGl0KFxyXG5cdFx0XHRuZXcgUmVnRXhwKGAoPz08VGFnQ2hhbmdlLip0YWc9XCIke0dhbWVUYWcuTVVMTElHQU5fU1RBVEV9XCIgdmFsdWU9XCIke011bGxpZ2FuLklOUFVUfVwiLiovPilgKSxcclxuXHRcdCk7XHJcblx0XHQvLyBXZSBpc29sYXRlIHRoZSBwcmUtbXVsbGlnYW4gc3R1ZmZcclxuXHRcdGNvbnN0IFtzZXR1cENodW5rLCAuLi5nYW1lQ2h1bmtzXSA9IG11bGxpZ2FuU3BsaXRzO1xyXG5cdFx0Ly8gY29uc29sZS5kZWJ1ZygnW2dhbWUtcGFyc2VyXSBbeG1sLXBhcnNlcl0gc2V0dXBDaHVuaycsIHNldHVwQ2h1bmssIGdhbWVDaHVua3MubGVuZ3RoKTtcclxuXHRcdC8vIFRoZW4gdGhlIG90aGVyIGNodW5rcyBhcmUgaGFuZGxlZCBvbmx5IG9uIGEgdHVybi1ieS10dXJuIGJhc2lzXHJcblx0XHQvLyBUaGlzIGxvZ2ljIGlzIGhlcmU