UNPKG

@firestone-hs/replay-parser

Version:

This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 8.2.9.

440 lines 73.3 kB
import { GameTag, MetaTags, Mulligan, Step } from '@firestone-hs/reference-data'; 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, [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: {} }; 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: {} }; break; case 'FullEntity': this.state.pop(); const fullEntityItem = new FullEntityHistoryItem(this.entityDefinition, this.buildTimestamp(ts), node.index); this.enqueueHistoryItem(fullEntityItem); this.entityDefinition = { tags: {} }; break; case 'ShowEntity': this.state.pop(); const showEntityItem = new ShowEntityHistoryItem(this.entityDefinition, this.buildTimestamp(ts), node.index); this.enqueueHistoryItem(showEntityItem); this.entityDefinition = { tags: {} }; break; case 'ChangeEntity': this.state.pop(); const changeEntityItem = new ChangeEntityHistoryItem(this.entityDefinition, this.buildTimestamp(ts), node.index); this.enqueueHistoryItem(changeEntityItem); this.entityDefinition = { tags: {} }; 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: {}, }; 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoieG1sLXBhcnNlci5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvcmVwbGF5LXBhcnNlci9zcmMvbGliL3NlcnZpY2VzL3htbC1wYXJzZXIuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFRLE1BQU0sOEJBQThCLENBQUM7QUFDdkYsT0FBTyxFQUFFLFdBQVcsRUFBaUIsTUFBTSxPQUFPLENBQUM7QUFDbkQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sdUNBQXVDLENBQUM7QUFDMUUsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sOENBQThDLENBQUM7QUFDdkYsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sd0NBQXdDLENBQUM7QUFDNUUsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sZ0RBQWdELENBQUM7QUFDekYsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sNENBQTRDLENBQUM7QUFDbkYsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHFDQUFxQyxDQUFDO0FBQ3RFLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLDRDQUE0QyxDQUFDO0FBRW5GLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLHlDQUF5QyxDQUFDO0FBQzlFLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHdDQUF3QyxDQUFDO0FBQzVFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHVDQUF1QyxDQUFDO0FBQzFFLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLDRDQUE0QyxDQUFDO0FBQ25GLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLDJDQUEyQyxDQUFDO0FBV2pGLCtDQUErQztBQUMvQyxNQUFNLE9BQU8sZ0JBQWdCO0lBb0I1QixnQkFBZSxDQUFDO0lBRVQsQ0FBQyxRQUFRLENBQUMs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QUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDekMsTUFBTSxLQUFLLEdBQUcsZUFBZSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUN6QyxNQUFNLFdBQVcsR0FBVyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3JHLE9BQU8sV0FBVyxHQUFHLENBQUMsSUFBSSxDQUFDLGdCQUFnQixJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQ25ELENBQUM7Q0FDRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEdhbWVUYWcsIE1ldGFUYWdzLCBNdWxsaWdhbiwgU3RlcCwgWm9uZSB9IGZyb20gJ0BmaXJlc3RvbmUtaHMvcmVmZXJlbmNlLWRhdGEnO1xyXG5pbXBvcnQgeyBTYXhlc1BhcnNlciwgU2F4ZXNUYWdQbGFpbiB9IGZyb20gJ3NheGVzJztcclxuaW1wb3J0IHsgQWN0aW9uSGlzdG9yeUl0ZW0gfSBmcm9tICcuLi9tb2RlbHMvaGlzdG9yeS9hY3Rpb24taGlzdG9yeS1pdGVtJztcclxuaW1wb3J0IHsgQ2hhbmdlRW50aXR5SGlzdG9yeUl0ZW0gfSBmcm9tICcuLi9tb2RlbHMvaGlzdG9yeS9jaGFuZ2UtZW50aXR5LWhpc3RvcnktaXRlbSc7XHJcbmltcG9ydCB7IENob2ljZXNIaXN0b3J5SXRlbSB9IGZyb20gJy4uL21vZGVscy9oaXN0b3J5L2Nob2ljZXMtaGlzdG9yeS1pdGVtJztcclxuaW1wb3J0IHsgQ2hvc2VuRW50aXR5SGlzdG9yeUl0ZW0gfSBmcm9tICcuLi9tb2RlbHMvaGlzdG9yeS9jaG9zZW4tZW50aXRpZXMtaGlzdG9yeS1pdGVtJztcclxuaW1wb3J0IHsgRnVsbEVudGl0eUhpc3RvcnlJdGVtIH0gZnJvbSAnLi4vbW9kZWxzL2hpc3RvcnkvZnVsbC1lbnRpdHktaGlzdG9yeS1pdGVtJztcclxuaW1wb3J0IHsgR2FtZUhpc3RvcnlJdGVtIH0gZnJvbSAnLi4vbW9kZWxzL2hpc3RvcnkvZ2FtZS1oaXN0b3J5LWl0ZW0nO1xyXG5pbXBvcnQgeyBIaWRlRW50aXR5SGlzdG9yeUl0ZW0gfSBmcm9tICcuLi9tb2RlbHMvaGlzdG9yeS9oaWRlLWVudGl0eS1oaXN0b3J5LWl0ZW0nO1xyXG5pbXBvcnQgeyBIaXN0b3J5SXRlbSB9IGZyb20gJy4uL21vZGVscy9oaXN0b3J5L2hpc3RvcnktaXRlbSc7XHJcbmltcG9ydCB7IE1ldGFkYXRhSGlzdG9yeUl0ZW0gfSBmcm9tICcuLi9tb2RlbHMvaGlzdG9yeS9tZXRhZGF0YS1oaXN0b3J5LWl0ZW0nO1xyXG5pbXBvcnQgeyBPcHRpb25zSGlzdG9yeUl0ZW0gfSBmcm9tICcuLi9tb2RlbHMvaGlzdG9yeS9vcHRpb25zLWhpc3RvcnktaXRlbSc7XHJcbmltcG9ydCB7IFBsYXllckhpc3RvcnlJdGVtIH0gZnJvbSAnLi4vbW9kZWxzL2hpc3RvcnkvcGxheWVyLWhpc3RvcnktaXRlbSc7XHJcbmltcG9ydCB7IFNob3dFbnRpdHlIaXN0b3J5SXRlbSB9IGZyb20gJy4uL21vZGVscy9oaXN0b3J5L3Nob3ctZW50aXR5LWhpc3RvcnktaXRlbSc7XHJcbmltcG9ydCB7IFRhZ0NoYW5nZUhpc3RvcnlJdGVtIH0gZnJvbSAnLi4vbW9kZWxzL2hpc3RvcnkvdGFnLWNoYW5nZS1oaXN0b3J5LWl0ZW0nO1xyXG5pbXBvcnQgeyBDaG9pY2VzIH0gZnJvbSAnLi4vbW9kZWxzL3BhcnNlci9jaG9pY2VzJztcclxuaW1wb3J0IHsgQ2hvc2VuVGFnIH0gZnJvbSAnLi4vbW9kZWxzL3BhcnNlci9jaG9zZW4tdGFnJztcclxuaW1wb3J0IHsgRW5yaWNoZWRUYWcgfSBmcm9tICcuLi9tb2RlbHMvcGFyc2VyL2VucmljaGVkLXRhZyc7XHJcbmltcG9ydCB7IEVudGl0eURlZmluaXRpb24gfSBmcm9tICcuLi9tb2RlbHMvcGFyc2VyL2VudGl0eS1kZWZpbml0aW9uJztcclxuaW1wb3J0IHsgRW50aXR5RGVmaW5pdGlvbkF0dHJpYnV0ZSB9IGZyb20gJy4uL21vZGVscy9wYXJzZXIvZW50aXR5LWRlZmluaXRpb24tYXR0cmlidXRlJztcclxuaW1wb3J0IHsgRW50aXR5VGFnIH0gZnJvbSAnLi4vbW9kZWxzL3BhcnNlci9lbnRpdHktdGFnJztcclxuaW1wb3J0IHsgSW5mbyB9IGZyb20gJy4uL21vZGVscy9wYXJzZXIvaW5mbyc7XHJcbmltcG9ydCB7IE1ldGFEYXRhIH0gZnJvbSAnLi4vbW9kZWxzL3BhcnNlci9tZXRhZGF0YSc7XHJcbmltcG9ydCB7IE9wdGlvbiB9IGZyb20gJy4uL21vZGVscy9wYXJzZXIvb3B0aW9uJztcclxuXHJcbi8vIERvbid0IGluamVjdCBpdCwgYmVjYXVzZSBvZiB0aGUgZ2xvYmFsIHN0YXRlXHJcbmV4cG9ydCBjbGFzcyBYbWxQYXJzZXJTZXJ2aWNlIHtcclxuXHRwcml2YXRlIHN0YWNrOiBFbnJpY2hlZFRhZ1tdO1xyXG5cdHByaXZhdGUgc3RhdGU6IHN0cmluZ1tdO1xyXG5cdHByaXZhdGUgaW5kZXg6IG51bWJlcjtcclxuXHRwcml2YXRlIGluaXRpYWxUaW1lc3RhbXA6IG51bWJlcjtcclxuXHRwcml2YXRlIGhpc3Rvcnk6IEhpc3RvcnlJdGVtW107XHJcblx0cHJpdmF0ZSBlbnRpdHlEZWZpbml0aW9uOiBFbnRpdHlEZWZpbml0aW9uO1xyXG5cdHByaXZhdGUgYWNjb3VudEhpOiBzdHJpbmc7XHJcblx0cHJpdmF0ZSBhY2NvdW50TG86IHN0cmluZztcclxuXHRwcml2YXRlIGlzTWFpblBsYXllcjogc3RyaW5nO1xyXG5cdHByaXZhdGUgY2hvaWNlczogQ2hvaWNlcztcclxuXHRwcml2YXRlIGNob3NlbjogQ2hvc2VuVGFnO1xyXG5cdHByaXZhdGUgbWV0YURhdGE6IE1ldGFEYXRhO1xyXG5cdHByaXZhdGUgdGltZXN0YW1wOiBudW1iZXI7XHJcblxyXG5cdHByaXZhdGUgYnVpbGROdW1iZXI6IG51bWJlcjtcclxuXHRwcml2YXRlIGdhbWVUeXBlOiBudW1iZXI7XHJcblx0cHJpdmF0ZSBmb3JtYXRUeXBlOiBudW1iZXI7XHJcblx0cHJpdmF0ZSBzY2VuYXJpb0lEOiBudW1iZXI7XHJcblxyXG5cdGNvbnN0cnVjdG9yKCkge31cclxuXHJcblx0cHVibGljICpwYXJzZVhtbCh4bWxBc1N0cmluZzogc3RyaW5nKTogSXRlcmFibGVJdGVyYXRvcjxyZWFkb25seSBIaXN0b3J5SXRlbVtdPiB7XHJcblx0XHR0aGlzLnJlc2V0KCk7XHJcblx0XHRpZiAoIXhtbEFzU3RyaW5nKSB7XHJcblx0XHRcdGNvbnNvbGUuZXJyb3IoJ1tnYW1lLXBhcnNlcl0gW3htbC1wYXJzZXJdIG5vIHhtbEFzU3RyaW5nIHByb3ZpZGVkJyk7XHJcblx0XHRcdHJldHVybiBudWxsO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIGNvbnNvbGUuZGVidWcoJ1tnYW1lLXBhcnNlcl0gW3htbC1wYXJzZXJdIHBhcnNpbmcnLCB4bWxBc1N0cmluZyk7XHJcblx0XHRjb25zdCBzYXhlc1BhcnNlciA9IG5ldyBTYXhlc1BhcnNlcih7XHJcblx0XHRcdC8vIGZyYWdtZW50OiB0cnVlLFxyXG5cdFx0fSk7XHJcblx0XHRzYXhlc1BhcnNlci5vbignb3BlbnRhZycsICh0YWcpID0+IHRoaXMub25PcGVuVGFnKHRhZykpO1xyXG5cdFx0c2F4ZXNQYXJzZXIub24oJ2Nsb3NldGFnJywgKHRhZykgPT4gdGhpcy5vbkNsb3NlVGFnKCkpO1xyXG5cdFx0Ly8gc2F4ZXNQYXJzZXIub24oJ2VuZCcsICgpID0+IGNvbnNvbGUuZGVidWcoJ3BhcnNpbmcgb3ZlcicpKTtcclxuXHRcdC8vIHNheGVzUGFyc2VyLm9uKCdlcnJvcicsIGVycm9yID0+IGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHdoaWxlIHBhcnNpbmcgeG1sJywgZXJyb3IpKTtcclxuXHJcblx0XHQvLyBXZSB3YW50IHRvIGhhdmU6XHJcblx0XHQvLyAtIGEgY2h1bmsgd2l0aCBwcmUtbXVsbGlnYW4gc3R1ZmYsIHRvIHNldHVwIHRoZSBib2FyZFxyXG5cdFx0Ly8gLSBvbmUgY2h1bmsgd2l0aCBib3RoIG11bGxpZ2Fuc1xyXG5cdFx0Ly8gLSBvbmUgY2h1bmsgZm9yIGVhY2ggdHVyblxyXG5cdFx0Y29uc3QgbXVsbGlnYW5TcGxpdHMgPSB4bWxBc1N0cmluZy5zcGxpdChcclxuXHRcdFx0bmV3IFJlZ0V4cChgKD89PFRhZ0NoYW5nZS4qdGFnPVwiJHtHYW1lVGFnLk1VTExJR0FOX1NUQVRFfVwiIHZhbHVlPVwiJHtNdWxsaWdhbi5JTlBVVH1cIi4qLz4pYCksXHJcblx0XHQpO1xyXG5cdFx0Ly8gV2UgaXNvbGF0ZSB0aGUgcHJlLW11bGxpZ2FuIHN0dWZmXHJcblx0XHRjb25zdCBbc2V0dXBDaHVuaywgLi4uZ2FtZUNodW5rc10gPSBtdWxsaWdhblNwbGl0cztcclxuXHRcdC8vIGNvbnNvbGUuZGVidWcoJ1tnYW1lLXBhcnNlcl0gW3htbC1wYXJzZXJdIHNldHVwQ2h1bmsnLCBzZXR1cENodW5rLCBnYW1lQ2h1bmtzLmxlbmd0aCk7XHJcblx0XHQvLyBUaGVuIHRoZSBvdGhlciBjaHVua3MgYXJlIGhhbmRsZWQgb25seSBvbiBhIHR1cm4tYnktdHVybiBiYXNpc1xyXG5cdFx0Ly8gVGhpcyBsb2dpYyBpcyBoZXJlIHRvIGhhbmRsZSB0aGUgY2FzZSB3aGVyZSB0aGVyZSBpcyBubyBtdWxsaWdhbiBpbmZvLiBJdCBzaG91bGQgdXN1YWxseSBub3QgaGFwcGVuLFxyXG5cdFx0Ly8gYnV0IEkndmUgc2VlbiBpdCBhdCBsZWFzdCBvbmNlXHJcblx0XHRjb25zdC