UNPKG

jsforce2

Version:

Salesforce API Library for JavaScript

1,054 lines (955 loc) 78.4 kB
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g=(g.jsforce||(g.jsforce = {}));g=(g.modules||(g.modules = {}));g=(g.api||(g.api = {}));g.Bulk = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){ (function (process){ /*global process*/ /** * @file Manages Salesforce Bulk API related operations * @author Shinichi Tomita <shinichi.tomita@gmail.com> */ 'use strict'; var inherits = window.jsforce.require('inherits'), stream = window.jsforce.require('readable-stream'), Duplex = stream.Duplex, events = window.jsforce.require('events'), _ = window.jsforce.require('lodash/core'), joinStreams = window.jsforce.require('multistream'), jsforce = window.jsforce.require('./core'), RecordStream = window.jsforce.require('./record-stream'), Promise = window.jsforce.require('./promise'), HttpApi = window.jsforce.require('./http-api'); /*--------------------------------------------*/ /** * Class for Bulk API Job * * @protected * @class Bulk~Job * @extends events.EventEmitter * * @param {Bulk} bulk - Bulk API object * @param {String} [type] - SObject type * @param {String} [operation] - Bulk load operation ('insert', 'update', 'upsert', 'delete', or 'hardDelete') * @param {Object} [options] - Options for bulk loading operation * @param {String} [options.extIdField] - External ID field name (used when upsert operation). * @param {String} [options.concurrencyMode] - 'Serial' or 'Parallel'. Defaults to Parallel. * @param {String} [jobId] - Job ID (if already available) */ var Job = function(bulk, type, operation, options, jobId) { this._bulk = bulk; this.type = type; this.operation = operation; this.options = options || {}; this.id = jobId; this.state = this.id ? 'Open' : 'Unknown'; this._batches = {}; }; inherits(Job, events.EventEmitter); /** * @typedef {Object} Bulk~JobInfo * @prop {String} id - Job ID * @prop {String} object - Object type name * @prop {String} operation - Operation type of the job * @prop {String} state - Job status */ /** * Return latest jobInfo from cache * * @method Bulk~Job#info * @param {Callback.<Bulk~JobInfo>} [callback] - Callback function * @returns {Promise.<Bulk~JobInfo>} */ Job.prototype.info = function(callback) { var self = this; // if cache is not available, check the latest if (!this._jobInfo) { this._jobInfo = this.check(); } return this._jobInfo.thenCall(callback); }; /** * Open new job and get jobinfo * * @method Bulk~Job#open * @param {Callback.<Bulk~JobInfo>} [callback] - Callback function * @returns {Promise.<Bulk~JobInfo>} */ Job.prototype.open = function(callback) { var self = this; var bulk = this._bulk; var logger = bulk._logger; // if not requested opening job if (!this._jobInfo) { var operation = this.operation.toLowerCase(); if (operation === 'harddelete') { operation = 'hardDelete'; } var body = [ '<?xml version="1.0" encoding="UTF-8"?>', '<jobInfo xmlns="http://www.force.com/2009/06/asyncapi/dataload">', '<operation>' + operation + '</operation>', '<object>' + this.type + '</object>', (this.options.extIdField ? '<externalIdFieldName>'+this.options.extIdField+'</externalIdFieldName>' : ''), (this.options.concurrencyMode ? '<concurrencyMode>'+this.options.concurrencyMode+'</concurrencyMode>' : ''), (this.options.assignmentRuleId ? '<assignmentRuleId>' + this.options.assignmentRuleId + '</assignmentRuleId>' : ''), '<contentType>CSV</contentType>', '</jobInfo>' ].join(''); this._jobInfo = bulk._request({ method : 'POST', path : "/job", body : body, headers : { "Content-Type" : "application/xml; charset=utf-8" }, responseType: "application/xml" }).then(function(res) { self.emit("open", res.jobInfo); self.id = res.jobInfo.id; self.state = res.jobInfo.state; return res.jobInfo; }, function(err) { self.emit("error", err); throw err; }); } return this._jobInfo.thenCall(callback); }; /** * Create a new batch instance in the job * * @method Bulk~Job#createBatch * @returns {Bulk~Batch} */ Job.prototype.createBatch = function() { var batch = new Batch(this); var self = this; batch.on('queue', function() { self._batches[batch.id] = batch; }); return batch; }; /** * Get a batch instance specified by given batch ID * * @method Bulk~Job#batch * @param {String} batchId - Batch ID * @returns {Bulk~Batch} */ Job.prototype.batch = function(batchId) { var batch = this._batches[batchId]; if (!batch) { batch = new Batch(this, batchId); this._batches[batchId] = batch; } return batch; }; /** * Check the latest job status from server * * @method Bulk~Job#check * @param {Callback.<Bulk~JobInfo>} [callback] - Callback function * @returns {Promise.<Bulk~JobInfo>} */ Job.prototype.check = function(callback) { var self = this; var bulk = this._bulk; var logger = bulk._logger; this._jobInfo = this._waitAssign().then(function() { return bulk._request({ method : 'GET', path : "/job/" + self.id, responseType: "application/xml" }); }).then(function(res) { logger.debug(res.jobInfo); self.id = res.jobInfo.id; self.type = res.jobInfo.object; self.operation = res.jobInfo.operation; self.state = res.jobInfo.state; return res.jobInfo; }); return this._jobInfo.thenCall(callback); }; /** * Wait till the job is assigned to server * * @method Bulk~Job#info * @param {Callback.<Bulk~JobInfo>} [callback] - Callback function * @returns {Promise.<Bulk~JobInfo>} */ Job.prototype._waitAssign = function(callback) { return (this.id ? Promise.resolve({ id: this.id }) : this.open()).thenCall(callback); }; /** * List all registered batch info in job * * @method Bulk~Job#list * @param {Callback.<Array.<Bulk~BatchInfo>>} [callback] - Callback function * @returns {Promise.<Array.<Bulk~BatchInfo>>} */ Job.prototype.list = function(callback) { var self = this; var bulk = this._bulk; var logger = bulk._logger; return this._waitAssign().then(function() { return bulk._request({ method : 'GET', path : "/job/" + self.id + "/batch", responseType: "application/xml" }); }).then(function(res) { logger.debug(res.batchInfoList.batchInfo); var batchInfoList = res.batchInfoList; batchInfoList = _.isArray(batchInfoList.batchInfo) ? batchInfoList.batchInfo : [ batchInfoList.batchInfo ]; return batchInfoList; }).thenCall(callback); }; /** * Close opened job * * @method Bulk~Job#close * @param {Callback.<Bulk~JobInfo>} [callback] - Callback function * @returns {Promise.<Bulk~JobInfo>} */ Job.prototype.close = function() { var self = this; return this._changeState("Closed").then(function(jobInfo) { self.id = null; self.emit("close", jobInfo); return jobInfo; }, function(err) { self.emit("error", err); throw err; }); }; /** * Set the status to abort * * @method Bulk~Job#abort * @param {Callback.<Bulk~JobInfo>} [callback] - Callback function * @returns {Promise.<Bulk~JobInfo>} */ Job.prototype.abort = function() { var self = this; return this._changeState("Aborted").then(function(jobInfo) { self.id = null; self.emit("abort", jobInfo); return jobInfo; }, function(err) { self.emit("error", err); throw err; }); }; /** * @private */ Job.prototype._changeState = function(state, callback) { var self = this; var bulk = this._bulk; var logger = bulk._logger; this._jobInfo = this._waitAssign().then(function() { var body = [ '<?xml version="1.0" encoding="UTF-8"?>', '<jobInfo xmlns="http://www.force.com/2009/06/asyncapi/dataload">', '<state>' + state + '</state>', '</jobInfo>' ].join(''); return bulk._request({ method : 'POST', path : "/job/" + self.id, body : body, headers : { "Content-Type" : "application/xml; charset=utf-8" }, responseType: "application/xml" }); }).then(function(res) { logger.debug(res.jobInfo); self.state = res.jobInfo.state; return res.jobInfo; }); return this._jobInfo.thenCall(callback); }; /*--------------------------------------------*/ /** * Batch (extends RecordStream) * * @protected * @class Bulk~Batch * @extends {stream.Writable} * @implements {Promise.<Array.<RecordResult>>} * @param {Bulk~Job} job - Bulk job object * @param {String} [batchId] - Batch ID (if already available) */ var Batch = function(job, batchId) { Batch.super_.call(this, { objectMode: true }); this.job = job; this.id = batchId; this._bulk = job._bulk; this._deferred = Promise.defer(); this._setupDataStreams(); }; inherits(Batch, stream.Writable); /** * @private */ Batch.prototype._setupDataStreams = function() { var batch = this; var converterOptions = { nullValue : '#N/A' }; this._uploadStream = new RecordStream.Serializable(); this._uploadDataStream = this._uploadStream.stream('csv', converterOptions); this._downloadStream = new RecordStream.Parsable(); this._downloadDataStream = this._downloadStream.stream('csv', converterOptions); this.on('finish', function() { batch._uploadStream.end(); }); this._uploadDataStream.once('readable', function() { batch.job.open().then(function() { // pipe upload data to batch API request stream batch._uploadDataStream.pipe(batch._createRequestStream()); }); }); // duplex data stream, opened access to API programmers by Batch#stream() var dataStream = this._dataStream = new Duplex(); dataStream._write = function(data, enc, cb) { batch._uploadDataStream.write(data, enc, cb); }; dataStream.on('finish', function() { batch._uploadDataStream.end(); }); this._downloadDataStream.on('readable', function() { dataStream.read(0); }); this._downloadDataStream.on('end', function() { dataStream.push(null); }); dataStream._read = function(size) { var chunk; while ((chunk = batch._downloadDataStream.read()) !== null) { dataStream.push(chunk); } }; }; /** * Connect batch API and create stream instance of request/response * * @private * @returns {stream.Duplex} */ Batch.prototype._createRequestStream = function() { var batch = this; var bulk = batch._bulk; var logger = bulk._logger; return bulk._request({ method : 'POST', path : "/job/" + batch.job.id + "/batch", headers: { "Content-Type": "text/csv" }, responseType: "application/xml" }, function(err, res) { if (err) { batch.emit('error', err); } else { logger.debug(res.batchInfo); batch.id = res.batchInfo.id; batch.emit('queue', res.batchInfo); } }).stream(); }; /** * Implementation of Writable * * @override * @private */ Batch.prototype._write = function(record, enc, cb) { record = _.clone(record); if (this.job.operation === "insert") { delete record.Id; } else if (this.job.operation === "delete") { record = { Id: record.Id }; } delete record.type; delete record.attributes; this._uploadStream.write(record, enc, cb); }; /** * Returns duplex stream which accepts CSV data input and batch result output * * @returns {stream.Duplex} */ Batch.prototype.stream = function() { return this._dataStream; }; /** * Execute batch operation * * @method Bulk~Batch#execute * @param {Array.<Record>|stream.Stream|String} [input] - Input source for batch operation. Accepts array of records, CSV string, and CSV data input stream in insert/update/upsert/delete/hardDelete operation, SOQL string in query operation. * @param {Callback.<Array.<RecordResult>|Array.<BatchResultInfo>>} [callback] - Callback function * @returns {Bulk~Batch} */ Batch.prototype.run = Batch.prototype.exec = Batch.prototype.execute = function(input, callback) { var self = this; if (typeof input === 'function') { // if input argument is omitted callback = input; input = null; } // if batch is already executed if (this._result) { throw new Error("Batch already executed."); } var rdeferred = Promise.defer(); this._result = rdeferred.promise; this._result.then(function(res) { self._deferred.resolve(res); }, function(err) { self._deferred.reject(err); }); this.once('response', function(res) { rdeferred.resolve(res); }); this.once('error', function(err) { rdeferred.reject(err); }); if (_.isObject(input) && _.isFunction(input.pipe)) { // if input has stream.Readable interface input.pipe(this._dataStream); } else { var data; if (_.isArray(input)) { _.forEach(input, function(record) { Object.keys(record).forEach(function(key) { if (typeof record[key] === 'boolean') { record[key] = String(record[key]) } }) self.write(record); }); self.end(); } else if (_.isString(input)){ data = input; this._dataStream.write(data, 'utf8'); this._dataStream.end(); } } // return Batch instance for chaining return this.thenCall(callback); }; /** * Promise/A+ interface * http://promises-aplus.github.io/promises-spec/ * * Delegate to deferred promise, return promise instance for batch result * * @method Bulk~Batch#then */ Batch.prototype.then = function(onResolved, onReject, onProgress) { return this._deferred.promise.then(onResolved, onReject, onProgress); }; /** * Promise/A+ extension * Call "then" using given node-style callback function * * @method Bulk~Batch#thenCall */ Batch.prototype.thenCall = function(callback) { if (_.isFunction(callback)) { this.then(function(res) { process.nextTick(function() { callback(null, res); }); }, function(err) { process.nextTick(function() { callback(err); }); }); } return this; }; /** * @typedef {Object} Bulk~BatchInfo * @prop {String} id - Batch ID * @prop {String} jobId - Job ID * @prop {String} state - Batch state * @prop {String} stateMessage - Batch state message */ /** * Check the latest batch status in server * * @method Bulk~Batch#check * @param {Callback.<Bulk~BatchInfo>} [callback] - Callback function * @returns {Promise.<Bulk~BatchInfo>} */ Batch.prototype.check = function(callback) { var self = this; var bulk = this._bulk; var logger = bulk._logger; var jobId = this.job.id; var batchId = this.id; if (!jobId || !batchId) { throw new Error("Batch not started."); } return bulk._request({ method : 'GET', path : "/job/" + jobId + "/batch/" + batchId, responseType: "application/xml" }).then(function(res) { logger.debug(res.batchInfo); return res.batchInfo; }).thenCall(callback); }; /** * Polling the batch result and retrieve * * @method Bulk~Batch#poll * @param {Number} interval - Polling interval in milliseconds * @param {Number} timeout - Polling timeout in milliseconds */ Batch.prototype.poll = function(interval, timeout) { var self = this; var jobId = this.job.id; var batchId = this.id; if (!jobId || !batchId) { throw new Error("Batch not started."); } var startTime = new Date().getTime(); var poll = function() { var now = new Date().getTime(); if (startTime + timeout < now) { var err = new Error("Polling time out. Job Id = " + jobId + " , batch Id = " + batchId); err.name = 'PollingTimeout'; err.jobId = jobId; err.batchId = batchId; self.emit('error', err); return; } self.check(function(err, res) { if (err) { self.emit('error', err); } else { if (res.state === "Failed") { if (parseInt(res.numberRecordsProcessed, 10) > 0) { self.retrieve(); } else { self.emit('error', new Error(res.stateMessage)); } } else if (res.state === "Completed") { self.retrieve(); } else { self.emit('progress', res); setTimeout(poll, interval); } } }); }; setTimeout(poll, interval); }; /** * @typedef {Object} Bulk~BatchResultInfo * @prop {String} id - Batch result ID * @prop {String} batchId - Batch ID which includes this batch result. * @prop {String} jobId - Job ID which includes this batch result. */ /** * Retrieve batch result * * @method Bulk~Batch#retrieve * @param {Callback.<Array.<RecordResult>|Array.<Bulk~BatchResultInfo>>} [callback] - Callback function * @returns {Promise.<Array.<RecordResult>|Array.<Bulk~BatchResultInfo>>} */ Batch.prototype.retrieve = function(callback) { var self = this; var bulk = this._bulk; var jobId = this.job.id; var job = this.job; var batchId = this.id; if (!jobId || !batchId) { throw new Error("Batch not started."); } return job.info().then(function(jobInfo) { return bulk._request({ method : 'GET', path : "/job/" + jobId + "/batch/" + batchId + "/result" }); }).then(function(res) { var results; if (job.operation === 'query') { var conn = bulk._conn; var resultIds = res['result-list'].result; results = res['result-list'].result; results = _.map(_.isArray(results) ? results : [ results ], function(id) { return { id: id, batchId: batchId, jobId: jobId }; }); } else { results = _.map(res, function(ret) { return { id: ret.Id || null, success: ret.Success === "true", errors: ret.Error ? [ ret.Error ] : [] }; }); } self.emit('response', results); return results; }).fail(function(err) { self.emit('error', err); throw err; }).thenCall(callback); }; /** * Fetch query result as a record stream * @param {String} resultId - Result id * @returns {RecordStream} - Record stream, convertible to CSV data stream */ Batch.prototype.result = function(resultId) { var jobId = this.job.id; var batchId = this.id; if (!jobId || !batchId) { throw new Error("Batch not started."); } var resultStream = new RecordStream.Parsable(); var resultDataStream = resultStream.stream('csv'); var reqStream = this._bulk._request({ method : 'GET', path : "/job/" + jobId + "/batch/" + batchId + "/result/" + resultId, responseType: "application/octet-stream" }).stream().pipe(resultDataStream); return resultStream; }; /*--------------------------------------------*/ /** * @private */ var BulkApi = function() { BulkApi.super_.apply(this, arguments); }; inherits(BulkApi, HttpApi); BulkApi.prototype.beforeSend = function(request) { request.headers = request.headers || {}; request.headers["X-SFDC-SESSION"] = this._conn.accessToken; }; BulkApi.prototype.isSessionExpired = function(response) { return response.statusCode === 400 && /<exceptionCode>InvalidSessionId<\/exceptionCode>/.test(response.body); }; BulkApi.prototype.hasErrorInResponseBody = function(body) { return !!body.error; }; BulkApi.prototype.parseError = function(body) { return { errorCode: body.error.exceptionCode, message: body.error.exceptionMessage }; }; /*--------------------------------------------*/ /** * Class for Bulk API * * @class * @param {Connection} conn - Connection object */ var Bulk = function(conn) { this._conn = conn; this._logger = conn._logger; }; /** * Polling interval in milliseconds * @type {Number} */ Bulk.prototype.pollInterval = 1000; /** * Polling timeout in milliseconds * @type {Number} */ Bulk.prototype.pollTimeout = 10000; /** @private **/ Bulk.prototype._request = function(request, callback) { var conn = this._conn; request = _.clone(request); var baseUrl = [ conn.instanceUrl, "services/async", conn.version ].join('/'); request.url = baseUrl + request.path; var options = { responseType: request.responseType }; delete request.path; delete request.responseType; return new BulkApi(this._conn, options).request(request).thenCall(callback); }; /** * Create and start bulkload job and batch * * @param {String} type - SObject type * @param {String} operation - Bulk load operation ('insert', 'update', 'upsert', 'delete', or 'hardDelete') * @param {Object} [options] - Options for bulk loading operation * @param {String} [options.extIdField] - External ID field name (used when upsert operation). * @param {String} [options.concurrencyMode] - 'Serial' or 'Parallel'. Defaults to Parallel. * @param {Array.<Record>|stream.Stream|String} [input] - Input source for bulkload. Accepts array of records, CSV string, and CSV data input stream in insert/update/upsert/delete/hardDelete operation, SOQL string in query operation. * @param {Callback.<Array.<RecordResult>|Array.<Bulk~BatchResultInfo>>} [callback] - Callback function * @returns {Bulk~Batch} */ Bulk.prototype.load = function(type, operation, options, input, callback) { var self = this; if (!type || !operation) { throw new Error("Insufficient arguments. At least, 'type' and 'operation' are required."); } if (!_.isObject(options) || options.constructor !== Object) { // when options is not plain hash object, it is omitted callback = input; input = options; options = null; } var job = this.createJob(type, operation, options); job.once('error', function (error) { if (batch) { batch.emit('error', error); // pass job error to batch } }); var batch = job.createBatch(); var cleanup = function() { batch = null; job.close(); }; var cleanupOnError = function(err) { if (err.name !== 'PollingTimeout') { cleanup(); } }; batch.on('response', cleanup); batch.on('error', cleanupOnError); batch.on('queue', function() { batch.poll(self.pollInterval, self.pollTimeout); }); return batch.execute(input, callback); }; /** * Execute bulk query and get record stream * * @param {String} soql - SOQL to execute in bulk job * @returns {RecordStream.Parsable} - Record stream, convertible to CSV data stream */ Bulk.prototype.query = function(soql) { var m = soql.replace(/\([\s\S]+\)/g, '').match(/FROM\s+(\w+)/i); if (!m) { throw new Error("No sobject type found in query, maybe caused by invalid SOQL."); } var type = m[1]; var self = this; var recordStream = new RecordStream.Parsable(); var dataStream = recordStream.stream('csv'); this.load(type, "query", soql).then(function(results) { var streams = results.map(function(result) { return self .job(result.jobId) .batch(result.batchId) .result(result.id) .stream(); }); joinStreams(streams).pipe(dataStream); }).fail(function(err) { recordStream.emit('error', err); }); return recordStream; }; /** * Create a new job instance * * @param {String} type - SObject type * @param {String} operation - Bulk load operation ('insert', 'update', 'upsert', 'delete', 'hardDelete', or 'query') * @param {Object} [options] - Options for bulk loading operation * @returns {Bulk~Job} */ Bulk.prototype.createJob = function(type, operation, options) { return new Job(this, type, operation, options); }; /** * Get a job instance specified by given job ID * * @param {String} jobId - Job ID * @returns {Bulk~Job} */ Bulk.prototype.job = function(jobId) { return new Job(this, null, null, null, jobId); }; /*--------------------------------------------*/ /* * Register hook in connection instantiation for dynamically adding this API module features */ jsforce.on('connection:new', function(conn) { conn.bulk = new Bulk(conn); }); module.exports = Bulk; }).call(this,require('_process')) },{"_process":2}],2:[function(require,module,exports){ // shim for using process in browser var process = module.exports = {}; // cached from whatever global is present so that test runners that stub it // don't break things. But we need to wrap it in a try catch in case it is // wrapped in strict mode code which doesn't define any globals. It's inside a // function because try/catches deoptimize in certain engines. var cachedSetTimeout; var cachedClearTimeout; function defaultSetTimout() { throw new Error('setTimeout has not been defined'); } function defaultClearTimeout () { throw new Error('clearTimeout has not been defined'); } (function () { try { if (typeof setTimeout === 'function') { cachedSetTimeout = setTimeout; } else { cachedSetTimeout = defaultSetTimout; } } catch (e) { cachedSetTimeout = defaultSetTimout; } try { if (typeof clearTimeout === 'function') { cachedClearTimeout = clearTimeout; } else { cachedClearTimeout = defaultClearTimeout; } } catch (e) { cachedClearTimeout = defaultClearTimeout; } } ()) function runTimeout(fun) { if (cachedSetTimeout === setTimeout) { //normal enviroments in sane situations return setTimeout(fun, 0); } // if setTimeout wasn't available but was latter defined if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { cachedSetTimeout = setTimeout; return setTimeout(fun, 0); } try { // when when somebody has screwed with setTimeout but no I.E. maddness return cachedSetTimeout(fun, 0); } catch(e){ try { // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally return cachedSetTimeout.call(null, fun, 0); } catch(e){ // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error return cachedSetTimeout.call(this, fun, 0); } } } function runClearTimeout(marker) { if (cachedClearTimeout === clearTimeout) { //normal enviroments in sane situations return clearTimeout(marker); } // if clearTimeout wasn't available but was latter defined if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { cachedClearTimeout = clearTimeout; return clearTimeout(marker); } try { // when when somebody has screwed with setTimeout but no I.E. maddness return cachedClearTimeout(marker); } catch (e){ try { // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally return cachedClearTimeout.call(null, marker); } catch (e){ // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. // Some versions of I.E. have different rules for clearTimeout vs setTimeout return cachedClearTimeout.call(this, marker); } } } var queue = []; var draining = false; var currentQueue; var queueIndex = -1; function cleanUpNextTick() { if (!draining || !currentQueue) { return; } draining = false; if (currentQueue.length) { queue = currentQueue.concat(queue); } else { queueIndex = -1; } if (queue.length) { drainQueue(); } } function drainQueue() { if (draining) { return; } var timeout = runTimeout(cleanUpNextTick); draining = true; var len = queue.length; while(len) { currentQueue = queue; queue = []; while (++queueIndex < len) { if (currentQueue) { currentQueue[queueIndex].run(); } } queueIndex = -1; len = queue.length; } currentQueue = null; draining = false; runClearTimeout(timeout); } process.nextTick = function (fun) { var args = new Array(arguments.length - 1); if (arguments.length > 1) { for (var i = 1; i < arguments.length; i++) { args[i - 1] = arguments[i]; } } queue.push(new Item(fun, args)); if (queue.length === 1 && !draining) { runTimeout(drainQueue); } }; // v8 likes predictible objects function Item(fun, array) { this.fun = fun; this.array = array; } Item.prototype.run = function () { this.fun.apply(null, this.array); }; process.title = 'browser'; process.browser = true; process.env = {}; process.argv = []; process.version = ''; // empty string to avoid regexp issues process.versions = {}; function noop() {} process.on = noop; process.addListener = noop; process.once = noop; process.off = noop; process.removeListener = noop; process.removeAllListeners = noop; process.emit = noop; process.prependListener = noop; process.prependOnceListener = noop; process.listeners = function (name) { return [] } process.binding = function (name) { throw new Error('process.binding is not supported'); }; process.cwd = function () { return '/' }; process.chdir = function (dir) { throw new Error('process.chdir is not supported'); }; process.umask = function() { return 0; }; },{}]},{},[1])(1) }); //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJsaWIvYXBpL2J1bGsuanMiLCJub2RlX21vZHVsZXMvcHJvY2Vzcy9icm93c2VyLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUMzMUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbigpe2Z1bmN0aW9uIHIoZSxuLHQpe2Z1bmN0aW9uIG8oaSxmKXtpZighbltpXSl7aWYoIWVbaV0pe3ZhciBjPVwiZnVuY3Rpb25cIj09dHlwZW9mIHJlcXVpcmUmJnJlcXVpcmU7aWYoIWYmJmMpcmV0dXJuIGMoaSwhMCk7aWYodSlyZXR1cm4gdShpLCEwKTt2YXIgYT1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK2krXCInXCIpO3Rocm93IGEuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixhfXZhciBwPW5baV09e2V4cG9ydHM6e319O2VbaV1bMF0uY2FsbChwLmV4cG9ydHMsZnVuY3Rpb24ocil7dmFyIG49ZVtpXVsxXVtyXTtyZXR1cm4gbyhufHxyKX0scCxwLmV4cG9ydHMscixlLG4sdCl9cmV0dXJuIG5baV0uZXhwb3J0c31mb3IodmFyIHU9XCJmdW5jdGlvblwiPT10eXBlb2YgcmVxdWlyZSYmcmVxdWlyZSxpPTA7aTx0Lmxlbmd0aDtpKyspbyh0W2ldKTtyZXR1cm4gb31yZXR1cm4gcn0pKCkiLCIvKmdsb2JhbCBwcm9jZXNzKi9cbi8qKlxuICogQGZpbGUgTWFuYWdlcyBTYWxlc2ZvcmNlIEJ1bGsgQVBJIHJlbGF0ZWQgb3BlcmF0aW9uc1xuICogQGF1dGhvciBTaGluaWNoaSBUb21pdGEgPHNoaW5pY2hpLnRvbWl0YUBnbWFpbC5jb20+XG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgaW5oZXJpdHMgICAgID0gd2luZG93LmpzZm9yY2UucmVxdWlyZSgnaW5oZXJpdHMnKSxcbiAgICBzdHJlYW0gICAgICAgPSB3aW5kb3cuanNmb3JjZS5yZXF1aXJlKCdyZWFkYWJsZS1zdHJlYW0nKSxcbiAgICBEdXBsZXggICAgICAgPSBzdHJlYW0uRHVwbGV4LFxuICAgIGV2ZW50cyAgICAgICA9IHdpbmRvdy5qc2ZvcmNlLnJlcXVpcmUoJ2V2ZW50cycpLFxuICAgIF8gICAgICAgICAgICA9IHdpbmRvdy5qc2ZvcmNlLnJlcXVpcmUoJ2xvZGFzaC9jb3JlJyksXG4gICAgam9pblN0cmVhbXMgID0gd2luZG93LmpzZm9yY2UucmVxdWlyZSgnbXVsdGlzdHJlYW0nKSxcbiAgICBqc2ZvcmNlICAgICAgPSB3aW5kb3cuanNmb3JjZS5yZXF1aXJlKCcuL2NvcmUnKSxcbiAgICBSZWNvcmRTdHJlYW0gPSB3aW5kb3cuanNmb3JjZS5yZXF1aXJlKCcuL3JlY29yZC1zdHJlYW0nKSxcbiAgICBQcm9taXNlICAgICAgPSB3aW5kb3cuanNmb3JjZS5yZXF1aXJlKCcuL3Byb21pc2UnKSxcbiAgICBIdHRwQXBpICAgICAgPSB3aW5kb3cuanNmb3JjZS5yZXF1aXJlKCcuL2h0dHAtYXBpJyk7XG5cbi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4vKipcbiAqIENsYXNzIGZvciBCdWxrIEFQSSBKb2JcbiAqXG4gKiBAcHJvdGVjdGVkXG4gKiBAY2xhc3MgQnVsa35Kb2JcbiAqIEBleHRlbmRzIGV2ZW50cy5FdmVudEVtaXR0ZXJcbiAqXG4gKiBAcGFyYW0ge0J1bGt9IGJ1bGsgLSBCdWxrIEFQSSBvYmplY3RcbiAqIEBwYXJhbSB7U3RyaW5nfSBbdHlwZV0gLSBTT2JqZWN0IHR5cGVcbiAqIEBwYXJhbSB7U3RyaW5nfSBbb3BlcmF0aW9uXSAtIEJ1bGsgbG9hZCBvcGVyYXRpb24gKCdpbnNlcnQnLCAndXBkYXRlJywgJ3Vwc2VydCcsICdkZWxldGUnLCBvciAnaGFyZERlbGV0ZScpXG4gKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdIC0gT3B0aW9ucyBmb3IgYnVsayBsb2FkaW5nIG9wZXJhdGlvblxuICogQHBhcmFtIHtTdHJpbmd9IFtvcHRpb25zLmV4dElkRmllbGRdIC0gRXh0ZXJuYWwgSUQgZmllbGQgbmFtZSAodXNlZCB3aGVuIHVwc2VydCBvcGVyYXRpb24pLlxuICogQHBhcmFtIHtTdHJpbmd9IFtvcHRpb25zLmNvbmN1cnJlbmN5TW9kZV0gLSAnU2VyaWFsJyBvciAnUGFyYWxsZWwnLiBEZWZhdWx0cyB0byBQYXJhbGxlbC5cbiAqIEBwYXJhbSB7U3RyaW5nfSBbam9iSWRdIC0gSm9iIElEIChpZiBhbHJlYWR5IGF2YWlsYWJsZSlcbiAqL1xudmFyIEpvYiA9IGZ1bmN0aW9uKGJ1bGssIHR5cGUsIG9wZXJhdGlvbiwgb3B0aW9ucywgam9iSWQpIHtcbiAgdGhpcy5fYnVsayA9IGJ1bGs7XG4gIHRoaXMudHlwZSA9IHR5cGU7XG4gIHRoaXMub3BlcmF0aW9uID0gb3BlcmF0aW9uO1xuICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuICB0aGlzLmlkID0gam9iSWQ7XG4gIHRoaXMuc3RhdGUgPSB0aGlzLmlkID8gJ09wZW4nIDogJ1Vua25vd24nO1xuICB0aGlzLl9iYXRjaGVzID0ge307XG59O1xuXG5pbmhlcml0cyhKb2IsIGV2ZW50cy5FdmVudEVtaXR0ZXIpO1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IEJ1bGt+Sm9iSW5mb1xuICogQHByb3Age1N0cmluZ30gaWQgLSBKb2IgSURcbiAqIEBwcm9wIHtTdHJpbmd9IG9iamVjdCAtIE9iamVjdCB0eXBlIG5hbWVcbiAqIEBwcm9wIHtTdHJpbmd9IG9wZXJhdGlvbiAtIE9wZXJhdGlvbiB0eXBlIG9mIHRoZSBqb2JcbiAqIEBwcm9wIHtTdHJpbmd9IHN0YXRlIC0gSm9iIHN0YXR1c1xuICovXG5cbi8qKlxuICogUmV0dXJuIGxhdGVzdCBqb2JJbmZvIGZyb20gY2FjaGVcbiAqXG4gKiBAbWV0aG9kIEJ1bGt+Sm9iI2luZm9cbiAqIEBwYXJhbSB7Q2FsbGJhY2suPEJ1bGt+Sm9iSW5mbz59IFtjYWxsYmFja10gLSBDYWxsYmFjayBmdW5jdGlvblxuICogQHJldHVybnMge1Byb21pc2UuPEJ1bGt+Sm9iSW5mbz59XG4gKi9cbkpvYi5wcm90b3R5cGUuaW5mbyA9IGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgLy8gaWYgY2FjaGUgaXMgbm90IGF2YWlsYWJsZSwgY2hlY2sgdGhlIGxhdGVzdFxuICBpZiAoIXRoaXMuX2pvYkluZm8pIHtcbiAgICB0aGlzLl9qb2JJbmZvID0gdGhpcy5jaGVjaygpO1xuICB9XG4gIHJldHVybiB0aGlzLl9qb2JJbmZvLnRoZW5DYWxsKGNhbGxiYWNrKTtcbn07XG5cbi8qKlxuICogT3BlbiBuZXcgam9iIGFuZCBnZXQgam9iaW5mb1xuICpcbiAqIEBtZXRob2QgQnVsa35Kb2Ijb3BlblxuICogQHBhcmFtIHtDYWxsYmFjay48QnVsa35Kb2JJbmZvPn0gW2NhbGxiYWNrXSAtIENhbGxiYWNrIGZ1bmN0aW9uXG4gKiBAcmV0dXJucyB7UHJvbWlzZS48QnVsa35Kb2JJbmZvPn1cbiAqL1xuSm9iLnByb3RvdHlwZS5vcGVuID0gZnVuY3Rpb24oY2FsbGJhY2spIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB2YXIgYnVsayA9IHRoaXMuX2J1bGs7XG4gIHZhciBsb2dnZXIgPSBidWxrLl9sb2dnZXI7XG5cbiAgLy8gaWYgbm90IHJlcXVlc3RlZCBvcGVuaW5nIGpvYlxuICBpZiAoIXRoaXMuX2pvYkluZm8pIHtcbiAgICB2YXIgb3BlcmF0aW9uID0gdGhpcy5vcGVyYXRpb24udG9Mb3dlckNhc2UoKTtcbiAgICBpZiAob3BlcmF0aW9uID09PSAnaGFyZGRlbGV0ZScpIHsgb3BlcmF0aW9uID0gJ2hhcmREZWxldGUnOyB9XG4gICAgdmFyIGJvZHkgPSBbXG4gICAgICAnPD94bWwgdmVyc2lvbj1cIjEuMFwiIGVuY29kaW5nPVwiVVRGLThcIj8+JyxcbiAgICAgICc8am9iSW5mbyAgeG1sbnM9XCJodHRwOi8vd3d3LmZvcmNlLmNvbS8yMDA5LzA2L2FzeW5jYXBpL2RhdGFsb2FkXCI+JyxcbiAgICAgICAgJzxvcGVyYXRpb24+JyArIG9wZXJhdGlvbiArICc8L29wZXJhdGlvbj4nLFxuICAgICAgICAnPG9iamVjdD4nICsgdGhpcy50eXBlICsgJzwvb2JqZWN0PicsXG4gICAgICAgICh0aGlzLm9wdGlvbnMuZXh0SWRGaWVsZCA/XG4gICAgICAgICAnPGV4dGVybmFsSWRGaWVsZE5hbWU+Jyt0aGlzLm9wdGlvbnMuZXh0SWRGaWVsZCsnPC9leHRlcm5hbElkRmllbGROYW1lPicgOlxuICAgICAgICAgJycpLFxuICAgICAgICAodGhpcy5vcHRpb25zLmNvbmN1cnJlbmN5TW9kZSA/XG4gICAgICAgICAnPGNvbmN1cnJlbmN5TW9kZT4nK3RoaXMub3B0aW9ucy5jb25jdXJyZW5jeU1vZGUrJzwvY29uY3VycmVuY3lNb2RlPicgOlxuICAgICAgICAgJycpLFxuICAgICAgICAodGhpcy5vcHRpb25zLmFzc2lnbm1lbnRSdWxlSWQgP1xuICAgICAgICAgICc8YXNzaWdubWVudFJ1bGVJZD4nICsgdGhpcy5vcHRpb25zLmFzc2lnbm1lbnRSdWxlSWQgKyAnPC9hc3NpZ25tZW50UnVsZUlkPicgOlxuICAgICAgICAgICcnKSxcbiAgICAgICAgJzxjb250ZW50VHlwZT5DU1Y8L2NvbnRlbnRUeXBlPicsXG4gICAgICAnPC9qb2JJbmZvPidcbiAgICBdLmpvaW4oJycpO1xuXG4gICAgdGhpcy5fam9iSW5mbyA9IGJ1bGsuX3JlcXVlc3Qoe1xuICAgICAgbWV0aG9kIDogJ1BPU1QnLFxuICAgICAgcGF0aCA6IFwiL2pvYlwiLFxuICAgICAgYm9keSA6IGJvZHksXG4gICAgICBoZWFkZXJzIDoge1xuICAgICAgICBcIkNvbnRlbnQtVHlwZVwiIDogXCJhcHBsaWNhdGlvbi94bWw7IGNoYXJzZXQ9dXRmLThcIlxuICAgICAgfSxcbiAgICAgIHJlc3BvbnNlVHlwZTogXCJhcHBsaWNhdGlvbi94bWxcIlxuICAgIH0pLnRoZW4oZnVuY3Rpb24ocmVzKSB7XG4gICAgICBzZWxmLmVtaXQoXCJvcGVuXCIsIHJlcy5qb2JJbmZvKTtcbiAgICAgIHNlbGYuaWQgPSByZXMuam9iSW5mby5pZDtcbiAgICAgIHNlbGYuc3RhdGUgPSByZXMuam9iSW5mby5zdGF0ZTtcbiAgICAgIHJldHVybiByZXMuam9iSW5mbztcbiAgICB9LCBmdW5jdGlvbihlcnIpIHtcbiAgICAgIHNlbGYuZW1pdChcImVycm9yXCIsIGVycik7XG4gICAgICB0aHJvdyBlcnI7XG4gICAgfSk7XG4gIH1cbiAgcmV0dXJuIHRoaXMuX2pvYkluZm8udGhlbkNhbGwoY2FsbGJhY2spO1xufTtcblxuLyoqXG4gKiBDcmVhdGUgYSBuZXcgYmF0Y2ggaW5zdGFuY2UgaW4gdGhlIGpvYlxuICpcbiAqIEBtZXRob2QgQnVsa35Kb2IjY3JlYXRlQmF0Y2hcbiAqIEByZXR1cm5zIHtCdWxrfkJhdGNofVxuICovXG5Kb2IucHJvdG90eXBlLmNyZWF0ZUJhdGNoID0gZnVuY3Rpb24oKSB7XG4gIHZhciBiYXRjaCA9IG5ldyBCYXRjaCh0aGlzKTtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICBiYXRjaC5vbigncXVldWUnLCBmdW5jdGlvbigpIHtcbiAgICBzZWxmLl9iYXRjaGVzW2JhdGNoLmlkXSA9IGJhdGNoO1xuICB9KTtcbiAgcmV0dXJuIGJhdGNoO1xufTtcblxuLyoqXG4gKiBHZXQgYSBiYXRjaCBpbnN0YW5jZSBzcGVjaWZpZWQgYnkgZ2l2ZW4gYmF0Y2ggSURcbiAqXG4gKiBAbWV0aG9kIEJ1bGt+Sm9iI2JhdGNoXG4gKiBAcGFyYW0ge1N0cmluZ30gYmF0Y2hJZCAtIEJhdGNoIElEXG4gKiBAcmV0dXJucyB7QnVsa35CYXRjaH1cbiAqL1xuSm9iLnByb3RvdHlwZS5iYXRjaCA9IGZ1bmN0aW9uKGJhdGNoSWQpIHtcbiAgdmFyIGJhdGNoID0gdGhpcy5fYmF0Y2hlc1tiYXRjaElkXTtcbiAgaWYgKCFiYXRjaCkge1xuICAgIGJhdGNoID0gbmV3IEJhdGNoKHRoaXMsIGJhdGNoSWQpO1xuICAgIHRoaXMuX2JhdGNoZXNbYmF0Y2hJZF0gPSBiYXRjaDtcbiAgfVxuICByZXR1cm4gYmF0Y2g7XG59O1xuXG4vKipcbiAqIENoZWNrIHRoZSBsYXRlc3Qgam9iIHN0YXR1cyBmcm9tIHNlcnZlclxuICpcbiAqIEBtZXRob2QgQnVsa35Kb2IjY2hlY2tcbiAqIEBwYXJhbSB7Q2FsbGJhY2suPEJ1bGt+Sm9iSW5mbz59IFtjYWxsYmFja10gLSBDYWxsYmFjayBmdW5jdGlvblxuICogQHJldHVybnMge1Byb21pc2UuPEJ1bGt+Sm9iSW5mbz59XG4gKi9cbkpvYi5wcm90b3R5cGUuY2hlY2sgPSBmdW5jdGlvbihjYWxsYmFjaykge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHZhciBidWxrID0gdGhpcy5fYnVsaztcbiAgdmFyIGxvZ2dlciA9IGJ1bGsuX2xvZ2dlcjtcblxuICB0aGlzLl9qb2JJbmZvID0gdGhpcy5fd2FpdEFzc2lnbigpLnRoZW4oZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGJ1bGsuX3JlcXVlc3Qoe1xuICAgICAgbWV0aG9kIDogJ0dFVCcsXG4gICAgICBwYXRoIDogXCIvam9iL1wiICsgc2VsZi5pZCxcbiAgICAgIHJlc3BvbnNlVHlwZTogXCJhcHBsaWNhdGlvbi94bWxcIlxuICAgIH0pO1xuICB9KS50aGVuKGZ1bmN0aW9uKHJlcykge1xuICAgIGxvZ2dlci5kZWJ1ZyhyZXMuam9iSW5mbyk7XG4gICAgc2VsZi5pZCA9IHJlcy5qb2JJbmZvLmlkO1xuICAgIHNlbGYudHlwZSA9IHJlcy5qb2JJbmZvLm9iamVjdDtcbiAgICBzZWxmLm9wZXJhdGlvbiA9IHJlcy5qb2JJbmZvLm9wZXJhdGlvbjtcbiAgICBzZWxmLnN0YXRlID0gcmVzLmpvYkluZm8uc3RhdGU7XG4gICAgcmV0dXJuIHJlcy5qb2JJbmZvO1xuICB9KTtcbiAgcmV0dXJuIHRoaXMuX2pvYkluZm8udGhlbkNhbGwoY2FsbGJhY2spO1xufTtcblxuLyoqXG4gKiBXYWl0IHRpbGwgdGhlIGpvYiBpcyBhc3NpZ25lZCB0byBzZXJ2ZXJcbiAqXG4gKiBAbWV0aG9kIEJ1bGt+Sm9iI2luZm9cbiAqIEBwYXJhbSB7Q2FsbGJhY2suPEJ1bGt+Sm9iSW5mbz59IFtjYWxsYmFja10gLSBDYWxsYmFjayBmdW5jdGlvblxuICogQHJldHVybnMge1Byb21pc2UuPEJ1bGt+Sm9iSW5mbz59XG4gKi9cbkpvYi5wcm90b3R5cGUuX3dhaXRBc3NpZ24gPSBmdW5jdGlvbihjYWxsYmFjaykge1xuICByZXR1cm4gKHRoaXMuaWQgPyBQcm9taXNlLnJlc29sdmUoeyBpZDogdGhpcy5pZCB9KSA6IHRoaXMub3BlbigpKS50aGVuQ2FsbChjYWxsYmFjayk7XG59O1xuXG5cbi8qKlxuICogTGlzdCBhbGwgcmVnaXN0ZXJlZCBiYXRjaCBpbmZvIGluIGpvYlxuICpcbiAqIEBtZXRob2QgQnVsa35Kb2IjbGlzdFxuICogQHBhcmFtIHtDYWxsYmFjay48QXJyYXkuPEJ1bGt+QmF0Y2hJbmZvPj59IFtjYWxsYmFja10gLSBDYWxsYmFjayBmdW5jdGlvblxuICogQHJldHVybnMge1Byb21pc2UuPEFycmF5LjxCdWxrfkJhdGNoSW5mbz4+fVxuICovXG5Kb2IucHJvdG90eXBlLmxpc3QgPSBmdW5jdGlvbihjYWxsYmFjaykge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHZhciBidWxrID0gdGhpcy5fYnVsaztcbiAgdmFyIGxvZ2dlciA9IGJ1bGsuX2xvZ2dlcjtcblxuICByZXR1cm4gdGhpcy5fd2FpdEFzc2lnbigpLnRoZW4oZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGJ1bGsuX3JlcXVlc3Qoe1xuICAgICAgbWV0aG9kIDogJ0dFVCcsXG4gICAgICBwYXRoIDogXCIvam9iL1wiICsgc2VsZi5pZCArIFwiL2JhdGNoXCIsXG4gICAgICByZXNwb25zZVR5cGU6IFwiYXBwbGljYXRpb24veG1sXCJcbiAgICB9KTtcbiAgfSkudGhlbihmdW5jdGlvbihyZXMpIHtcbiAgICBsb2dnZXIuZGVidWcocmVzLmJhdGNoSW5mb0xpc3QuYmF0Y2hJbmZvKTtcbiAgICB2YXIgYmF0Y2hJbmZvTGlzdCA9IHJlcy5iYXRjaEluZm9MaXN0O1xuICAgIGJhdGNoSW5mb0xpc3QgPSBfLmlzQXJyYXkoYmF0Y2hJbmZvTGlzdC5iYXRjaEluZm8pID8gYmF0Y2hJbmZvTGlzdC5iYXRjaEluZm8gOiBbIGJhdGNoSW5mb0xpc3QuYmF0Y2hJbmZvIF07XG4gICAgcmV0dXJuIGJhdGNoSW5mb0xpc3Q7XG4gIH0pLnRoZW5DYWxsKGNhbGxiYWNrKTtcblxufTtcblxuLyoqXG4gKiBDbG9zZSBvcGVuZWQgam9iXG4gKlxuICogQG1ldGhvZCBCdWxrfkpvYiNjbG9zZVxuICogQHBhcmFtIHtDYWxsYmFjay48QnVsa35Kb2JJbmZvPn0gW2NhbGxiYWNrXSAtIENhbGxiYWNrIGZ1bmN0aW9uXG4gKiBAcmV0dXJucyB7UHJvbWlzZS48QnVsa35Kb2JJbmZvPn1cbiAqL1xuSm9iLnByb3RvdHlwZS5jbG9zZSA9IGZ1bmN0aW9uKCkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHJldHVybiB0aGlzLl9jaGFuZ2VTdGF0ZShcIkNsb3NlZFwiKS50aGVuKGZ1bmN0aW9uKGpvYkluZm8pIHtcbiAgICBzZWxmLmlkID0gbnVsbDtcbiAgICBzZWxmLmVtaXQoXCJjbG9zZVwiLCBqb2JJbmZvKTtcbiAgICByZXR1cm4gam9iSW5mbztcbiAgfSwgZnVuY3Rpb24oZXJyKSB7XG4gICAgc2VsZi5lbWl0KFwiZXJyb3JcIiwgZXJyKTtcbiAgICB0aHJvdyBlcnI7XG4gIH0pO1xufTtcblxuLyoqXG4gKiBTZXQgdGhlIHN0YXR1cyB0byBhYm9ydFxuICpcbiAqIEBtZXRob2QgQnVsa35Kb2IjYWJvcnRcbiAqIEBwYXJhbSB7Q2FsbGJhY2suPEJ1bGt+Sm9iSW5mbz59IFtjYWxsYmFja10gLSBDYWxsYmFjayBmdW5jdGlvblxuICogQHJldHVybnMge1Byb21pc2UuPEJ1bGt+Sm9iSW5mbz59XG4gKi9cbkpvYi5wcm90b3R5cGUuYWJvcnQgPSBmdW5jdGlvbigpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICByZXR1cm4gdGhpcy5fY2hhbmdlU3RhdGUoXCJBYm9ydGVkXCIpLnRoZW4oZnVuY3Rpb24oam9iSW5mbykge1xuICAgIHNlbGYuaWQgPSBudWxsO1xuICAgIHNlbGYuZW1pdChcImFib3J0XCIsIGpvYkluZm8pO1xuICAgIHJldHVybiBqb2JJbmZvO1xuICB9LCBmdW5jdGlvbihlcnIpIHtcbiAgICBzZWxmLmVtaXQoXCJlcnJvclwiLCBlcnIpO1xuICAgIHRocm93IGVycjtcbiAgfSk7XG59O1xuXG4vKipcbiAqIEBwcml2YXRlXG4gKi9cbkpvYi5wcm90b3R5cGUuX2NoYW5nZVN0YXRlID0gZnVuY3Rpb24oc3RhdGUsIGNhbGxiYWNrKSB7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgdmFyIGJ1bGsgPSB0aGlzLl9idWxrO1xuICB2YXIgbG9nZ2VyID0gYnVsay5fbG9nZ2VyO1xuXG4gIHRoaXMuX2pvYkluZm8gPSB0aGlzLl93YWl0QXNzaWduKCkudGhlbihmdW5jdGlvbigpIHtcbiAgICB2YXIgYm9keSA9IFtcbiAgICAgICc8P3htbCB2ZXJzaW9uPVwiMS4wXCIgZW5jb2Rpbmc9XCJVVEYtOFwiPz4nLFxuICAgICAgJzxqb2JJbmZvIHhtbG5zPVwiaHR0cDovL3d3dy5mb3JjZS5jb20vMjAwOS8wNi9hc3luY2FwaS9kYXRhbG9hZFwiPicsXG4gICAgICAgICc8c3RhdGU+JyArIHN0YXRlICsgJzwvc3RhdGU+JyxcbiAgICAgICc8L2pvYkluZm8+J1xuICAgIF0uam9pbignJyk7XG4gICAgcmV0dXJuIGJ1bGsuX3JlcXVlc3Qoe1xuICAgICAgbWV0aG9kIDogJ1BPU1QnLFxuICAgICAgcGF0aCA6IFwiL2pvYi9cIiArIHNlbGYuaWQsXG4gICAgICBib2R5IDogYm9keSxcbiAgICAgIGhlYWRlcnMgOiB7XG4gICAgICAgIFwiQ29udGVudC1UeXBlXCIgOiBcImFwcGxpY2F0aW9uL3htbDsgY2hhcnNldD11dGYtOFwiXG4gICAgICB9LFxuICAgICAgcmVzcG9uc2VUeXBlOiBcImFwcGxpY2F0aW9uL3htbFwiXG4gICAgfSk7XG4gIH0pLnRoZW4oZnVuY3Rpb24ocmVzKSB7XG4gICAgbG9nZ2VyLmRlYnVnKHJlcy5qb2JJbmZvKTtcbiAgICBzZWxmLnN0YXRlID0gcmVzLmpvYkluZm8uc3RhdGU7XG4gICAgcmV0dXJuIHJlcy5qb2JJbmZvO1xuICB9KTtcbiAgcmV0dXJuIHRoaXMuX2pvYkluZm8udGhlbkNhbGwoY2FsbGJhY2spO1xuXG59O1xuXG5cbi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4vKipcbiAqIEJhdGNoIChleHRlbmRzIFJlY29yZFN0cmVhbSlcbiAqXG4gKiBAcHJvdGVjdGVkXG4gKiBAY2xhc3MgQnVsa35CYXRjaFxuICogQGV4dGVuZHMge3N0cmVhbS5Xcml0YWJsZX1cbiAqIEBpbXBsZW1lbnRzIHtQcm9taXNlLjxBcnJheS48UmVjb3JkUmVzdWx0Pj59XG4gKiBAcGFyYW0ge0J1bGt+Sm9ifSBqb2IgLSBCdWxrIGpvYiBvYmplY3RcbiAqIEBwYXJhbSB7U3RyaW5nfSBbYmF0Y2hJZF0gLSBCYXRjaCBJRCAoaWYgYWxyZWFkeSBhdmFpbGFibGUpXG4gKi9cbnZhciBCYXRjaCA9IGZ1bmN0aW9uKGpvYiwgYmF0Y2hJZCkge1xuICBCYXRjaC5zdXBlcl8uY2FsbCh0aGlzLCB7IG9iamVjdE1vZGU6IHRydWUgfSk7XG4gIHRoaXMuam9iID0gam9iO1xuICB0aG