UNPKG

@orbit/record-cache

Version:

Orbit base classes used to access and maintain a set of records.

276 lines 49.7 kB
import { Assertion, Orbit } from '@orbit/core'; import { buildQuery, buildTransform, OperationTerm } from '@orbit/data'; import { recordsReferencedByOperations } from '@orbit/records'; import { deepGet, toArray } from '@orbit/utils'; import { SyncLiveQuery } from './live-query/sync-live-query'; import { SyncCacheIntegrityProcessor } from './operation-processors/sync-cache-integrity-processor'; import { SyncSchemaConsistencyProcessor } from './operation-processors/sync-schema-consistency-processor'; import { SyncSchemaValidationProcessor } from './operation-processors/sync-schema-validation-processor'; import { SyncInverseTransformOperators } from './operators/sync-inverse-transform-operators'; import { SyncQueryOperators } from './operators/sync-query-operators'; import { SyncTransformOperators } from './operators/sync-transform-operators'; import { RecordCache } from './record-cache'; import { SyncOperationProcessor } from './sync-operation-processor'; const { assert, deprecate } = Orbit; export class SyncRecordCache extends RecordCache { constructor(settings) { var _a, _b, _c; super(settings); this._queryOperators = (_a = settings.queryOperators) !== null && _a !== void 0 ? _a : SyncQueryOperators; this._transformOperators = (_b = settings.transformOperators) !== null && _b !== void 0 ? _b : SyncTransformOperators; this._inverseTransformOperators = (_c = settings.inverseTransformOperators) !== null && _c !== void 0 ? _c : SyncInverseTransformOperators; this._debounceLiveQueries = settings.debounceLiveQueries !== false; this._transformBuffer = settings.transformBuffer; const processors = settings.processors ? settings.processors : [SyncSchemaConsistencyProcessor, SyncCacheIntegrityProcessor]; if (settings.autoValidate !== false && settings.processors === undefined) { processors.push(SyncSchemaValidationProcessor); } this._processors = processors.map((Processor) => { let processor = new Processor(this); assert('Each processor must extend SyncOperationProcessor', processor instanceof SyncOperationProcessor); return processor; }); } get processors() { return this._processors; } getQueryOperator(op) { return this._queryOperators[op]; } getTransformOperator(op) { return this._transformOperators[op]; } getInverseTransformOperator(op) { return this._inverseTransformOperators[op]; } applyRecordChangesetSync(changeset) { const { setRecords, removeRecords, addInverseRelationships, removeInverseRelationships } = changeset; if (setRecords && setRecords.length > 0) { this.setRecordsSync(setRecords); } if (removeRecords && removeRecords.length > 0) { this.removeRecordsSync(removeRecords); } if (addInverseRelationships && addInverseRelationships.length > 0) { this.addInverseRelationshipsSync(addInverseRelationships); } if (removeInverseRelationships && removeInverseRelationships.length > 0) { this.removeInverseRelationshipsSync(removeInverseRelationships); } } getRelatedRecordSync(identity, relationship) { const record = this.getRecordSync(identity); if (record) { return deepGet(record, ['relationships', relationship, 'data']); } return undefined; } getRelatedRecordsSync(identity, relationship) { const record = this.getRecordSync(identity); if (record) { return deepGet(record, ['relationships', relationship, 'data']); } return undefined; } query(queryOrExpressions, options, id) { const query = buildQuery(queryOrExpressions, options, id, this._queryBuilder); const response = this._query(query, options); if (options === null || options === void 0 ? void 0 : options.fullResponse) { return response; } else { return response.data; } } update(transformOrOperations, options, id) { const transform = buildTransform(transformOrOperations, options, id, this._transformBuilder); const response = this._update(transform, options); if (options === null || options === void 0 ? void 0 : options.fullResponse) { return response; } else { return response.data; } } /** * Patches the cache with an operation or operations. * * @deprecated since v0.17 */ patch(operationOrOperations) { deprecate('SyncRecordCache#patch has been deprecated. Use SyncRecordCache#update instead.'); // TODO - Why is this `this` cast necessary for TS to understand the correct // method overload? const { data, details } = this.update(operationOrOperations, { fullResponse: true }); return { inverse: (details === null || details === void 0 ? void 0 : details.inverseOperations) || [], data: Array.isArray(data) ? data : [data] }; } liveQuery(queryOrExpressions, options, id) { const query = buildQuery(queryOrExpressions, options, id, this.queryBuilder); let debounce = options && options.debounce; if (typeof debounce !== 'boolean') { debounce = this._debounceLiveQueries; } return new SyncLiveQuery({ debounce, cache: this, query }); } ///////////////////////////////////////////////////////////////////////////// // Protected methods ///////////////////////////////////////////////////////////////////////////// _query(query, // eslint-disable-next-line @typescript-eslint/no-unused-vars options) { let data; if (Array.isArray(query.expressions)) { data = []; for (let expression of query.expressions) { const queryOperator = this.getQueryOperator(expression.op); if (!queryOperator) { throw new Error(`Unable to find query operator: ${expression.op}`); } data.push(queryOperator(this, expression, this.getQueryOptions(query, expression))); } } else { const expression = query.expressions; const queryOperator = this.getQueryOperator(expression.op); if (!queryOperator) { throw new Error(`Unable to find query operator: ${expression.op}`); } data = queryOperator(this, expression, this.getQueryOptions(query, expression)); } return { data: data }; } _update(transform, options) { var _a, _b; if ((_a = this.getTransformOptions(transform)) === null || _a === void 0 ? void 0 : _a.useBuffer) { const buffer = this._initTransformBuffer(transform); buffer.startTrackingChanges(); const response = buffer.update(transform, { fullResponse: true }); const changes = buffer.stopTrackingChanges(); this.applyRecordChangesetSync(changes); const { appliedOperations, appliedOperationResults } = response.details; for (let i = 0, len = appliedOperations.length; i < len; i++) { this.emit('patch', appliedOperations[i], appliedOperationResults[i]); } return response; } else { const response = { data: [] }; if (options === null || options === void 0 ? void 0 : options.fullResponse) { response.details = { appliedOperations: [], appliedOperationResults: [], inverseOperations: [] }; } let data; if (Array.isArray(transform.operations)) { this._applyTransformOperations(transform, transform.operations, response, true); data = response.data; } else { this._applyTransformOperation(transform, transform.operations, response, true); if (Array.isArray(response.data)) { data = response.data[0]; } } if (options === null || options === void 0 ? void 0 : options.fullResponse) { (_b = response.details) === null || _b === void 0 ? void 0 : _b.inverseOperations.reverse(); } return { ...response, data }; } } _getTransformBuffer() { if (this._transformBuffer === undefined) { throw new Assertion('transformBuffer must be provided to cache via constructor settings'); } return this._transformBuffer; } _initTransformBuffer(transform) { const buffer = this._getTransformBuffer(); const records = recordsReferencedByOperations(toArray(transform.operations)); const inverseRelationships = this.getInverseRelationshipsSync(records); const relatedRecords = inverseRelationships.map((ir) => ir.record); Array.prototype.push.apply(records, relatedRecords); buffer.resetState(); buffer.setRecordsSync(this.getRecordsSync(records)); buffer.addInverseRelationshipsSync(inverseRelationships); return buffer; } _applyTransformOperations(transform, ops, response, primary = false) { for (const op of ops) { this._applyTransformOperation(transform, op, response, primary); } } _applyTransformOperation(transform, operation, response, primary = false) { var _a, _b, _c, _d; if (operation instanceof OperationTerm) { operation = operation.toOperation(); } for (let processor of this._processors) { processor.validate(operation); } const inverseTransformOperator = this.getInverseTransformOperator(operation.op); const inverseOp = inverseTransformOperator(this, operation, this.getTransformOptions(transform, operation)); if (inverseOp) { (_b = (_a = response.details) === null || _a === void 0 ? void 0 : _a.inverseOperations) === null || _b === void 0 ? void 0 : _b.push(inverseOp); // Query and perform related `before` operations for (let processor of this._processors) { this._applyTransformOperations(transform, processor.before(operation), response); } // Query related `after` operations before performing // the requested operation. These will be applied on success. let preparedOps = []; for (let processor of this._processors) { preparedOps.push(processor.after(operation)); } // Perform the requested operation let transformOperator = this.getTransformOperator(operation.op); let data = transformOperator(this, operation, this.getTransformOptions(transform, operation)); if (primary) { (_c = response.data) === null || _c === void 0 ? void 0 : _c.push(data); } if (response.details) { response.details.appliedOperationResults.push(data); response.details.appliedOperations.push(operation); } // Query and perform related `immediate` operations for (let processor of this._processors) { processor.immediate(operation); } // Emit event this.emit('patch', operation, data); // Perform prepared operations after performing the requested operation for (let ops of preparedOps) { this._applyTransformOperations(transform, ops, response); } // Query and perform related `finally` operations for (let processor of this._processors) { this._applyTransformOperations(transform, processor.finally(operation), response); } } else if (primary) { (_d = response.data) === null || _d === void 0 ? void 0 : _d.push(undefined); } } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3luYy1yZWNvcmQtY2FjaGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc3luYy1yZWNvcmQtY2FjaGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDL0MsT0FBTyxFQUNMLFVBQVUsRUFDVixjQUFjLEVBSWQsYUFBYSxFQUlkLE1BQU0sYUFBYSxDQUFDO0FBQ3JCLE9BQU8sRUFVTCw2QkFBNkIsRUFPOUIsTUFBTSxnQkFBZ0IsQ0FBQztBQUN4QixPQUFPLEVBQUUsT0FBTyxFQUFRLE9BQU8sRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUN0RCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDN0QsT0FBTyxFQUFFLDJCQUEyQixFQUFFLE1BQU0sdURBQXVELENBQUM7QUFDcEcsT0FBTyxFQUFFLDhCQUE4QixFQUFFLE1BQU0sMERBQTBELENBQUM7QUFDMUcsT0FBTyxFQUFFLDZCQUE2QixFQUFFLE1BQU0seURBQXlELENBQUM7QUFDeEcsT0FBTyxFQUVMLDZCQUE2QixFQUM5QixNQUFNLDhDQUE4QyxDQUFDO0FBQ3RELE9BQU8sRUFFTCxrQkFBa0IsRUFDbkIsTUFBTSxrQ0FBa0MsQ0FBQztBQUMxQyxPQUFPLEVBRUwsc0JBQXNCLEVBQ3ZCLE1BQU0sc0NBQXNDLENBQUM7QUFNOUMsT0FBTyxFQUNMLFdBQVcsRUFJWixNQUFNLGdCQUFnQixDQUFDO0FBR3hCLE9BQU8sRUFDTCxzQkFBc0IsRUFFdkIsTUFBTSw0QkFBNEIsQ0FBQztBQUVwQyxNQUFNLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxHQUFHLEtBQUssQ0FBQztBQWdCcEMsTUFBTSxPQUFnQixlQVFwQixTQUFRLFdBQTJCO0lBWW5DLFlBQVksUUFBaUQ7O1FBQzNELEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUVoQixJQUFJLENBQUMsZUFBZSxHQUFH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QUUsU0FBUyxFQUFFLElBQUksQ0FBQyxDQUFDO1lBRXBDLHVFQUF1RTtZQUN2RSxLQUFLLElBQUksR0FBRyxJQUFJLFdBQVcsRUFBRTtnQkFDM0IsSUFBSSxDQUFDLHlCQUF5QixDQUFDLFNBQVMsRUFBRSxHQUFHLEVBQUUsUUFBUSxDQUFDLENBQUM7YUFDMUQ7WUFFRCxpREFBaUQ7WUFDakQsS0FBSyxJQUFJLFNBQVMsSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFO2dCQUN0QyxJQUFJLENBQUMseUJBQXlCLENBQzVCLFNBQVMsRUFDVCxTQUFTLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxFQUM1QixRQUFRLENBQ1QsQ0FBQzthQUNIO1NBQ0Y7YUFBTSxJQUFJLE9BQU8sRUFBRTtZQUNsQixNQUFBLFFBQVEsQ0FBQyxJQUFJLDBDQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztTQUNoQztJQUNILENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFzc2VydGlvbiwgT3JiaXQgfSBmcm9tICdAb3JiaXQvY29yZSc7XG5pbXBvcnQge1xuICBidWlsZFF1ZXJ5LFxuICBidWlsZFRyYW5zZm9ybSxcbiAgRGVmYXVsdFJlcXVlc3RPcHRpb25zLFxuICBGdWxsUmVxdWVzdE9wdGlvbnMsXG4gIEZ1bGxSZXNwb25zZSxcbiAgT3BlcmF0aW9uVGVybSxcbiAgUXVlcnlPckV4cHJlc3Npb25zLFxuICBSZXF1ZXN0T3B0aW9ucyxcbiAgVHJhbnNmb3JtT3JPcGVyYXRpb25zXG59IGZyb20gJ0BvcmJpdC9kYXRhJztcbmltcG9ydCB7XG4gIEluaXRpYWxpemVkUmVjb3JkLFxuICBSZWNvcmRJZGVudGl0eSxcbiAgUmVjb3JkT3BlcmF0aW9uLFxuICBSZWNvcmRPcGVyYXRpb25SZXN1bHQsXG4gIFJlY29yZE9wZXJhdGlvblRlcm0sXG4gIFJlY29yZFF1ZXJ5LFxuICBSZWNvcmRRdWVyeUJ1aWxkZXIsXG4gIFJlY29yZFF1ZXJ5RXhwcmVzc2lvbixcbiAgUmVjb3JkUXVlcnlSZXN1bHQsXG4gIHJlY29yZHNSZWZlcmVuY2VkQnlPcGVyYXRpb25zLFxuICBSZWNvcmRUcmFuc2Zvcm0sXG4gIFJlY29yZFRyYW5zZm9ybUJ1aWxkZXIsXG4gIFJlY29yZFRyYW5zZm9ybUJ1aWxkZXJGdW5jLFxuICBSZWNvcmRUcmFuc2Zvcm1SZXN1bHQsXG4gIFN5bmNSZWNvcmRRdWVyeWFibGUsXG4gIFN5bmNSZWNvcmRVcGRhdGFibGVcbn0gZnJvbSAnQG9yYml0L3JlY29yZHMnO1xuaW1wb3J0IHsgZGVlcEdldCwgRGljdCwgdG9BcnJheSB9IGZyb20gJ0BvcmJpdC91dGlscyc7XG5pbXBvcnQgeyBTeW5jTGl2ZVF1ZXJ5IH0gZnJvbSAnLi9saXZlLXF1ZXJ5L3N5bmMtbGl2ZS1xdWVyeSc7XG5pbXBvcnQgeyBTeW5jQ2FjaGVJbnRlZ3JpdHlQcm9jZXNzb3IgfSBmcm9tICcuL29wZXJhdGlvbi1wcm9jZXNzb3JzL3N5bmMtY2FjaGUtaW50ZWdyaXR5LXByb2Nlc3Nvcic7XG5pbXBvcnQgeyBTeW5jU2NoZW1hQ29uc2lzdGVuY3lQcm9jZXNzb3IgfSBmcm9tICcuL29wZXJhdGlvbi1wcm9jZXNzb3JzL3N5bmMtc2NoZW1hLWNvbnNpc3RlbmN5LXByb2Nlc3Nvcic7XG5pbXBvcnQgeyBTeW5jU2NoZW1hVmFsaWRhdGlvblByb2Nlc3NvciB9IGZyb20gJy4vb3BlcmF0aW9uLXByb2Nlc3NvcnMvc3luYy1zY2hlbWEtdmFsaWRhdGlvbi1wcm9jZXNzb3InO1xuaW1wb3J0IHtcbiAgU3luY0ludmVyc2VUcmFuc2Zvcm1PcGVyYXRvcixcbiAgU3luY0ludmVyc2VUcmFuc2Zvcm1PcGVyYXRvcnNcbn0gZnJvbSAnLi9vcGVyYXRvcnMvc3luYy1pbnZlcnNlLXRyYW5zZm9ybS1vcGVyYXRvcnMnO1xuaW1wb3J0IHtcbiAgU3luY1F1ZXJ5T3BlcmF0b3IsXG4gIFN5bmNRdWVyeU9wZXJhdG9yc1xufSBmcm9tICcuL29wZXJhdG9ycy9zeW5jLXF1ZXJ5LW9wZXJhdG9ycyc7XG5pbXBvcnQge1xuICBTeW5jVHJhbnNmb3JtT3BlcmF0b3IsXG4gIFN5bmNUcmFuc2Zvcm1PcGVyYXRvcnNcbn0gZnJvbSAnLi9vcGVyYXRvcnMvc3luYy10cmFuc2Zvcm0tb3BlcmF0b3JzJztcbmltcG9ydCB7XG4gIFJlY29yZENoYW5nZXNldCxcbiAgUmVjb3JkUmVsYXRpb25zaGlwSWRlbnRpdHksXG4gIFN5bmNSZWNvcmRBY2Nlc3NvclxufSBmcm9tICcuL3JlY29yZC1hY2Nlc3Nvcic7XG5pbXBvcnQge1xuICBSZWNvcmRDYWNoZSxcbiAgUmVjb3JkQ2FjaGVRdWVyeU9wdGlvbnMsXG4gIFJlY29yZENhY2hlU2V0dGluZ3MsXG4gIFJlY29yZENhY2hlVHJhbnNmb3JtT3B0aW9uc1xufSBmcm9tICcuL3JlY29yZC1jYWNoZSc7XG5pbXBvcnQgeyBSZWNvcmRUcmFuc2Zvcm1CdWZmZXIgfSBmcm9tICcuL3JlY29yZC10cmFuc2Zvcm0tYnVmZmVyJztcbmltcG9ydCB7IFBhdGNoUmVzdWx0LCBSZWNvcmRDYWNoZVVwZGF0ZURldGFpbHMgfSBmcm9tICcuL3Jlc3BvbnNlJztcbmltcG9ydCB7XG4gIFN5bmNPcGVyYXRpb25Qcm9jZXNzb3IsXG4gIFN5bmNPcGVyYXRpb25Qcm9jZXNzb3JDbGFzc1xufSBmcm9tICcuL3N5bmMtb3BlcmF0aW9uLXByb2Nlc3Nvcic7XG5cbmNvbnN0IHsgYXNzZXJ0LCBkZXByZWNhdGUgfSA9IE9yYml0O1xuXG5leHBvcnQgaW50ZXJmYWNlIFN5bmNSZWNvcmRDYWNoZVNldHRpbmdzPFxuICBRTyBleHRlbmRzIFJlcXVlc3RPcHRpb25zID0gUmVjb3JkQ2FjaGVRdWVyeU9wdGlvbnMsXG4gIFRPIGV4dGVuZHMgUmVxdWVzdE9wdGlvbnMgPSBSZWNvcmRDYWNoZVRyYW5zZm9ybU9wdGlvbnMsXG4gIFFCID0gUmVjb3JkUXVlcnlCdWlsZGVyLFxuICBUQiA9IFJlY29yZFRyYW5zZm9ybUJ1aWxkZXJcbj4gZXh0ZW5kcyBSZWNvcmRDYWNoZVNldHRpbmdzPFFPLCBUTywgUUIsIFRCPiB7XG4gIHByb2Nlc3NvcnM/OiBTeW5jT3BlcmF0aW9uUHJvY2Vzc29yQ2xhc3NbXTtcbiAgcXVlcnlPcGVyYXRvcnM/OiBEaWN0PFN5bmNRdWVyeU9wZXJhdG9yPjtcbiAgdHJhbnNmb3JtT3BlcmF0b3JzPzogRGljdDxTeW5jVHJhbnNmb3JtT3BlcmF0b3I+O1xuICBpbnZlcnNlVHJhbnNmb3JtT3BlcmF0b3JzPzogRGljdDxTeW5jSW52ZXJzZVRyYW5zZm9ybU9wZXJhdG9yPjtcbiAgZGVib3VuY2VMaXZlUXVlcmllcz86IGJvb2xlYW47XG4gIHRyYW5zZm9ybUJ1ZmZlcj86IFJlY29yZFRyYW5zZm9ybUJ1ZmZlcjtcbn1cblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIFN5bmNSZWNvcmRDYWNoZTxcbiAgICBRTyBleHRlbmRzIFJlcXVlc3RPcHRpb25zID0gUmVjb3JkQ2FjaGVRdWVyeU9wdGlvbnMsXG4gICAgVE8gZXh0ZW5kcyBSZXF1ZXN0T3B0aW9ucyA9IFJlY29yZENhY2hlVHJhbnNmb3JtT3B0aW9ucyxcbiAgICBRQiA9IFJlY29yZFF1ZXJ5QnVpbGRlcixcbiAgICBUQiA9IFJlY29yZFRyYW5zZm9ybUJ1aWxkZXIsXG4gICAgUXVlcnlSZXNwb25zZURldGFpbHMgPSB1bmtub3duLFxuICAgIFRyYW5zZm9ybVJlc3BvbnNlRGV0YWlscyBleHRlbmRzIFJlY29yZENhY2hlVXBkYXRlRGV0YWlscyA9IFJlY29yZENhY2hlVXBkYXRlRGV0YWlsc1xuICA+XG4gIGV4dGVuZHMgUmVjb3JkQ2FjaGU8UU8sIFRPLCBRQiwgVEI+XG4gIGltcGxlbWVudHNcbiAgICBTeW5jUmVjb3JkQWNjZXNzb3IsXG4gICAgU3luY1JlY29yZFF1ZXJ5YWJsZTxRdWVyeVJlc3BvbnNlRGV0YWlscywgUUIsIFFPPixcbiAgICBTeW5jUmVjb3JkVXBkYXRhYmxlPFRyYW5zZm9ybVJlc3BvbnNlRGV0YWlscywgVEIsIFRPPiB7XG4gIHByb3RlY3RlZCBfcHJvY2Vzc29yczogU3luY09wZXJhdGlvblByb2Nlc3NvcltdO1xuICBwcm90ZWN0ZWQgX3F1ZXJ5T3BlcmF0b3JzOiBEaWN0PFN5bmNRdWVyeU9wZXJhdG9yPjtcbiAgcHJvdGVjdGVkIF90cmFuc2Zvcm1PcGVyYXRvcnM6IERpY3Q8U3luY1RyYW5zZm9ybU9wZXJhdG9yPjtcbiAgcHJvdGVjdGVkIF9pbnZlcnNlVHJhbnNmb3JtT3BlcmF0b3JzOiBEaWN0PFN5bmNJbnZlcnNlVHJhbnNmb3JtT3BlcmF0b3I+O1xuICBwcm90ZWN0ZWQgX2RlYm91bmNlTGl2ZVF1ZXJpZXM6IGJvb2xlYW47XG4gIHByb3RlY3RlZCBfdHJhbnNmb3JtQnVmZmVyPzogUmVjb3JkVHJhbnNmb3JtQnVmZmVyO1xuXG4gIGNvbnN0cnVjdG9yKHNldHRpbmdzOiBTeW5jUmVjb3JkQ2FjaGVTZXR0aW5nczxRTywgVE8sIFFCLCBUQj4pIHtcbiAgICBzdXBlcihzZXR0aW5ncyk7XG5cbiAgICB0aGlzLl9xdWVyeU9wZXJhdG9ycyA9IHNldHRpbmdzLnF1ZXJ5T3BlcmF0b3JzID8/IFN5bmNRdWVyeU9wZXJhdG9ycztcbiAgICB0aGlzLl90cmFuc2Zvcm1PcGVyYXRvcnMgPVxuICAgICAgc2V0dGluZ3MudHJhbnNmb3JtT3BlcmF0b3JzID8/IFN5bmNUcmFuc2Zvcm1PcGVyYXRvcnM7XG4gICAgdGhpcy5faW52ZXJzZVRyYW5zZm9ybU9wZXJhdG9ycyA9XG4gICAgICBzZXR0aW5ncy5pbnZlcnNlVHJhbnNmb3JtT3BlcmF0b3JzID8/IFN5bmNJbnZlcnNlVHJhbnNmb3JtT3BlcmF0b3JzO1xuICAgIHRoaXMuX2RlYm91bmNlTGl2ZVF1ZXJpZXMgPSBzZXR0aW5ncy5kZWJvdW5jZUxpdmVRdWVyaWVzICE9PSBmYWxzZTtcbiAgICB0aGlzLl90cmFuc2Zvcm1CdWZmZXIgPSBzZXR0aW5ncy50cmFuc2Zvcm1CdWZmZXI7XG5cbiAgICBjb25zdCBwcm9jZXNzb3JzOiBTeW5jT3BlcmF0aW9uUHJvY2Vzc29yQ2xhc3NbXSA9IHNldHRpbmdzLnByb2Nlc3NvcnNcbiAgICAgID8gc2V0dGluZ3MucHJvY2Vzc29yc1xuICAgICAgOiBbU3luY1NjaGVtYUNvbnNpc3RlbmN5UHJvY2Vzc29yLCBTeW5jQ2FjaGVJbnRlZ3JpdHlQcm9jZXNzb3JdO1xuXG4gICAgaWYgKHNldHRpbmdzLmF1dG9WYWxpZGF0ZSAhPT0gZmFsc2UgJiYgc2V0dGluZ3MucHJvY2Vzc29ycyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBwcm9jZXNzb3JzLnB1c2goU3luY1NjaGVtYVZhbGlkYXRpb25Qcm9jZXNzb3IpO1xuICAgIH1cblxuICAgIHRoaXMuX3Byb2Nlc3NvcnMgPSBwcm9jZXNzb3JzLm1hcCgoUHJvY2Vzc29yKSA9PiB7XG4gICAgICBsZXQgcHJvY2Vzc29yID0gbmV3IFByb2Nlc3Nvcih0aGlzKTtcbiAgICAgIGFzc2VydChcbiAgICAgICAgJ0VhY2ggcHJvY2Vzc29yIG11c3QgZXh0ZW5kIFN5bmNPcGVyYXRpb25Qcm9jZXNzb3InLFxuICAgICAgICBwcm9jZXNzb3IgaW5zdGFuY2VvZiBTeW5jT3BlcmF0aW9uUHJvY2Vzc29yXG4gICAgICApO1xuICAgICAgcmV0dXJuIHByb2Nlc3NvcjtcbiAgICB9KTtcbiAgfVxuXG4gIGdldCBwcm9jZXNzb3JzKCk6IFN5bmNPcGVyYXRpb25Qcm9jZXNzb3JbXSB7XG4gICAgcmV0dXJuIHRoaXMuX3Byb2Nlc3NvcnM7XG4gIH1cblxuICBnZXRRdWVyeU9wZXJhdG9yKG9wOiBzdHJpbmcpOiBTeW5jUXVlcnlPcGVyYXRvciB7XG4gICAgcmV0dXJuIHRoaXMuX3F1ZXJ5T3BlcmF0b3JzW29wXTtcbiAgfVxuXG4gIGdldFRyYW5zZm9ybU9wZXJhdG9yKG9wOiBzdHJpbmcpOiBTeW5jVHJhbnNmb3JtT3BlcmF0b3Ige1xuICAgIHJldHVybiB0aGlzLl90cmFuc2Zvcm1PcGVyYXRvcnNbb3BdO1xuICB9XG5cbiAgZ2V0SW52ZXJzZVRyYW5zZm9ybU9wZXJhdG9yKG9wOiBzdHJpbmcpOiBTeW5jSW52ZXJzZVRyYW5zZm9ybU9wZXJhdG9yIHtcbiAgICByZXR1cm4gdGhpcy5faW52ZXJzZVRyYW5zZm9ybU9wZXJhdG9yc1tvcF07XG4gIH1cblxuICAvLyBBYnN0cmFjdCBtZXRob2RzIGZvciBnZXR0aW5nIHJlY29yZHMgYW5kIHJlbGF0aW9uc2hpcHNcbiAgYWJzdHJhY3QgZ2V0UmVjb3JkU3luYyhcbiAgICByZWNvcmRJZGVudGl0eTogUmVjb3JkSWRlbnRpdHlcbiAgKTogSW5pdGlhbGl6ZWRSZWNvcmQgfCB1bmRlZmluZWQ7XG4gIGFic3RyYWN0IGdldFJlY29yZHNTeW5jKFxuICAgIHR5cGVPcklkZW50aXRpZXM/OiBzdHJpbmcgfCBSZWNvcmRJZGVudGl0eVtdXG4gICk6IEluaXRpYWxpemVkUmVjb3JkW107XG4gIGFic3RyYWN0IGdldEludmVyc2VSZWxhdGlvbnNoaXBzU3luYyhcbiAgICByZWNvcmRJZGVudGl0eU9ySWRlbnRpdGllczogUmVjb3JkSWRlbnRpdHkgfCBSZWNvcmRJZGVudGl0eVtdXG4gICk6IFJlY29yZFJlbGF0aW9uc2hpcElkZW50aXR5W107XG5cbiAgLy8gQWJzdHJhY3QgbWV0aG9kcyBmb3Igc2V0dGluZyByZWNvcmRzIGFuZCByZWxhdGlvbnNoaXBzXG4gIGFic3RyYWN0IHNldFJlY29yZFN5bmMocmVjb3JkOiBJbml0aWFsaXplZFJlY29yZCk6IHZvaWQ7XG4gIGFic3RyYWN0IHNldFJlY29yZHNTeW5jKHJlY29yZHM6IEluaXRpYWxpemVkUmVjb3JkW10pOiB2b2lkO1xuICBhYnN0cmFjdCByZW1vdmVSZWNvcmRTeW5jKFxuICAgIHJlY29yZElkZW50aXR5OiBSZWNvcmRJZGVudGl0eVxuICApOiBJbml0aWFsaXplZFJlY29yZCB8IHVuZGVmaW5lZDtcbiAgYWJzdHJhY3QgcmVtb3ZlUmVjb3Jkc1N5bmMoXG4gICAgcmVjb3JkSWRlbnRpdGllczogUmVjb3JkSWRlbnRpdHlbXVxuICApOiBJbml0aWFsaXplZFJlY29yZFtdO1xuICBhYnN0cmFjdCBhZGRJbnZlcnNlUmVsYXRpb25zaGlwc1N5bmMoXG4gICAgcmVsYXRpb25zaGlwczogUmVjb3JkUmVsYXRpb25zaGlwSWRlbnRpdHlbXVxuICApOiB2b2lkO1xuICBhYnN0cmFjdCByZW1vdmVJbnZlcnNlUmVsYXRpb25zaGlwc1N5bmMoXG4gICAgcmVsYXRpb25zaGlwczogUmVjb3JkUmVsYXRpb25zaGlwSWRlbnRpdHlbXVxuICApOiB2b2lkO1xuXG4gIGFwcGx5UmVjb3JkQ2hhbmdlc2V0U3luYyhjaGFuZ2VzZXQ6IFJlY29yZENoYW5nZXNldCk6IHZvaWQge1xuICAgIGNvbnN0IHtcbiAgICAgIHNldFJlY29yZHMsXG4gICAgICByZW1vdmVSZWNvcmRzLFxuICAgICAgYWRkSW52ZXJzZVJlbGF0aW9uc2hpcHMsXG4gICAgICByZW1vdmVJbnZlcnNlUmVsYXRpb25zaGlwc1xuICAgIH0gPSBjaGFuZ2VzZXQ7XG5cbiAgICBpZiAoc2V0UmVjb3JkcyAmJiBzZXRSZWNvcmRzLmxlbmd0aCA+IDApIHtcbiAgICAgIHRoaXMuc2V0UmVjb3Jkc1N5bmMoc2V0UmVjb3Jkcyk7XG4gICAgfVxuICAgIGlmIChyZW1vdmVSZWNvcmRzICYmIHJlbW92ZVJlY29yZHMubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy5yZW1vdmVSZWNvcmRzU3luYyhyZW1vdmVSZWNvcmRzKTtcbiAgICB9XG4gICAgaWYgKGFkZEludmVyc2VSZWxhdGlvbnNoaXBzICYmIGFkZEludmVyc2VSZWxhdGlvbnNoaXBzLmxlbmd0aCA+IDApIHtcbiAgICAgIHRoaXMuYWRkSW52ZXJzZVJlbGF0aW9uc2hpcHNTeW5jKGFkZEludmVyc2VSZWxhdGlvbnNoaXBzKTtcbiAgICB9XG4gICAgaWYgKHJlbW92ZUludmVyc2VSZWxhdGlvbnNoaXBzICYmIHJlbW92ZUludmVyc2VSZWxhdGlvbnNoaXBzLmxlbmd0aCA+IDApIHtcbiAgICAgIHRoaXMucmVtb3ZlSW52ZXJzZVJlbGF0aW9uc2hpcHNTeW5jKHJlbW92ZUludmVyc2VSZWxhdGlvbnNoaXBzKTtcbiAgICB9XG4gIH1cblxuICBnZXRSZWxhdGVkUmVjb3JkU3luYyhcbiAgICBpZGVudGl0eTogUmVjb3JkSWRlbnRpdHksXG4gICAgcmVsYXRpb25zaGlwOiBzdHJpbmdcbiAgKTogUmVjb3JkSWRlbnRpdHkgfCBudWxsIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCByZWNvcmQgPSB0aGlzLmdldFJlY29yZFN5bmMoaWRlbnRpdHkpO1xuICAgIGlmIChyZWNvcmQpIHtcbiAgICAgIHJldHVybiBkZWVwR2V0KHJlY29yZCwgWydyZWxhdGlvbnNoaXBzJywgcmVsYXRpb25zaGlwLCAnZGF0YSddKTtcbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIGdldFJlbGF0ZWRSZWNvcmRzU3luYyhcbiAgICBpZGVudGl0eTogUmVjb3JkSWRlbnRpdHksXG4gICAgcmVsYXRpb25zaGlwOiBzdHJpbmdcbiAgKTogUmVjb3JkSWRlbnRpdHlbXSB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgcmVjb3JkID0gdGhpcy5nZXRSZWNvcmRTeW5jKGlkZW50aXR5KTtcbiAgICBpZiAocmVjb3JkKSB7XG4gICAgICByZXR1cm4gZGVlcEdldChyZWNvcmQsIFsncmVsYXRpb25zaGlwcycsIHJlbGF0aW9uc2hpcCwgJ2RhdGEnXSk7XG4gICAgfVxuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICAvKipcbiAgICogUXVlcmllcyB0aGUgY2FjaGUuXG4gICAqL1xuICBxdWVyeTxSZXF1ZXN0RGF0YSBleHRlbmRzIFJlY29yZFF1ZXJ5UmVzdWx0ID0gUmVjb3JkUXVlcnlSZXN1bHQ+KFxuICAgIHF1ZXJ5T3JFeHByZXNzaW9uczogUXVlcnlPckV4cHJlc3Npb25zPFJlY29yZFF1ZXJ5RXhwcmVzc2lvbiwgUUI+LFxuICAgIG9wdGlvbnM/OiBEZWZhdWx0UmVxdWVzdE9wdGlvbnM8UU8+LFxuICAgIGlkPzogc3RyaW5nXG4gICk6IFJlcXVlc3REYXRhO1xuICBxdWVyeTxSZXF1ZXN0RGF0YSBleHRlbmRzIFJlY29yZFF1ZXJ5UmVzdWx0ID0gUmVjb3JkUXVlcnlSZXN1bHQ+KFxuICAgIHF1ZXJ5T3JFeHByZXNzaW9uczogUXVlcnlPckV4cHJlc3Npb25zPFJlY29yZFF1ZXJ5RXhwcmVzc2lvbiwgUUI+LFxuICAgIG9wdGlvbnM6IEZ1bGxSZXF1ZXN0T3B0aW9uczxRTz4sXG4gICAgaWQ/OiBzdHJpbmdcbiAgKTogRnVsbFJlc3BvbnNlPFJlcXVlc3REYXRhLCBRdWVyeVJlc3BvbnNlRGV0YWlscywgUmVjb3JkT3BlcmF0aW9uPjtcbiAgcXVlcnk8UmVxdWVzdERhdGEgZXh0ZW5kcyBSZWNvcmRRdWVyeVJlc3VsdCA9IFJlY29yZFF1ZXJ5UmVzdWx0PihcbiAgICBxdWVyeU9yRXhwcmVzc2lvbnM6IFF1ZXJ5T3JFeHByZXNzaW9uczxSZWNvcmRRdWVyeUV4cHJlc3Npb24sIFFCPixcbiAgICBvcHRpb25zPzogUU8sXG4gICAgaWQ/OiBzdHJpbmdcbiAgKTpcbiAgICB8IFJlcXVlc3REYXRhXG4gICAgfCBGdWxsUmVzcG9uc2U8UmVxdWVzdERhdGEsIFF1ZXJ5UmVzcG9uc2VEZXRhaWxzLCBSZWNvcmRPcGVyYXRpb24+IHtcbiAgICBjb25zdCBxdWVyeSA9IGJ1aWxkUXVlcnk8UmVjb3JkUXVlcnlFeHByZXNzaW9uLCBRQj4oXG4gICAgICBxdWVyeU9yRXhwcmVzc2lvbnMsXG4gICAgICBvcHRpb25zLFxuICAgICAgaWQsXG4gICAgICB0aGlzLl9xdWVyeUJ1aWxkZXJcbiAgICApO1xuXG4gICAgY29uc3QgcmVzcG9uc2UgPSB0aGlzLl9xdWVyeTxSZXF1ZXN0RGF0YT4ocXVlcnksIG9wdGlvbnMpO1xuXG4gICAgaWYgKG9wdGlvbnM/LmZ1bGxSZXNwb25zZSkge1xuICAgICAgcmV0dXJuIHJlc3BvbnNlO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gcmVzcG9uc2UuZGF0YSBhcyBSZXF1ZXN0RGF0YTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVXBkYXRlcyB0aGUgY2FjaGUuXG4gICAqL1xuICB1cGRhdGU8UmVxdWVzdERhdGEgZXh0ZW5kcyBSZWNvcmRUcmFuc2Zvcm1SZXN1bHQgPSBSZWNvcmRUcmFuc2Zvcm1SZXN1bHQ+KFxuICAgIHRyYW5zZm9ybU9yT3BlcmF0aW9uczogVHJhbnNmb3JtT3JPcGVyYXRpb25zPFJlY29yZE9wZXJhdGlvbiwgVEI+LFxuICAgIG9wdGlvbnM/OiBEZWZhdWx0UmVxdWVzdE9wdGlvbnM8VE8+LFxuICAgIGlkPzogc3RyaW5nXG4gICk6IFJlcXVlc3REYXRhO1xuICB1cGRhdGU8UmVxdWVzdERhdGEgZXh0ZW5kcyBSZWNvcmRUcmFuc2Zvcm1SZXN1bHQgPSBSZWNvcmRUcmFuc2Zvcm1SZXN1bHQ+KFxuICAgIHRyYW5zZm9ybU9yT3BlcmF0aW9uczogVHJhbnNmb3JtT3JPcGVyYXRpb25zPFJlY29yZE9wZXJhdGlvbiwgVEI+LFxuICAgIG9wdGlvbnM6IEZ1bGxSZXF1ZXN0T3B0aW9uczxUTz4sXG4gICAgaWQ/OiBzdHJpbmdcbiAgKTogRnVsbFJlc3BvbnNlPFJlcXVlc3REYXRhLCBUcmFuc2Zvcm1SZXNwb25zZURldGFpbHMsIFJlY29yZE9wZXJhdGlvbj47XG4gIHVwZGF0ZTxSZXF1ZXN0RGF0YSBleHRlbmRzIFJlY29yZFRyYW5zZm9ybVJlc3VsdCA9IFJlY29yZFRyYW5zZm9ybVJlc3VsdD4oXG4gICAgdHJhbnNmb3JtT3JPcGVyYXRpb25zOiBUcmFuc2Zvcm1Pck9wZXJhdGlvbnM8UmVjb3JkT3BlcmF0aW9uLCBUQj4sXG4gICAgb3B0aW9ucz86IFRPLFxuICAgIGlkPzogc3RyaW5nXG4gICk6XG4gICAgfCBSZXF1ZXN0RGF0YVxuICAgIHwgRnVsbFJlc3BvbnNlPFJlcXVlc3REYXRhLCBUcmFuc2Zvcm1SZXNwb25zZURldGFpbHMsIFJlY29yZE9wZXJhdGlvbj4ge1xuICAgIGNvbnN0IHRyYW5zZm9ybSA9IGJ1aWxkVHJhbnNmb3JtKFxuICAgICAgdHJhbnNmb3JtT3JPcGVyYXRpb25zLFxuICAgICAgb3B0aW9ucyxcbiAgICAgIGlkLFxuICAgICAgdGhpcy5fdHJhbnNmb3JtQnVpbGRlclxuICAgICk7XG5cbiAgICBjb25zdCByZXNwb25zZSA9IHRoaXMuX3VwZGF0ZTxSZXF1ZXN0RGF0YT4odHJhbnNmb3JtLCBvcHRpb25zKTtcblxuICAgIGlmIChvcHRpb25zPy5mdWxsUmVzcG9uc2UpIHtcbiAgICAgIHJldHVybiByZXNwb25zZTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHJlc3BvbnNlLmRhdGEgYXMgUmVxdWVzdERhdGE7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFBhdGNoZXMgdGhlIGNhY2hlIHdpdGggYW4gb3BlcmF0aW9uIG9yIG9wZXJhdGlvbnMuXG4gICAqXG4gICAqIEBkZXByZWNhdGVkIHNpbmNlIHYwLjE3XG4gICAqL1xuICBwYXRjaChcbiAgICBvcGVyYXRpb25Pck9wZXJhdGlvbnM6XG4gICAgICB8IFJlY29yZE9wZXJhdGlvblxuICAgICAgfCBSZWNvcmRPcGVyYXRpb25bXVxuICAgICAgfCBSZWNvcmRPcGVyYXRpb25UZXJtXG4gICAgICB8IFJlY29yZE9wZXJhdGlvblRlcm1bXVxuICAgICAgfCBSZWNvcmRUcmFuc2Zvcm1CdWlsZGVyRnVuY1xuICApOiBQYXRjaFJlc3VsdCB7XG4gICAgZGVwcmVjYXRlKFxuICAgICAgJ1N5bmNSZWNvcmRDYWNoZSNwYXRjaCBoYXMgYmVlbiBkZXByZWNhdGVkLiBVc2UgU3luY1JlY29yZENhY2hlI3VwZGF0ZSBpbnN0ZWFkLidcbiAgICApO1xuXG4gICAgLy8gVE9ETyAtIFdoeSBpcyB0aGlzIGB0aGlzYCBjYXN0IG5lY2Vzc2FyeSBmb3IgVFMgdG8gdW5kZXJzdGFuZCB0aGUgY29ycmVjdFxuICAgIC8vIG1ldGhvZCBvdmVybG9hZD9cbiAgICBjb25zdCB7IGRhdGEsIGRldGFpbHMgfSA9ICh0aGlzIGFzIGFueSkudXBkYXRlKG9wZXJhdGlvbk9yT3BlcmF0aW9ucywge1xuICAgICAgZnVsbFJlc3BvbnNlOiB0cnVlXG4gICAgfSk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgaW52ZXJzZTogZGV0YWlscz8uaW52ZXJzZU9wZXJhdGlvbnMgfHwgW10sXG4gICAgICBkYXRhOiBBcnJheS5pc0FycmF5KGRhdGEpID8gZGF0YSA6IFtkYXRhXVxuICAgIH07XG4gIH1cblxuICBsaXZlUXVlcnkoXG4gICAgcXVlcnlPckV4cHJlc3Npb25zOiBRdWVyeU9yRXhwcmVzc2lvbnM8UmVjb3JkUXVlcnlFeHByZXNzaW9uLCBRQj4sXG4gICAgb3B0aW9ucz86IERlZmF1bHRSZXF1ZXN0T3B0aW9uczxRTz4sXG4gICAgaWQ/OiBzdHJpbmdcbiAgKTogU3luY0xpdmVRdWVyeTxRTywgVE8sIFFCLCBUQj4ge1xuICAgIGNvbnN0IHF1ZXJ5ID0gYnVpbGRRdWVyeShcbiAgICAgIHF1ZXJ5T3JFeHByZXNzaW9ucyxcbiAgICAgIG9wdGlvbnMsXG4gICAgICBpZCxcbiAgICAgIHRoaXMucXVlcnlCdWlsZGVyXG4gICAgKTtcblxuICAgIGxldCBkZWJvdW5jZSA9IG9wdGlvbnMgJiYgKG9wdGlvbnMgYXMgYW55KS5kZWJvdW5jZTtcbiAgICBpZiAodHlwZW9mIGRlYm91bmNlICE9PSAnYm9vbGVhbicpIHtcbiAgICAgIGRlYm91bmNlID0gdGhpcy5fZGVib3VuY2VMaXZlUXVlcmllcztcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IFN5bmNMaXZlUXVlcnk8UU8sIFRPLCBRQiwgVEI+KHtcbiAgICAgIGRlYm91bmNlLFxuICAgICAgY2FjaGU6IHRoaXMsXG4gICAgICBxdWVyeVxuICAgIH0pO1xuICB9XG5cbiAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbiAgLy8gUHJvdGVjdGVkIG1ldGhvZHNcbiAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuICBwcm90ZWN0ZWQgX3F1ZXJ5PFJlcXVlc3REYXRhIGV4dGVuZHMgUmVjb3JkUXVlcnlSZXN1bHQgPSBSZWNvcmRRdWVyeVJlc3VsdD4oXG4gICAgcXVlcnk6IFJlY29yZFF1ZXJ5LFxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICBvcHRpb25zPzogUU9cbiAgKTogRnVsbFJlc3BvbnNlPFJlcXVlc3REYXRhLCBRdWVyeVJlc3BvbnNlRGV0YWlscywgUmVjb3JkT3BlcmF0aW9uPiB7XG4gICAgbGV0IGRhdGE7XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheShxdWVyeS5leHByZXNzaW9ucykpIHtcbiAgICAgIGRhdGEgPSBbXTtcbiAgICAgIGZvciAobGV0IGV4cHJlc3Npb24gb2YgcXVlcnkuZXhwcmVzc2lvbnMpIHtcbiAgICAgICAgY29uc3QgcXVlcnlPcGVyYXRvciA9IHRoaXMuZ2V0UXVlcnlPcGVyYXRvcihleHByZXNzaW9uLm9wKTtcbiAgICAgICAgaWYgKCFxdWVyeU9wZXJhdG9yKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmFibGUgdG8gZmluZCBxdWVyeSBvcGVyYXRvcjogJHtleHByZXNzaW9uLm9wfWApO1xuICAgICAgICB9XG4gICAgICAgIGRhdGEucHVzaChcbiAgICAgICAgICBxdWVyeU9wZXJhdG9yKFxuICAgICAgICAgICAgdGhpcyxcbiAgICAgICAgICAgIGV4cHJlc3Npb24sXG4gICAgICAgICAgICB0aGlzLmdldFF1ZXJ5T3B0aW9ucyhxdWVyeSwgZXhwcmVzc2lvbilcbiAgICAgICAgICApXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGV4cHJlc3Npb24gPSBxdWVyeS5leHByZXNzaW9ucyBhcyBSZWNvcmRRdWVyeUV4cHJlc3Npb247XG4gICAgICBjb25zdCBxdWVyeU9wZXJhdG9yID0gdGhpcy5nZXRRdWVyeU9wZXJhdG9yKGV4cHJlc3Npb24ub3ApO1xuICAgICAgaWYgKCFxdWVyeU9wZXJhdG9yKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5hYmxlIHRvIGZpbmQgcXVlcnkgb3BlcmF0b3I6ICR7ZXhwcmVzc2lvbi5vcH1gKTtcbiAgICAgIH1cbiAgICAgIGRhdGEgPSBxdWVyeU9wZXJhdG9yKFxuICAgICAgICB0aGlzLFxuICAgICAgICBleHByZXNzaW9uLFxuICAgICAgICB0aGlzLmdldFF1ZXJ5T3B0aW9ucyhxdWVyeSwgZXhwcmVzc2lvbilcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgZGF0YTogZGF0YSBhcyBSZXF1ZXN0RGF0YSB9O1xuICB9XG5cbiAgcHJvdGVjdGVkIF91cGRhdGU8XG4gICAgUmVxdWVzdERhdGEgZXh0ZW5kcyBSZWNvcmRUcmFuc2Zvcm1SZXN1bHQgPSBSZWNvcmRUcmFuc2Zvcm1SZXN1bHRcbiAgPihcbiAgICB0cmFuc2Zvcm06IFJlY29yZFRyYW5zZm9ybSxcbiAgICBvcHRpb25zPzogVE9cbiAgKTogRnVsbFJlc3BvbnNlPFJlcXVlc3REYXRhLCBUcmFuc2Zvcm1SZXNwb25zZURldGFpbHMsIFJlY29yZE9wZXJhdGlvbj4ge1xuICAgIGlmICh0aGlzLmdldFRyYW5zZm9ybU9wdGlvbnModHJhbnNmb3JtKT8udXNlQnVmZmVyKSB7XG4gICAgICBjb25zdCBidWZmZXIgPSB0aGlzLl9pbml0VHJhbnNmb3JtQnVmZmVyKHRyYW5zZm9ybSk7XG5cbiAgICAgIGJ1ZmZlci5zdGFydFRyYWNraW5nQ2hhbmdlcygpO1xuXG4gICAgICBjb25zdCByZXNwb25zZSA9IGJ1ZmZlci51cGRhdGUodHJhbnNmb3JtLCB7XG4gICAgICAgIGZ1bGxSZXNwb25zZTogdHJ1ZVxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IGNoYW5nZXMgPSBidWZmZXIuc3RvcFRyYWNraW5nQ2hhbmdlcygpO1xuXG4gICAgICB0aGlzLmFwcGx5UmVjb3JkQ2hhbmdlc2V0U3luYyhjaGFuZ2VzKTtcblxuICAgICAgY29uc3Qge1xuICAgICAgICBhcHBsaWVkT3BlcmF0aW9ucyxcbiAgICAgICAgYXBwbGllZE9wZXJhdGlvblJlc3VsdHNcbiAgICAgIH0gPSByZXNwb25zZS5kZXRhaWxzIGFzIFRyYW5zZm9ybVJlc3BvbnNlRGV0YWlscztcblxuICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGFwcGxpZWRPcGVyYXRpb25zLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgIHRoaXMuZW1pdCgncGF0Y2gnLCBhcHBsaWVkT3BlcmF0aW9uc1tpXSwgYXBwbGllZE9wZXJhdGlvblJlc3VsdHNbaV0pO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcmVzcG9uc2UgYXMgRnVsbFJlc3BvbnNlPFxuICAgICAgICBSZXF1ZXN0RGF0YSxcbiAgICAgICAgVHJhbnNmb3JtUmVzcG9uc2VEZXRhaWxzLFxuICAgICAgICBSZWNvcmRPcGVyYXRpb25cbiAgICAgID47XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0ge1xuICAgICAgICBkYXRhOiBbXVxuICAgICAgfSBhcyBGdWxsUmVzcG9uc2U8XG4gICAgICAgIFJlY29yZE9wZXJhdGlvblJlc3VsdFtdLFxuICAgICAgICBSZWNvcmRDYWNoZVVwZGF0ZURldGFpbHMsXG4gICAgICAgIFJlY29yZE9wZXJhdGlvblxuICAgICAgPjtcblxuICAgICAgaWYgKG9wdGlvbnM/LmZ1bGxSZXNwb25zZSkge1xuICAgICAgICByZXNwb25zZS5kZXRhaWxzID0ge1xuICAgICAgICAgIGFwcGxpZWRPcGVyYXRpb25zOiBbXSxcbiAgICAgICAgICBhcHBsaWVkT3BlcmF0aW9uUmVzdWx0czogW10sXG4gICAgICAgICAgaW52ZXJzZU9wZXJhdGlvbnM6IFtdXG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIGxldCBkYXRhOiBSZWNvcmRUcmFuc2Zvcm1SZXN1bHQ7XG5cbiAgICAgIGlmIChBcnJheS5pc0FycmF5KHRyYW5zZm9ybS5vcGVyYXRpb25zKSkge1xuICAgICAgICB0aGlzLl9hcHBseVRyYW5zZm9ybU9wZXJhdGlvbnMoXG4gICAgICAgICAgdHJhbnNmb3JtLFxuICAgICAgICAgIHRyYW5zZm9ybS5vcGVyYXRpb25zLFxuICAgICAgICAgIHJlc3BvbnNlLFxuICAgICAgICAgIHRydWVcbiAgICAgICAgKTtcbiAgICAgICAgZGF0YSA9IHJlc3BvbnNlLmRhdGE7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLl9hcHBseVRyYW5zZm9ybU9wZXJhdGlvbihcbiAgICAgICAgICB0cmFuc2Zvcm0sXG4gICAgICAgICAgdHJhbnNmb3JtLm9wZXJhdGlvbnMsXG4gICAgICAgICAgcmVzcG9uc2UsXG4gICAgICAgICAgdHJ1ZVxuICAgICAgICApO1xuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShyZXNwb25zZS5kYXRhKSkge1xuICAgICAgICAgIGRhdGEgPSByZXNwb25zZS5kYXRhWzBdO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChvcHRpb25zPy5mdWxsUmVzcG9uc2UpIHtcbiAgICAgICAgcmVzcG9uc2UuZGV0YWlscz8uaW52ZXJzZU9wZXJhdGlvbnMucmV2ZXJzZSgpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi5yZXNwb25zZSxcbiAgICAgICAgZGF0YVxuICAgICAgfSBhcyBGdWxsUmVzcG9uc2U8UmVxdWVzdERhdGEsIFRyYW5zZm9ybVJlc3BvbnNlRGV0YWlscywgUmVjb3JkT3BlcmF0aW9uPjtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgX2dldFRyYW5zZm9ybUJ1ZmZlcigpOiBSZWNvcmRUcmFuc2Zvcm1CdWZmZXIge1xuICAgIGlmICh0aGlzLl90cmFuc2Zvcm1CdWZmZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbihcbiAgICAgICAgJ3RyYW5zZm9ybUJ1ZmZlciBtdXN0IGJlIHByb3ZpZGVkIHRvIGNhY2hlIHZpYSBjb25zdHJ1Y3RvciBzZXR0aW5ncydcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl90cmFuc2Zvcm1CdWZmZXI7XG4gIH1cblxuICBwcm90ZWN0ZWQgX2luaXRUcmFuc2Zvcm1CdWZmZXIoXG4gICAgdHJhbnNmb3JtOiBSZWNvcmRUcmFuc2Zvcm1cbiAgKTogUmVjb3JkVHJhbnNmb3JtQnVmZmVyIHtcbiAgICBjb25zdCBidWZmZXIgPSB0aGlzLl9nZXRUcmFuc2Zvcm1CdWZmZXIoKTtcblxuICAgIGNvbnN0IHJlY29yZHMgPSByZWNvcmRzUmVmZXJlbmNlZEJ5T3BlcmF0aW9ucyhcbiAgICAgIHRvQXJyYXkodHJhbnNmb3JtLm9wZXJhdGlvbnMpXG4gICAgKTtcbiAgICBjb25zdCBpbnZlcnNlUmVsYXRpb25zaGlwcyA9IHRoaXMuZ2V0SW52ZXJzZVJlbGF0aW9uc2hpcHNTeW5jKHJlY29yZHMpO1xuICAgIGNvbnN0IHJlbGF0ZWRSZWNvcmRzID0gaW52ZXJzZVJlbGF0aW9uc2hpcHMubWFwKChpcikgPT4gaXIucmVjb3JkKTtcbiAgICBBcnJheS5wcm90b3R5cGUucHVzaC5hcHBseShyZWNvcmRzLCByZWxhdGVkUmVjb3Jkcyk7XG5cbiAgICBidWZmZXIucmVzZXRTdGF0ZSgpO1xuICAgIGJ1ZmZlci5zZXRSZWNvcmRzU3luYyh0aGlzLmdldFJlY29yZHNTeW5jKHJlY29yZHMpKTtcbiAgICBidWZmZXIuYWRkSW52ZXJzZVJlbGF0aW9uc2hpcHNTeW5jKGludmVyc2VSZWxhdGlvbnNoaXBzKTtcblxuICAgIHJldHVybiBidWZmZXI7XG4gIH1cblxuICBwcm90ZWN0ZWQgX2FwcGx5VHJhbnNmb3JtT3BlcmF0aW9ucyhcbiAgICB0cmFuc2Zvcm06IFJlY29yZFRyYW5zZm9ybSxcbiAgICBvcHM6IFJlY29yZE9wZXJhdGlvbltdIHwgUmVjb3JkT3BlcmF0aW9uVGVybVtdLFxuICAgIHJlc3BvbnNlOiBGdWxsUmVzcG9uc2U8XG4gICAgICBSZWNvcmRPcGVyYXRpb25SZXN1bHRbXSxcbiAgICAgIFJlY29yZENhY2hlVXBkYXRlRGV0YWlscyxcbiAgICAgIFJlY29yZE9wZXJhdGlvblxuICAgID4sXG4gICAgcHJpbWFyeSA9IGZhbHNlXG4gICk6IHZvaWQge1xuICAgIGZvciAoY29uc3Qgb3Agb2Ygb3BzKSB7XG4gICAgICB0aGlzLl9hcHBseVRyYW5zZm9ybU9wZXJhdGlvbih0cmFuc2Zvcm0sIG9wLCByZXNwb25zZSwgcHJpbWFyeSk7XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIF9hcHBseVRyYW5zZm9ybU9wZXJhdGlvbihcbiAgICB0cmFuc2Zvcm06IFJlY29yZFRyYW5zZm9ybSxcbiAgICBvcGVyYXRpb246IFJlY29yZE9wZXJhdGlvbiB8IFJlY29yZE9wZXJhdGlvblRlcm0sXG4gICAgcmVzcG9uc2U6IEZ1bGxSZXNwb25zZTxcbiAgICAgIFJlY29yZE9wZXJhdGlvblJlc3VsdFtdLFxuICAgICAgUmVjb3JkQ2FjaGVVcGRhdGVEZXRhaWxzLFxuICAgICAgUmVjb3JkT3BlcmF0aW9uXG4gICAgPixcbiAgICBwcmltYXJ5ID0gZmFsc2VcbiAgKTogdm9pZCB7XG4gICAgaWYgKG9wZXJhdGlvbiBpbnN0YW5jZW9mIE9wZXJhdGlvblRlcm0pIHtcbiAgICAgIG9wZXJhdGlvbiA9IG9wZXJhdGlvbi50b09wZXJhdGlvbigpIGFzIFJlY29yZE9wZXJhdGlvbjtcbiAgICB9XG4gICAgZm9yIChsZXQgcHJvY2Vzc29yIG9mIHRoaXMuX3Byb2Nlc3NvcnMpIHtcbiAgICAgIHByb2Nlc3Nvci52YWxpZGF0ZShvcGVyYXRpb24pO1xuICAgIH1cblxuICAgIGNvbnN0IGludmVyc2VUcmFuc2Zvcm1PcGVyYXRvciA9IHRoaXMuZ2V0SW52ZXJzZVRyYW5zZm9ybU9wZXJhdG9yKFxuICAgICAgb3BlcmF0aW9uLm9wXG4gICAgKTtcbiAgICBjb25zdCBpbnZlcnNlT3A6IFJlY29yZE9wZXJhdGlvbiB8IHVuZGVmaW5lZCA9IGludmVyc2VUcmFuc2Zvcm1PcGVyYXRvcihcbiAgICAgIHRoaXMsXG4gICAgICBvcGVyYXRpb24sXG4gICAgICB0aGlzLmdldFRyYW5zZm9ybU9wdGlvbnModHJhbnNmb3JtLCBvcGVyYXRpb24pXG4gICAgKTtcbiAgICBpZiAoaW52ZXJzZU9wKSB7XG4gICAgICByZXNwb25zZS5kZXRhaWxzPy5pbnZlcnNlT3BlcmF0aW9ucz8ucHVzaChpbnZlcnNlT3ApO1xuXG4gICAgICAvLyBRdWVyeSBhbmQgcGVyZm9ybSByZWxhdGVkIGBiZWZvcmVgIG9wZXJhdGlvbnNcbiAgICAgIGZvciAobGV0IHByb2Nlc3NvciBvZiB0aGlzLl9wcm9jZXNzb3JzKSB7XG4gICAgICAgIHRoaXMuX2FwcGx5VHJhbnNmb3JtT3BlcmF0aW9ucyhcbiAgICAgICAgICB0cmFuc2Zvcm0sXG4gICAgICAgICAgcHJvY2Vzc29yLmJlZm9yZShvcGVyYXRpb24pLFxuICAgICAgICAgIHJlc3BvbnNlXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIC8vIFF1ZXJ5IHJlbGF0ZWQgYGFmdGVyYCBvcGVyYXRpb25zIGJlZm9yZSBwZXJmb3JtaW5nXG4gICAgICAvLyB0aGUgcmVxdWVzdGVkIG9wZXJhdGlvbi4gVGhlc2Ugd2lsbCBiZSBhcHBsaWVkIG9uIHN1Y2Nlc3MuXG4gICAgICBsZXQgcHJlcGFyZWRPcHMgPSBbXTtcbiAgICAgIGZvciAobGV0IHByb2Nlc3NvciBvZiB0aGlzLl9wcm9jZXNzb3JzKSB7XG4gICAgICAgIHByZXBhcmVkT3BzLnB1c2gocHJvY2Vzc29yLmFmdGVyKG9wZXJhdGlvbikpO1xuICAgICAgfVxuXG4gICAgICAvLyBQZXJmb3JtIHRoZSByZXF1ZXN0ZWQgb3BlcmF0aW9uXG4gICAgICBsZXQgdHJhbnNmb3JtT3BlcmF0b3IgPSB0aGlzLmdldFRyYW5zZm9ybU9wZXJhdG9yKG9wZXJhdGlvbi5vcCk7XG4gICAgICBsZXQgZGF0YSA9IHRyYW5zZm9ybU9wZXJhdG9yKFxuICAgICAgICB0aGlzLFxuICAgICAgICBvcGVyYXRpb24sXG4gICAgICAgIHRoaXMuZ2V0VHJhbnNmb3JtT3B0aW9ucyh0cmFuc2Zvcm0sIG9wZXJhdGlvbilcbiAgICAgICk7XG4gICAgICBpZiAocHJpbWFyeSkge1xuICAgICAgICByZXNwb25zZS5kYXRhPy5wdXNoKGRhdGEpO1xuICAgICAgfVxuICAgICAgaWYgKHJlc3BvbnNlLmRldGFpbHMpIHtcbiAgICAgICAgcmVzcG9uc2UuZGV0YWlscy5hcHBsaWVkT3BlcmF0aW9uUmVzdWx0cy5wdXNoKGRhdGEpO1xuICAgICAgICByZXNwb25zZS5kZXRhaWxzLmFwcGxpZWRPcGVyYXRpb25zLnB1c2gob3BlcmF0aW9uKTtcbiAgICAgIH1cblxuICAgICAgLy8gUXVlcnkgYW5kIHBlcmZvcm0gcmVsYXRlZCBgaW1tZWRpYXRlYCBvcGVyYXRpb25zXG4gICAgICBmb3IgKGxldCBwcm9jZXNzb3Igb2YgdGhpcy5fcHJvY2Vzc29ycykge1xuICAgICAgICBwcm9jZXNzb3IuaW1tZWRpYXRlKG9wZXJhdGlvbik7XG4gICAgICB9XG5cbiAgICAgIC8vIEVtaXQgZXZlbnRcbiAgICAgIHRoaXMuZW1pdCgncGF0Y2gnLCBvcGVyYXRpb24sIGRhdGEpO1xuXG4gICAgICAvLyBQZXJmb3JtIHByZXBhcmVkIG9wZXJhdGlvbnMgYWZ0ZXIgcGVyZm9ybWluZyB0aGUgcmVxdWVzdGVkIG9wZXJhdGlvblxuICAgICAgZm9yIChsZXQgb3BzIG9mIHByZXBhcmVkT3BzKSB7XG4gICAgICAgIHRoaXMuX2FwcGx5VHJhbnNmb3JtT3BlcmF0aW9ucyh0cmFuc2Zvcm0sIG9wcywgcmVzcG9uc2UpO1xuICAgICAgfVxuXG4gICAgICAvLyBRdWVyeSBhbmQgcGVyZm9ybSByZWxhdGVkIGBmaW5hbGx5YCBvcGVyYXRpb25zXG4gICAgICBmb3IgKGxldCBwcm9jZXNzb3Igb2YgdGhpcy5fcHJvY2Vzc29ycykge1xuICAgICAgICB0aGlzLl9hcHBseVRyYW5zZm9ybU9wZXJhdGlvbnMoXG4gICAgICAgICAgdHJhbnNmb3JtLFxuICAgICAgICAgIHByb2Nlc3Nvci5maW5hbGx5KG9wZXJhdGlvbiksXG4gICAgICAgICAgcmVzcG9uc2VcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHByaW1hcnkpIHtcbiAgICAgIHJlc3BvbnNlLmRhdGE/LnB1c2godW5kZWZpbmVkKTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==