UNPKG

@orbit/core

Version:

Core library for Orbit - a flexible data access and synchronization layer.

328 lines 35.3 kB
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; }; import { Orbit } from './main'; import { TaskProcessor } from './task-processor'; import { evented, settleInSeries } from './evented'; const { assert } = Orbit; /** * `TaskQueue` is a FIFO queue of asynchronous tasks that should be * performed sequentially. * * Tasks are added to the queue with `push`. Each task will be processed by * calling its `process` method. * * By default, task queues will be processed automatically, as soon as tasks * are pushed to them. This can be overridden by setting the `autoProcess` * setting to `false` and calling `process` when you'd like to start * processing. */ let TaskQueue = class TaskQueue { /** * Creates an instance of `TaskQueue`. */ constructor(target, settings = {}) { this._tasks = []; this._processors = []; this._performer = target; this._name = settings.name; this._bucket = settings.bucket; this.autoProcess = settings.autoProcess === undefined ? true : settings.autoProcess; if (this._bucket) { assert('TaskQueue requires a name if it has a bucket', !!this._name); } const autoActivate = settings.autoActivate === undefined || settings.autoActivate; if (autoActivate) { this.activate(); } else { this._reify(); } } async activate() { await this._reify(); if (this.length > 0 && this.autoProcess) { this.process(); } } /** * Name used for tracking / debugging this queue. */ get name() { return this._name; } /** * The object which will `perform` the tasks in this queue. */ get performer() { return this._performer; } /** * A bucket used to persist the state of this queue. */ get bucket() { return this._bucket; } /** * The number of tasks in the queue. */ get length() { return this._tasks.length; } /** * The tasks in the queue. */ get entries() { return this._tasks; } /** * The current task being processed (if actively processing), or the next * task to be processed (if not actively processing). */ get current() { return this._tasks[0]; } /** * The processor wrapper that is processing the current task (or next task, * if none are being processed). */ get currentProcessor() { return this._processors[0]; } /** * If an error occurs while processing a task, processing will be halted, the * `fail` event will be emitted, and this property will reflect the error * encountered. */ get error() { return this._error; } /** * Is the queue empty? */ get empty() { return this.length === 0; } /** * Is the queue actively processing a task? */ get processing() { const processor = this.currentProcessor; return processor !== undefined && processor.started && !processor.settled; } /** * Resolves when the queue has been fully reified from its associated bucket, * if applicable. */ get reified() { return this._reified; } /** * Push a new task onto the end of the queue. * * If `autoProcess` is enabled, this will automatically trigger processing of * the queue. * * Returns the result of processing the pushed task. */ async push(task) { await this._reified; const processor = new TaskProcessor(this._performer, task); this._tasks.push(task); this._processors.push(processor); await this._persist(); if (this.autoProcess) this._settle(); return processor.settle(); } /** * Cancels and re-tries processing the current task. * * Returns the result of the retried task. */ async retry() { await this._reified; this._cancel(); let processor = this.currentProcessor; processor.reset(); await this._persist(); this._settle(); return processor.settle(); } /** * Cancels and discards the current task. * * If `autoProcess` is enabled, this will automatically trigger processing of * the queue. */ async skip(e) { await this._reified; this._cancel(); this._tasks.shift(); let processor = this._processors.shift(); if (processor !== undefined && !processor.settled) { processor.reject(e || new Error('Processing cancelled via `TaskQueue#skip`')); } await this._persist(); if (this.autoProcess) this._settle(); } /** * Cancels the current task and completely clears the queue. */ async clear(e) { await this._reified; this._cancel(); this._tasks = []; for (let processor of this._processors) { if (!processor.settled) { processor.reject(e || new Error('Processing cancelled via `TaskQueue#clear`')); } } this._processors = []; await this._persist(); await this._settle(); } /** * Cancels the current task and removes it, but does not continue processing. * * Returns the canceled and removed task. */ async shift(e) { await this._reified; let task = this._tasks.shift(); if (task) { this._cancel(); let processor = this._processors.shift(); if (processor !== undefined && !processor.settled) { processor.reject(e || new Error('Processing cancelled via `TaskQueue#shift`')); } await this._persist(); } return task; } /** * Cancels processing the current task and inserts a new task at the beginning * of the queue. This new task will be processed next. * * Returns the result of processing the new task. */ async unshift(task) { await this._reified; let processor = new TaskProcessor(this._performer, task); this._cancel(); this._tasks.unshift(task); this._processors.unshift(processor); await this._persist(); if (this.autoProcess) this._settle(); return processor.settle(); } /** * Processes all the tasks in the queue. Resolves when the queue is empty. */ async process() { await this._reified; let resolution = this._resolution; if (!resolution) { if (this._tasks.length === 0) { resolution = this._complete(); } else { this._error = undefined; this._resolution = resolution = new Promise((resolve, reject) => { this._resolve = resolve; this._reject = reject; }); await this._settleEach(resolution); } } return resolution; } async _settle() { try { await this.process(); } catch (e) { } } async _complete() { if (this._resolve) { this._resolve(); } this._resolve = undefined; this._reject = undefined; this._error = undefined; this._resolution = undefined; await settleInSeries(this, 'complete'); } async _fail(task, e) { if (this._reject) { this._reject(e); } this._resolve = undefined; this._reject = undefined; this._error = e; this._resolution = undefined; await settleInSeries(this, 'fail', task, e); } _cancel() { this._error = undefined; this._resolution = undefined; } async _settleEach(resolution) { if (this._tasks.length === 0) { return this._complete(); } else { const task = this._tasks[0]; const processor = this._processors[0]; try { await settleInSeries(this, 'beforeTask', task); await processor.process(); if (resolution === this._resolution) { this._tasks.shift(); this._processors.shift(); await this._persist(); await settleInSeries(this, 'task', task); await this._settleEach(resolution); } } catch (e) { if (resolution === this._resolution) { return this._fail(task, e); } } } } _reify() { this._tasks = []; this._processors = []; this._reified = this._loadTasksFromBucket().then((tasks) => { if (tasks) { this._tasks = tasks; this._processors = tasks.map((task) => new TaskProcessor(this._performer, task)); } }); return this._reified; } async _loadTasksFromBucket() { if (this._bucket && this._name) { return this._bucket.getItem(this._name); } } async _persist() { this.emit('change'); if (this._bucket && this._name) { await this._bucket.setItem(this._name, this._tasks); } } }; TaskQueue = __decorate([ evented ], TaskQueue); export { TaskQueue }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFzay1xdWV1ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90YXNrLXF1ZXVlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxRQUFRLENBQUM7QUFFL0IsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBRWpELE9BQU8sRUFBRSxPQUFPLEVBQVcsY0FBYyxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBRTdELE1BQU0sRUFBRSxNQUFNLEVBQUUsR0FBRyxLQUFLLENBQUM7QUF5Q3pCOzs7Ozs7Ozs7OztHQVdHO0FBRUgsSUFBYSxTQUFTLEdBQXRCLE1BQWEsU0FBUztJQW1CcEI7O09BRUc7SUFDSCxZQUNFLE1BQThDLEVBQzlDLFdBQW1ELEVBQUU7UUFiL0MsV0FBTSxHQUFnQyxFQUFFLENBQUM7UUFDekMsZ0JBQVcsR0FBaUQsRUFBRSxDQUFDO1FBY3JFLElBQUksQ0FBQyxVQUFVLEdBQUcsTUFBTSxDQUFDO1FBQ3pCLElBQUksQ0FBQyxLQUFLLEdBQUcsUUFBUSxDQUFDLElBQUksQ0FBQztRQUMzQixJQUFJLENBQUMsT0FBTyxHQUFHLFFBQVEsQ0FBQyxNQUFNLENBQUM7UUFDL0IsSUFBSSxDQUFDLFdBQVc7WUFDZCxRQUFRLENBQUMsV0FBVyxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDO1FBRW5FLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRTtZQUNoQixNQUFNLENBQUMsOENBQThDLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztTQUN0RTtRQUVELE1BQU0sWUFBWSxHQUNoQixRQUFRLENBQUMsWUFBWSxLQUFLLFNBQVMsSUFBSSxRQUFRLENBQUMsWUFBWSxDQUFDO1FBRS9ELElBQUksWUFBWSxFQUFFO1lBQ2hCLElBQUksQ0FBQyxRQUFRLEVBQUUs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QUMsS0FBSyxFQUFFO1lBQzlCLE1BQU0sSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7U0FDckQ7SUFDSCxDQUFDO0NBQ0YsQ0FBQTtBQWxYWSxTQUFTO0lBRHJCLE9BQU87R0FDSyxTQUFTLENBa1hyQjtTQWxYWSxTQUFTIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgT3JiaXQgfSBmcm9tICcuL21haW4nO1xuaW1wb3J0IHsgVGFzaywgUGVyZm9ybWVyIH0gZnJvbSAnLi90YXNrJztcbmltcG9ydCB7IFRhc2tQcm9jZXNzb3IgfSBmcm9tICcuL3Rhc2stcHJvY2Vzc29yJztcbmltcG9ydCB7IEJ1Y2tldCB9IGZyb20gJy4vYnVja2V0JztcbmltcG9ydCB7IGV2ZW50ZWQsIEV2ZW50ZWQsIHNldHRsZUluU2VyaWVzIH0gZnJvbSAnLi9ldmVudGVkJztcblxuY29uc3QgeyBhc3NlcnQgfSA9IE9yYml0O1xuXG4vKipcbiAqIFNldHRpbmdzIGZvciBhIGBUYXNrUXVldWVgLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFRhc2tRdWV1ZVNldHRpbmdzPFxuICBUeXBlID0gc3RyaW5nLFxuICBEYXRhID0gdW5rbm93bixcbiAgT3B0aW9ucyA9IHVua25vd25cbj4ge1xuICAvKipcbiAgICogTmFtZSB1c2VkIGZvciB0cmFja2luZyBhbmQgZGVidWdnaW5nIGEgdGFzayBxdWV1ZS5cbiAgICovXG4gIG5hbWU/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEEgYnVja2V0IGluIHdoaWNoIHRvIHBlcnNpc3QgcXVldWUgc3RhdGUuXG4gICAqL1xuICBidWNrZXQ/OiBCdWNrZXQ8VGFzazxUeXBlLCBEYXRhLCBPcHRpb25zPltdPjtcblxuICAvKipcbiAgICogQSBmbGFnIGluZGljYXRpbmcgd2hldGhlciB0YXNrcyBzaG91bGQgYmUgcHJvY2Vzc2VkIGFzIHNvb24gYXMgdGhleSBhcmVcbiAgICogcHVzaGVkIGludG8gYSBxdWV1ZS4gU2V0IHRvIGBmYWxzZWAgdG8gb3ZlcnJpZGUgdGhlIGRlZmF1bHQgYHRydWVgXG4gICAqIGJlaGF2aW9yLlxuICAgKi9cbiAgYXV0b1Byb2Nlc3M/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBBIGZsYWcgaW5kaWNhdGluZyB3aGV0aGVyIGFjdGl2YXRpb24gc2hvdWxkIGhhcHBlbiBhcyBwYXJ0IG9mXG4gICAqIGluc3RhbnRpYXRpb24uIFNldCB0byBgZmFsc2VgIHRvIG92ZXJyaWRlIHRoZSBkZWZhdWx0IGB0cnVlYCBiZWhhdmlvci4gV2hlblxuICAgKiBgYXV0b0FjdGl2YXRlID09PSBmYWxzZWAsIG5vIHRhc2tzIHJlaWZpZWQgZnJvbSB0aGUgcXVldWUncyBidWNrZXQgd2lsbCBiZVxuICAgKiBhdXRvbWF0aWNhbGx5IHByb2Nlc3NlZCBhcyBwYXJ0IG9mIHF1ZXVlIGluc3RhbnRpYXRpb24sIHJlZ2FyZGxlc3Mgb2YgdGhlXG4gICAqIGBhdXRvUHJvY2Vzc2Agc2V0dGluZy4gSW52b2tlIGBxdWV1ZS5hY3RpdmF0ZSgpYCBhcyBhIHNlcGFyYXRlIHN0ZXAgdG9cbiAgICogZmluaXNoIGFjdGl2YXRpb24gYW5kIHN0YXJ0IHByb2Nlc3NpbmcgdGFza3MuXG4gICAqL1xuICBhdXRvQWN0aXZhdGU/OiBib29sZWFuO1xufVxuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWVtcHR5LWludGVyZmFjZVxuZXhwb3J0IGludGVyZmFjZSBUYXNrUXVldWUgZXh0ZW5kcyBFdmVudGVkIHt9XG5cbi8qKlxuICogYFRhc2tRdWV1ZWAgaXMgYSBGSUZPIHF1ZXVlIG9mIGFzeW5jaHJvbm91cyB0YXNrcyB0aGF0IHNob3VsZCBiZVxuICogcGVyZm9ybWVkIHNlcXVlbnRpYWxseS5cbiAqXG4gKiBUYXNrcyBhcmUgYWRkZWQgdG8gdGhlIHF1ZXVlIHdpdGggYHB1c2hgLiBFYWNoIHRhc2sgd2lsbCBiZSBwcm9jZXNzZWQgYnlcbiAqIGNhbGxpbmcgaXRzIGBwcm9jZXNzYCBtZXRob2QuXG4gKlxuICogQnkgZGVmYXVsdCwgdGFzayBxdWV1ZXMgd2lsbCBiZSBwcm9jZXNzZWQgYXV0b21hdGljYWxseSwgYXMgc29vbiBhcyB0YXNrc1xuICogYXJlIHB1c2hlZCB0byB0aGVtLiBUaGlzIGNhbiBiZSBvdmVycmlkZGVuIGJ5IHNldHRpbmcgdGhlIGBhdXRvUHJvY2Vzc2BcbiAqIHNldHRpbmcgdG8gYGZhbHNlYCBhbmQgY2FsbGluZyBgcHJvY2Vzc2Agd2hlbiB5b3UnZCBsaWtlIHRvIHN0YXJ0XG4gKiBwcm9jZXNzaW5nLlxuICovXG5AZXZlbnRlZFxuZXhwb3J0IGNsYXNzIFRhc2tRdWV1ZTxcbiAgVHlwZSA9IHN0cmluZyxcbiAgRGF0YSA9IHVua25vd24sXG4gIE9wdGlvbnMgPSB1bmtub3duLFxuICBSZXN1bHQgPSB1bmtub3duXG4+IHtcbiAgcHVibGljIGF1dG9Qcm9jZXNzOiBib29sZWFuO1xuXG4gIHByaXZhdGUgX3BlcmZvcm1lcjogUGVyZm9ybWVyPFR5cGUsIERhdGEsIE9wdGlvbnMsIFJlc3VsdD47XG4gIHByaXZhdGUgX25hbWU/OiBzdHJpbmc7XG4gIHByaXZhdGUgX2J1Y2tldD86IEJ1Y2tldDxUYXNrPFR5cGUsIERhdGEsIE9wdGlvbnM+W10+O1xuICBwcml2YXRlIF90YXNrczogVGFzazxUeXBlLCBEYXRhLCBPcHRpb25zPltdID0gW107XG4gIHByaXZhdGUgX3Byb2Nlc3NvcnM6IFRhc2tQcm9jZXNzb3I8VHlwZSwgRGF0YSwgT3B0aW9ucywgUmVzdWx0PltdID0gW107XG4gIHByaXZhdGUgX2Vycm9yPzogRXJyb3I7XG4gIHByaXZhdGUgX3Jlc29sdXRpb24/OiBQcm9taXNlPHZvaWQ+O1xuICBwcml2YXRlIF9yZXNvbHZlPzogKCkgPT4gdm9pZDtcbiAgcHJpdmF0ZSBfcmVqZWN0PzogKGU6IEVycm9yKSA9PiB2b2lkO1xuICBwcml2YXRlIF9yZWlmaWVkITogUHJvbWlzZTx2b2lkPjtcblxuICAvKipcbiAgICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBgVGFza1F1ZXVlYC5cbiAgICovXG4gIGNvbnN0cnVjdG9yKFxuICAgIHRhcmdldDogUGVyZm9ybWVyPFR5cGUsIERhdGEsIE9wdGlvbnMsIFJlc3VsdD4sXG4gICAgc2V0dGluZ3M6IFRhc2tRdWV1ZVNldHRpbmdzPFR5cGUsIERhdGEsIE9wdGlvbnM+ID0ge31cbiAgKSB7XG4gICAgdGhpcy5fcGVyZm9ybWVyID0gdGFyZ2V0O1xuICAgIHRoaXMuX25hbWUgPSBzZXR0aW5ncy5uYW1lO1xuICAgIHRoaXMuX2J1Y2tldCA9IHNldHRpbmdzLmJ1Y2tldDtcbiAgICB0aGlzLmF1dG9Qcm9jZXNzID1cbiAgICAgIHNldHRpbmdzLmF1dG9Qcm9jZXNzID09PSB1bmRlZmluZWQgPyB0cnVlIDogc2V0dGluZ3MuYXV0b1Byb2Nlc3M7XG5cbiAgICBpZiAodGhpcy5fYnVja2V0KSB7XG4gICAgICBhc3NlcnQoJ1Rhc2tRdWV1ZSByZXF1aXJlcyBhIG5hbWUgaWYgaXQgaGFzIGEgYnVja2V0JywgISF0aGlzLl9uYW1lKTtcbiAgICB9XG5cbiAgICBjb25zdCBhdXRvQWN0aXZhdGUgPVxuICAgICAgc2V0dGluZ3MuYXV0b0FjdGl2YXRlID09PSB1bmRlZmluZWQgfHwgc2V0dGluZ3MuYXV0b0FjdGl2YXRlO1xuXG4gICAgaWYgKGF1dG9BY3RpdmF0ZSkge1xuICAgICAgdGhpcy5hY3RpdmF0ZSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9yZWlmeSgpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGFjdGl2YXRlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IHRoaXMuX3JlaWZ5KCk7XG5cbiAgICBpZiAodGhpcy5sZW5ndGggPiAwICYmIHRoaXMuYXV0b1Byb2Nlc3MpIHtcbiAgICAgIHRoaXMucHJvY2VzcygpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBOYW1lIHVzZWQgZm9yIHRyYWNraW5nIC8gZGVidWdnaW5nIHRoaXMgcXVldWUuXG4gICAqL1xuICBnZXQgbmFtZSgpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLl9uYW1lO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBvYmplY3Qgd2hpY2ggd2lsbCBgcGVyZm9ybWAgdGhlIHRhc2tzIGluIHRoaXMgcXVldWUuXG4gICAqL1xuICBnZXQgcGVyZm9ybWVyKCk6IFBlcmZvcm1lcjxUeXBlLCBEYXRhLCBPcHRpb25zLCBSZXN1bHQ+IHtcbiAgICByZXR1cm4gdGhpcy5fcGVyZm9ybWVyO1xuICB9XG5cbiAgLyoqXG4gICAqIEEgYnVja2V0IHVzZWQgdG8gcGVyc2lzdCB0aGUgc3RhdGUgb2YgdGhpcyBxdWV1ZS5cbiAgICovXG4gIGdldCBidWNrZXQoKTogQnVja2V0PFRhc2s8VHlwZSwgRGF0YT5bXT4gfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLl9idWNrZXQ7XG4gIH1cblxuICAvKipcbiAgICogVGhlIG51bWJlciBvZiB0YXNrcyBpbiB0aGUgcXVldWUuXG4gICAqL1xuICBnZXQgbGVuZ3RoKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuX3Rhc2tzLmxlbmd0aDtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgdGFza3MgaW4gdGhlIHF1ZXVlLlxuICAgKi9cbiAgZ2V0IGVudHJpZXMoKTogVGFzazxUeXBlLCBEYXRhPltdIHtcbiAgICByZXR1cm4gdGhpcy5fdGFza3M7XG4gIH1cblxuICAvKipcbiAgICogVGhlIGN1cnJlbnQgdGFzayBiZWluZyBwcm9jZXNzZWQgKGlmIGFjdGl2ZWx5IHByb2Nlc3NpbmcpLCBvciB0aGUgbmV4dFxuICAgKiB0YXNrIHRvIGJlIHByb2Nlc3NlZCAoaWYgbm90IGFjdGl2ZWx5IHByb2Nlc3NpbmcpLlxuICAgKi9cbiAgZ2V0IGN1cnJlbnQoKTogVGFzazxUeXBlLCBEYXRhPiB7XG4gICAgcmV0dXJuIHRoaXMuX3Rhc2tzWzBdO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBwcm9jZXNzb3Igd3JhcHBlciB0aGF0IGlzIHByb2Nlc3NpbmcgdGhlIGN1cnJlbnQgdGFzayAob3IgbmV4dCB0YXNrLFxuICAgKiBpZiBub25lIGFyZSBiZWluZyBwcm9jZXNzZWQpLlxuICAgKi9cbiAgZ2V0IGN1cnJlbnRQcm9jZXNzb3IoKTogVGFza1Byb2Nlc3NvcjxUeXBlLCBEYXRhLCBPcHRpb25zLCBSZXN1bHQ+IHtcbiAgICByZXR1cm4gdGhpcy5fcHJvY2Vzc29yc1swXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgcHJvY2Vzc2luZyBhIHRhc2ssIHByb2Nlc3Npbmcgd2lsbCBiZSBoYWx0ZWQsIHRoZVxuICAgKiBgZmFpbGAgZXZlbnQgd2lsbCBiZSBlbWl0dGVkLCBhbmQgdGhpcyBwcm9wZXJ0eSB3aWxsIHJlZmxlY3QgdGhlIGVycm9yXG4gICAqIGVuY291bnRlcmVkLlxuICAgKi9cbiAgZ2V0IGVycm9yKCk6IEVycm9yIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5fZXJyb3I7XG4gIH1cblxuICAvKipcbiAgICogSXMgdGhlIHF1ZXVlIGVtcHR5P1xuICAgKi9cbiAgZ2V0IGVtcHR5KCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmxlbmd0aCA9PT0gMDtcbiAgfVxuXG4gIC8qKlxuICAgKiBJcyB0aGUgcXVldWUgYWN0aXZlbHkgcHJvY2Vzc2luZyBhIHRhc2s/XG4gICAqL1xuICBnZXQgcHJvY2Vzc2luZygpOiBib29sZWFuIHtcbiAgICBjb25zdCBwcm9jZXNzb3IgPSB0aGlzLmN1cnJlbnRQcm9jZXNzb3I7XG5cbiAgICByZXR1cm4gcHJvY2Vzc29yICE9PSB1bmRlZmluZWQgJiYgcHJvY2Vzc29yLnN0YXJ0ZWQgJiYgIXByb2Nlc3Nvci5zZXR0bGVkO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlc29sdmVzIHdoZW4gdGhlIHF1ZXVlIGhhcyBiZWVuIGZ1bGx5IHJlaWZpZWQgZnJvbSBpdHMgYXNzb2NpYXRlZCBidWNrZXQsXG4gICAqIGlmIGFwcGxpY2FibGUuXG4gICAqL1xuICBnZXQgcmVpZmllZCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gdGhpcy5fcmVpZmllZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBQdXNoIGEgbmV3IHRhc2sgb250byB0aGUgZW5kIG9mIHRoZSBxdWV1ZS5cbiAgICpcbiAgICogSWYgYGF1dG9Qcm9jZXNzYCBpcyBlbmFibGVkLCB0aGlzIHdpbGwgYXV0b21hdGljYWxseSB0cmlnZ2VyIHByb2Nlc3Npbmcgb2ZcbiAgICogdGhlIHF1ZXVlLlxuICAgKlxuICAgKiBSZXR1cm5zIHRoZSByZXN1bHQgb2YgcHJvY2Vzc2luZyB0aGUgcHVzaGVkIHRhc2suXG4gICAqL1xuICBhc3luYyBwdXNoKHRhc2s6IFRhc2s8VHlwZSwgRGF0YSwgT3B0aW9ucz4pOiBQcm9taXNlPFJlc3VsdD4ge1xuICAgIGF3YWl0IHRoaXMuX3JlaWZpZWQ7XG5cbiAgICBjb25zdCBwcm9jZXNzb3IgPSBuZXcgVGFza1Byb2Nlc3Nvcih0aGlzLl9wZXJmb3JtZXIsIHRhc2spO1xuICAgIHRoaXMuX3Rhc2tzLnB1c2godGFzayk7XG4gICAgdGhpcy5fcHJvY2Vzc29ycy5wdXNoKHByb2Nlc3Nvcik7XG4gICAgYXdhaXQgdGhpcy5fcGVyc2lzdCgpO1xuICAgIGlmICh0aGlzLmF1dG9Qcm9jZXNzKSB0aGlzLl9zZXR0bGUoKTtcbiAgICByZXR1cm4gcHJvY2Vzc29yLnNldHRsZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIENhbmNlbHMgYW5kIHJlLXRyaWVzIHByb2Nlc3NpbmcgdGhlIGN1cnJlbnQgdGFzay5cbiAgICpcbiAgICogUmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSByZXRyaWVkIHRhc2suXG4gICAqL1xuICBhc3luYyByZXRyeSgpOiBQcm9taXNlPFJlc3VsdD4ge1xuICAgIGF3YWl0IHRoaXMuX3JlaWZpZWQ7XG5cbiAgICB0aGlzLl9jYW5jZWwoKTtcbiAgICBsZXQgcHJvY2Vzc29yID0gdGhpcy5jdXJyZW50UHJvY2Vzc29yO1xuICAgIHByb2Nlc3Nvci5yZXNldCgpO1xuICAgIGF3YWl0IHRoaXMuX3BlcnNpc3QoKTtcbiAgICB0aGlzLl9zZXR0bGUoKTtcbiAgICByZXR1cm4gcHJvY2Vzc29yLnNldHRsZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIENhbmNlbHMgYW5kIGRpc2NhcmRzIHRoZSBjdXJyZW50IHRhc2suXG4gICAqXG4gICAqIElmIGBhdXRvUHJvY2Vzc2AgaXMgZW5hYmxlZCwgdGhpcyB3aWxsIGF1dG9tYXRpY2FsbHkgdHJpZ2dlciBwcm9jZXNzaW5nIG9mXG4gICAqIHRoZSBxdWV1ZS5cbiAgICovXG4gIGFzeW5jIHNraXAoZT86IEVycm9yKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy5fcmVpZmllZDtcblxuICAgIHRoaXMuX2NhbmNlbCgpO1xuICAgIHRoaXMuX3Rhc2tzLnNoaWZ0KCk7XG4gICAgbGV0IHByb2Nlc3NvciA9IHRoaXMuX3Byb2Nlc3NvcnMuc2hpZnQoKTtcbiAgICBpZiAocHJvY2Vzc29yICE9PSB1bmRlZmluZWQgJiYgIXByb2Nlc3Nvci5zZXR0bGVkKSB7XG4gICAgICBwcm9jZXNzb3IucmVqZWN0KFxuICAgICAgICBlIHx8IG5ldyBFcnJvcignUHJvY2Vzc2luZyBjYW5jZWxsZWQgdmlhIGBUYXNrUXVldWUjc2tpcGAnKVxuICAgICAgKTtcbiAgICB9XG4gICAgYXdhaXQgdGhpcy5fcGVyc2lzdCgpO1xuICAgIGlmICh0aGlzLmF1dG9Qcm9jZXNzKSB0aGlzLl9zZXR0bGUoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDYW5jZWxzIHRoZSBjdXJyZW50IHRhc2sgYW5kIGNvbXBsZXRlbHkgY2xlYXJzIHRoZSBxdWV1ZS5cbiAgICovXG4gIGFzeW5jIGNsZWFyKGU/OiBFcnJvcik6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IHRoaXMuX3JlaWZpZWQ7XG5cbiAgICB0aGlzLl9jYW5jZWwoKTtcbiAgICB0aGlzLl90YXNrcyA9IFtdO1xuICAgIGZvciAobGV0IHByb2Nlc3NvciBvZiB0aGlzLl9wcm9jZXNzb3JzKSB7XG4gICAgICBpZiAoIXByb2Nlc3Nvci5zZXR0bGVkKSB7XG4gICAgICAgIHByb2Nlc3Nvci5yZWplY3QoXG4gICAgICAgICAgZSB8fCBuZXcgRXJyb3IoJ1Byb2Nlc3NpbmcgY2FuY2VsbGVkIHZpYSBgVGFza1F1ZXVlI2NsZWFyYCcpXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMuX3Byb2Nlc3NvcnMgPSBbXTtcbiAgICBhd2FpdCB0aGlzLl9wZXJzaXN0KCk7XG4gICAgYXdhaXQgdGhpcy5fc2V0dGxlKCk7XG4gIH1cblxuICAvKipcbiAgICogQ2FuY2VscyB0aGUgY3VycmVudCB0YXNrIGFuZCByZW1vdmVzIGl0LCBidXQgZG9lcyBub3QgY29udGludWUgcHJvY2Vzc2luZy5cbiAgICpcbiAgICogUmV0dXJucyB0aGUgY2FuY2VsZWQgYW5kIHJlbW92ZWQgdGFzay5cbiAgICovXG4gIGFzeW5jIHNoaWZ0KGU/OiBFcnJvcik6IFByb21pc2U8VGFzazxUeXBlLCBEYXRhPiB8IHVuZGVmaW5lZD4ge1xuICAgIGF3YWl0IHRoaXMuX3JlaWZpZWQ7XG5cbiAgICBsZXQgdGFzayA9IHRoaXMuX3Rhc2tzLnNoaWZ0KCk7XG4gICAgaWYgKHRhc2spIHtcbiAgICAgIHRoaXMuX2NhbmNlbCgpO1xuICAgICAgbGV0IHByb2Nlc3NvciA9IHRoaXMuX3Byb2Nlc3NvcnMuc2hpZnQoKTtcbiAgICAgIGlmIChwcm9jZXNzb3IgIT09IHVuZGVmaW5lZCAmJiAhcHJvY2Vzc29yLnNldHRsZWQpIHtcbiAgICAgICAgcHJvY2Vzc29yLnJlamVjdChcbiAgICAgICAgICBlIHx8IG5ldyBFcnJvcignUHJvY2Vzc2luZyBjYW5jZWxsZWQgdmlhIGBUYXNrUXVldWUjc2hpZnRgJylcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGF3YWl0IHRoaXMuX3BlcnNpc3QoKTtcbiAgICB9XG4gICAgcmV0dXJuIHRhc2s7XG4gIH1cblxuICAvKipcbiAgICogQ2FuY2VscyBwcm9jZXNzaW5nIHRoZSBjdXJyZW50IHRhc2sgYW5kIGluc2VydHMgYSBuZXcgdGFzayBhdCB0aGUgYmVnaW5uaW5nXG4gICAqIG9mIHRoZSBxdWV1ZS4gVGhpcyBuZXcgdGFzayB3aWxsIGJlIHByb2Nlc3NlZCBuZXh0LlxuICAgKlxuICAgKiBSZXR1cm5zIHRoZSByZXN1bHQgb2YgcHJvY2Vzc2luZyB0aGUgbmV3IHRhc2suXG4gICAqL1xuICBhc3luYyB1bnNoaWZ0KHRhc2s6IFRhc2s8VHlwZSwgRGF0YSwgT3B0aW9ucz4pOiBQcm9taXNlPFJlc3VsdD4ge1xuICAgIGF3YWl0IHRoaXMuX3JlaWZpZWQ7XG5cbiAgICBsZXQgcHJvY2Vzc29yID0gbmV3IFRhc2tQcm9jZXNzb3I8VHlwZSwgRGF0YSwgT3B0aW9ucywgUmVzdWx0PihcbiAgICAgIHRoaXMuX3BlcmZvcm1lcixcbiAgICAgIHRhc2tcbiAgICApO1xuICAgIHRoaXMuX2NhbmNlbCgpO1xuICAgIHRoaXMuX3Rhc2tzLnVuc2hpZnQodGFzayk7XG4gICAgdGhpcy5fcHJvY2Vzc29ycy51bnNoaWZ0KHByb2Nlc3Nvcik7XG4gICAgYXdhaXQgdGhpcy5fcGVyc2lzdCgpO1xuICAgIGlmICh0aGlzLmF1dG9Qcm9jZXNzKSB0aGlzLl9zZXR0bGUoKTtcbiAgICByZXR1cm4gcHJvY2Vzc29yLnNldHRsZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFByb2Nlc3NlcyBhbGwgdGhlIHRhc2tzIGluIHRoZSBxdWV1ZS4gUmVzb2x2ZXMgd2hlbiB0aGUgcXVldWUgaXMgZW1wdHkuXG4gICAqL1xuICBhc3luYyBwcm9jZXNzKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IHRoaXMuX3JlaWZpZWQ7XG5cbiAgICBsZXQgcmVzb2x1dGlvbiA9IHRoaXMuX3Jlc29sdXRpb247XG4gICAgaWYgKCFyZXNvbHV0aW9uKSB7XG4gICAgICBpZiAodGhpcy5fdGFza3MubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJlc29sdXRpb24gPSB0aGlzLl9jb21wbGV0ZSgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5fZXJyb3IgPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMuX3Jlc29sdXRpb24gPSByZXNvbHV0aW9uID0gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgIHRoaXMuX3Jlc29sdmUgPSByZXNvbHZlO1xuICAgICAgICAgIHRoaXMuX3JlamVjdCA9IHJlamVjdDtcbiAgICAgICAgfSk7XG4gICAgICAgIGF3YWl0IHRoaXMuX3NldHRsZUVhY2gocmVzb2x1dGlvbik7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXNvbHV0aW9uO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBfc2V0dGxlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLnByb2Nlc3MoKTtcbiAgICB9IGNhdGNoIChlKSB7fVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBfY29tcGxldGUoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMuX3Jlc29sdmUpIHtcbiAgICAgIHRoaXMuX3Jlc29sdmUoKTtcbiAgICB9XG4gICAgdGhpcy5fcmVzb2x2ZSA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLl9yZWplY3QgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5fZXJyb3IgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5fcmVzb2x1dGlvbiA9IHVuZGVmaW5lZDtcbiAgICBhd2FpdCBzZXR0bGVJblNlcmllcyh0aGlzLCAnY29tcGxldGUnKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgX2ZhaWwodGFzazogVGFzazxUeXBlLCBEYXRhPiwgZTogRXJyb3IpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAodGhpcy5fcmVqZWN0KSB7XG4gICAgICB0aGlzLl9yZWplY3QoZSk7XG4gICAgfVxuICAgIHRoaXMuX3Jlc29sdmUgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5fcmVqZWN0ID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuX2Vycm9yID0gZTtcbiAgICB0aGlzLl9yZXNvbHV0aW9uID0gdW5kZWZpbmVkO1xuICAgIGF3YWl0IHNldHRsZUluU2VyaWVzKHRoaXMsICdmYWlsJywgdGFzaywgZSk7XG4gIH1cblxuICBwcml2YXRlIF9jYW5jZWwoKTogdm9pZCB7XG4gICAgdGhpcy5fZXJyb3IgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5fcmVzb2x1dGlvbiA9IHVuZGVmaW5lZDtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgX3NldHRsZUVhY2gocmVzb2x1dGlvbjogYW55KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMuX3Rhc2tzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIHRoaXMuX2NvbXBsZXRlKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IHRhc2sgPSB0aGlzLl90YXNrc1swXTtcbiAgICAgIGNvbnN0IHByb2Nlc3NvciA9IHRoaXMuX3Byb2Nlc3NvcnNbMF07XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHNldHRsZUluU2VyaWVzKHRoaXMsICdiZWZvcmVUYXNrJywgdGFzayk7XG4gICAgICAgIGF3YWl0IHByb2Nlc3Nvci5wcm9jZXNzKCk7XG4gICAgICAgIGlmIChyZXNvbHV0aW9uID09PSB0aGlzLl9yZXNvbHV0aW9uKSB7XG4gICAgICAgICAgdGhpcy5fdGFza3Muc2hpZnQoKTtcbiAgICAgICAgICB0aGlzLl9wcm9jZXNzb3JzLnNoaWZ0KCk7XG5cbiAgICAgICAgICBhd2FpdCB0aGlzLl9wZXJzaXN0KCk7XG4gICAgICAgICAgYXdhaXQgc2V0dGxlSW5TZXJpZXModGhpcywgJ3Rhc2snLCB0YXNrKTtcbiAgICAgICAgICBhd2FpdCB0aGlzLl9zZXR0bGVFYWNoKHJlc29sdXRpb24pO1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGlmIChyZXNvbHV0aW9uID09PSB0aGlzLl9yZXNvbHV0aW9uKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuX2ZhaWwodGFzaywgZSBhcyBFcnJvcik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIF9yZWlmeSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aGlzLl90YXNrcyA9IFtdO1xuICAgIHRoaXMuX3Byb2Nlc3NvcnMgPSBbXTtcblxuICAgIHRoaXMuX3JlaWZpZWQgPSB0aGlzLl9sb2FkVGFza3NGcm9tQnVja2V0KCkudGhlbihcbiAgICAgICh0YXNrczogVGFzazxUeXBlLCBEYXRhLCBPcHRpb25zPltdIHwgdW5kZWZpbmVkKSA9PiB7XG4gICAgICAgIGlmICh0YXNrcykge1xuICAgICAgICAgIHRoaXMuX3Rhc2tzID0gdGFza3M7XG4gICAgICAgICAgdGhpcy5fcHJvY2Vzc29ycyA9IHRhc2tzLm1hcChcbiAgICAgICAgICAgICh0YXNrKSA9PiBuZXcgVGFza1Byb2Nlc3Nvcih0aGlzLl9wZXJmb3JtZXIsIHRhc2spXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICk7XG5cbiAgICByZXR1cm4gdGhpcy5fcmVpZmllZDtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgX2xvYWRUYXNrc0Zyb21CdWNrZXQoKTogUHJvbWlzZTxcbiAgICBUYXNrPFR5cGUsIERhdGEsIE9wdGlvbnM+W10gfCB1bmRlZmluZWRcbiAgPiB7XG4gICAgaWYgKHRoaXMuX2J1Y2tldCAmJiB0aGlzLl9uYW1lKSB7XG4gICAgICByZXR1cm4gdGhpcy5fYnVja2V0LmdldEl0ZW0odGhpcy5fbmFtZSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBfcGVyc2lzdCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aGlzLmVtaXQoJ2NoYW5nZScpO1xuICAgIGlmICh0aGlzLl9idWNrZXQgJiYgdGhpcy5fbmFtZSkge1xuICAgICAgYXdhaXQgdGhpcy5fYnVja2V0LnNldEl0ZW0odGhpcy5fbmFtZSwgdGhpcy5fdGFza3MpO1xuICAgIH1cbiAgfVxufVxuIl19