@orbit/memory
Version:
Orbit source for managing in-memory records.
334 lines • 50.9 kB
JavaScript
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var MemorySource_1;
import { Assertion, Orbit } from '@orbit/core';
import { queryable, syncable, updatable } from '@orbit/data';
import { coalesceRecordOperations, RecordSource } from '@orbit/records';
import { toArray } from '@orbit/utils';
import { MemoryCache } from './memory-cache';
const { assert, deprecate } = Orbit;
let MemorySource = MemorySource_1 = class MemorySource extends RecordSource {
constructor(settings) {
var _a, _b, _c, _d, _e, _f, _g, _h;
const { keyMap, schema, base } = settings;
settings.name = (_a = settings.name) !== null && _a !== void 0 ? _a : 'memory';
super(settings);
this._transforms = {};
this._transformInverses = {};
this.transformLog.on('clear', this._logCleared.bind(this));
this.transformLog.on('truncate', this._logTruncated.bind(this));
this.transformLog.on('rollback', this._logRolledback.bind(this));
let cacheSettings = (_b = settings.cacheSettings) !== null && _b !== void 0 ? _b : {};
cacheSettings.schema = schema;
cacheSettings.keyMap = keyMap;
(_c = cacheSettings.queryBuilder) !== null && _c !== void 0 ? _c : (cacheSettings.queryBuilder = this.queryBuilder);
(_d = cacheSettings.transformBuilder) !== null && _d !== void 0 ? _d : (cacheSettings.transformBuilder = this.transformBuilder);
(_e = cacheSettings.defaultQueryOptions) !== null && _e !== void 0 ? _e : (cacheSettings.defaultQueryOptions = this.defaultQueryOptions);
(_f = cacheSettings.defaultTransformOptions) !== null && _f !== void 0 ? _f : (cacheSettings.defaultTransformOptions = this.defaultTransformOptions);
(_g = cacheSettings.autoValidate) !== null && _g !== void 0 ? _g : (cacheSettings.autoValidate = settings.autoValidate);
if (cacheSettings.autoValidate !== false &&
cacheSettings.validatorFor === undefined &&
cacheSettings.validators === undefined) {
cacheSettings.validatorFor = this._validatorFor;
}
if (base) {
this._base = base;
this._forkPoint = base.transformLog.head;
cacheSettings.base = base.cache;
}
const cacheClass = (_h = settings.cacheClass) !== null && _h !== void 0 ? _h : MemoryCache;
this._cache = new cacheClass(cacheSettings);
}
get cache() {
return this._cache;
}
get base() {
return this._base;
}
get forkPoint() {
return this._forkPoint;
}
async upgrade() {
this._cache.upgrade();
}
/////////////////////////////////////////////////////////////////////////////
// Syncable interface implementation
/////////////////////////////////////////////////////////////////////////////
async _sync(transform) {
if (!this.transformLog.contains(transform.id)) {
this._applyTransform(transform);
await this.transformed([transform]);
}
}
/////////////////////////////////////////////////////////////////////////////
// Updatable interface implementation
/////////////////////////////////////////////////////////////////////////////
async _update(transform, hints) {
let results;
const response = {};
if (!this.transformLog.contains(transform.id)) {
results = this._applyTransform(transform);
response.transforms = [transform];
}
if (hints === null || hints === void 0 ? void 0 : hints.data) {
if (Array.isArray(transform.operations)) {
assert('MemorySource#update: `hints.data` must be an array if `transform.operations` is an array', Array.isArray(hints.data));
response.data = hints.data.map((h) => this._retrieveOperationResult(h));
}
else {
response.data = this._retrieveOperationResult(hints.data);
}
}
else if (results) {
response.data = results;
}
if (hints === null || hints === void 0 ? void 0 : hints.details) {
response.details = hints.details;
}
return response;
}
/////////////////////////////////////////////////////////////////////////////
// Queryable interface implementation
/////////////////////////////////////////////////////////////////////////////
async _query(query, hints) {
let response;
if (hints === null || hints === void 0 ? void 0 : hints.data) {
response = {};
if (Array.isArray(query.expressions)) {
assert('MemorySource#query: `hints.data` must be an array if `query.expressions` is an array', Array.isArray(hints.data));
response.data = hints.data.map((h) => this._retrieveQueryExpressionResult(h));
}
else {
response.data = this._retrieveQueryExpressionResult(hints.data);
}
}
else {
response = this._cache.query(query, {
fullResponse: true
});
}
if (hints === null || hints === void 0 ? void 0 : hints.details) {
response.details = hints.details;
}
return response;
}
/////////////////////////////////////////////////////////////////////////////
// Public methods
/////////////////////////////////////////////////////////////////////////////
/**
* Create a clone, or "fork", from a "base" source.
*
* The forked source will have the same `schema` and `keyMap` as its base source.
* The forked source's cache will start with the same immutable document as
* the base source. Its contents and log will evolve independently.
*
* @returns The forked source.
*/
fork(settings = {}) {
var _a, _b, _c, _d, _e;
// required settings
settings.base = this;
settings.schema = this.schema;
settings.keyMap = this.keyMap;
// customizable settings
(_a = settings.queryBuilder) !== null && _a !== void 0 ? _a : (settings.queryBuilder = this._queryBuilder);
(_b = settings.transformBuilder) !== null && _b !== void 0 ? _b : (settings.transformBuilder = this._transformBuilder);
(_c = settings.defaultQueryOptions) !== null && _c !== void 0 ? _c : (settings.defaultQueryOptions = this._defaultQueryOptions);
(_d = settings.defaultTransformOptions) !== null && _d !== void 0 ? _d : (settings.defaultTransformOptions = this._defaultTransformOptions);
if (settings.autoValidate !== false) {
(_e = settings.validatorFor) !== null && _e !== void 0 ? _e : (settings.validatorFor = this._validatorFor);
if (settings.autoValidate === undefined &&
settings.validatorFor === undefined) {
settings.autoValidate = false;
}
}
return new MemorySource_1(settings);
}
async merge(forkedSource, options) {
let { coalesce, sinceTransformId, transformOptions, ...remainingOptions } = options !== null && options !== void 0 ? options : {};
let requestOptions;
if (transformOptions) {
deprecate('In MemorySource#merge, passing `transformOptions` nested within `options` is deprecated. Instead, include them directly alongside other options.');
requestOptions = transformOptions;
}
else {
requestOptions = (remainingOptions !== null && remainingOptions !== void 0 ? remainingOptions : {});
}
let ops = [];
if (forkedSource.cache.isTrackingUpdateOperations) {
ops = forkedSource.cache.getAllUpdateOperations();
}
else {
let transforms;
if (sinceTransformId) {
deprecate('In MemorySource#merge, passing `sinceTransformId` is deprecated. Instead, call `update` with a custom transform/operations.');
transforms = forkedSource.getTransformsSince(sinceTransformId);
}
else {
transforms = forkedSource.getAllTransforms();
}
transforms.forEach((t) => {
Array.prototype.push.apply(ops, toArray(t.operations));
});
}
if (coalesce !== false) {
ops = coalesceRecordOperations(ops);
}
if (requestOptions.fullResponse) {
return this.update(ops, requestOptions);
}
else {
return this.update(ops, requestOptions);
}
}
/**
* Rebase works similarly to a git rebase:
*
* After a source is forked, there is a parent- and a child-source. Both may
* be updated with transforms. When `childSource.rebase()` is called, the
* child source's state will be reset to match the current state of its
* parent, and then any locally made transforms will be replayed on the child
* source.
*/
rebase() {
const base = this._base;
if (!base) {
throw new Assertion('A `base` source must be defined for `rebase` to work');
}
// reset the state of the cache to match the base cache
this.cache.reset();
// replay all locally made transforms
this.getAllTransforms().forEach((t) => this._applyTransform(t));
// reset the fork point
this._forkPoint = base.transformLog.head;
}
/**
* Reset the source's cache and transform log to its initial state, which will
* be either empty or a matching its `base`, if it has one.
*/
async reset() {
// reset the state of the cache (which will match a base cache, if present)
this.cache.reset();
// reset the fork point
this._forkPoint = this._base ? this._base.transformLog.head : undefined;
// clear the transform log, which in turn will clear any tracked transforms
await this.transformLog.clear();
}
/**
* Rolls back the source to a particular `transformId`.
*
* `relativePosition` can be a positive or negative integer used to specify a
* position relative to `transformId`.
*/
rollback(transformId, relativePosition = 0) {
return this.transformLog.rollback(transformId, relativePosition);
}
/**
* Returns all logged transforms since a particular `transformId`.
*/
getTransformsSince(transformId) {
return this.transformLog
.after(transformId)
.map((id) => this._transforms[id]);
}
/**
* @deprecated since v0.17, call `getTransformsSince` instead
*/
transformsSince(transformId) {
deprecate('MemorySource#transformsSince has been deprecated. Please call `source.getTransformsSince(tranformId)` instead.');
return this.getTransformsSince(transformId);
}
/**
* Returns all logged transforms.
*/
getAllTransforms() {
return this.transformLog.entries.map((id) => this._transforms[id]);
}
/**
* @deprecated since v0.17, call `getAllTransforms` instead
*/
allTransforms() {
deprecate('MemorySource#allTransforms has been deprecated. Please call `source.getAllTransforms()` instead.');
return this.getAllTransforms();
}
getTransform(transformId) {
return this._transforms[transformId];
}
getInverseOperations(transformId) {
return this._transformInverses[transformId];
}
get defaultQueryOptions() {
return super.defaultQueryOptions;
}
set defaultQueryOptions(options) {
super.defaultQueryOptions = this._cache.defaultQueryOptions = options;
}
get defaultTransformOptions() {
return super.defaultTransformOptions;
}
set defaultTransformOptions(options) {
this._defaultTransformOptions = this._cache.defaultTransformOptions = options;
}
/////////////////////////////////////////////////////////////////////////////
// Protected methods
/////////////////////////////////////////////////////////////////////////////
_retrieveQueryExpressionResult(result) {
if (Array.isArray(result)) {
return this._cache.getRecordsSync(result);
}
else if (result) {
return this._cache.getRecordSync(result);
}
else {
return result;
}
}
_retrieveOperationResult(result) {
if (result) {
return this._cache.getRecordSync(result);
}
else {
return result;
}
}
_applyTransform(transform) {
var _a;
const { data, details } = this.cache.update(transform, {
fullResponse: true
});
this._transforms[transform.id] = transform;
this._transformInverses[transform.id] = (_a = details === null || details === void 0 ? void 0 : details.inverseOperations) !== null && _a !== void 0 ? _a : [];
return data;
}
_clearTransformFromHistory(transformId) {
delete this._transforms[transformId];
delete this._transformInverses[transformId];
}
_logCleared() {
this._transforms = {};
this._transformInverses = {};
}
_logTruncated(transformId, relativePosition, removed) {
removed.forEach((id) => this._clearTransformFromHistory(id));
}
_logRolledback(transformId, relativePosition, removed) {
removed.reverse().forEach((id) => {
const inverseOperations = this._transformInverses[id];
if (inverseOperations) {
this.cache.update(inverseOperations);
}
this._clearTransformFromHistory(id);
});
}
};
MemorySource = MemorySource_1 = __decorate([
syncable,
queryable,
updatable
], MemorySource);
export { MemorySource };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVtb3J5LXNvdXJjZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9tZW1vcnktc291cmNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUMvQyxPQUFPLEVBSUwsU0FBUyxFQUlULFFBQVEsRUFDUixTQUFTLEVBQ1YsTUFBTSxhQUFhLENBQUM7QUFFckIsT0FBTyxFQUNMLHdCQUF3QixFQVF4QixZQUFZLEVBUWIsTUFBTSxnQkFBZ0IsQ0FBQztBQUN4QixPQUFPLEVBQVEsT0FBTyxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQzdDLE9BQU8sRUFDTCxXQUFXLEVBR1osTUFBTSxnQkFBZ0IsQ0FBQztBQUV4QixNQUFNLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxHQUFHLEtBQUssQ0FBQztBQTRDcEMsSUFBYSxZQUFZLG9CQUF6QixNQUFhLFlBUVgsU0FBUSxZQUE0QjtJQVlwQyxZQUFZLFFBQXdEOztRQUNsRSxNQUFNLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsR0FBRyxRQUFRLENBQUM7UUFFMUMsUUFBUSxDQUFDLElBQUksR0FBRyxNQUFBLFFBQVEsQ0FBQyxJQUFJLG1DQUFJLFFBQVEsQ0FBQztRQUUxQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUM7UUFFaEIsSUFBSSxDQUFDLFdBQVcsR0FBRyxFQUFFLENBQUM7UUFDdEIsSUFBSSxDQUFDLGtCQUFrQixHQUFHLEVBQUUsQ0FBQztRQUU3QixJQUFJLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUMzRCxJQUFJLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFD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LE9BQWlCO1FBRWpCLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQywwQkFBMEIsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQy9ELENBQUM7SUFFUyxjQUFjLENBQ3RCLFdBQW1CLEVBQ25CLGdCQUF3QixFQUN4QixPQUFpQjtRQUVqQixPQUFPLENBQUMsT0FBTyxFQUFFLENBQUMsT0FBTyxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUU7WUFDL0IsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDdEQsSUFBSSxpQkFBaUIsRUFBRTtnQkFDckIsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsaUJBQWlCLENBQUMsQ0FBQzthQUN0QztZQUNELElBQUksQ0FBQywwQkFBMEIsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUN0QyxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7Q0FDRixDQUFBO0FBNWRZLFlBQVk7SUFIeEIsUUFBUTtJQUNSLFNBQVM7SUFDVCxTQUFTO0dBQ0csWUFBWSxDQTRkeEI7U0E1ZFksWUFBWSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFzc2VydGlvbiwgT3JiaXQgfSBmcm9tICdAb3JiaXQvY29yZSc7XG5pbXBvcnQge1xuICBEZWZhdWx0UmVxdWVzdE9wdGlvbnMsXG4gIEZ1bGxSZXF1ZXN0T3B0aW9ucyxcbiAgRnVsbFJlc3BvbnNlLFxuICBxdWVyeWFibGUsXG4gIFJlcXVlc3RPcHRpb25zLFxuICBSZXNldHRhYmxlLFxuICBSZXNwb25zZUhpbnRzLFxuICBzeW5jYWJsZSxcbiAgdXBkYXRhYmxlXG59IGZyb20gJ0BvcmJpdC9kYXRhJztcbmltcG9ydCB7IFJlY29yZENhY2hlVXBkYXRlRGV0YWlscyB9IGZyb20gJ0BvcmJpdC9yZWNvcmQtY2FjaGUnO1xuaW1wb3J0IHtcbiAgY29hbGVzY2VSZWNvcmRPcGVyYXRpb25zLFxuICBSZWNvcmRPcGVyYXRpb24sXG4gIFJlY29yZE9wZXJhdGlvblJlc3VsdCxcbiAgUmVjb3JkUXVlcnksXG4gIFJlY29yZFF1ZXJ5YWJsZSxcbiAgUmVjb3JkUXVlcnlCdWlsZGVyLFxuICBSZWNvcmRRdWVyeUV4cHJlc3Npb25SZXN1bHQsXG4gIFJlY29yZFF1ZXJ5UmVzdWx0LFxuICBSZWNvcmRTb3VyY2UsXG4gIFJlY29yZFNvdXJjZVF1ZXJ5T3B0aW9ucyxcbiAgUmVjb3JkU291cmNlU2V0dGluZ3MsXG4gIFJlY29yZFN5bmNhYmxlLFxuICBSZWNvcmRUcmFuc2Zvcm0sXG4gIFJlY29yZFRyYW5zZm9ybUJ1aWxkZXIsXG4gIFJlY29yZFRyYW5zZm9ybVJlc3VsdCxcbiAgUmVjb3JkVXBkYXRhYmxlXG59IGZyb20gJ0BvcmJpdC9yZWNvcmRzJztcbmltcG9ydCB7IERpY3QsIHRvQXJyYXkgfSBmcm9tICdAb3JiaXQvdXRpbHMnO1xuaW1wb3J0IHtcbiAgTWVtb3J5Q2FjaGUsXG4gIE1lbW9yeUNhY2hlQ2xhc3MsXG4gIE1lbW9yeUNhY2hlU2V0dGluZ3Ncbn0gZnJvbSAnLi9tZW1vcnktY2FjaGUnO1xuXG5jb25zdCB7IGFzc2VydCwgZGVwcmVjYXRlIH0gPSBPcmJpdDtcblxuZXhwb3J0IGludGVyZmFjZSBNZW1vcnlTb3VyY2VTZXR0aW5nczxcbiAgUU8gZXh0ZW5kcyBSZXF1ZXN0T3B0aW9ucyA9IFJlY29yZFNvdXJjZVF1ZXJ5T3B0aW9ucyxcbiAgVE8gZXh0ZW5kcyBSZXF1ZXN0T3B0aW9ucyA9IFJlcXVlc3RPcHRpb25zLFxuICBRQiA9IFJlY29yZFF1ZXJ5QnVpbGRlcixcbiAgVEIgPSBSZWNvcmRUcmFuc2Zvcm1CdWlsZGVyLFxuICBRUkQgPSB1bmtub3duLFxuICBUUkQgZXh0ZW5kcyBSZWNvcmRDYWNoZVVwZGF0ZURldGFpbHMgPSBSZWNvcmRDYWNoZVVwZGF0ZURldGFpbHNcbj4gZXh0ZW5kcyBSZWNvcmRTb3VyY2VTZXR0aW5nczxRTywgVE8sIFFCLCBUQj4ge1xuICBiYXNlPzogTWVtb3J5U291cmNlPFFPLCBUTywgUUIsIFRCLCBRUkQsIFRSRD47XG4gIGNhY2hlQ2xhc3M/OiBNZW1vcnlDYWNoZUNsYXNzPFFPLCBUTywgUUIsIFRCLCBRUkQsIFRSRD47XG4gIGNhY2hlU2V0dGluZ3M/OiBQYXJ0aWFsPE1lbW9yeUNhY2hlU2V0dGluZ3M8UU8sIFRPLCBRQiwgVEIsIFFSRCwgVFJEPj47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTWVtb3J5U291cmNlTWVyZ2VPcHRpb25zIHtcbiAgY29hbGVzY2U/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBAZGVwcmVjYXRlZCBzaW5jZSB2MC4xN1xuICAgKi9cbiAgc2luY2VUcmFuc2Zvcm1JZD86IHN0cmluZztcblxuICAvKipcbiAgICogQGRlcHJlY2F0ZWQgc2luY2UgdjAuMTcsIGluY2x1ZGUgdHJhbnNmb3JtIG9wdGlvbnMgYWxvbmdzaWRlIG1lcmdlIG9wdGlvbnMgaW5zdGVhZFxuICAgKi9cbiAgdHJhbnNmb3JtT3B0aW9ucz86IFJlcXVlc3RPcHRpb25zO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIE1lbW9yeVNvdXJjZTxcbiAgUU8gZXh0ZW5kcyBSZXF1ZXN0T3B0aW9ucyA9IFJlY29yZFNvdXJjZVF1ZXJ5T3B0aW9ucyxcbiAgVE8gZXh0ZW5kcyBSZXF1ZXN0T3B0aW9ucyA9IFJlcXVlc3RPcHRpb25zLFxuICBRQiA9IFJlY29yZFF1ZXJ5QnVpbGRlcixcbiAgVEIgPSBSZWNvcmRUcmFuc2Zvcm1CdWlsZGVyLFxuICBRUkQgPSB1bmtub3duLFxuICBUUkQgZXh0ZW5kcyBSZWNvcmRDYWNoZVVwZGF0ZURldGFpbHMgPSBSZWNvcmRDYWNoZVVwZGF0ZURldGFpbHNcbj4gZXh0ZW5kcyBSZWNvcmRTb3VyY2U8UU8sIFRPLCBRQiwgVEI+LFxuICAgIFJlY29yZFN5bmNhYmxlLFxuICAgIFJlY29yZFF1ZXJ5YWJsZTxRUkQsIFFCLCBRTz4sXG4gICAgUmVjb3JkVXBkYXRhYmxlPFRSRCwgVEIsIFRPPiB7fVxuXG5Ac3luY2FibGVcbkBxdWVyeWFibGVcbkB1cGRhdGFibGVcbmV4cG9ydCBjbGFzcyBNZW1vcnlTb3VyY2U8XG4gICAgUU8gZXh0ZW5kcyBSZXF1ZXN0T3B0aW9ucyA9IFJlY29yZFNvdXJjZVF1ZXJ5T3B0aW9ucyxcbiAgICBUTyBleHRlbmRzIFJlcXVlc3RPcHRpb25zID0gUmVxdWVzdE9wdGlvbnMsXG4gICAgUUIgPSBSZWNvcmRRdWVyeUJ1aWxkZXIsXG4gICAgVEIgPSBSZWNvcmRUcmFuc2Zvcm1CdWlsZGVyLFxuICAgIFFSRCA9IHVua25vd24sXG4gICAgVFJEIGV4dGVuZHMgUmVjb3JkQ2FjaGVVcGRhdGVEZXRhaWxzID0gUmVjb3JkQ2FjaGVVcGRhdGVEZXRhaWxzXG4gID5cbiAgZXh0ZW5kcyBSZWNvcmRTb3VyY2U8UU8sIFRPLCBRQiwgVEI+XG4gIGltcGxlbWVudHNcbiAgICBSZWNvcmRTeW5jYWJsZSxcbiAgICBSZWNvcmRRdWVyeWFibGU8UVJELCBRQiwgUU8+LFxuICAgIFJlY29yZFVwZGF0YWJsZTxUUkQsIFRCLCBUTz4sXG4gICAgUmVzZXR0YWJsZSB7XG4gIHByb3RlY3RlZCBfY2FjaGU6IE1lbW9yeUNhY2hlPFFPLCBUTywgUUIsIFRCLCBRUkQsIFRSRD47XG4gIHByb3RlY3RlZCBfYmFzZT86IE1lbW9yeVNvdXJjZTxRTywgVE8sIFFCLCBUQiwgUVJELCBUUkQ+O1xuICBwcm90ZWN0ZWQgX2ZvcmtQb2ludD86IHN0cmluZztcbiAgcHJvdGVjdGVkIF90cmFuc2Zvcm1zOiBEaWN0PFJlY29yZFRyYW5zZm9ybT47XG4gIHByb3RlY3RlZCBfdHJhbnNmb3JtSW52ZXJzZXM6IERpY3Q8UmVjb3JkT3BlcmF0aW9uW10+O1xuXG4gIGNvbnN0cnVjdG9yKHNldHRpbmdzOiBNZW1vcnlTb3VyY2VTZXR0aW5nczxRTywgVE8sIFFCLCBUQiwgUVJELCBUUkQ+KSB7XG4gICAgY29uc3QgeyBrZXlNYXAsIHNjaGVtYSwgYmFzZSB9ID0gc2V0dGluZ3M7XG5cbiAgICBzZXR0aW5ncy5uYW1lID0gc2V0dGluZ3MubmFtZSA/PyAnbWVtb3J5JztcblxuICAgIHN1cGVyKHNldHRpbmdzKTtcblxuICAgIHRoaXMuX3RyYW5zZm9ybXMgPSB7fTtcbiAgICB0aGlzLl90cmFuc2Zvcm1JbnZlcnNlcyA9IHt9O1xuXG4gICAgdGhpcy50cmFuc2Zvcm1Mb2cub24oJ2NsZWFyJywgdGhpcy5fbG9nQ2xlYXJlZC5iaW5kKHRoaXMpKTtcbiAgICB0aGlzLnRyYW5zZm9ybUxvZy5vbigndHJ1bmNhdGUnLCB0aGlzLl9sb2dUcnVuY2F0ZWQuYmluZCh0aGlzKSk7XG4gICAgdGhpcy50cmFuc2Zvcm1Mb2cub24oJ3JvbGxiYWNrJywgdGhpcy5fbG9nUm9sbGVkYmFjay5iaW5kKHRoaXMpKTtcblxuICAgIGxldCBjYWNoZVNldHRpbmdzOiBQYXJ0aWFsPE1lbW9yeUNhY2hlU2V0dGluZ3M8UU8sIFRPLCBRQiwgVEIsIFFSRCwgVFJEPj4gPVxuICAgICAgc2V0dGluZ3MuY2FjaGVTZXR0aW5ncyA/PyB7fTtcbiAgICBjYWNoZVNldHRpbmdzLnNjaGVtYSA9IHNjaGVtYTtcbiAgICBjYWNoZVNldHRpbmdzLmtleU1hcCA9IGtleU1hcDtcbiAgICBjYWNoZVNldHRpbmdzLnF1ZXJ5QnVpbGRlciA/Pz0gdGhpcy5xdWVyeUJ1aWxkZXI7XG4gICAgY2FjaGVTZXR0aW5ncy50cmFuc2Zvcm1CdWlsZGVyID8/PSB0aGlzLnRyYW5zZm9ybUJ1aWxkZXI7XG4gICAgY2FjaGVTZXR0aW5ncy5kZWZhdWx0UXVlcnlPcHRpb25zID8/PSB0aGlzLmRlZmF1bHRRdWVyeU9wdGlvbnM7XG4gICAgY2FjaGVTZXR0aW5ncy5kZWZhdWx0VHJhbnNmb3JtT3B0aW9ucyA/Pz0gdGhpcy5kZWZhdWx0VHJhbnNmb3JtT3B0aW9ucztcbiAgICBjYWNoZVNldHRpbmdzLmF1dG9WYWxpZGF0ZSA/Pz0gc2V0dGluZ3MuYXV0b1ZhbGlkYXRlO1xuXG4gICAgaWYgKFxuICAgICAgY2FjaGVTZXR0aW5ncy5hdXRvVmFsaWRhdGUgIT09IGZhbHNlICYmXG4gICAgICBjYWNoZVNldHRpbmdzLnZhbGlkYXRvckZvciA9PT0gdW5kZWZpbmVkICYmXG4gICAgICBjYWNoZVNldHRpbmdzLnZhbGlkYXRvcnMgPT09IHVuZGVmaW5lZFxuICAgICkge1xuICAgICAgY2FjaGVTZXR0aW5ncy52YWxpZGF0b3JGb3IgPSB0aGlzLl92YWxpZGF0b3JGb3I7XG4gICAgfVxuXG4gICAgaWYgKGJhc2UpIHtcbiAgICAgIHRoaXMuX2Jhc2UgPSBiYXNlO1xuICAgICAgdGhpcy5fZm9ya1BvaW50ID0gYmFzZS50cmFuc2Zvcm1Mb2cuaGVhZDtcbiAgICAgIGNhY2hlU2V0dGluZ3MuYmFzZSA9IGJhc2UuY2FjaGU7XG4gICAgfVxuXG4gICAgY29uc3QgY2FjaGVDbGFzcyA9IHNldHRpbmdzLmNhY2hlQ2xhc3MgPz8gTWVtb3J5Q2FjaGU7XG4gICAgdGhpcy5fY2FjaGUgPSBuZXcgY2FjaGVDbGFzcyhcbiAgICAgIGNhY2hlU2V0dGluZ3MgYXMgTWVtb3J5Q2FjaGVTZXR0aW5nczxRTywgVE8sIFFCLCBUQiwgUVJELCBUUkQ+XG4gICAgKTtcbiAgfVxuXG4gIGdldCBjYWNoZSgpOiBNZW1vcnlDYWNoZTxRTywgVE8sIFFCLCBUQiwgUVJELCBUUkQ+IHtcbiAgICByZXR1cm4gdGhpcy5fY2FjaGU7XG4gIH1cblxuICBnZXQgYmFzZSgpOiBNZW1vcnlTb3VyY2U8UU8sIFRPLCBRQiwgVEIsIFFSRCwgVFJEPiB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuX2Jhc2U7XG4gIH1cblxuICBnZXQgZm9ya1BvaW50KCk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuX2ZvcmtQb2ludDtcbiAgfVxuXG4gIGFzeW5jIHVwZ3JhZGUoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5fY2FjaGUudXBncmFkZSgpO1xuICB9XG5cbiAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbiAgLy8gU3luY2FibGUgaW50ZXJmYWNlIGltcGxlbWVudGF0aW9uXG4gIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbiAgYXN5bmMgX3N5bmModHJhbnNmb3JtOiBSZWNvcmRUcmFuc2Zvcm0pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoIXRoaXMudHJhbnNmb3JtTG9nLmNvbnRhaW5zKHRyYW5zZm9ybS5pZCkpIHtcbiAgICAgIHRoaXMuX2FwcGx5VHJhbnNmb3JtKHRyYW5zZm9ybSk7XG4gICAgICBhd2FpdCB0aGlzLnRyYW5zZm9ybWVkKFt0cmFuc2Zvcm1dKTtcbiAgICB9XG4gIH1cblxuICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuICAvLyBVcGRhdGFibGUgaW50ZXJmYWNlIGltcGxlbWVudGF0aW9uXG4gIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbiAgYXN5bmMgX3VwZGF0ZShcbiAgICB0cmFuc2Zvcm06IFJlY29yZFRyYW5zZm9ybSxcbiAgICBoaW50cz86IFJlc3BvbnNlSGludHM8UmVjb3JkVHJhbnNmb3JtUmVzdWx0LCBUUkQ+XG4gICk6IFByb21pc2U8RnVsbFJlc3BvbnNlPFJlY29yZFRyYW5zZm9ybVJlc3VsdCwgVFJELCBSZWNvcmRPcGVyYXRpb24+PiB7XG4gICAgbGV0IHJlc3VsdHM6IFJlY29yZFRyYW5zZm9ybVJlc3VsdDtcbiAgICBjb25zdCByZXNwb25zZTogRnVsbFJlc3BvbnNlPFxuICAgICAgUmVjb3JkVHJhbnNmb3JtUmVzdWx0LFxuICAgICAgVFJELFxuICAgICAgUmVjb3JkT3BlcmF0aW9uXG4gICAgPiA9IHt9O1xuXG4gICAgaWYgKCF0aGlzLnRyYW5zZm9ybUxvZy5jb250YWlucyh0cmFuc2Zvcm0uaWQpKSB7XG4gICAgICByZXN1bHRzID0gdGhpcy5fYXBwbHlUcmFuc2Zvcm0odHJhbnNmb3JtKTtcbiAgICAgIHJlc3BvbnNlLnRyYW5zZm9ybXMgPSBbdHJhbnNmb3JtXTtcbiAgICB9XG5cbiAgICBpZiAoaGludHM/LmRhdGEpIHtcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KHRyYW5zZm9ybS5vcGVyYXRpb25zKSkge1xuICAgICAgICBhc3NlcnQoXG4gICAgICAgICAgJ01lbW9yeVNvdXJjZSN1cGRhdGU6IGBoaW50cy5kYXRhYCBtdXN0IGJlIGFuIGFycmF5IGlmIGB0cmFuc2Zvcm0ub3BlcmF0aW9uc2AgaXMgYW4gYXJyYXknLFxuICAgICAgICAgIEFycmF5LmlzQXJyYXkoaGludHMuZGF0YSlcbiAgICAgICAgKTtcblxuICAgICAgICByZXNwb25zZS5kYXRhID0gKGhpbnRzLmRhdGEgYXMgUmVjb3JkT3BlcmF0aW9uUmVzdWx0W10pLm1hcCgoaCkgPT5cbiAgICAgICAgICB0aGlzLl9yZXRyaWV2ZU9wZXJhdGlvblJlc3VsdChoKVxuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzcG9uc2UuZGF0YSA9IHRoaXMuX3JldHJpZXZlT3BlcmF0aW9uUmVzdWx0KFxuICAgICAgICAgIGhpbnRzLmRhdGEgYXMgUmVjb3JkT3BlcmF0aW9uUmVzdWx0XG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChyZXN1bHRzKSB7XG4gICAgICByZXNwb25zZS5kYXRhID0gcmVzdWx0cztcbiAgICB9XG5cbiAgICBpZiAoaGludHM/LmRldGFpbHMpIHtcbiAgICAgIHJlc3BvbnNlLmRldGFpbHMgPSBoaW50cy5kZXRhaWxzO1xuICAgIH1cblxuICAgIHJldHVybiByZXNwb25zZTtcbiAgfVxuXG4gIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4gIC8vIFF1ZXJ5YWJsZSBpbnRlcmZhY2UgaW1wbGVtZW50YXRpb25cbiAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuICBhc3luYyBfcXVlcnkoXG4gICAgcXVlcnk6IFJlY29yZFF1ZXJ5LFxuICAgIGhpbnRzPzogUmVzcG9uc2VIaW50czxSZWNvcmRRdWVyeVJlc3VsdCwgUVJEPlxuICApOiBQcm9taXNlPEZ1bGxSZXNwb25zZTxSZWNvcmRRdWVyeVJlc3VsdCwgUVJELCBSZWNvcmRPcGVyYXRpb24+PiB7XG4gICAgbGV0IHJlc3BvbnNlOiBGdWxsUmVzcG9uc2U8UmVjb3JkUXVlcnlSZXN1bHQsIFFSRCwgUmVjb3JkT3BlcmF0aW9uPjtcblxuICAgIGlmIChoaW50cz8uZGF0YSkge1xuICAgICAgcmVzcG9uc2UgPSB7fTtcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KHF1ZXJ5LmV4cHJlc3Npb25zKSkge1xuICAgICAgICBhc3NlcnQoXG4gICAgICAgICAgJ01lbW9yeVNvdXJjZSNxdWVyeTogYGhpbnRzLmRhdGFgIG11c3QgYmUgYW4gYXJyYXkgaWYgYHF1ZXJ5LmV4cHJlc3Npb25zYCBpcyBhbiBhcnJheScsXG4gICAgICAgICAgQXJyYXkuaXNBcnJheShoaW50cy5kYXRhKVxuICAgICAgICApO1xuXG4gICAgICAgIHJlc3BvbnNlLmRhdGEgPSAoaGludHMuZGF0YSBhcyBSZWNvcmRRdWVyeUV4cHJlc3Npb25SZXN1bHRbXSkubWFwKChoKSA9PlxuICAgICAgICAgIHRoaXMuX3JldHJpZXZlUXVlcnlFeHByZXNzaW9uUmVzdWx0KGgpXG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXNwb25zZS5kYXRhID0gdGhpcy5fcmV0cmlldmVRdWVyeUV4cHJlc3Npb25SZXN1bHQoXG4gICAgICAgICAgaGludHMuZGF0YSBhcyBSZWNvcmRRdWVyeUV4cHJlc3Npb25SZXN1bHRcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgcmVzcG9uc2UgPSB0aGlzLl9jYWNoZS5xdWVyeShxdWVyeSwge1xuICAgICAgICBmdWxsUmVzcG9uc2U6IHRydWVcbiAgICAgIH0gYXMgRnVsbFJlcXVlc3RPcHRpb25zPFFPPik7XG4gICAgfVxuXG4gICAgaWYgKGhpbnRzPy5kZXRhaWxzKSB7XG4gICAgICByZXNwb25zZS5kZXRhaWxzID0gaGludHMuZGV0YWlscztcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzcG9uc2U7XG4gIH1cblxuICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuICAvLyBQdWJsaWMgbWV0aG9kc1xuICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBjbG9uZSwgb3IgXCJmb3JrXCIsIGZyb20gYSBcImJhc2VcIiBzb3VyY2UuXG4gICAqXG4gICAqIFRoZSBmb3JrZWQgc291cmNlIHdpbGwgaGF2ZSB0aGUgc2FtZSBgc2NoZW1hYCBhbmQgYGtleU1hcGAgYXMgaXRzIGJhc2Ugc291cmNlLlxuICAgKiBUaGUgZm9ya2VkIHNvdXJjZSdzIGNhY2hlIHdpbGwgc3RhcnQgd2l0aCB0aGUgc2FtZSBpbW11dGFibGUgZG9jdW1lbnQgYXNcbiAgICogdGhlIGJhc2Ugc291cmNlLiBJdHMgY29udGVudHMgYW5kIGxvZyB3aWxsIGV2b2x2ZSBpbmRlcGVuZGVudGx5LlxuICAgKlxuICAgKiBAcmV0dXJucyBUaGUgZm9ya2VkIHNvdXJjZS5cbiAgICovXG4gIGZvcmsoXG4gICAgc2V0dGluZ3M6IFBhcnRpYWw8TWVtb3J5U291cmNlU2V0dGluZ3M8UU8sIFRPLCBRQiwgVEIsIFFSRCwgVFJEPj4gPSB7fVxuICApOiBNZW1vcnlTb3VyY2U8UU8sIFRPLCBRQiwgVEIsIFFSRCwgVFJEPiB7XG4gICAgLy8gcmVxdWlyZWQgc2V0dGluZ3NcbiAgICBzZXR0aW5ncy5iYXNlID0gdGhpcztcbiAgICBzZXR0aW5ncy5zY2hlbWEgPSB0aGlzLnNjaGVtYTtcbiAgICBzZXR0aW5ncy5rZXlNYXAgPSB0aGlzLmtleU1hcDtcblxuICAgIC8vIGN1c3RvbWl6YWJsZSBzZXR0aW5nc1xuICAgIHNldHRpbmdzLnF1ZXJ5QnVpbGRlciA/Pz0gdGhpcy5fcXVlcnlCdWlsZGVyO1xuICAgIHNldHRpbmdzLnRyYW5zZm9ybUJ1aWxkZXIgPz89IHRoaXMuX3RyYW5zZm9ybUJ1aWxkZXI7XG4gICAgc2V0dGluZ3MuZGVmYXVsdFF1ZXJ5T3B0aW9ucyA/Pz0gdGhpcy5fZGVmYXVsdFF1ZXJ5T3B0aW9ucztcbiAgICBzZXR0aW5ncy5kZWZhdWx0VHJhbnNmb3JtT3B0aW9ucyA/Pz0gdGhpcy5fZGVmYXVsdFRyYW5zZm9ybU9wdGlvbnM7XG4gICAgaWYgKHNldHRpbmdzLmF1dG9WYWxpZGF0ZSAhPT0gZmFsc2UpIHtcbiAgICAgIHNldHRpbmdzLnZhbGlkYXRvckZvciA/Pz0gdGhpcy5fdmFsaWRhdG9yRm9yO1xuICAgICAgaWYgKFxuICAgICAgICBzZXR0aW5ncy5hdXRvVmFsaWRhdGUgPT09IHVuZGVmaW5lZCAmJlxuICAgICAgICBzZXR0aW5ncy52YWxpZGF0b3JGb3IgPT09IHVuZGVmaW5lZFxuICAgICAgKSB7XG4gICAgICAgIHNldHRpbmdzLmF1dG9WYWxpZGF0ZSA9IGZhbHNlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBuZXcgTWVtb3J5U291cmNlPFFPLCBUTywgUUIsIFRCLCBRUkQsIFRSRD4oXG4gICAgICBzZXR0aW5ncyBhcyBNZW1vcnlTb3VyY2VTZXR0aW5nczxRTywgVE8sIFFCLCBUQiwgUVJELCBUUkQ+XG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNZXJnZSB0cmFuc2Zvcm1zIGZyb20gYSBmb3JrZWQgc291cmNlIGJhY2sgaW50byBhIGJhc2Ugc291cmNlLlxuICAgKlxuICAgKiBCeSBkZWZhdWx0LCBhbGwgb2YgdGhlIG9wZXJhdGlvbnMgZnJvbSBhbGwgb2YgdGhlIHRyYW5zZm9ybXMgaW4gdGhlIGZvcmtlZFxuICAgKiBzb3VyY2UncyBoaXN0b3J5IHdpbGwgYmUgcmVkdWNlZCBpbnRvIGEgc2luZ2xlIHRyYW5zZm9ybS4gQSBzdWJzZXQgb2ZcbiAgICogb3BlcmF0aW9ucyBjYW4gYmUgc2VsZWN0ZWQgYnkgc3BlY2lmeWluZyB0aGUgYHNpbmNlVHJhbnNmb3JtSWRgIG9wdGlvbi5cbiAgICpcbiAgICogVGhlIGBjb2FsZXNjZWAgb3B0aW9uIGNvbnRyb2xzIHdoZXRoZXIgb3BlcmF0aW9ucyBhcmUgY29hbGVzY2VkIGludG8gYVxuICAgKiBtaW5pbWFsIGVxdWl2YWxlbnQgc2V0IGJlZm9yZSBiZWluZyByZWR1Y2VkIGludG8gYSB0cmFuc2Zvcm0uXG4gICAqXG4gICAqIEBwYXJhbSBmb3JrZWRTb3VyY2UgLSBUaGUgc291cmNlIHRvIG1lcmdlLlxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIE1lcmdlIG9wdGlvbnNcbiAgICogQHJldHVybnMgVGhlIHJlc3VsdCBvZiBjYWxsaW5nIGB1cGRhdGUoKWAgd2l0aCB0aGUgZm9ya2VkIHRyYW5zZm9ybXMuXG4gICAqL1xuICBtZXJnZTxSZXF1ZXN0RGF0YSBleHRlbmRzIFJlY29yZFRyYW5zZm9ybVJlc3VsdCA9IFJlY29yZFRyYW5zZm9ybVJlc3VsdD4oXG4gICAgZm9ya2VkU291cmNlOiBNZW1vcnlTb3VyY2U8UU8sIFRPLCBRQiwgVEIsIFFSRCwgVFJEPixcbiAgICBvcHRpb25zPzogRGVmYXVsdFJlcXVlc3RPcHRpb25zPFRPPiAmIE1lbW9yeVNvdXJjZU1lcmdlT3B0aW9uc1xuICApOiBQcm9taXNlPFJlcXVlc3REYXRhPjtcbiAgbWVyZ2U8UmVxdWVzdERhdGEgZXh0ZW5kcyBSZWNvcmRUcmFuc2Zvcm1SZXN1bHQgPSBSZWNvcmRUcmFuc2Zvcm1SZXN1bHQ+KFxuICAgIGZvcmtlZFNvdXJjZTogTWVtb3J5U291cmNlPFFPLCBUTywgUUIsIFRCLCBRUkQsIFRSRD4sXG4gICAgb3B0aW9uczogRnVsbFJlcXVlc3RPcHRpb25zPFRPPiAmIE1lbW9yeVNvdXJjZU1lcmdlT3B0aW9uc1xuICApOiBQcm9taXNlPEZ1bGxSZXNwb25zZTxSZXF1ZXN0RGF0YSwgVFJELCBSZWNvcmRPcGVyYXRpb24+PjtcbiAgYXN5bmMgbWVyZ2U8XG4gICAgUmVxdWVzdERhdGEgZXh0ZW5kcyBSZWNvcmRUcmFuc2Zvcm1SZXN1bHQgPSBSZWNvcmRUcmFuc2Zvcm1SZXN1bHRcbiAgPihcbiAgICBmb3JrZWRTb3VyY2U6IE1lbW9yeVNvdXJjZTxRTywgVE8sIFFCLCBUQiwgUVJELCBUUkQ+LFxuICAgIG9wdGlvbnM/OiBUTyAmIE1lbW9yeVNvdXJjZU1lcmdlT3B0aW9uc1xuICApOiBQcm9taXNlPFxuICAgIFJlY29yZFRyYW5zZm9ybVJlc3VsdCB8IEZ1bGxSZXNwb25zZTxSZXF1ZXN0RGF0YSwgVFJELCBSZWNvcmRPcGVyYXRpb24+XG4gID4ge1xuICAgIGxldCB7IGNvYWxlc2NlLCBzaW5jZVRyYW5zZm9ybUlkLCB0cmFuc2Zvcm1PcHRpb25zLCAuLi5yZW1haW5pbmdPcHRpb25zIH0gPVxuICAgICAgb3B0aW9ucyA/PyB7fTtcblxuICAgIGxldCByZXF1ZXN0T3B0aW9uczogVE87XG4gICAgaWYgKHRyYW5zZm9ybU9wdGlvbnMpIHtcbiAgICAgIGRlcHJlY2F0ZShcbiAgICAgICAgJ0luIE1lbW9yeVNvdXJjZSNtZXJnZSwgcGFzc2luZyBgdHJhbnNmb3JtT3B0aW9uc2AgbmVzdGVkIHdpdGhpbiBgb3B0aW9uc2AgaXMgZGVwcmVjYXRlZC4gSW5zdGVhZCwgaW5jbHVkZSB0aGVtIGRpcmVjdGx5IGFsb25nc2lkZSBvdGhlciBvcHRpb25zLidcbiAgICAgICk7XG4gICAgICByZXF1ZXN0T3B0aW9ucyA9IHRyYW5zZm9ybU9wdGlvbnMgYXMgVE87XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlcXVlc3RPcHRpb25zID0gKHJlbWFpbmluZ09wdGlvbnMgPz8ge30pIGFzIFRPO1xuICAgIH1cblxuICAgIGxldCBvcHM6IFJlY29yZE9wZXJhdGlvbltdID0gW107XG5cbiAgICBpZiAoZm9ya2VkU291cmNlLmNhY2hlLmlzVHJhY2tpbmdVcGRhdGVPcGVyYXRpb25zKSB7XG4gICAgICBvcHMgPSBmb3JrZWRTb3VyY2UuY2FjaGUuZ2V0QWxsVXBkYXRlT3BlcmF0aW9ucygpO1xuICAgIH0gZWxzZSB7XG4gICAgICBsZXQgdHJhbnNmb3JtczogUmVjb3JkVHJhbnNmb3JtW107XG4gICAgICBpZiAoc2luY2VUcmFuc2Zvcm1JZCkge1xuICAgICAgICBkZXByZWNhdGUoXG4gICAgICAgICAgJ0luIE1lbW9yeVNvdXJjZSNtZXJnZSwgcGFzc2luZyBgc2luY2VUcmFuc2Zvcm1JZGAgaXMgZGVwcmVjYXRlZC4gSW5zdGVhZCwgY2FsbCBgdXBkYXRlYCB3aXRoIGEgY3VzdG9tIHRyYW5zZm9ybS9vcGVyYXRpb25zLidcbiAgICAgICAgKTtcbiAgICAgICAgdHJhbnNmb3JtcyA9IGZvcmtlZFNvdXJjZS5nZXRUcmFuc2Zvcm1zU2luY2Uoc2luY2VUcmFuc2Zvcm1JZCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0cmFuc2Zvcm1zID0gZm9ya2VkU291cmNlLmdldEFsbFRyYW5zZm9ybXMoKTtcbiAgICAgIH1cblxuICAgICAgdHJhbnNmb3Jtcy5mb3JFYWNoKCh0KSA9PiB7XG4gICAgICAgIEFycmF5LnByb3RvdHlwZS5wdXNoLmFwcGx5KG9wcywgdG9BcnJheSh0Lm9wZXJhdGlvbnMpKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChjb2FsZXNjZSAhPT0gZmFsc2UpIHtcbiAgICAgIG9wcyA9IGNvYWxlc2NlUmVjb3JkT3BlcmF0aW9ucyhvcHMpO1xuICAgIH1cblxuICAgIGlmIChyZXF1ZXN0T3B0aW9ucy5mdWxsUmVzcG9uc2UpIHtcbiAgICAgIHJldHVybiB0aGlzLnVwZGF0ZTxSZXF1ZXN0RGF0YT4oXG4gICAgICAgIG9wcyxcbiAgICAgICAgcmVxdWVzdE9wdGlvbnMgYXMgRnVsbFJlcXVlc3RPcHRpb25zPFRPPlxuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHRoaXMudXBkYXRlPFJlcXVlc3REYXRhPihcbiAgICAgICAgb3BzLFxuICAgICAgICByZXF1ZXN0T3B0aW9ucyBhcyBEZWZhdWx0UmVxdWVzdE9wdGlvbnM8VE8+XG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZWJhc2Ugd29ya3Mgc2ltaWxhcmx5IHRvIGEgZ2l0IHJlYmFzZTpcbiAgICpcbiAgICogQWZ0ZXIgYSBzb3VyY2UgaXMgZm9ya2VkLCB0aGVyZSBpcyBhIHBhcmVudC0gYW5kIGEgY2hpbGQtc291cmNlLiBCb3RoIG1heVxuICAgKiBiZSB1cGRhdGVkIHdpdGggdHJhbnNmb3Jtcy4gV2hlbiBgY2hpbGRTb3VyY2UucmViYXNlKClgIGlzIGNhbGxlZCwgdGhlXG4gICAqIGNoaWxkIHNvdXJjZSdzIHN0YXRlIHdpbGwgYmUgcmVzZXQgdG8gbWF0Y2ggdGhlIGN1cnJlbnQgc3RhdGUgb2YgaXRzXG4gICAqIHBhcmVudCwgYW5kIHRoZW4gYW55IGxvY2FsbHkgbWFkZSB0cmFuc2Zvcm1zIHdpbGwgYmUgcmVwbGF5ZWQgb24gdGhlIGNoaWxkXG4gICAqIHNvdXJjZS5cbiAgICovXG4gIHJlYmFzZSgpOiB2b2lkIHtcbiAgICBjb25zdCBiYXNlID0gdGhpcy5fYmFzZTtcblxuICAgIGlmICghYmFzZSkge1xuICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbihcbiAgICAgICAgJ0EgYGJhc2VgIHNvdXJjZSBtdXN0IGJlIGRlZmluZWQgZm9yIGByZWJhc2VgIHRvIHdvcmsnXG4gICAgICApO1xuICAgIH1cblxuICAgIC8vIHJlc2V0IHRoZSBzdGF0ZSBvZiB0aGUgY2FjaGUgdG8gbWF0Y2ggdGhlIGJhc2UgY2FjaGVcbiAgICB0aGlzLmNhY2hlLnJlc2V0KCk7XG5cbiAgICAvLyByZXBsYXkgYWxsIGxvY2FsbHkgbWFkZSB0cmFuc2Zvcm1zXG4gICAgdGhpcy5nZXRBbGxUcmFuc2Zvcm1zKCkuZm9yRWFjaCgodCkgPT4gdGhpcy5fYXBwbHlUcmFuc2Zvcm0odCkpO1xuXG4gICAgLy8gcmVzZXQgdGhlIGZvcmsgcG9pbnRcbiAgICB0aGlzLl9mb3JrUG9pbnQgPSBiYXNlLnRyYW5zZm9ybUxvZy5oZWFkO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlc2V0IHRoZSBzb3VyY2UncyBjYWNoZSBhbmQgdHJhbnNmb3JtIGxvZyB0byBpdHMgaW5pdGlhbCBzdGF0ZSwgd2hpY2ggd2lsbFxuICAgKiBiZSBlaXRoZXIgZW1wdHkgb3IgYSBtYXRjaGluZyBpdHMgYGJhc2VgLCBpZiBpdCBoYXMgb25lLlxuICAgKi9cbiAgYXN5bmMgcmVzZXQoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgLy8gcmVzZXQgdGhlIHN0YXRlIG9mIHRoZSBjYWNoZSAod2hpY2ggd2lsbCBtYXRjaCBhIGJhc2UgY2FjaGUsIGlmIHByZXNlbnQpXG4gICAgdGhpcy5jYWNoZS5yZXNldCgpO1xuXG4gICAgLy8gcmVzZXQgdGhlIGZvcmsgcG9pbnRcbiAgICB0aGlzLl9mb3JrUG9pbnQgPSB0aGlzLl9iYXNlID8gdGhpcy5fYmFzZS50cmFuc2Zvcm1Mb2cuaGVhZCA6IHVuZGVmaW5lZDtcblxuICAgIC8vIGNsZWFyIHRoZSB0cmFuc2Zvcm0gbG9nLCB3aGljaCBpbiB0dXJuIHdpbGwgY2xlYXIgYW55IHRyYWNrZWQgdHJhbnNmb3Jtc1xuICAgIGF3YWl0IHRoaXMudHJhbnNmb3JtTG9nLmNsZWFyKCk7XG4gIH1cblxuICAvKipcbiAgICogUm9sbHMgYmFjayB0aGUgc291cmNlIHRvIGEgcGFydGljdWxhciBgdHJhbnNmb3JtSWRgLlxuICAgKlxuICAgKiBgcmVsYXRpdmVQb3NpdGlvbmAgY2FuIGJlIGEgcG9zaXRpdmUgb3IgbmVnYXRpdmUgaW50ZWdlciB1c2VkIHRvIHNwZWNpZnkgYVxuICAgKiBwb3NpdGlvbiByZWxhdGl2ZSB0byBgdHJhbnNmb3JtSWRgLlxuICAgKi9cbiAgcm9sbGJhY2sodHJhbnNmb3JtSWQ6IHN0cmluZywgcmVsYXRpdmVQb3NpdGlvbiA9IDApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gdGhpcy50cmFuc2Zvcm1Mb2cucm9sbGJhY2sodHJhbnNmb3JtSWQsIHJlbGF0aXZlUG9zaXRpb24pO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYWxsIGxvZ2dlZCB0cmFuc2Zvcm1zIHNpbmNlIGEgcGFydGljdWxhciBgdHJhbnNmb3JtSWRgLlxuICAgKi9cbiAgZ2V0VHJhbnNmb3Jtc1NpbmNlKHRyYW5zZm9ybUlkOiBzdHJpbmcpOiBSZWNvcmRUcmFuc2Zvcm1bXSB7XG4gICAgcmV0dXJuIHRoaXMudHJhbnNmb3JtTG9nXG4gICAgICAuYWZ0ZXIodHJhbnNmb3JtSWQpXG4gICAgICAubWFwKChpZCkgPT4gdGhpcy5fdHJhbnNmb3Jtc1tpZF0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXByZWNhdGVkIHNpbmNlIHYwLjE3LCBjYWxsIGBnZXRUcmFuc2Zvcm1zU2luY2VgIGluc3RlYWRcbiAgICovXG4gIHRyYW5zZm9ybXNTaW5jZSh0cmFuc2Zvcm1JZDogc3RyaW5nKTogUmVjb3JkVHJhbnNmb3JtW10ge1xuICAgIGRlcHJlY2F0ZShcbiAgICAgICdNZW1vcnlTb3VyY2UjdHJhbnNmb3Jtc1NpbmNlIGhhcyBiZWVuIGRlcHJlY2F0ZWQuIFBsZWFzZSBjYWxsIGBzb3VyY2UuZ2V0VHJhbnNmb3Jtc1NpbmNlKHRyYW5mb3JtSWQpYCBpbnN0ZWFkLidcbiAgICApO1xuICAgIHJldHVybiB0aGlzLmdldFRyYW5zZm9ybXNTaW5jZSh0cmFuc2Zvcm1JZCk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhbGwgbG9nZ2VkIHRyYW5zZm9ybXMuXG4gICAqL1xuICBnZXRBbGxUcmFuc2Zvcm1zKCk6IFJlY29yZFRyYW5zZm9ybVtdIHtcbiAgICByZXR1cm4gdGhpcy50cmFuc2Zvcm1Mb2cuZW50cmllcy5tYXAoKGlkKSA9PiB0aGlzLl90cmFuc2Zvcm1zW2lkXSk7XG4gIH1cblxuICAvKipcbiAgICogQGRlcHJlY2F0ZWQgc2luY2UgdjAuMTcsIGNhbGwgYGdldEFsbFRyYW5zZm9ybXNgIGluc3RlYWRcbiAgICovXG4gIGFsbFRyYW5zZm9ybXMoKTogUmVjb3JkVHJhbnNmb3JtW10ge1xuICAgIGRlcHJlY2F0ZShcbiAgICAgICdNZW1vcnlTb3VyY2UjYWxsVHJhbnNmb3JtcyBoYXMgYmVlbiBkZXByZWNhdGVkLiBQbGVhc2UgY2FsbCBgc291cmNlLmdldEFsbFRyYW5zZm9ybXMoKWAgaW5zdGVhZC4nXG4gICAgKTtcbiAgICByZXR1cm4gdGhpcy5nZXRBbGxUcmFuc2Zvcm1zKCk7XG4gIH1cblxuICBnZXRUcmFuc2Zvcm0odHJhbnNmb3JtSWQ6IHN0cmluZyk6IFJlY29yZFRyYW5zZm9ybSB7XG4gICAgcmV0dXJuIHRoaXMuX3RyYW5zZm9ybXNbdHJhbnNmb3JtSWRdO1xuICB9XG5cbiAgZ2V0SW52ZXJzZU9wZXJhdGlvbnModHJhbnNmb3JtSWQ6IHN0cmluZyk6IFJlY29yZE9wZXJhdGlvbltdIHtcbiAgICByZXR1cm4gdGhpcy5fdHJhbnNmb3JtSW52ZXJzZXNbdHJhbnNmb3JtSWRdO1xuICB9XG5cbiAgZ2V0IGRlZmF1bHRRdWVyeU9wdGlvbnMoKTogRGVmYXVsdFJlcXVlc3RPcHRpb25zPFFPPiB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHN1cGVyLmRlZmF1bHRRdWVyeU9wdGlvbnM7XG4gIH1cblxuICBzZXQgZGVmYXVsdFF1ZXJ5T3B0aW9ucyhvcHRpb25zOiBEZWZhdWx0UmVxdWVzdE9wdGlvbnM8UU8+IHwgdW5kZWZpbmVkKSB7XG4gICAgc3VwZXIuZGVmYXVsdFF1ZXJ5T3B0aW9ucyA9IHRoaXMuX2NhY2hlLmRlZmF1bHRRdWVyeU9wdGlvbnMgPSBvcHRpb25zO1xuICB9XG5cbiAgZ2V0IGRlZmF1bHRUcmFuc2Zvcm1PcHRpb25zKCk6IERlZmF1bHRSZXF1ZXN0T3B0aW9uczxUTz4gfCB1bmRlZmluZWQge1xuICAgIHJldHVybiBzdXBlci5kZWZhdWx0VHJhbnNmb3JtT3B0aW9ucztcbiAgfVxuXG4gIHNldCBkZWZhdWx0VHJhbnNmb3JtT3B0aW9ucyhvcHRpb25zOiBEZWZhdWx0UmVxdWVzdE9wdGlvbnM8VE8+IHwgdW5kZWZpbmVkKSB7XG4gICAgdGhpcy5fZGVmYXVsdFRyYW5zZm9ybU9wdGlvbnMgPSB0aGlzLl9jYWNoZS5kZWZhdWx0VHJhbnNmb3JtT3B0aW9ucyA9IG9wdGlvbnM7XG4gIH1cblxuICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuICAvLyBQcm90ZWN0ZWQgbWV0aG9kc1xuICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG4gIHByb3RlY3RlZCBfcmV0cmlldmVRdWVyeUV4cHJlc3Npb25SZXN1bHQoXG4gICAgcmVzdWx0OiBSZWNvcmRRdWVyeUV4cHJlc3Npb25SZXN1bHRcbiAgKTogUmVjb3JkUXVlcnlFeHByZXNzaW9uUmVzdWx0IHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShyZXN1bHQpKSB7XG4gICAgICByZXR1cm4gdGhpcy5fY2FjaGUuZ2V0UmVjb3Jkc1N5bmMocmVzdWx0KTtcbiAgICB9IGVsc2UgaWYgKHJlc3VsdCkge1xuICAgICAgcmV0dXJuIHRoaXMuX2NhY2hlLmdldFJlY29yZFN5bmMocmVzdWx0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgX3JldHJpZXZlT3BlcmF0aW9uUmVzdWx0KFxuICAgIHJlc3VsdDogUmVjb3JkT3BlcmF0aW9uUmVzdWx0XG4gICk6IFJlY29yZE9wZXJhdGlvblJlc3VsdCB7XG4gICAgaWYgKHJlc3VsdCkge1xuICAgICAgcmV0dXJuIHRoaXMuX2NhY2hlLmdldFJlY29yZFN5bmMocmVzdWx0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgX2FwcGx5VHJhbnNmb3JtKHRyYW5zZm9ybTogUmVjb3JkVHJhbnNmb3JtKTogUmVjb3JkVHJhbnNmb3JtUmVzdWx0IHtcbiAgICBjb25zdCB7IGRhdGEsIGRldGFpbHMgfSA9IHRoaXMuY2FjaGUudXBkYXRlKHRyYW5zZm9ybSwge1xuICAgICAgZnVsbFJlc3BvbnNlOiB0cnVlXG4gICAgfSBhcyBGdWxsUmVxdWVzdE9wdGlvbnM8VE8+KTtcbiAgICB0aGlzLl90cmFuc2Zvcm1zW3RyYW5zZm9ybS5pZF0gPSB0cmFuc2Zvcm07XG4gICAgdGhpcy5fdHJhbnNmb3JtSW52ZXJzZXNbdHJhbnNmb3JtLmlkXSA9IGRldGFpbHM/LmludmVyc2VPcGVyYXRpb25zID8/IFtdO1xuICAgIHJldHVybiBkYXRhO1xuICB9XG5cbiAgcHJvdGVjdGVkIF9jbGVhclRyYW5zZm9ybUZyb21IaXN0b3J5KHRyYW5zZm9ybUlkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBkZWxldGUgdGhpcy5fdHJhbnNmb3Jtc1t0cmFuc2Zvcm1JZF07XG4gICAgZGVsZXRlIHRoaXMuX3RyYW5zZm9ybUludmVyc2VzW3RyYW5zZm9ybUlkXTtcbiAgfVxu