@firestone-hs/replay-parser
Version:
This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 8.2.9.
171 lines • 23.3 kB
JavaScript
import { Injectable } from '@angular/core';
import { GameTag } from '@firestone-hs/reference-data';
import { ChangeEntityHistoryItem } from '../models/history/change-entity-history-item';
import { FullEntityHistoryItem } from '../models/history/full-entity-history-item';
import { ShowEntityHistoryItem } from '../models/history/show-entity-history-item';
import { TagChangeHistoryItem } from '../models/history/tag-change-history-item';
import * as i0 from "@angular/core";
export class StateProcessorService {
constructor() {
this.USEFUL_TAGS = [
GameTag._333,
GameTag.ARMOR,
GameTag.ATK,
GameTag.ATTACHED,
GameTag.BACON_HERO_CAN_BE_DRAFTED,
GameTag.BOARD_VISUAL_STATE,
GameTag.CANT_BE_TARGETED_BY_HERO_POWERS,
GameTag.CANT_BE_TARGETED_BY_SPELLS,
GameTag.CARDTYPE,
GameTag.CHARGE,
GameTag.CLASS,
GameTag.CONTROLLER,
GameTag.COST,
GameTag.CREATOR,
GameTag.CURRENT_HEROPOWER_DAMAGE_BONUS,
GameTag.CURRENT_PLAYER,
GameTag.CURRENT_SPELLPOWER_BASE,
GameTag.DAMAGE,
GameTag.DEATHRATTLE,
GameTag.DIVINE_SHIELD,
GameTag.DURABILITY,
GameTag.EXHAUSTED,
GameTag.EXHAUSTED,
GameTag.FROZEN,
GameTag.GAME_MODE_BUTTON_SLOT,
GameTag.HEALTH,
GameTag.HEAVILY_ARMORED,
GameTag.HERO_ENTITY,
GameTag.HERO_POWER_DISABLED,
GameTag.HERO_POWER_DISABLED,
GameTag.HERO_POWER_DOUBLE,
GameTag.HIDDEN_CHOICE,
GameTag.HIDE_STATS,
GameTag.IMMUNE,
GameTag.INSPIRE,
GameTag.JUST_PLAYED,
GameTag.LIFESTEAL,
GameTag.MULLIGAN_STATE,
GameTag.NEXT_OPPONENT_PLAYER_ID,
GameTag.NUM_CARDS_PLAYED_THIS_TURN,
GameTag.NUM_RESOURCES_SPENT_THIS_GAME,
GameTag.OVERLOAD_LOCKED,
GameTag.OVERLOAD_OWED,
GameTag.PARENT_CARD,
GameTag.PLAYER_ID,
GameTag.PLAYER_LEADERBOARD_PLACE,
GameTag.PLAYER_TECH_LEVEL,
GameTag.PLAYSTATE,
GameTag.POISONOUS,
GameTag.PREMIUM,
GameTag.PREMIUM,
GameTag.QUEST_PROGRESS_TOTAL,
GameTag.QUEST_PROGRESS,
GameTag.QUEST,
GameTag.REBORN,
GameTag.RECEIVES_DOUBLE_SPELLDAMAGE_BONUS,
GameTag.RESOURCES_USED,
GameTag.RESOURCES,
GameTag.SECRET,
GameTag.SILENCED,
GameTag.SPELLPOWER_DOUBLE,
GameTag.STEALTH,
GameTag.STEP,
GameTag.TAG_SCRIPT_DATA_NUM_1,
GameTag.TAG_SCRIPT_DATA_NUM_2,
GameTag.TAUNT,
GameTag.TECH_LEVEL_MANA_GEM,
GameTag.TECH_LEVEL,
GameTag.TRIGGER_VISUAL,
GameTag.TURN,
GameTag.WINDFURY,
GameTag.ZONE_POSITION,
GameTag.ZONE,
];
}
applyHistoryUntilEnd(previousStateEntities, history, previousProcessedItem) {
const startIndex = history.indexOf(previousProcessedItem);
const futureHistory = history.slice(startIndex);
let newStateEntities = previousStateEntities;
// // console.log('applying history until now', startIndex, futureHistory, history);
for (const historyItem of futureHistory) {
newStateEntities = this.applyHistoryItem(newStateEntities, historyItem);
}
// // console.log('after history applied 150', newStateEntities.get(150) && newStateEntities.get(150).tags.toJS());
return newStateEntities;
}
applyHistoryItem(entities, item) {
if (item instanceof TagChangeHistoryItem) {
return this.updateWithTagChange(item, entities);
}
else if (item instanceof ShowEntityHistoryItem || item instanceof FullEntityHistoryItem) {
return this.updateWithEntity(item, entities);
}
else if (item instanceof ChangeEntityHistoryItem) {
return this.updateWithChangeEntity(item, entities);
}
return entities;
// TODO: options, choices, chosen entities
}
updateWithEntity(historyItem, entities) {
if (historyItem.entityDefintion.id === 35) {
// console.log('applying history item', historyItem, historyItem.entityDefintion.tags?.toJS());
}
if (!entities.get(historyItem.entityDefintion.id)) {
console.warn('[state-processor] could not update entity', historyItem.entityDefintion.id);
return entities;
}
// if (historyItem.entityDefintion.id === 73 || historyItem.entityDefintion.id === 74) {
// // console.log('enriching state', historyItem);
// }
const entity = entities.get(historyItem.entityDefintion.id).update(historyItem.entityDefintion);
// if (entity.id === 150) {
// // console.log(
// 'updating with 150',
// entity,
// entity.tags.toJS(),
// entities
// .set(entity.id, entity)
// .get(150)
// .tags.toJS(),
// );
// }
return entities.set(entity.id, entity);
}
updateWithChangeEntity(historyItem, entities) {
if (!entities.get(historyItem.entityDefintion.id)) {
console.warn('[state-processor] could not update entity', historyItem.entityDefintion.id);
return entities;
}
const entity = entities.get(historyItem.entityDefintion.id).update(historyItem.entityDefintion);
return entities.set(entity.id, entity);
}
updateWithTagChange(historyItem, entities) {
// Only a limited number of tags are useful for replay reconstitution. If the tag isn't
// one of them, we simply ignore it. Thanks to this, we will have less differences
// between our entities, which will improve the memory footprint and performances
if (this.USEFUL_TAGS.indexOf(historyItem.tag.tag) === -1) {
return entities;
}
// No default creation - if the entity is not registered yet, it's a bug
// It sometimes happens that the XML itself doesn't have the right entity
// so we safeguard here
if (!entities.get(historyItem.tag.entity)) {
console.warn('[state-processor] could not update entity', historyItem.tag.entity);
return entities;
}
const entity = entities
.get(historyItem.tag.entity)
.updateTag(historyItem.tag.tag, historyItem.tag.value);
return entities.set(entity.id, entity);
}
}
StateProcessorService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: StateProcessorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
StateProcessorService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: StateProcessorService, providedIn: 'root' });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: StateProcessorService, decorators: [{
type: Injectable,
args: [{
providedIn: 'root',
}]
}], ctorParameters: function () { return []; } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhdGUtcHJvY2Vzc29yLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9yZXBsYXktcGFyc2VyL3NyYy9saWIvc2VydmljZXMvc3RhdGUtcHJvY2Vzc29yLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFHdkQsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sOENBQThDLENBQUM7QUFDdkYsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sNENBQTRDLENBQUM7QUFFbkYsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sNENBQTRDLENBQUM7QUFDbkYsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sMkNBQTJDLENBQUM7O0FBS2pGLE1BQU0sT0FBTyxxQkFBcUI7SUFDakM7UUFFaUIsZ0JBQVcsR0FBdUI7WUFDbEQsT0FBTyxDQUFDLElBQUk7WUFDWixPQUFPLENBQUMsS0FBSztZQUNiLE9BQU8sQ0FBQyxHQUFHO1lBQ1gsT0FBTyxDQUFDLFFBQVE7WUFDaEIsT0FBTyxDQUFDLHlCQUF5QjtZQUNqQyxPQUFPLENBQUMsa0JBQWtCO1lBQzFCLE9BQU8sQ0FBQywrQkFBK0I7WUFDdkMsT0FBTyxDQUFDLDBCQUEwQjtZQUNsQyxPQUFPLENBQUMsUUFBUTtZQUNoQixPQUFPLENBQUMsTUFBTTtZQUNkLE9BQU8sQ0FBQyxLQUFLO1lBQ2IsT0FBTyxDQUFDLFVBQVU7WUFDbEIsT0FBTyxDQUFDLElBQUk7WUFDWixPQUFPLENBQUMsT0FBTztZQUNmLE9BQU8sQ0FBQyw4QkFBOEI7WUFDdEMsT0FBTyxDQUFDLGNBQWM7WUFDdEIsT0FBTyxDQUFDLHVCQUF1QjtZQUMvQixPQUFPLENBQUMsTUFBTTtZQUNkLE9BQU8sQ0FBQyxXQUFXO1lB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QkFBcUIsY0FGckIsTUFBTTsyRkFFTixxQkFBcUI7a0JBSGpDLFVBQVU7bUJBQUM7b0JBQ1gsVUFBVSxFQUFFLE1BQU07aUJBQ2xCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBHYW1lVGFnIH0gZnJvbSAnQGZpcmVzdG9uZS1ocy9yZWZlcmVuY2UtZGF0YSc7XHJcbmltcG9ydCB7IE1hcCB9IGZyb20gJ2ltbXV0YWJsZSc7XHJcbmltcG9ydCB7IEVudGl0eSB9IGZyb20gJy4uL21vZGVscy9nYW1lL2VudGl0eSc7XHJcbmltcG9ydCB7IENoYW5nZUVudGl0eUhpc3RvcnlJdGVtIH0gZnJvbSAnLi4vbW9kZWxzL2hpc3RvcnkvY2hhbmdlLWVudGl0eS1oaXN0b3J5LWl0ZW0nO1xyXG5pbXBvcnQgeyBGdWxsRW50aXR5SGlzdG9yeUl0ZW0gfSBmcm9tICcuLi9tb2RlbHMvaGlzdG9yeS9mdWxsLWVudGl0eS1oaXN0b3J5LWl0ZW0nO1xyXG5pbXBvcnQgeyBIaXN0b3J5SXRlbSB9IGZyb20gJy4uL21vZGVscy9oaXN0b3J5L2hpc3RvcnktaXRlbSc7XHJcbmltcG9ydCB7IFNob3dFbnRpdHlIaXN0b3J5SXRlbSB9IGZyb20gJy4uL21vZGVscy9oaXN0b3J5L3Nob3ctZW50aXR5LWhpc3RvcnktaXRlbSc7XHJcbmltcG9ydCB7IFRhZ0NoYW5nZUhpc3RvcnlJdGVtIH0gZnJvbSAnLi4vbW9kZWxzL2hpc3RvcnkvdGFnLWNoYW5nZS1oaXN0b3J5LWl0ZW0nO1xyXG5cclxuQEluamVjdGFibGUoe1xyXG5cdHByb3ZpZGVkSW46ICdyb290JyxcclxufSlcclxuZXhwb3J0IGNsYXNzIFN0YXRlUHJvY2Vzc29yU2VydmljZSB7XHJcblx0Y29uc3RydWN0b3IoKSB7fVxyXG5cclxuXHRwcml2YXRlIHJlYWRvbmx5IFVTRUZVTF9UQUdTOiByZWFkb25seSBHYW1lVGFnW10gPSBbXHJcblx0XHRHYW1lVGFnLl8zMzMsXHJcblx0XHRHYW1lVGFnLkFSTU9SLFxyXG5cdFx0R2FtZVRhZy5BVEssXHJcblx0XHRHYW1lVGFnLkFUVEFDSEVELFxyXG5cdFx0R2FtZVRhZy5CQUNPTl9IRVJPX0NBTl9CRV9EUkFGVEVELFxyXG5cdFx0R2FtZVRhZy5CT0FSRF9WSVNVQUxfU1RBVEUsXHJcblx0XHRHYW1lVGFnLkNBTlRfQkVfVEFSR0VURURfQllfSEVST19QT1dFUlMsXHJcblx0XHRHYW1lVGFnLkNBTlRfQkVfVEFSR0VURURfQllfU1BFTExTLFxyXG5cdFx0R2FtZVRhZy5DQVJEVFlQRSxcclxuXHRcdEdhbWVUYWcuQ0hBUkdFLFxyXG5cdFx0R2FtZVRhZy5DTEFTUyxcclxuXHRcdEdhbWVUYWcuQ09OVFJPTExFUixcclxuXHRcdEdhbWVUYWcuQ09TVCxcclxuXHRcdEdhbWVUYWcuQ1JFQVRPUixcclxuXHRcdEdhbWVUYWcuQ1VSUkVOVF9IRVJPUE9XRVJfREFNQUdFX0JPTlVTLFxyXG5cdFx0R2FtZVRhZy5DVVJSRU5UX1BMQVlFUixcclxuXHRcdEdhbWVUYWcuQ1VSUkVOVF9TUEVMTFBPV0VSX0JBU0UsXHJcblx0XHRHYW1lVGFnLkRBTUFHRSxcclxuXHRcdEdhbWVUYWcuREVBVEhSQVRUTEUsXHJcblx0XHRHYW1lVGFnLkRJVklORV9TSElFTEQsXHJcblx0XHRHYW1lVGFnLkRVUkFCSUxJVFksXHJcblx0XHRHYW1lVGFnLkVYSEFVU1RFRCxcclxuXHRcdEdhbWVUYWcuRVhIQVVTVEVELFxyXG5cdFx0R2FtZVRhZy5GUk9aRU4sXHJcblx0XHRHYW1lVGFnLkdBTUVfTU9ERV9CVVRUT05fU0xPVCwgLy8gVXNlZCB0byBrbm93IHdoYXQgYnV0dG9uIGlzIGFjdGl2ZSBpbiBhIHNwZWNpZmljIHNsb3RcclxuXHRcdEdhbWVUYWcuSEVBTFRILFxyXG5cdFx0R2FtZVRhZy5IRUFWSUxZX0FSTU9SRUQsXHJcblx0XHRHYW1lVGFnLkhFUk9fRU5USVRZLFxyXG5cdFx0R2FtZVRhZy5IRVJPX1BPV0VSX0RJU0FCTEVELFxyXG5cdFx0R2FtZVRhZy5IRVJPX1BPV0VSX0RJU0FCTEVELFxyXG5cdFx0R2FtZVRhZy5IRVJPX1BPV0VSX0RPVUJMRSxcclxuXHRcdEdhbWVUYWcuSElEREVOX0NIT0lDRSxcclxuXHRcdEdhbWVUYWcuSElERV9TVEFUUyxcclxuXHRcdEdhbWVUYWcuSU1NVU5FLFxyXG5cdFx0R2FtZVRhZy5JTlNQSVJFLFxyXG5cdFx0R2FtZVRhZy5KVVNUX1BMQVlFRCxcclxuXHRcdEdhbWVUYWcuTElGRVNURUFMLFxyXG5cdFx0R2FtZVRhZy5NVUxMSUdBTl9TVEFURSxcclxuXHRcdEdhbWVUYWcuTkVYVF9PUFBPTkVOVF9QTEFZRVJfSUQsXHJcblx0XHRHYW1lVGFnLk5VTV9DQVJEU19QTEFZRURfVEhJU19UVVJOLFxyXG5cdFx0R2FtZVRhZy5OVU1fUkVTT1VSQ0VTX1NQRU5UX1RISVNfR0FNRSxcclxuXHRcdEdhbWVUYWcuT1ZFUkxPQURfTE9DS0VELFxyXG5cdFx0R2FtZVRhZy5PVkVSTE9BRF9PV0VELFxyXG5cdFx0R2FtZVRhZy5QQVJFTlRfQ0FSRCxcclxuXHRcdEdhbWVUYWcuUExBWUVSX0lELFxyXG5cdFx0R2FtZVRhZy5QTEFZRVJfTEVBREVSQk9BUkRfUExBQ0UsXHJcblx0XHRHYW1lVGFnLlBMQVlFUl9URUNIX0xFVkVMLFxyXG5cdFx0R2FtZVRhZy5QTEFZU1RBVEUsXHJcblx0XHRHYW1lVGFnLlBPSVNPTk9VUyxcclxuXHRcdEdhbWVUYWcuUFJFTUlVTSxcclxuXHRcdEdhbWVUYWcuUFJFTUlVTSxcclxuXHRcdEdhbWVUYWcuUVVFU1RfUFJPR1JFU1NfVE9UQUwsXHJcblx0XHRHYW1lVGFnLlFVRVNUX1BST0dSRVNTLFxyXG5cdFx0R2FtZVRhZy5RVUVTVCxcclxuXHRcdEdhbWVUYWcuUkVCT1JOLFxyXG5cdFx0R2FtZVRhZy5SRUNFSVZFU19ET1VCTEVfU1BFTExEQU1BR0VfQk9OVVMsXHJcblx0XHRHYW1lVGFnLlJFU09VUkNFU19VU0VELFxyXG5cdFx0R2FtZVRhZy5SRVNPVVJDRVMsXHJcblx0XHRHYW1lVGFnLlNFQ1JFVCxcclxuXHRcdEdhbWVUYWcuU0lMRU5DRUQsXHJcblx0XHRHYW1lVGFnLlNQRUxMUE9XRVJfRE9VQkxFLFxyXG5cdFx0R2FtZVRhZy5TVEVBTFRILFxyXG5cdFx0R2FtZVRhZy5TVEVQLFxyXG5cdFx0R2FtZVRhZy5UQUdfU0NSSVBUX0RBVEFfTlVNXzEsXHJcblx0XHRHYW1lVGFnLlRBR19TQ1JJUFRfREFUQV9OVU1fMixcclxuXHRcdEdhbWVUYWcuVEFVTlQsXHJcblx0XHRHYW1lVGFnLlRFQ0hfTEVWRUxfTUFOQV9HRU0sXHJcblx0XHRHYW1lVGFnLlRFQ0hfTEVWRUwsXHJcblx0XHRHYW1lVGFnLlRSSUdHRVJfVklTVUFMLFxyXG5cdFx0R2FtZVRhZy5UVVJOLFxyXG5cdFx0R2FtZVRhZy5XSU5ERlVSWSxcclxuXHRcdEdhbWVUYWcuWk9ORV9QT1NJVElPTixcclxuXHRcdEdhbWVUYWcuWk9ORSxcclxuXHRdO1xyXG5cclxuXHRwdWJsaWMgYXBwbHlIaXN0b3J5VW50aWxFbmQoXHJcblx0XHRwcmV2aW91c1N0YXRlRW50aXRpZXM6IE1hcDxudW1iZXIsIEVudGl0eT4sXHJcblx0XHRoaXN0b3J5OiByZWFkb25seSBIaXN0b3J5SXRlbVtdLFxyXG5cdFx0cHJldmlvdXNQcm9jZXNzZWRJdGVtOiBIaXN0b3J5SXRlbSxcclxuXHQpOiBNYXA8bnVtYmVyLCBFbnRpdHk+IHtcclxuXHRcdGNvbnN0IHN0YXJ0SW5kZXggPSBoaXN0b3J5LmluZGV4T2YocHJldmlvdXNQcm9jZXNzZWRJdGVtKTtcclxuXHRcdGNvbnN0IGZ1dHVyZUhpc3RvcnkgPSBoaXN0b3J5LnNsaWNlKHN0YXJ0SW5kZXgpO1xyXG5cdFx0bGV0IG5ld1N0YXRlRW50aXRpZXMgPSBwcmV2aW91c1N0YXRlRW50aXRpZXM7XHJcblx0XHQvLyAvLyBjb25zb2xlLmxvZygnYXBwbHlpbmcgaGlzdG9yeSB1bnRpbCBub3cnLCBzdGFydEluZGV4LCBmdXR1cmVIaXN0b3J5LCBoaXN0b3J5KTtcclxuXHRcdGZvciAoY29uc3QgaGlzdG9yeUl0ZW0gb2YgZnV0dXJlSGlzdG9yeSkge1xyXG5cdFx0XHRuZXdTdGF0ZUVudGl0aWVzID0gdGhpcy5hcHBseUhpc3RvcnlJdGVtKG5ld1N0YXRlRW50aXRpZXMsIGhpc3RvcnlJdGVtKTtcclxuXHRcdH1cclxuXHRcdC8vIC8vIGNvbnNvbGUubG9nKCdhZnRlciBoaXN0b3J5IGFwcGxpZWQgMTUwJywgbmV3U3RhdGVFbnRpdGllcy5nZXQoMTUwKSAmJiBuZXdTdGF0ZUVudGl0aWVzLmdldCgxNTApLnRhZ3MudG9KUygpKTtcclxuXHRcdHJldHVybiBuZXdTdGF0ZUVudGl0aWVzO1xyXG5cdH1cclxuXHJcblx0cHVibGljIGFwcGx5SGlzdG9yeUl0ZW0oZW50aXRpZXM6IE1hcDxudW1iZXIsIEVudGl0eT4sIGl0ZW06IEhpc3RvcnlJdGVtKTogTWFwPG51bWJlciwgRW50aXR5PiB7XHJcblx0XHRpZiAoaXRlbSBpbnN0YW5jZW9mIFRhZ0NoYW5nZUhpc3RvcnlJdGVtKSB7XHJcblx0XHRcdHJldHVybiB0aGlzLnVwZGF0ZVdpdGhUYWdDaGFuZ2UoaXRlbSwgZW50aXRpZXMpO1xyXG5cdFx0fSBlbHNlIGlmIChpdGVtIGluc3RhbmNlb2YgU2hvd0VudGl0eUhpc3RvcnlJdGVtIHx8IGl0ZW0gaW5zdGFuY2VvZiBGdWxsRW50aXR5SGlzdG9yeUl0ZW0pIHtcclxuXHRcdFx0cmV0dXJuIHRoaXMudXBkYXRlV2l0aEVudGl0eShpdGVtLCBlbnRpdGllcyk7XHJcblx0XHR9IGVsc2UgaWYgKGl0ZW0gaW5zdGFuY2VvZiBDaGFuZ2VFbnRpdHlIaXN0b3J5SXRlbSkge1xyXG5cdFx0XHRyZXR1cm4gdGhpcy51cGRhdGVXaXRoQ2hhbmdlRW50aXR5KGl0ZW0sIGVudGl0aWVzKTtcclxuXHRcdH1cclxuXHRcdHJldHVybiBlbnRpdGllcztcclxuXHRcdC8vIFRPRE86IG9wdGlvbnMsIGNob2ljZXMsIGNob3NlbiBlbnRpdGllc1xyXG5cdH1cclxuXHJcblx0cHJpdmF0ZSB1cGRhdGVXaXRoRW50aXR5KFxyXG5cdFx0aGlzdG9yeUl0ZW06IFNob3dFbnRpdHlIaXN0b3J5SXRlbSB8IEZ1bGxFbnRpdHlIaXN0b3J5SXRlbSxcclxuXHRcdGVudGl0aWVzOiBNYXA8bnVtYmVyLCBFbnRpdHk+LFxyXG5cdCk6IE1hcDxudW1iZXIsIEVudGl0eT4ge1xyXG5cdFx0aWYgKGhpc3RvcnlJdGVtLmVudGl0eURlZmludGlvbi5pZCA9PT0gMzUpIHtcclxuXHRcdFx0Ly8gY29uc29sZS5sb2coJ2FwcGx5aW5nIGhpc3RvcnkgaXRlbScsIGhpc3RvcnlJdGVtLCBoaXN0b3J5SXRlbS5lbnRpdHlEZWZpbnRpb24udGFncz8udG9KUygpKTtcclxuXHRcdH1cclxuXHRcdGlmICghZW50aXRpZXMuZ2V0KGhpc3RvcnlJdGVtLmVudGl0eURlZmludGlvbi5pZCkpIHtcclxuXHRcdFx0Y29uc29sZS53YXJuKCdbc3RhdGUtcHJvY2Vzc29yXSBjb3VsZCBub3QgdXBkYXRlIGVudGl0eScsIGhpc3RvcnlJdGVtLmVudGl0eURlZmludGlvbi5pZCk7XHJcblx0XHRcdHJldHVybiBlbnRpdGllcztcclxuXHRcdH1cclxuXHJcblx0XHQvLyBpZiAoaGlzdG9yeUl0ZW0uZW50aXR5RGVmaW50aW9uLmlkID09PSA3MyB8fCBoaXN0b3J5SXRlbS5lbnRpdHlEZWZpbnRpb24uaWQgPT09IDc0KSB7XHJcblx0XHQvLyBcdC8vIGNvbnNvbGUubG9nKCdlbnJpY2hpbmcgc3RhdGUnLCBoaXN0b3J5SXRlbSk7XHJcblx0XHQvLyB9XHJcblx0XHRjb25zdCBlbnRpdHk6IEVudGl0eSA9IGVudGl0aWVzLmdldChoaXN0b3J5SXRlbS5lbnRpdHlEZWZpbnRpb24uaWQpLnVwZGF0ZShoaXN0b3J5SXRlbS5lbnRpdHlEZWZpbnRpb24pO1xyXG5cdFx0Ly8gaWYgKGVudGl0eS5pZCA9PT0gMTUwKSB7XHJcblx0XHQvLyBcdC8vIGNvbnNvbGUubG9nKFxyXG5cdFx0Ly8gXHRcdCd1cGRhdGluZyB3aXRoIDE1MCcsXHJcblx0XHQvLyBcdFx0ZW50aXR5LFxyXG5cdFx0Ly8gXHRcdGVudGl0eS50YWdzLnRvSlMoKSxcclxuXHRcdC8vIFx0XHRlbnRpdGllc1xyXG5cdFx0Ly8gXHRcdFx0LnNldChlbnRpdHkuaWQsIGVudGl0eSlcclxuXHRcdC8vIFx0XHRcdC5nZXQoMTUwKVxyXG5cdFx0Ly8gXHRcdFx0LnRhZ3MudG9KUygpLFxyXG5cdFx0Ly8gXHQpO1xyXG5cdFx0Ly8gfVxyXG5cdFx0cmV0dXJuIGVudGl0aWVzLnNldChlbnRpdHkuaWQsIGVudGl0eSk7XHJcblx0fVxyXG5cclxuXHRwcml2YXRlIHVwZGF0ZVdpdGhDaGFuZ2VFbnRpdHkoXHJcblx0XHRoaXN0b3J5SXRlbTogQ2hhbmdlRW50aXR5SGlzdG9yeUl0ZW0sXHJcblx0XHRlbnRpdGllczogTWFwPG51bWJlciwgRW50aXR5PixcclxuXHQpOiBNYXA8bnVtYmVyLCBFbnRpdHk+IHtcclxuXHRcdGlmICghZW50aXRpZXMuZ2V0KGhpc3RvcnlJdGVtLmVudGl0eURlZmludGlvbi5pZCkpIHtcclxuXHRcdFx0Y29uc29sZS53YXJuKCdbc3RhdGUtcHJvY2Vzc29yXSBjb3VsZCBub3QgdXBkYXRlIGVudGl0eScsIGhpc3RvcnlJdGVtLmVudGl0eURlZmludGlvbi5pZCk7XHJcblx0XHRcdHJldHVybiBlbnRpdGllcztcclxuXHRcdH1cclxuXHRcdGNvbnN0IGVudGl0eTogRW50aXR5ID0gZW50aXRpZXMuZ2V0KGhpc3RvcnlJdGVtLmVudGl0eURlZmludGlvbi5pZCkudXBkYXRlKGhpc3RvcnlJdGVtLmVudGl0eURlZmludGlvbik7XHJcblx0XHRyZXR1cm4gZW50aXRpZXMuc2V0KGVudGl0eS5pZCwgZW50aXR5KTtcclxuXHR9XHJcblxyXG5cdHByaXZhdGUgdXBkYXRlV2l0aFRhZ0NoYW5nZShoaXN0b3J5SXRlbTogVGFnQ2hhbmdlSGlzdG9yeUl0ZW0sIGVudGl0aWVzOiBNYXA8bnVtYmVyLCBFbnRpdHk+KTogTWFwPG51bWJlciwgRW50aXR5PiB7XHJcblx0XHQvLyBPbmx5IGEgbGltaXRlZCBudW1iZXIgb2YgdGFncyBhcmUgdXNlZnVsIGZvciByZXBsYXkgcmVjb25zdGl0dXRpb24uIElmIHRoZSB0YWcgaXNuJ3RcclxuXHRcdC8vIG9uZSBvZiB0aGVtLCB3ZSBzaW1wbHkgaWdub3JlIGl0LiBUaGFua3MgdG8gdGhpcywgd2Ugd2lsbCBoYXZlIGxlc3MgZGlmZmVyZW5jZXNcclxuXHRcdC8vIGJldHdlZW4gb3VyIGVudGl0aWVzLCB3aGljaCB3aWxsIGltcHJvdmUgdGhlIG1lbW9yeSBmb290cHJpbnQgYW5kIHBlcmZvcm1hbmNlc1xyXG5cdFx0aWYgKHRoaXMuVVNFRlVMX1RBR1MuaW5kZXhPZihoaXN0b3J5SXRlbS50YWcudGFnKSA9PT0gLTEpIHtcclxuXHRcdFx0cmV0dXJuIGVudGl0aWVzO1xyXG5cdFx0fVxyXG5cdFx0Ly8gTm8gZGVmYXVsdCBjcmVhdGlvbiAtIGlmIHRoZSBlbnRpdHkgaXMgbm90IHJlZ2lzdGVyZWQgeWV0LCBpdCdzIGEgYnVnXHJcblx0XHQvLyBJdCBzb21ldGltZXMgaGFwcGVucyB0aGF0IHRoZSBYTUwgaXRzZWxmIGRvZXNuJ3QgaGF2ZSB0aGUgcmlnaHQgZW50aXR5XHJcblx0XHQvLyBzbyB3ZSBzYWZlZ3VhcmQgaGVyZVxyXG5cdFx0aWYgKCFlbnRpdGllcy5nZXQoaGlzdG9yeUl0ZW0udGFnLmVudGl0eSkpIHtcclxuXHRcdFx0Y29uc29sZS53YXJuKCdbc3RhdGUtcHJvY2Vzc29yXSBjb3VsZCBub3QgdXBkYXRlIGVudGl0eScsIGhpc3RvcnlJdGVtLnRhZy5lbnRpdHkpO1xyXG5cdFx0XHRyZXR1cm4gZW50aXRpZXM7XHJcblx0XHR9XHJcblxyXG5cdFx0Y29uc3QgZW50aXR5OiBFbnRpdHkgPSBlbnRpdGllc1xyXG5cdFx0XHQuZ2V0KGhpc3RvcnlJdGVtLnRhZy5lbnRpdHkpXHJcblx0XHRcdC51cGRhdGVUYWcoaGlzdG9yeUl0ZW0udGFnLnRhZywgaGlzdG9yeUl0ZW0udGFnLnZhbHVlKTtcclxuXHRcdHJldHVybiBlbnRpdGllcy5zZXQoZW50aXR5LmlkLCBlbnRpdHkpO1xyXG5cdH1cclxufVxyXG4iXX0=