UNPKG

@orbit/record-cache

Version:

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

280 lines 49.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SyncRecordCache = void 0; const core_1 = require("@orbit/core"); const data_1 = require("@orbit/data"); const records_1 = require("@orbit/records"); const utils_1 = require("@orbit/utils"); const sync_live_query_1 = require("./live-query/sync-live-query"); const sync_cache_integrity_processor_1 = require("./operation-processors/sync-cache-integrity-processor"); const sync_schema_consistency_processor_1 = require("./operation-processors/sync-schema-consistency-processor"); const sync_schema_validation_processor_1 = require("./operation-processors/sync-schema-validation-processor"); const sync_inverse_transform_operators_1 = require("./operators/sync-inverse-transform-operators"); const sync_query_operators_1 = require("./operators/sync-query-operators"); const sync_transform_operators_1 = require("./operators/sync-transform-operators"); const record_cache_1 = require("./record-cache"); const sync_operation_processor_1 = require("./sync-operation-processor"); const { assert, deprecate } = core_1.Orbit; class SyncRecordCache extends record_cache_1.RecordCache { constructor(settings) { var _a, _b, _c; super(settings); this._queryOperators = (_a = settings.queryOperators) !== null && _a !== void 0 ? _a : sync_query_operators_1.SyncQueryOperators; this._transformOperators = (_b = settings.transformOperators) !== null && _b !== void 0 ? _b : sync_transform_operators_1.SyncTransformOperators; this._inverseTransformOperators = (_c = settings.inverseTransformOperators) !== null && _c !== void 0 ? _c : sync_inverse_transform_operators_1.SyncInverseTransformOperators; this._debounceLiveQueries = settings.debounceLiveQueries !== false; this._transformBuffer = settings.transformBuffer; const processors = settings.processors ? settings.processors : [sync_schema_consistency_processor_1.SyncSchemaConsistencyProcessor, sync_cache_integrity_processor_1.SyncCacheIntegrityProcessor]; if (settings.autoValidate !== false && settings.processors === undefined) { processors.push(sync_schema_validation_processor_1.SyncSchemaValidationProcessor); } this._processors = processors.map((Processor) => { let processor = new Processor(this); assert('Each processor must extend SyncOperationProcessor', processor instanceof sync_operation_processor_1.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 (0, utils_1.deepGet)(record, ['relationships', relationship, 'data']); } return undefined; } getRelatedRecordsSync(identity, relationship) { const record = this.getRecordSync(identity); if (record) { return (0, utils_1.deepGet)(record, ['relationships', relationship, 'data']); } return undefined; } query(queryOrExpressions, options, id) { const query = (0, data_1.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 = (0, data_1.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 = (0, data_1.buildQuery)(queryOrExpressions, options, id, this.queryBuilder); let debounce = options && options.debounce; if (typeof debounce !== 'boolean') { debounce = this._debounceLiveQueries; } return new sync_live_query_1.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 core_1.Assertion('transformBuffer must be provided to cache via constructor settings'); } return this._transformBuffer; } _initTransformBuffer(transform) { const buffer = this._getTransformBuffer(); const records = (0, records_1.recordsReferencedByOperations)((0, utils_1.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 data_1.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); } } } exports.SyncRecordCache = SyncRecordCache; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3luYy1yZWNvcmQtY2FjaGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc3luYy1yZWNvcmQtY2FjaGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsc0NBQStDO0FBQy9DLHNDQVVxQjtBQUNyQiw0Q0FpQndCO0FBQ3hCLHdDQUFzRDtBQUN0RCxrRUFBNkQ7QUFDN0QsMEdBQW9HO0FBQ3BHLGdIQUEwRztBQUMxRyw4R0FBd0c7QUFDeEcsbUdBR3NEO0FBQ3RELDJFQUcwQztBQUMxQyxtRkFHOEM7QUFNOUMsaURBS3dCO0FBR3hCLHlFQUdvQztBQUVwQyxNQUFNLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxHQUFHLFlBQUssQ0FBQztBQWdCcEMsTUFBc0IsZUFRcEIsU0FBUSwwQkFBMkI7SUFZbkMsWUFBWSxRQUFpRDs7UUFDM0QsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBRWhCLElBQUksQ0FBQyxlQUFlLEdBQUcsTUFBQSxRQUFRLENBQUMsY0FBYyxtQ0FBSSx5Q0FBa0IsQ0FBQztRQUNyRSxJQUFJLENBQUMsbUJBQW1CO1lBQ3RCLE1BQUEsUUFBUSxDQUFDLGtCQUFrQixtQ0FBSSxpREFBc0IsQ0FBQztRQUN4RCxJQUFJLENBQUMsMEJBQTBCO1lBQzdCLE1BQUEsUUFBUSxDQUFDLHlCQUF5QixtQ0FBSSxnRUFBNkIsQ0FBQztRQUN0RSxJQUFJLENBQUMsb0JBQW9CLEdBQUcsUUFBUSxDQUFDLG1CQUFtQixLQUFLLEtBQUssQ0FBQztRQUNuRSxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsUUFBUSxDQUFDLGVBQWUsQ0FBQztRQUVqRCxNQUFNLFVBQVUsR0FBa0MsUUFBUSxDQUFDLFVBQVU7WUFDbkUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxVQUFVO1lBQ3JCLENBQUMsQ0FBQyxDQUFDLGtFQUE4QixFQUFFLDREQUEyQixDQUFDLENBQUM7UUFFbEUsSUFBSSxRQUFRLENBQUMsWUFBWSxLQUFLLEtBQUssSUFBSSxR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QUFqZ0JELDBDQWlnQkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBc3NlcnRpb24sIE9yYml0IH0gZnJvbSAnQG9yYml0L2NvcmUnO1xuaW1wb3J0IHtcbiAgYnVpbGRRdWVyeSxcbiAgYnVpbGRUcmFuc2Zvcm0sXG4gIERlZmF1bHRSZXF1ZXN0T3B0aW9ucyxcbiAgRnVsbFJlcXVlc3RPcHRpb25zLFxuICBGdWxsUmVzcG9uc2UsXG4gIE9wZXJhdGlvblRlcm0sXG4gIFF1ZXJ5T3JFeHByZXNzaW9ucyxcbiAgUmVxdWVzdE9wdGlvbnMsXG4gIFRyYW5zZm9ybU9yT3BlcmF0aW9uc1xufSBmcm9tICdAb3JiaXQvZGF0YSc7XG5pbXBvcnQge1xuICBJbml0aWFsaXplZFJlY29yZCxcbiAgUmVjb3JkSWRlbnRpdHksXG4gIFJlY29yZE9wZXJhdGlvbixcbiAgUmVjb3JkT3BlcmF0aW9uUmVzdWx0LFxuICBSZWNvcmRPcGVyYXRpb25UZXJtLFxuICBSZWNvcmRRdWVyeSxcbiAgUmVjb3JkUXVlcnlCdWlsZGVyLFxuICBSZWNvcmRRdWVyeUV4cHJlc3Npb24sXG4gIFJlY29yZFF1ZXJ5UmVzdWx0LFxuICByZWNvcmRzUmVmZXJlbmNlZEJ5T3BlcmF0aW9ucyxcbiAgUmVjb3JkVHJhbnNmb3JtLFxuICBSZWNvcmRUcmFuc2Zvcm1CdWlsZGVyLFxuICBSZWNvcmRUcmFuc2Zvcm1CdWlsZGVyRnVuYyxcbiAgUmVjb3JkVHJhbnNmb3JtUmVzdWx0LFxuICBTeW5jUmVjb3JkUXVlcnlhYmxlLFxuICBTeW5jUmVjb3JkVXBkYXRhYmxlXG59IGZyb20gJ0BvcmJpdC9yZWNvcmRzJztcbmltcG9ydCB7IGRlZXBHZXQsIERpY3QsIHRvQXJyYXkgfSBmcm9tICdAb3JiaXQvdXRpbHMnO1xuaW1wb3J0IHsgU3luY0xpdmVRdWVyeSB9IGZyb20gJy4vbGl2ZS1xdWVyeS9zeW5jLWxpdmUtcXVlcnknO1xuaW1wb3J0IHsgU3luY0NhY2hlSW50ZWdyaXR5UHJvY2Vzc29yIH0gZnJvbSAnLi9vcGVyYXRpb24tcHJvY2Vzc29ycy9zeW5jLWNhY2hlLWludGVncml0eS1wcm9jZXNzb3InO1xuaW1wb3J0IHsgU3luY1NjaGVtYUNvbnNpc3RlbmN5UHJvY2Vzc29yIH0gZnJvbSAnLi9vcGVyYXRpb24tcHJvY2Vzc29ycy9zeW5jLXNjaGVtYS1jb25zaXN0ZW5jeS1wcm9jZXNzb3InO1xuaW1wb3J0IHsgU3luY1NjaGVtYVZhbGlkYXRpb25Qcm9jZXNzb3IgfSBmcm9tICcuL29wZXJhdGlvbi1wcm9jZXNzb3JzL3N5bmMtc2NoZW1hLXZhbGlkYXRpb24tcHJvY2Vzc29yJztcbmltcG9ydCB7XG4gIFN5bmNJbnZlcnNlVHJhbnNmb3JtT3BlcmF0b3IsXG4gIFN5bmNJbnZlcnNlVHJhbnNmb3JtT3BlcmF0b3JzXG59IGZyb20gJy4vb3BlcmF0b3JzL3N5bmMtaW52ZXJzZS10cmFuc2Zvcm0tb3BlcmF0b3JzJztcbmltcG9ydCB7XG4gIFN5bmNRdWVyeU9wZXJhdG9yLFxuICBTeW5jUXVlcnlPcGVyYXRvcnNcbn0gZnJvbSAnLi9vcGVyYXRvcnMvc3luYy1xdWVyeS1vcGVyYXRvcnMnO1xuaW1wb3J0IHtcbiAgU3luY1RyYW5zZm9ybU9wZXJhdG9yLFxuICBTeW5jVHJhbnNmb3JtT3BlcmF0b3JzXG59IGZyb20gJy4vb3BlcmF0b3JzL3N5bmMtdHJhbnNmb3JtLW9wZXJhdG9ycyc7XG5pbXBvcnQge1xuICBSZWNvcmRDaGFuZ2VzZXQsXG4gIFJlY29yZFJlbGF0aW9uc2hpcElkZW50aXR5LFxuICBTeW5jUmVjb3JkQWNjZXNzb3Jcbn0gZnJvbSAnLi9yZWNvcmQtYWNjZXNzb3InO1xuaW1wb3J0IHtcbiAgUmVjb3JkQ2FjaGUsXG4gIFJlY29yZENhY2hlUXVlcnlPcHRpb25zLFxuICBSZWNvcmRDYWNoZVNldHRpbmdzLFxuICBSZWNvcmRDYWNoZVRyYW5zZm9ybU9wdGlvbnNcbn0gZnJvbSAnLi9yZWNvcmQtY2FjaGUnO1xuaW1wb3J0IHsgUmVjb3JkVHJhbnNmb3JtQnVmZmVyIH0gZnJvbSAnLi9yZWNvcmQtdHJhbnNmb3JtLWJ1ZmZlcic7XG5pbXBvcnQgeyBQYXRjaFJlc3VsdCwgUmVjb3JkQ2FjaGVVcGRhdGVEZXRhaWxzIH0gZnJvbSAnLi9yZXNwb25zZSc7XG5pbXBvcnQge1xuICBTeW5jT3BlcmF0aW9uUHJvY2Vzc29yLFxuICBTeW5jT3BlcmF0aW9uUHJvY2Vzc29yQ2xhc3Ncbn0gZnJvbSAnLi9zeW5jLW9wZXJhdGlvbi1wcm9jZXNzb3InO1xuXG5jb25zdCB7IGFzc2VydCwgZGVwcmVjYXRlIH0gPSBPcmJpdDtcblxuZXhwb3J0IGludGVyZmFjZSBTeW5jUmVjb3JkQ2FjaGVTZXR0aW5nczxcbiAgUU8gZXh0ZW5kcyBSZXF1ZXN0T3B0aW9ucyA9IFJlY29yZENhY2hlUXVlcnlPcHRpb25zLFxuICBUTyBleHRlbmRzIFJlcXVlc3RPcHRpb25zID0gUmVjb3JkQ2FjaGVUcmFuc2Zvcm1PcHRpb25zLFxuICBRQiA9IFJlY29yZFF1ZXJ5QnVpbGRlcixcbiAgVEIgPSBSZWNvcmRUcmFuc2Zvcm1CdWlsZGVyXG4+IGV4dGVuZHMgUmVjb3JkQ2FjaGVTZXR0aW5nczxRTywgVE8sIFFCLCBUQj4ge1xuICBwcm9jZXNzb3JzPzogU3luY09wZXJhdGlvblByb2Nlc3NvckNsYXNzW107XG4gIHF1ZXJ5T3BlcmF0b3JzPzogRGljdDxTeW5jUXVlcnlPcGVyYXRvcj47XG4gIHRyYW5zZm9ybU9wZXJhdG9ycz86IERpY3Q8U3luY1RyYW5zZm9ybU9wZXJhdG9yPjtcbiAgaW52ZXJzZVRyYW5zZm9ybU9wZXJhdG9ycz86IERpY3Q8U3luY0ludmVyc2VUcmFuc2Zvcm1PcGVyYXRvcj47XG4gIGRlYm91bmNlTGl2ZVF1ZXJpZXM/OiBib29sZWFuO1xuICB0cmFuc2Zvcm1CdWZmZXI/OiBSZWNvcmRUcmFuc2Zvcm1CdWZmZXI7XG59XG5cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBTeW5jUmVjb3JkQ2FjaGU8XG4gICAgUU8gZXh0ZW5kcyBSZXF1ZXN0T3B0aW9ucyA9IFJlY29yZENhY2hlUXVlcnlPcHRpb25zLFxuICAgIFRPIGV4dGVuZHMgUmVxdWVzdE9wdGlvbnMgPSBSZWNvcmRDYWNoZVRyYW5zZm9ybU9wdGlvbnMsXG4gICAgUUIgPSBSZWNvcmRRdWVyeUJ1aWxkZXIsXG4gICAgVEIgPSBSZWNvcmRUcmFuc2Zvcm1CdWlsZGVyLFxuICAgIFF1ZXJ5UmVzcG9uc2VEZXRhaWxzID0gdW5rbm93bixcbiAgICBUcmFuc2Zvcm1SZXNwb25zZURldGFpbHMgZXh0ZW5kcyBSZWNvcmRDYWNoZVVwZGF0ZURldGFpbHMgPSBSZWNvcmRDYWNoZVVwZGF0ZURldGFpbHNcbiAgPlxuICBleHRlbmRzIFJlY29yZENhY2hlPFFPLCBUTywgUUIsIFRCPlxuICBpbXBsZW1lbnRzXG4gICAgU3luY1JlY29yZEFjY2Vzc29yLFxuICAgIFN5bmNSZWNvcmRRdWVyeWFibGU8UXVlcnlSZXNwb25zZURldGFpbHMsIFFCLCBRTz4sXG4gICAgU3luY1JlY29yZFVwZGF0YWJsZTxUcmFuc2Zvcm1SZXNwb25zZURldGFpbHMsIFRCLCBUTz4ge1xuICBwcm90ZWN0ZWQgX3Byb2Nlc3NvcnM6IFN5bmNPcGVyYXRpb25Qcm9jZXNzb3JbXTtcbiAgcHJvdGVjdGVkIF9xdWVyeU9wZXJhdG9yczogRGljdDxTeW5jUXVlcnlPcGVyYXRvcj47XG4gIHByb3RlY3RlZCBfdHJhbnNmb3JtT3BlcmF0b3JzOiBEaWN0PFN5bmNUcmFuc2Zvcm1PcGVyYXRvcj47XG4gIHByb3RlY3RlZCBfaW52ZXJzZVRyYW5zZm9ybU9wZXJhdG9yczogRGljdDxTeW5jSW52ZXJzZVRyYW5zZm9ybU9wZXJhdG9yPjtcbiAgcHJvdGVjdGVkIF9kZWJvdW5jZUxpdmVRdWVyaWVzOiBib29sZWFuO1xuICBwcm90ZWN0ZWQgX3RyYW5zZm9ybUJ1ZmZlcj86IFJlY29yZFRyYW5zZm9ybUJ1ZmZlcjtcblxuICBjb25zdHJ1Y3RvcihzZXR0aW5nczogU3luY1JlY29yZENhY2hlU2V0dGluZ3M8UU8sIFRPLCBRQiwgVEI+KSB7XG4gICAgc3VwZXIoc2V0dGluZ3MpO1xuXG4gICAgdGhpcy5fcXVlcnlPcGVyYXRvcnMgPSBzZXR0aW5ncy5xdWVyeU9wZXJhdG9ycyA/PyBTeW5jUXVlcnlPcGVyYXRvcnM7XG4gICAgdGhpcy5fdHJhbnNmb3JtT3BlcmF0b3JzID1cbiAgICAgIHNldHRpbmdzLnRyYW5zZm9ybU9wZXJhdG9ycyA/PyBTeW5jVHJhbnNmb3JtT3BlcmF0b3JzO1xuICAgIHRoaXMuX2ludmVyc2VUcmFuc2Zvcm1PcGVyYXRvcnMgPVxuICAgICAgc2V0dGluZ3MuaW52ZXJzZVRyYW5zZm9ybU9wZXJhdG9ycyA/PyBTeW5jSW52ZXJzZVRyYW5zZm9ybU9wZXJhdG9ycztcbiAgICB0aGlzLl9kZWJvdW5jZUxpdmVRdWVyaWVzID0gc2V0dGluZ3MuZGVib3VuY2VMaXZlUXVlcmllcyAhPT0gZmFsc2U7XG4gICAgdGhpcy5fdHJhbnNmb3JtQnVmZmVyID0gc2V0dGluZ3MudHJhbnNmb3JtQnVmZmVyO1xuXG4gICAgY29uc3QgcHJvY2Vzc29yczogU3luY09wZXJhdGlvblByb2Nlc3NvckNsYXNzW10gPSBzZXR0aW5ncy5wcm9jZXNzb3JzXG4gICAgICA/IHNldHRpbmdzLnByb2Nlc3NvcnNcbiAgICAgIDogW1N5bmNTY2hlbWFDb25zaXN0ZW5jeVByb2Nlc3NvciwgU3luY0NhY2hlSW50ZWdyaXR5UHJvY2Vzc29yXTtcblxuICAgIGlmIChzZXR0aW5ncy5hdXRvVmFsaWRhdGUgIT09IGZhbHNlICYmIHNldHRpbmdzLnByb2Nlc3NvcnMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcHJvY2Vzc29ycy5wdXNoKFN5bmNTY2hlbWFWYWxpZGF0aW9uUHJvY2Vzc29yKTtcbiAgICB9XG5cbiAgICB0aGlzLl9wcm9jZXNzb3JzID0gcHJvY2Vzc29ycy5tYXAoKFByb2Nlc3NvcikgPT4ge1xuICAgICAgbGV0IHByb2Nlc3NvciA9IG5ldyBQcm9jZXNzb3IodGhpcyk7XG4gICAgICBhc3NlcnQoXG4gICAgICAgICdFYWNoIHByb2Nlc3NvciBtdXN0IGV4dGVuZCBTeW5jT3BlcmF0aW9uUHJvY2Vzc29yJyxcbiAgICAgICAgcHJvY2Vzc29yIGluc3RhbmNlb2YgU3luY09wZXJhdGlvblByb2Nlc3NvclxuICAgICAgKTtcbiAgICAgIHJldHVybiBwcm9jZXNzb3I7XG4gICAgfSk7XG4gIH1cblxuICBnZXQgcHJvY2Vzc29ycygpOiBTeW5jT3BlcmF0aW9uUHJvY2Vzc29yW10ge1xuICAgIHJldHVybiB0aGlzLl9wcm9jZXNzb3JzO1xuICB9XG5cbiAgZ2V0UXVlcnlPcGVyYXRvcihvcDogc3RyaW5nKTogU3luY1F1ZXJ5T3BlcmF0b3Ige1xuICAgIHJldHVybiB0aGlzLl9xdWVyeU9wZXJhdG9yc1tvcF07XG4gIH1cblxuICBnZXRUcmFuc2Zvcm1PcGVyYXRvcihvcDogc3RyaW5nKTogU3luY1RyYW5zZm9ybU9wZXJhdG9yIHtcbiAgICByZXR1cm4gdGhpcy5fdHJhbnNmb3JtT3BlcmF0b3JzW29wXTtcbiAgfVxuXG4gIGdldEludmVyc2VUcmFuc2Zvcm1PcGVyYXRvcihvcDogc3RyaW5nKTogU3luY0ludmVyc2VUcmFuc2Zvcm1PcGVyYXRvciB7XG4gICAgcmV0dXJuIHRoaXMuX2ludmVyc2VUcmFuc2Zvcm1PcGVyYXRvcnNbb3BdO1xuICB9XG5cbiAgLy8gQWJzdHJhY3QgbWV0aG9kcyBmb3IgZ2V0dGluZyByZWNvcmRzIGFuZCByZWxhdGlvbnNoaXBzXG4gIGFic3RyYWN0IGdldFJlY29yZFN5bmMoXG4gICAgcmVjb3JkSWRlbnRpdHk6IFJlY29yZElkZW50aXR5XG4gICk6IEluaXRpYWxpemVkUmVjb3JkIHwgdW5kZWZpbmVkO1xuICBhYnN0cmFjdCBnZXRSZWNvcmRzU3luYyhcbiAgICB0eXBlT3JJZGVudGl0aWVzPzogc3RyaW5nIHwgUmVjb3JkSWRlbnRpdHlbXVxuICApOiBJbml0aWFsaXplZFJlY29yZFtdO1xuICBhYnN0cmFjdCBnZXRJbnZlcnNlUmVsYXRpb25zaGlwc1N5bmMoXG4gICAgcmVjb3JkSWRlbnRpdHlPcklkZW50aXRpZXM6IFJlY29yZElkZW50aXR5IHwgUmVjb3JkSWRlbnRpdHlbXVxuICApOiBSZWNvcmRSZWxhdGlvbnNoaXBJZGVudGl0eVtdO1xuXG4gIC8vIEFic3RyYWN0IG1ldGhvZHMgZm9yIHNldHRpbmcgcmVjb3JkcyBhbmQgcmVsYXRpb25zaGlwc1xuICBhYnN0cmFjdCBzZXRSZWNvcmRTeW5jKHJlY29yZDogSW5pdGlhbGl6ZWRSZWNvcmQpOiB2b2lkO1xuICBhYnN0cmFjdCBzZXRSZWNvcmRzU3luYyhyZWNvcmRzOiBJbml0aWFsaXplZFJlY29yZFtdKTogdm9pZDtcbiAgYWJzdHJhY3QgcmVtb3ZlUmVjb3JkU3luYyhcbiAgICByZWNvcmRJZGVudGl0eTogUmVjb3JkSWRlbnRpdHlcbiAgKTogSW5pdGlhbGl6ZWRSZWNvcmQgfCB1bmRlZmluZWQ7XG4gIGFic3RyYWN0IHJlbW92ZVJlY29yZHNTeW5jKFxuICAgIHJlY29yZElkZW50aXRpZXM6IFJlY29yZElkZW50aXR5W11cbiAgKTogSW5pdGlhbGl6ZWRSZWNvcmRbXTtcbiAgYWJzdHJhY3QgYWRkSW52ZXJzZVJlbGF0aW9uc2hpcHNTeW5jKFxuICAgIHJlbGF0aW9uc2hpcHM6IFJlY29yZFJlbGF0aW9uc2hpcElkZW50aXR5W11cbiAgKTogdm9pZDtcbiAgYWJzdHJhY3QgcmVtb3ZlSW52ZXJzZVJlbGF0aW9uc2hpcHNTeW5jKFxuICAgIHJlbGF0aW9uc2hpcHM6IFJlY29yZFJlbGF0aW9uc2hpcElkZW50aXR5W11cbiAgKTogdm9pZDtcblxuICBhcHBseVJlY29yZENoYW5nZXNldFN5bmMoY2hhbmdlc2V0OiBSZWNvcmRDaGFuZ2VzZXQpOiB2b2lkIHtcbiAgICBjb25zdCB7XG4gICAgICBzZXRSZWNvcmRzLFxuICAgICAgcmVtb3ZlUmVjb3JkcyxcbiAgICAgIGFkZEludmVyc2VSZWxhdGlvbnNoaXBzLFxuICAgICAgcmVtb3ZlSW52ZXJzZVJlbGF0aW9uc2hpcHNcbiAgICB9ID0gY2hhbmdlc2V0O1xuXG4gICAgaWYgKHNldFJlY29yZHMgJiYgc2V0UmVjb3Jkcy5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLnNldFJlY29yZHNTeW5jKHNldFJlY29yZHMpO1xuICAgIH1cbiAgICBpZiAocmVtb3ZlUmVjb3JkcyAmJiByZW1vdmVSZWNvcmRzLmxlbmd0aCA+IDApIHtcbiAgICAgIHRoaXMucmVtb3ZlUmVjb3Jkc1N5bmMocmVtb3ZlUmVjb3Jkcyk7XG4gICAgfVxuICAgIGlmIChhZGRJbnZlcnNlUmVsYXRpb25zaGlwcyAmJiBhZGRJbnZlcnNlUmVsYXRpb25zaGlwcy5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLmFkZEludmVyc2VSZWxhdGlvbnNoaXBzU3luYyhhZGRJbnZlcnNlUmVsYXRpb25zaGlwcyk7XG4gICAgfVxuICAgIGlmIChyZW1vdmVJbnZlcnNlUmVsYXRpb25zaGlwcyAmJiByZW1vdmVJbnZlcnNlUmVsYXRpb25zaGlwcy5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLnJlbW92ZUludmVyc2VSZWxhdGlvbnNoaXBzU3luYyhyZW1vdmVJbnZlcnNlUmVsYXRpb25zaGlwcyk7XG4gICAgfVxuICB9XG5cbiAgZ2V0UmVsYXRlZFJlY29yZFN5bmMoXG4gICAgaWRlbnRpdHk6IFJlY29yZElkZW50aXR5LFxuICAgIHJlbGF0aW9uc2hpcDogc3RyaW5nXG4gICk6IFJlY29yZElkZW50aXR5IHwgbnVsbCB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgcmVjb3JkID0gdGhpcy5nZXRSZWNvcmRTeW5jKGlkZW50aXR5KTtcbiAgICBpZiAocmVjb3JkKSB7XG4gICAgICByZXR1cm4gZGVlcEdldChyZWNvcmQsIFsncmVsYXRpb25zaGlwcycsIHJlbGF0aW9uc2hpcCwgJ2RhdGEnXSk7XG4gICAgfVxuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBnZXRSZWxhdGVkUmVjb3Jkc1N5bmMoXG4gICAgaWRlbnRpdHk6IFJlY29yZElkZW50aXR5LFxuICAgIHJlbGF0aW9uc2hpcDogc3RyaW5nXG4gICk6IFJlY29yZElkZW50aXR5W10gfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IHJlY29yZCA9IHRoaXMuZ2V0UmVjb3JkU3luYyhpZGVudGl0eSk7XG4gICAgaWYgKHJlY29yZCkge1xuICAgICAgcmV0dXJuIGRlZXBHZXQocmVjb3JkLCBbJ3JlbGF0aW9uc2hpcHMnLCByZWxhdGlvbnNoaXAsICdkYXRhJ10pO1xuICAgIH1cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgLyoqXG4gICAqIFF1ZXJpZXMgdGhlIGNhY2hlLlxuICAgKi9cbiAgcXVlcnk8UmVxdWVzdERhdGEgZXh0ZW5kcyBSZWNvcmRRdWVyeVJlc3VsdCA9IFJlY29yZFF1ZXJ5UmVzdWx0PihcbiAgICBxdWVyeU9yRXhwcmVzc2lvbnM6IFF1ZXJ5T3JFeHByZXNzaW9uczxSZWNvcmRRdWVyeUV4cHJlc3Npb24sIFFCPixcbiAgICBvcHRpb25zPzogRGVmYXVsdFJlcXVlc3RPcHRpb25zPFFPPixcbiAgICBpZD86IHN0cmluZ1xuICApOiBSZXF1ZXN0RGF0YTtcbiAgcXVlcnk8UmVxdWVzdERhdGEgZXh0ZW5kcyBSZWNvcmRRdWVyeVJlc3VsdCA9IFJlY29yZFF1ZXJ5UmVzdWx0PihcbiAgICBxdWVyeU9yRXhwcmVzc2lvbnM6IFF1ZXJ5T3JFeHByZXNzaW9uczxSZWNvcmRRdWVyeUV4cHJlc3Npb24sIFFCPixcbiAgICBvcHRpb25zOiBGdWxsUmVxdWVzdE9wdGlvbnM8UU8+LFxuICAgIGlkPzogc3RyaW5nXG4gICk6IEZ1bGxSZXNwb25zZTxSZXF1ZXN0RGF0YSwgUXVlcnlSZXNwb25zZURldGFpbHMsIFJlY29yZE9wZXJhdGlvbj47XG4gIHF1ZXJ5PFJlcXVlc3REYXRhIGV4dGVuZHMgUmVjb3JkUXVlcnlSZXN1bHQgPSBSZWNvcmRRdWVyeVJlc3VsdD4oXG4gICAgcXVlcnlPckV4cHJlc3Npb25zOiBRdWVyeU9yRXhwcmVzc2lvbnM8UmVjb3JkUXVlcnlFeHByZXNzaW9uLCBRQj4sXG4gICAgb3B0aW9ucz86IFFPLFxuICAgIGlkPzogc3RyaW5nXG4gICk6XG4gICAgfCBSZXF1ZXN0RGF0YVxuICAgIHwgRnVsbFJlc3BvbnNlPFJlcXVlc3REYXRhLCBRdWVyeVJlc3BvbnNlRGV0YWlscywgUmVjb3JkT3BlcmF0aW9uPiB7XG4gICAgY29uc3QgcXVlcnkgPSBidWlsZFF1ZXJ5PFJlY29yZFF1ZXJ5RXhwcmVzc2lvbiwgUUI+KFxuICAgICAgcXVlcnlPckV4cHJlc3Npb25zLFxuICAgICAgb3B0aW9ucyxcbiAgICAgIGlkLFxuICAgICAgdGhpcy5fcXVlcnlCdWlsZGVyXG4gICAgKTtcblxuICAgIGNvbnN0IHJlc3BvbnNlID0gdGhpcy5fcXVlcnk8UmVxdWVzdERhdGE+KHF1ZXJ5LCBvcHRpb25zKTtcblxuICAgIGlmIChvcHRpb25zPy5mdWxsUmVzcG9uc2UpIHtcbiAgICAgIHJldHVybiByZXNwb25zZTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHJlc3BvbnNlLmRhdGEgYXMgUmVxdWVzdERhdGE7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZXMgdGhlIGNhY2hlLlxuICAgKi9cbiAgdXBkYXRlPFJlcXVlc3REYXRhIGV4dGVuZHMgUmVjb3JkVHJhbnNmb3JtUmVzdWx0ID0gUmVjb3JkVHJhbnNmb3JtUmVzdWx0PihcbiAgICB0cmFuc2Zvcm1Pck9wZXJhdGlvbnM6IFRyYW5zZm9ybU9yT3BlcmF0aW9uczxSZWNvcmRPcGVyYXRpb24sIFRCPixcbiAgICBvcHRpb25zPzogRGVmYXVsdFJlcXVlc3RPcHRpb25zPFRPPixcbiAgICBpZD86IHN0cmluZ1xuICApOiBSZXF1ZXN0RGF0YTtcbiAgdXBkYXRlPFJlcXVlc3REYXRhIGV4dGVuZHMgUmVjb3JkVHJhbnNmb3JtUmVzdWx0ID0gUmVjb3JkVHJhbnNmb3JtUmVzdWx0PihcbiAgICB0cmFuc2Zvcm1Pck9wZXJhdGlvbnM6IFRyYW5zZm9ybU9yT3BlcmF0aW9uczxSZWNvcmRPcGVyYXRpb24sIFRCPixcbiAgICBvcHRpb25zOiBGdWxsUmVxdWVzdE9wdGlvbnM8VE8+LFxuICAgIGlkPzogc3RyaW5nXG4gICk6IEZ1bGxSZXNwb25zZTxSZXF1ZXN0RGF0YSwgVHJhbnNmb3JtUmVzcG9uc2VEZXRhaWxzLCBSZWNvcmRPcGVyYXRpb24+O1xuICB1cGRhdGU8UmVxdWVzdERhdGEgZXh0ZW5kcyBSZWNvcmRUcmFuc2Zvcm1SZXN1bHQgPSBSZWNvcmRUcmFuc2Zvcm1SZXN1bHQ+KFxuICAgIHRyYW5zZm9ybU9yT3BlcmF0aW9uczogVHJhbnNmb3JtT3JPcGVyYXRpb25zPFJlY29yZE9wZXJhdGlvbiwgVEI+LFxuICAgIG9wdGlvbnM/OiBUTyxcbiAgICBpZD86IHN0cmluZ1xuICApOlxuICAgIHwgUmVxdWVzdERhdGFcbiAgICB8IEZ1bGxSZXNwb25zZTxSZXF1ZXN0RGF0YSwgVHJhbnNmb3JtUmVzcG9uc2VEZXRhaWxzLCBSZWNvcmRPcGVyYXRpb24+IHtcbiAgICBjb25zdCB0cmFuc2Zvcm0gPSBidWlsZFRyYW5zZm9ybShcbiAgICAgIHRyYW5zZm9ybU9yT3BlcmF0aW9ucyxcbiAgICAgIG9wdGlvbnMsXG4gICAgICBpZCxcbiAgICAgIHRoaXMuX3RyYW5zZm9ybUJ1aWxkZXJcbiAgICApO1xuXG4gICAgY29uc3QgcmVzcG9uc2UgPSB0aGlzLl91cGRhdGU8UmVxdWVzdERhdGE+KHRyYW5zZm9ybSwgb3B0aW9ucyk7XG5cbiAgICBpZiAob3B0aW9ucz8uZnVsbFJlc3BvbnNlKSB7XG4gICAgICByZXR1cm4gcmVzcG9uc2U7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiByZXNwb25zZS5kYXRhIGFzIFJlcXVlc3REYXRhO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBQYXRjaGVzIHRoZSBjYWNoZSB3aXRoIGFuIG9wZXJhdGlvbiBvciBvcGVyYXRpb25zLlxuICAgKlxuICAgKiBAZGVwcmVjYXRlZCBzaW5jZSB2MC4xN1xuICAgKi9cbiAgcGF0Y2goXG4gICAgb3BlcmF0aW9uT3JPcGVyYXRpb25zOlxuICAgICAgfCBSZWNvcmRPcGVyYXRpb25cbiAgICAgIHwgUmVjb3JkT3BlcmF0aW9uW11cbiAgICAgIHwgUmVjb3JkT3BlcmF0aW9uVGVybVxuICAgICAgfCBSZWNvcmRPcGVyYXRpb25UZXJtW11cbiAgICAgIHwgUmVjb3JkVHJhbnNmb3JtQnVpbGRlckZ1bmNcbiAgKTogUGF0Y2hSZXN1bHQge1xuICAgIGRlcHJlY2F0ZShcbiAgICAgICdTeW5jUmVjb3JkQ2FjaGUjcGF0Y2ggaGFzIGJlZW4gZGVwcmVjYXRlZC4gVXNlIFN5bmNSZWNvcmRDYWNoZSN1cGRhdGUgaW5zdGVhZC4nXG4gICAgKTtcblxuICAgIC8vIFRPRE8gLSBXaHkgaXMgdGhpcyBgdGhpc2AgY2FzdCBuZWNlc3NhcnkgZm9yIFRTIHRvIHVuZGVyc3RhbmQgdGhlIGNvcnJlY3RcbiAgICAvLyBtZXRob2Qgb3ZlcmxvYWQ/XG4gICAgY29uc3QgeyBkYXRhLCBkZXRhaWxzIH0gPSAodGhpcyBhcyBhbnkpLnVwZGF0ZShvcGVyYXRpb25Pck9wZXJhdGlvbnMsIHtcbiAgICAgIGZ1bGxSZXNwb25zZTogdHJ1ZVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGludmVyc2U6IGRldGFpbHM/LmludmVyc2VPcGVyYXRpb25zIHx8IFtdLFxuICAgICAgZGF0YTogQXJyYXkuaXNBcnJheShkYXRhKSA/IGRhdGEgOiBbZGF0YV1cbiAgICB9O1xuICB9XG5cbiAgbGl2ZVF1ZXJ5KFxuICAgIHF1ZXJ5T3JFeHByZXNzaW9uczogUXVlcnlPckV4cHJlc3Npb25zPFJlY29yZFF1ZXJ5RXhwcmVzc2lvbiwgUUI+LFxuICAgIG9wdGlvbnM/OiBEZWZhdWx0UmVxdWVzdE9wdGlvbnM8UU8+LFxuICAgIGlkPzogc3RyaW5nXG4gICk6IFN5bmNMaXZlUXVlcnk8UU8sIFRPLCBRQiwgVEI+IHtcbiAgICBjb25zdCBxdWVyeSA9IGJ1aWxkUXVlcnkoXG4gICAgICBxdWVyeU9yRXhwcmVzc2lvbnMsXG4gICAgICBvcHRpb25zLFxuICAgICAgaWQsXG4gICAgICB0aGlzLnF1ZXJ5QnVpbGRlclxuICAgICk7XG5cbiAgICBsZXQgZGVib3VuY2UgPSBvcHRpb25zICYmIChvcHRpb25zIGFzIGFueSkuZGVib3VuY2U7XG4gICAgaWYgKHR5cGVvZiBkZWJvdW5jZSAhPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICBkZWJvdW5jZSA9IHRoaXMuX2RlYm91bmNlTGl2ZVF1ZXJpZXM7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBTeW5jTGl2ZVF1ZXJ5PFFPLCBUTywgUUIsIFRCPih7XG4gICAgICBkZWJvdW5jZSxcbiAgICAgIGNhY2hlOiB0aGlzLFxuICAgICAgcXVlcnlcbiAgICB9KTtcbiAgfVxuXG4gIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4gIC8vIFByb3RlY3RlZCBtZXRob2RzXG4gIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbiAgcHJvdGVjdGVkIF9xdWVyeTxSZXF1ZXN0RGF0YSBleHRlbmRzIFJlY29yZFF1ZXJ5UmVzdWx0ID0gUmVjb3JkUXVlcnlSZXN1bHQ+KFxuICAgIHF1ZXJ5OiBSZWNvcmRRdWVyeSxcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgb3B0aW9ucz86IFFPXG4gICk6IEZ1bGxSZXNwb25zZTxSZXF1ZXN0RGF0YSwgUXVlcnlSZXNwb25zZURldGFpbHMsIFJlY29yZE9wZXJhdGlvbj4ge1xuICAgIGxldCBkYXRhO1xuXG4gICAgaWYgKEFycmF5LmlzQXJyYXkocXVlcnkuZXhwcmVzc2lvbnMpKSB7XG4gICAgICBkYXRhID0gW107XG4gICAgICBmb3IgKGxldCBleHByZXNzaW9uIG9mIHF1ZXJ5LmV4cHJlc3Npb25zKSB7XG4gICAgICAgIGNvbnN0IHF1ZXJ5T3BlcmF0b3IgPSB0aGlzLmdldFF1ZXJ5T3BlcmF0b3IoZXhwcmVzc2lvbi5vcCk7XG4gICAgICAgIGlmICghcXVlcnlPcGVyYXRvcikge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5hYmxlIHRvIGZpbmQgcXVlcnkgb3BlcmF0b3I6ICR7ZXhwcmVzc2lvbi5vcH1gKTtcbiAgICAgICAgfVxuICAgICAgICBkYXRhLnB1c2goXG4gICAgICAgICAgcXVlcnlPcGVyYXRvcihcbiAgICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgICBleHByZXNzaW9uLFxuICAgICAgICAgICAgdGhpcy5nZXRRdWVyeU9wdGlvbnMocXVlcnksIGV4cHJlc3Npb24pXG4gICAgICAgICAgKVxuICAgICAgICApO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBleHByZXNzaW9uID0gcXVlcnkuZXhwcmVzc2lvbnMgYXMgUmVjb3JkUXVlcnlFeHByZXNzaW9uO1xuICAgICAgY29uc3QgcXVlcnlPcGVyYXRvciA9IHRoaXMuZ2V0UXVlcnlPcGVyYXRvcihleHByZXNzaW9uLm9wKTtcbiAgICAgIGlmICghcXVlcnlPcGVyYXRvcikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuYWJsZSB0byBmaW5kIHF1ZXJ5IG9wZXJhdG9yOiAke2V4cHJlc3Npb24ub3B9YCk7XG4gICAgICB9XG4gICAgICBkYXRhID0gcXVlcnlPcGVyYXRvcihcbiAgICAgICAgdGhpcyxcbiAgICAgICAgZXhwcmVzc2lvbixcbiAgICAgICAgdGhpcy5nZXRRdWVyeU9wdGlvbnMocXVlcnksIGV4cHJlc3Npb24pXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiB7IGRhdGE6IGRhdGEgYXMgUmVxdWVzdERhdGEgfTtcbiAgfVxuXG4gIHByb3RlY3RlZCBfdXBkYXRlPFxuICAgIFJlcXVlc3REYXRhIGV4dGVuZHMgUmVjb3JkVHJhbnNmb3JtUmVzdWx0ID0gUmVjb3JkVHJhbnNmb3JtUmVzdWx0XG4gID4oXG4gICAgdHJhbnNmb3JtOiBSZWNvcmRUcmFuc2Zvcm0sXG4gICAgb3B0aW9ucz86IFRPXG4gICk6IEZ1bGxSZXNwb25zZTxSZXF1ZXN0RGF0YSwgVHJhbnNmb3JtUmVzcG9uc2VEZXRhaWxzLCBSZWNvcmRPcGVyYXRpb24+IHtcbiAgICBpZiAodGhpcy5nZXRUcmFuc2Zvcm1PcHRpb25zKHRyYW5zZm9ybSk/LnVzZUJ1ZmZlcikge1xuICAgICAgY29uc3QgYnVmZmVyID0gdGhpcy5faW5pdFRyYW5zZm9ybUJ1ZmZlcih0cmFuc2Zvcm0pO1xuXG4gICAgICBidWZmZXIuc3RhcnRUcmFja2luZ0NoYW5nZXMoKTtcblxuICAgICAgY29uc3QgcmVzcG9uc2UgPSBidWZmZXIudXBkYXRlKHRyYW5zZm9ybSwge1xuICAgICAgICBmdWxsUmVzcG9uc2U6IHRydWVcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBjaGFuZ2VzID0gYnVmZmVyLnN0b3BUcmFja2luZ0NoYW5nZXMoKTtcblxuICAgICAgdGhpcy5hcHBseVJlY29yZENoYW5nZXNldFN5bmMoY2hhbmdlcyk7XG5cbiAgICAgIGNvbnN0IHtcbiAgICAgICAgYXBwbGllZE9wZXJhdGlvbnMsXG4gICAgICAgIGFwcGxpZWRPcGVyYXRpb25SZXN1bHRzXG4gICAgICB9ID0gcmVzcG9uc2UuZGV0YWlscyBhcyBUcmFuc2Zvcm1SZXNwb25zZURldGFpbHM7XG5cbiAgICAgIGZvciAobGV0IGkgPSAwLCBsZW4gPSBhcHBsaWVkT3BlcmF0aW9ucy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICB0aGlzLmVtaXQoJ3BhdGNoJywgYXBwbGllZE9wZXJhdGlvbnNbaV0sIGFwcGxpZWRPcGVyYXRpb25SZXN1bHRzW2ldKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHJlc3BvbnNlIGFzIEZ1bGxSZXNwb25zZTxcbiAgICAgICAgUmVxdWVzdERhdGEsXG4gICAgICAgIFRyYW5zZm9ybVJlc3BvbnNlRGV0YWlscyxcbiAgICAgICAgUmVjb3JkT3BlcmF0aW9uXG4gICAgICA+O1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCByZXNwb25zZSA9IHtcbiAgICAgICAgZGF0YTogW11cbiAgICAgIH0gYXMgRnVsbFJlc3BvbnNlPFxuICAgICAgICBSZWNvcmRPcGVyYXRpb25SZXN1bHRbXSxcbiAgICAgICAgUmVjb3JkQ2FjaGVVcGRhdGVEZXRhaWxzLFxuICAgICAgICBSZWNvcmRPcGVyYXRpb25cbiAgICAgID47XG5cbiAgICAgIGlmIChvcHRpb25zPy5mdWxsUmVzcG9uc2UpIHtcbiAgICAgICAgcmVzcG9uc2UuZGV0YWlscyA9IHtcbiAgICAgICAgICBhcHBsaWVkT3BlcmF0aW9uczogW10sXG4gICAgICAgICAgYXBwbGllZE9wZXJhdGlvblJlc3VsdHM6IFtdLFxuICAgICAgICAgIGludmVyc2VPcGVyYXRpb25zOiBbXVxuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICBsZXQgZGF0YTogUmVjb3JkVHJhbnNmb3JtUmVzdWx0O1xuXG4gICAgICBpZiAoQXJyYXkuaXNBcnJheSh0cmFuc2Zvcm0ub3BlcmF0aW9ucykpIHtcbiAgICAgICAgdGhpcy5fYXBwbHlUcmFuc2Zvcm1PcGVyYXRpb25zKFxuICAgICAgICAgIHRyYW5zZm9ybSxcbiAgICAgICAgICB0cmFuc2Zvcm0ub3BlcmF0aW9ucyxcbiAgICAgICAgICByZXNwb25zZSxcbiAgICAgICAgICB0cnVlXG4gICAgICAgICk7XG4gICAgICAgIGRhdGEgPSByZXNwb25zZS5kYXRhO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5fYXBwbHlUcmFuc2Zvcm1PcGVyYXRpb24oXG4gICAgICAgICAgdHJhbnNmb3JtLFxuICAgICAgICAgIHRyYW5zZm9ybS5vcGVyYXRpb25zLFxuICAgICAgICAgIHJlc3BvbnNlLFxuICAgICAgICAgIHRydWVcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkocmVzcG9uc2UuZGF0YSkpIHtcbiAgICAgICAgICBkYXRhID0gcmVzcG9uc2UuZGF0YVswXTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAob3B0aW9ucz8uZnVsbFJlc3BvbnNlKSB7XG4gICAgICAgIHJlc3BvbnNlLmRldGFpbHM/LmludmVyc2VPcGVyYXRpb25zLnJldmVyc2UoKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4ucmVzcG9uc2UsXG4gICAgICAgIGRhdGFcbiAgICAgIH0gYXMgRnVsbFJlc3BvbnNlPFJlcXVlc3REYXRhLCBUcmFuc2Zvcm1SZXNwb25zZURldGFpbHMsIFJlY29yZE9wZXJhdGlvbj47XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIF9nZXRUcmFuc2Zvcm1CdWZmZXIoKTogUmVjb3JkVHJhbnNmb3JtQnVmZmVyIHtcbiAgICBpZiAodGhpcy5fdHJhbnNmb3JtQnVmZmVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBBc3NlcnRpb24oXG4gICAgICAgICd0cmFuc2Zvcm1CdWZmZXIgbXVzdCBiZSBwcm92aWRlZCB0byBjYWNoZSB2aWEgY29uc3RydWN0b3Igc2V0dGluZ3MnXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fdHJhbnNmb3JtQnVmZmVyO1xuICB9XG5cbiAgcHJvdGVjdGVkIF9pbml0VHJhbnNmb3JtQnVmZmVyKFxuICAgIHRyYW5zZm9ybTogUmVjb3JkVHJhbnNmb3JtXG4gICk6IFJlY29yZFRyYW5zZm9ybUJ1ZmZlciB7XG4gICAgY29uc3QgYnVmZmVyID0gdGhpcy5fZ2V0VHJhbnNmb3JtQnVmZmVyKCk7XG5cbiAgICBjb25zdCByZWNvcmRzID0gcmVjb3Jkc1JlZmVyZW5jZWRCeU9wZXJhdGlvbnMoXG4gICAgICB0b0FycmF5KHRyYW5zZm9ybS5vcGVyYXRpb25zKVxuICAgICk7XG4gICAgY29uc3QgaW52ZXJzZVJlbGF0aW9uc2hpcHMgPSB0aGlzLmdldEludmVyc2VSZWxhdGlvbnNoaXBzU3luYyhyZWNvcmRzKTtcbiAgICBjb25zdCByZWxhdGVkUmVjb3JkcyA9IGludmVyc2VSZWxhdGlvbnNoaXBzLm1hcCgoaXIpID0+IGlyLnJlY29yZCk7XG4gICAgQXJyYXkucHJvdG90eXBlLnB1c2guYXBwbHkocmVjb3JkcywgcmVsYXRlZFJlY29yZHMpO1xuXG4gICAgYnVmZmVyLnJlc2V0U3RhdGUoKTtcbiAgICBidWZmZXIuc2V0UmVjb3Jkc1N5bmModGhpcy5nZXRSZWNvcmRzU3luYyhyZWNvcmRzKSk7XG4gICAgYnVmZmVyLmFkZEludmVyc2VSZWxhdGlvbnNoaXBzU3luYyhpbnZlcnNlUmVsYXRpb25zaGlwcyk7XG5cbiAgICByZXR1cm4gYnVmZmVyO1xuICB9XG5cbiAgcHJvdGVjdGVkIF9hcHBseVRyYW5zZm9ybU9wZXJhdGlvbnMoXG4gICAgdHJhbnNmb3JtOiBSZWNvcmRUcmFuc2Zvcm0sXG4gICAgb3BzOiBSZWNvcmRPcGVyYXRpb25bXSB8IFJlY29yZE9wZXJhdGlvblRlcm1bXSxcbiAgICByZXNwb25zZTogRnVsbFJlc3BvbnNlPFxuICAgICAgUmVjb3JkT3BlcmF0aW9uUmVzdWx0W10sXG4gICAgICBSZWNvcmRDYWNoZVVwZGF0ZURldGFpbHMsXG4gICAgICBSZWNvcmRPcGVyYXRpb25cbiAgICA+LFxuICAgIHByaW1hcnkgPSBmYWxzZVxuICApOiB2b2lkIHtcbiAgICBmb3IgKGNvbnN0IG9wIG9mIG9wcykge1xuICAgICAgdGhpcy5fYXBwbHlUcmFuc2Zvcm1PcGVyYXRpb24odHJhbnNmb3JtLCBvcCwgcmVzcG9uc2UsIHByaW1hcnkpO1xuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBfYXBwbHlUcmFuc2Zvcm1PcGVyYXRpb24oXG4gICAgdHJhbnNmb3JtOiBSZWNvcmRUcmFuc2Zvcm0sXG4gICAgb3BlcmF0aW9uOiBSZWNvcmRPcGVyYXRpb24gfCBSZWNvcmRPcGVyYXRpb25UZXJtLFxuICAgIHJlc3BvbnNlOiBGdWxsUmVzcG9uc2U8XG4gICAgICBSZWNvcmRPcGVyYXRpb25SZXN1bHRbXSxcbiAgICAgIFJlY29yZENhY2hlVXBkYXRlRGV0YWlscyxcbiAgICAgIFJlY29yZE9wZXJhdGlvblxuICAgID4sXG4gICAgcHJpbWFyeSA9IGZhbHNlXG4gICk6IHZvaWQge1xuICAgIGlmIChvcGVyYXRpb24gaW5zdGFuY2VvZiBPcGVyYXRpb25UZXJtKSB7XG4gICAgICBvcGVyYXRpb24gPSBvcGVyYXRpb24udG9PcGVyYXRpb24oKSBhcyBSZWNvcmRPcGVyYXRpb247XG4gICAgfVxuICAgIGZvciAobGV0IHByb2Nlc3NvciBvZiB0aGlzLl9wcm9jZXNzb3JzKSB7XG4gICAgICBwcm9jZXNzb3IudmFsaWRhdGUob3BlcmF0aW9uKTtcbiAgICB9XG5cbiAgICBjb25zdCBpbnZlcnNlVHJhbnNmb3JtT3BlcmF0b3IgPSB0aGlzLmdldEludmVyc2VUcmFuc2Zvcm1PcGVyYXRvcihcbiAgICAgIG9wZXJhdGlvbi5vcFxuICAgICk7XG4gICAgY29uc3QgaW52ZXJzZU9wOiBSZWNvcmRPcGVyYXRpb24gfCB1bmRlZmluZWQgPSBpbnZlcnNlVHJhbnNmb3JtT3BlcmF0b3IoXG4gICAgICB0aGlzLFxuICAgICAgb3BlcmF0aW9uLFxuICAgICAgdGhpcy5nZXRUcmFuc2Zvcm1PcHRpb25zKHRyYW5zZm9ybSwgb3BlcmF0aW9uKVxuICAgICk7XG4gICAgaWYgKGludmVyc2VPcCkge1xuICAgICAgcmVzcG9uc2UuZGV0YWlscz8uaW52ZXJzZU9wZXJhdGlvbnM/LnB1c2goaW52ZXJzZU9wKTtcblxuICAgICAgLy8gUXVlcnkgYW5kIHBlcmZvcm0gcmVsYXRlZCBgYmVmb3JlYCBvcGVyYXRpb25zXG4gICAgICBmb3IgKGxldCBwcm9jZXNzb3Igb2YgdGhpcy5fcHJvY2Vzc29ycykge1xuICAgICAgICB0aGlzLl9hcHBseVRyYW5zZm9ybU9wZXJhdGlvbnMoXG4gICAgICAgICAgdHJhbnNmb3JtLFxuICAgICAgICAgIHByb2Nlc3Nvci5iZWZvcmUob3BlcmF0aW9uKSxcbiAgICAgICAgICByZXNwb25zZVxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICAvLyBRdWVyeSByZWxhdGVkIGBhZnRlcmAgb3BlcmF0aW9ucyBiZWZvcmUgcGVyZm9ybWluZ1xuICAgICAgLy8gdGhlIHJlcXVlc3RlZCBvcGVyYXRpb24uIFRoZXNlIHdpbGwgYmUgYXBwbGllZCBvbiBzdWNjZXNzLlxuICAgICAgbGV0IHByZXBhcmVkT3BzID0gW107XG4gICAgICBmb3IgKGxldCBwcm9jZXNzb3Igb2YgdGhpcy5fcHJvY2Vzc29ycykge1xuICAgICAgICBwcmVwYXJlZE9wcy5wdXNoKHByb2Nlc3Nvci5hZnRlcihvcGVyYXRpb24pKTtcbiAgICAgIH1cblxuICAgICAgLy8gUGVyZm9ybSB0aGUgcmVxdWVzdGVkIG9wZXJhdGlvblxuICAgICAgbGV0IHRyYW5zZm9ybU9wZXJhdG9yID0gdGhpcy5nZXRUcmFuc2Zvcm1PcGVyYXRvcihvcGVyYXRpb24ub3ApO1xuICAgICAgbGV0IGRhdGEgPSB0cmFuc2Zvcm1PcGVyYXRvcihcbiAgICAgICAgdGhpcyxcbiAgICAgICAgb3BlcmF0aW9uLFxuICAgICAgICB0aGlzLmdldFRyYW5zZm9ybU9wdGlvbnModHJhbnNmb3JtLCBvcGVyYXRpb24pXG4gICAgICApO1xuICAgICAgaWYgKHByaW1hcnkpIHtcbiAgICAgICAgcmVzcG9uc2UuZGF0YT8ucHVzaChkYXRhKTtcbiAgICAgIH1cbiAgICAgIGlmIChyZXNwb25zZS5kZXRhaWxzKSB7XG4gICAgICAgIHJlc3BvbnNlLmRldGFpbHMuYXBwbGllZE9wZXJhdGlvblJlc3VsdHMucHVzaChkYXRhKTtcbiAgICAgICAgcmVzcG9uc2UuZGV0YWlscy5hcHBsaWVkT3BlcmF0aW9ucy5wdXNoKG9wZXJhdGlvbik7XG4gICAgICB9XG5cbiAgICAgIC8vIFF1ZXJ5IGFuZCBwZXJmb3JtIHJlbGF0ZWQgYGltbWVkaWF0ZWAgb3BlcmF0aW9uc1xuICAgICAgZm9yIChsZXQgcHJvY2Vzc29yIG9mIHRoaXMuX3Byb2Nlc3NvcnMpIHtcbiAgICAgICAgcHJvY2Vzc29yLmltbWVkaWF0ZShvcGVyYXRpb24pO1xuICAgICAgfVxuXG4gICAgICAvLyBFbWl0IGV2ZW50XG4gICAgICB0aGlzLmVtaXQoJ3BhdGNoJywgb3BlcmF0aW9uLCBkYXRhKTtcblxuICAgICAgLy8gUGVyZm9ybSBwcmVwYXJlZCBvcGVyYXRpb25zIGFmdGVyIHBlcmZvcm1pbmcgdGhlIHJlcXVlc3RlZCBvcGVyYXRpb25cbiAgICAgIGZvciAobGV0IG9wcyBvZiBwcmVwYXJlZE9wcykge1xuICAgICAgICB0aGlzLl9hcHBseVRyYW5zZm9ybU9wZXJhdGlvbnModHJhbnNmb3JtLCBvcHMsIHJlc3BvbnNlKTtcbiAgICAgIH1cblxuICAgICAgLy8gUXVlcnkgYW5kIHBlcmZvcm0gcmVsYXRlZCBgZmluYWxseWAgb3BlcmF0aW9uc1xuICAgICAgZm9yIChsZXQgcHJvY2Vzc29yIG9mIHRoaXMuX3Byb2Nlc3NvcnMpIHtcbiAgICAgICAgdGhpcy5fYXBwbHlUcmFuc2Zvcm1PcGVyYXRpb25zKFxuICAgICAgICAgIHRyYW5zZm9ybSxcbiAgICAgICAgICBwcm9jZXNzb3IuZmluYWxseShvcGVyYXRpb24pLFxuICAgICAgICAgIHJlc3BvbnNlXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChwcmltYXJ5KSB7XG4gICAgICByZXNwb25zZS5kYXRhPy5wdXNoKHVuZGVmaW5lZCk7XG4gICAgfVxuICB9XG59XG4iXX0=