@ortoo/angular-resource
Version:
Magical CRUD resource management for angular
216 lines • 26.2 kB
JavaScript
// tslint:disable max-classes-per-file
import * as jiff from 'jiff';
import * as moment from 'moment';
import { Subject } from 'rxjs/Subject';
import { ObjectUnsubscribedError } from 'rxjs/util/ObjectUnsubscribedError';
import { clone } from 'lodash';
import { isObject } from 'lodash';
import { isString } from 'lodash';
import { map } from 'lodash';
let hiddenKeyRegex = /^\$+/;
let TIMESTAMP_RE = /^(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+)|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d)|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d)$/; // tslint:disable-line max-line-length
export function convertJsonDates(jsonData) {
let outObj;
if (Array.isArray(jsonData)) {
outObj = [];
}
else {
outObj = {};
}
for (let key of Object.keys(jsonData)) {
let val = jsonData[key];
let res = val;
if (isString(val)) {
// The value is a string - does it match any of our things we want to convert
if (TIMESTAMP_RE.test(val)) {
// We're probably a timestamp
let dt = moment(val);
if (dt.isValid()) {
res = dt.toDate();
}
}
}
else if (Array.isArray(val) || isObject(val)) {
res = convertJsonDates(val);
}
outObj[key] = res;
}
return outObj;
}
export function toJSON(obj) {
return JSON.parse(JSON.stringify(obj));
}
export function diff(obj1, obj2) {
obj1 = toJSON(obj1);
obj2 = toJSON(obj2);
return jiff.diff(obj1, obj2);
}
export function applyPatch(res, patch) {
// Go to JSON - don't do anything with dates
let obj = JSON.parse(JSON.stringify(res, toJsonReplacer));
obj = jiff.patch(patch, obj);
// Go back to dates etc
obj = convertJsonDates(obj);
removeResValues(res);
setResValues(res, obj);
}
export function mergeObjects(mine, old, yours) {
// Make copies - we might modify the objects if ids dont exist
mine = clone(mine);
old = clone(old);
// First sort out _id's. We could have a new id if one doesn't exist on mine and old
if (!mine._id && !old._id && yours._id) {
mine._id = yours._id;
old._id = yours._id;
}
// We also need to convert into and out of dates
mine = toJSON(mine);
old = toJSON(old);
yours = toJSON(yours);
let yourpatch = jiff.diff(old, yours);
let mypatch = jiff.diff(old, mine);
let mypaths = map(mypatch, 'path');
let patch = yourpatch.filter((patchval) => {
return mypaths.indexOf(patchval.path) === -1;
});
let patched = jiff.patch(patch, mine);
return convertJsonDates(patched);
}
export function forEachVal(res, cb) {
for (let key in res) {
if (!hiddenKeyRegex.test(key)) {
cb(res, key);
}
}
}
export function toJsonReplacer(key, value) {
let val = value;
if (isString(key) && key.charAt(0) === '$') {
val = undefined;
}
return val;
}
export function fromJsonReviver(_, value) {
let val = value;
if (isString(value) && TIMESTAMP_RE.test(value)) {
let dt = moment(value);
if (dt.isValid()) {
val = dt.toDate();
}
}
return val;
}
export function toObject(res) {
// The toJsonReplacer gets rid of attributes beginning with $ and the fromJsonReviver
// converts date strings back into dates
let str = JSON.stringify(res, toJsonReplacer);
try {
return JSON.parse(str, fromJsonReviver);
}
catch (err) {
// Older versions of IE8 throw 'Out of stack space' errors if we use a reviver function
// due to the bug described here: http://support.microsoft.com/kb/976662. Everyone hates
// IE
if (err.message === 'Out of stack space') {
return convertJsonDates(JSON.parse(str));
}
throw (err);
}
}
export function removeResValues(res) {
forEachVal(res, (_, key) => {
delete res[key];
});
}
export function setResValues(res, vals) {
for (let key of Object.keys(vals)) {
res[key] = vals[key];
}
}
export function persistentStorageKey(url) {
return 'or2ws:' + url;
}
export function advancedStorage(localForage) {
return localForage.driver() !== 'localStorageWrapper';
}
// lifted from here -> http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#2117523
export function uuid() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
let r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); // tslint:disable-line
return v.toString(16);
});
}
export class Deferred {
constructor() {
/* A method to resolve the associated Promise with the value passed.
* If the promise is already settled it does nothing.
*
* @param {anything} value : This value is used to resolve the promise
* If the value is a Promise then the associated promise assumes the state
* of Promise passed as value.
*/
this.resolve = null;
/* A method to reject the assocaited Promise with the value passed.
* If the promise is already settled it does nothing.
*
* @param {anything} reason: The reason for the rejection of the Promise.
* Generally its an Error object. If however a Promise is passed, then the Promise
* itself will be the reason for rejection no matter the state of the Promise.
*/
this.reject = null;
/* A newly created Pomise object.
* Initially in pending state.
*/
this.promise = new Promise((resolve, reject) => {
this.resolve = resolve;
this.reject = reject;
});
Object.freeze(this);
}
}
export function isSubscribableOrPromise(value) {
return value && (typeof value.subscribe === 'function' || typeof value.then === 'function');
}
// Like BehaviorSubject but waits for a promise to resolve
export class ResolvedSubject extends Subject {
constructor(promise) {
super();
promise.then(val => {
this._resolved = true;
this.next(val);
});
}
get value() {
return this.getValue();
}
getValue() {
if (this.hasError) {
throw this.thrownError;
}
else if (this.closed) {
throw new ObjectUnsubscribedError();
}
else {
return this._value;
}
}
next(value) {
if (this._resolved) {
this._value = value;
super.next(value);
}
}
_subscribe(subscriber) {
const subscription = super._subscribe(subscriber);
if (this._resolved && subscription && !subscription.closed) {
subscriber.next(this._value);
}
return subscription;
}
}
export function convertToResolvedSubject(subject, promise) {
let resolvedSub = new ResolvedSubject(promise);
subject.subscribe(resolvedSub);
return resolvedSub;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiL0BvcnRvby9hbmd1bGFyLXJlc291cmNlLyIsInNvdXJjZXMiOlsidXRpbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsc0NBQXNDO0FBRXRDLE9BQU8sS0FBSyxJQUFJLE1BQU0sTUFBTSxDQUFDO0FBQzdCLE9BQU8sS0FBSyxNQUFNLE1BQU0sUUFBUSxDQUFDO0FBR2pDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFHdkMsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFFNUUsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLFFBQVEsQ0FBQztBQUMvQixPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sUUFBUSxDQUFDO0FBQ2xDLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxRQUFRLENBQUM7QUFDbEMsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLFFBQVEsQ0FBQztBQUk3QixJQUFJLGNBQWMsR0FBRyxNQUFNLENBQUM7QUFFNUIsSUFBSSxZQUFZLEdBQUcsNklBQTZJLENBQUMsQ0FBQyxzQ0FBc0M7QUFFeE0sTUFBTSwyQkFBMkIsUUFBYTtJQUM1QyxJQUFJLE1BQU0sQ0FBQztJQUNYLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzVCLE1BQU0sR0FBRyxFQUFFLENBQUM7SUFDZCxDQUFDO0lBQUMsSUFBSSxDQUFDLENBQUM7UUFDTixNQUFNLEdBQUcsRUFBRSxDQUFDO0lBQ2QsQ0FBQztJQUNELEdBQUcsQ0FBQyxDQUFDLElBQUksR0FBRyxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RDLElBQUksR0FBRyxHQUFHLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUN4QixJQUFJLEdBQUcsR0FBRyxHQUFHLENBQUM7UUFDZCxFQUFFLENBQUMs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QixDQUFDO0lBQ0gsQ0FBQztJQUVTLFVBQVUsQ0FBQyxVQUF5QjtRQUM1QyxNQUFNLFlBQVksR0FBRyxLQUFLLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ2xELEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLElBQUksWUFBWSxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7WUFDekQsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDakMsQ0FBQztRQUNELE1BQU0sQ0FBQyxZQUFZLENBQUM7SUFDdEIsQ0FBQztDQUNGO0FBRUQsTUFBTSxtQ0FBc0MsT0FBbUIsRUFBRSxPQUFtQjtJQUNsRixJQUFJLFdBQVcsR0FBRyxJQUFJLGVBQWUsQ0FBSSxPQUFPLENBQUMsQ0FBQztJQUNsRCxPQUFPLENBQUMsU0FBUyxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQy9CLE1BQU0sQ0FBQyxXQUFXLENBQUM7QUFDckIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIHRzbGludDpkaXNhYmxlIG1heC1jbGFzc2VzLXBlci1maWxlXG5cbmltcG9ydCAqIGFzIGppZmYgZnJvbSAnamlmZic7XG5pbXBvcnQgKiBhcyBtb21lbnQgZnJvbSAnbW9tZW50JztcblxuaW1wb3J0IHsgU3Vic2NyaWJhYmxlT3JQcm9taXNlIH0gZnJvbSAncnhqcy9PYnNlcnZhYmxlJztcbmltcG9ydCB7IFN1YmplY3QgfSBmcm9tICdyeGpzL1N1YmplY3QnO1xuaW1wb3J0IHsgU3Vic2NyaWJlciB9IGZyb20gJ3J4anMvU3Vic2NyaWJlcic7XG5pbXBvcnQgeyBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzL1N1YnNjcmlwdGlvbic7XG5pbXBvcnQgeyBPYmplY3RVbnN1YnNjcmliZWRFcnJvciB9IGZyb20gJ3J4anMvdXRpbC9PYmplY3RVbnN1YnNjcmliZWRFcnJvcic7XG5cbmltcG9ydCB7IGNsb25lIH0gZnJvbSAnbG9kYXNoJztcbmltcG9ydCB7IGlzT2JqZWN0IH0gZnJvbSAnbG9kYXNoJztcbmltcG9ydCB7IGlzU3RyaW5nIH0gZnJvbSAnbG9kYXNoJztcbmltcG9ydCB7IG1hcCB9IGZyb20gJ2xvZGFzaCc7XG5cbmltcG9ydCB7IERlZmVycmVkIGFzIElEZWZlcnJlZCwgSlNPTlBhdGNoLCBMb2NhbEZvcmFnZSB9IGZyb20gJy4vdHlwZXMnO1xuXG5sZXQgaGlkZGVuS2V5UmVnZXggPSAvXlxcJCsvO1xuXG5sZXQgVElNRVNUQU1QX1JFID0gL14oXFxkezR9LVswMV1cXGQtWzAtM11cXGRUWzAtMl1cXGQ6WzAtNV1cXGQ6WzAtNV1cXGRcXC5cXGQrKXwoXFxkezR9LVswMV1cXGQtWzAtM11cXGRUWzAtMl1cXGQ6WzAtNV1cXGQ6WzAtNV1cXGQpfChcXGR7NH0tWzAxXVxcZC1bMC0zXVxcZFRbMC0yXVxcZDpbMC01XVxcZCkkLzsgLy8gdHNsaW50OmRpc2FibGUtbGluZSBtYXgtbGluZS1sZW5ndGhcblxuZXhwb3J0IGZ1bmN0aW9uIGNvbnZlcnRKc29uRGF0ZXMoanNvbkRhdGE6IGFueSkge1xuICBsZXQgb3V0T2JqO1xuICBpZiAoQXJyYXkuaXNBcnJheShqc29uRGF0YSkpIHtcbiAgICBvdXRPYmogPSBbXTtcbiAgfSBlbHNlIHtcbiAgICBvdXRPYmogPSB7fTtcbiAgfVxuICBmb3IgKGxldCBrZXkgb2YgT2JqZWN0LmtleXMoanNvbkRhdGEpKSB7XG4gICAgbGV0IHZhbCA9IGpzb25EYXRhW2tleV07XG4gICAgbGV0IHJlcyA9IHZhbDtcbiAgICBpZiAoaXNTdHJpbmcodmFsKSkge1xuICAgICAgLy8gVGhlIHZhbHVlIGlzIGEgc3RyaW5nIC0gZG9lcyBpdCBtYXRjaCBhbnkgb2Ygb3VyIHRoaW5ncyB3ZSB3YW50IHRvIGNvbnZlcnRcbiAgICAgIGlmIChUSU1FU1RBTVBfUkUudGVzdCh2YWwpKSB7XG4gICAgICAgIC8vIFdlJ3JlIHByb2JhYmx5IGEgdGltZXN0YW1wXG4gICAgICAgIGxldCBkdCA9IG1vbWVudCh2YWwpO1xuICAgICAgICBpZiAoZHQuaXNWYWxpZCgpKSB7XG4gICAgICAgICAgcmVzID0gZHQudG9EYXRlKCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKEFycmF5LmlzQXJyYXkodmFsKSB8fCBpc09iamVjdCh2YWwpKSB7XG4gICAgICByZXMgPSBjb252ZXJ0SnNvbkRhdGVzKHZhbCk7XG4gICAgfVxuXG4gICAgb3V0T2JqW2tleV0gPSByZXM7XG4gIH1cblxuICByZXR1cm4gb3V0T2JqO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gdG9KU09OKG9iajogYW55KSB7XG4gIHJldHVybiBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KG9iaikpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZGlmZihvYmoxOiBhbnksIG9iajI6IGFueSkge1xuICBvYmoxID0gdG9KU09OKG9iajEpO1xuICBvYmoyID0gdG9KU09OKG9iajIpO1xuXG4gIHJldHVybiBqaWZmLmRpZmYob2JqMSwgb2JqMik7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhcHBseVBhdGNoKHJlczogYW55LCBwYXRjaDogSlNPTlBhdGNoKSB7XG4gIC8vIEdvIHRvIEpTT04gLSBkb24ndCBkbyBhbnl0aGluZyB3aXRoIGRhdGVzXG4gIGxldCBvYmogPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHJlcywgdG9Kc29uUmVwbGFjZXIpKTtcbiAgb2JqID0gamlmZi5wYXRjaChwYXRjaCwgb2JqKTtcblxuICAvLyBHbyBiYWNrIHRvIGRhdGVzIGV0Y1xuICBvYmogPSBjb252ZXJ0SnNvbkRhdGVzKG9iaik7XG5cbiAgcmVtb3ZlUmVzVmFsdWVzKHJlcyk7XG4gIHNldFJlc1ZhbHVlcyhyZXMsIG9iaik7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBtZXJnZU9iamVjdHMobWluZTogYW55LCBvbGQ6IGFueSwgeW91cnM6IGFueSkge1xuXG4gIC8vIE1ha2UgY29waWVzIC0gd2UgbWlnaHQgbW9kaWZ5IHRoZSBvYmplY3RzIGlmIGlkcyBkb250IGV4aXN0XG4gIG1pbmUgPSBjbG9uZShtaW5lKTtcbiAgb2xkID0gY2xvbmUob2xkKTtcblxuICAvLyBGaXJzdCBzb3J0IG91dCBfaWQncy4gV2UgY291bGQgaGF2ZSBhIG5ldyBpZCBpZiBvbmUgZG9lc24ndCBleGlzdCBvbiBtaW5lIGFuZCBvbGRcbiAgaWYgKCFtaW5lLl9pZCAmJiAhb2xkLl9pZCAmJiB5b3Vycy5faWQpIHtcbiAgICBtaW5lLl9pZCA9IHlvdXJzLl9pZDtcbiAgICBvbGQuX2lkID0geW91cnMuX2lkO1xuICB9XG5cbiAgLy8gV2UgYWxzbyBuZWVkIHRvIGNvbnZlcnQgaW50byBhbmQgb3V0IG9mIGRhdGVzXG4gIG1pbmUgPSB0b0pTT04obWluZSk7XG4gIG9sZCA9IHRvSlNPTihvbGQpO1xuICB5b3VycyA9IHRvSlNPTih5b3Vycyk7XG5cbiAgbGV0IHlvdXJwYXRjaCA9IGppZmYuZGlmZihvbGQsIHlvdXJzKTtcbiAgbGV0IG15cGF0Y2ggPSBqaWZmLmRpZmYob2xkLCBtaW5lKTtcblxuICBsZXQgbXlwYXRocyA9IG1hcChteXBhdGNoLCAncGF0aCcpO1xuICBsZXQgcGF0Y2ggPSB5b3VycGF0Y2guZmlsdGVyKChwYXRjaHZhbDogYW55KSA9PiB7XG4gICAgcmV0dXJuIG15cGF0aHMuaW5kZXhPZihwYXRjaHZhbC5wYXRoKSA9PT0gLTE7XG4gIH0pO1xuXG4gIGxldCBwYXRjaGVkID0gamlmZi5wYXRjaChwYXRjaCwgbWluZSk7XG4gIHJldHVybiBjb252ZXJ0SnNvbkRhdGVzKHBhdGNoZWQpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZm9yRWFjaFZhbChyZXM6IGFueSwgY2I6IEZ1bmN0aW9uKSB7XG4gIGZvciAobGV0IGtleSBpbiByZXMpIHtcbiAgICBpZiAoIWhpZGRlbktleVJlZ2V4LnRlc3Qoa2V5KSkge1xuICAgICAgY2IocmVzLCBrZXkpO1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gdG9Kc29uUmVwbGFjZXIoa2V5OiBhbnksIHZhbHVlOiBhbnkpIHtcbiAgbGV0IHZhbCA9IHZhbHVlO1xuICBpZiAoaXNTdHJpbmcoa2V5KSAmJiBrZXkuY2hhckF0KDApID09PSAnJCcpIHtcbiAgICB2YWwgPSB1bmRlZmluZWQ7XG4gIH1cblxuICByZXR1cm4gdmFsO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZnJvbUpzb25SZXZpdmVyKF86IGFueSwgdmFsdWU6IGFueSkge1xuICBsZXQgdmFsID0gdmFsdWU7XG4gIGlmIChpc1N0cmluZyh2YWx1ZSkgJiYgVElNRVNUQU1QX1JFLnRlc3QodmFsdWUpKSB7XG4gICAgbGV0IGR0ID0gbW9tZW50KHZhbHVlKTtcbiAgICBpZiAoZHQuaXNWYWxpZCgpKSB7XG4gICAgICB2YWwgPSBkdC50b0RhdGUoKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdmFsO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gdG9PYmplY3QocmVzOiBhbnkpIHtcbiAgLy8gVGhlIHRvSnNvblJlcGxhY2VyIGdldHMgcmlkIG9mIGF0dHJpYnV0ZXMgYmVnaW5uaW5nIHdpdGggJCBhbmQgdGhlIGZyb21Kc29uUmV2aXZlclxuICAvLyBjb252ZXJ0cyBkYXRlIHN0cmluZ3MgYmFjayBpbnRvIGRhdGVzXG4gIGxldCBzdHIgPSBKU09OLnN0cmluZ2lmeShyZXMsIHRvSnNvblJlcGxhY2VyKTtcblxuICB0cnkge1xuICAgIHJldHVybiBKU09OLnBhcnNlKHN0ciwgZnJvbUpzb25SZXZpdmVyKTtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgLy8gT2xkZXIgdmVyc2lvbnMgb2YgSUU4IHRocm93ICdPdXQgb2Ygc3RhY2sgc3BhY2UnIGVycm9ycyBpZiB3ZSB1c2UgYSByZXZpdmVyIGZ1bmN0aW9uXG4gICAgLy8gZHVlIHRvIHRoZSBidWcgZGVzY3JpYmVkIGhlcmU6IGh0dHA6Ly9zdXBwb3J0Lm1pY3Jvc29mdC5jb20va2IvOTc2NjYyLiBFdmVyeW9uZSBoYXRlc1xuICAgIC8vIElFXG4gICAgaWYgKGVyci5tZXNzYWdlID09PSAnT3V0IG9mIHN0YWNrIHNwYWNlJykge1xuICAgICAgcmV0dXJuIGNvbnZlcnRKc29uRGF0ZXMoSlNPTi5wYXJzZShzdHIpKTtcbiAgICB9XG5cbiAgICB0aHJvdyhlcnIpO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZW1vdmVSZXNWYWx1ZXMocmVzOiBhbnkpIHtcbiAgZm9yRWFjaFZhbChyZXMsIChfOiBhbnksIGtleTogYW55KSA9PiB7XG4gICAgZGVsZXRlIHJlc1trZXldO1xuICB9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNldFJlc1ZhbHVlcyhyZXM6IGFueSwgdmFsczogYW55KSB7XG4gIGZvciAobGV0IGtleSBvZiBPYmplY3Qua2V5cyh2YWxzKSkge1xuICAgIHJlc1trZXldID0gdmFsc1trZXldO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBwZXJzaXN0ZW50U3RvcmFnZUtleSh1cmw6IHN0cmluZykge1xuICByZXR1cm4gJ29yMndzOicgKyB1cmw7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhZHZhbmNlZFN0b3JhZ2UobG9jYWxGb3JhZ2U6IExvY2FsRm9yYWdlKSB7XG4gIHJldHVybiBsb2NhbEZvcmFnZS5kcml2ZXIoKSAhPT0gJ2xvY2FsU3RvcmFnZVdyYXBwZXInO1xufVxuXG4vLyBsaWZ0ZWQgZnJvbSBoZXJlIC0+IGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMTA1MDM0L2hvdy10by1jcmVhdGUtYS1ndWlkLXV1aWQtaW4tamF2YXNjcmlwdC8yMTE3NTIzIzIxMTc1MjNcbmV4cG9ydCBmdW5jdGlvbiB1dWlkKCkge1xuICByZXR1cm4gJ3h4eHh4eHh4LXh4eHgtNHh4eC15eHh4LXh4eHh4eHh4eHh4eCcucmVwbGFjZSgvW3h5XS9nLCBjID0+IHtcbiAgICBsZXQgciA9IE1hdGgucmFuZG9tKCkqMTZ8MCwgdiA9IGMgPT0gJ3gnID8gciA6IChyJjB4M3wweDgpOyAvLyB0c2xpbnQ6ZGlzYWJsZS1saW5lXG4gICAgcmV0dXJuIHYudG9TdHJpbmcoMTYpO1xuICB9KTtcbn1cblxuZXhwb3J0IGNsYXNzIERlZmVycmVkPFQ+IGltcGxlbWVudHMgSURlZmVycmVkPFQ+IHtcbiAgcHVibGljIHByb21pc2U6IFByb21pc2U8VD47XG4gIHB1YmxpYyByZXNvbHZlOiAodmFsPzogVCkgPT4gdm9pZDtcbiAgcHVibGljIHJlamVjdDogKGVycjogRXJyb3IpID0+IHZvaWQ7XG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgLyogQSBtZXRob2QgdG8gcmVzb2x2ZSB0aGUgYXNzb2NpYXRlZCBQcm9taXNlIHdpdGggdGhlIHZhbHVlIHBhc3NlZC5cbiAgICAgKiBJZiB0aGUgcHJvbWlzZSBpcyBhbHJlYWR5IHNldHRsZWQgaXQgZG9lcyBub3RoaW5nLlxuICAgICAqXG4gICAgICogQHBhcmFtIHthbnl0aGluZ30gdmFsdWUgOiBUaGlzIHZhbHVlIGlzIHVzZWQgdG8gcmVzb2x2ZSB0aGUgcHJvbWlzZVxuICAgICAqIElmIHRoZSB2YWx1ZSBpcyBhIFByb21pc2UgdGhlbiB0aGUgYXNzb2NpYXRlZCBwcm9taXNlIGFzc3VtZXMgdGhlIHN0YXRlXG4gICAgICogb2YgUHJvbWlzZSBwYXNzZWQgYXMgdmFsdWUuXG4gICAgICovXG4gICAgdGhpcy5yZXNvbHZlID0gbnVsbDtcblxuICAgIC8qIEEgbWV0aG9kIHRvIHJlamVjdCB0aGUgYXNzb2NhaXRlZCBQcm9taXNlIHdpdGggdGhlIHZhbHVlIHBhc3NlZC5cbiAgICAgKiBJZiB0aGUgcHJvbWlzZSBpcyBhbHJlYWR5IHNldHRsZWQgaXQgZG9lcyBub3RoaW5nLlxuICAgICAqXG4gICAgICogQHBhcmFtIHthbnl0aGluZ30gcmVhc29uOiBUaGUgcmVhc29uIGZvciB0aGUgcmVqZWN0aW9uIG9mIHRoZSBQcm9taXNlLlxuICAgICAqIEdlbmVyYWxseSBpdHMgYW4gRXJyb3Igb2JqZWN0LiBJZiBob3dldmVyIGEgUHJvbWlzZSBpcyBwYXNzZWQsIHRoZW4gdGhlIFByb21pc2VcbiAgICAgKiBpdHNlbGYgd2lsbCBiZSB0aGUgcmVhc29uIGZvciByZWplY3Rpb24gbm8gbWF0dGVyIHRoZSBzdGF0ZSBvZiB0aGUgUHJvbWlzZS5cbiAgICAgKi9cbiAgICB0aGlzLnJlamVjdCA9IG51bGw7XG5cbiAgICAvKiBBIG5ld2x5IGNyZWF0ZWQgUG9taXNlIG9iamVjdC5cbiAgICAgKiBJbml0aWFsbHkgaW4gcGVuZGluZyBzdGF0ZS5cbiAgICAgKi9cbiAgICB0aGlzLnByb21pc2UgPSBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLnJlc29sdmUgPSByZXNvbHZlO1xuICAgICAgdGhpcy5yZWplY3QgPSByZWplY3Q7XG4gICAgfSk7XG4gICAgT2JqZWN0LmZyZWV6ZSh0aGlzKTtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNTdWJzY3JpYmFibGVPclByb21pc2U8VD4odmFsdWU6IGFueSk6IHZhbHVlIGlzIFN1YnNjcmliYWJsZU9yUHJvbWlzZTxUPiB7XG4gIHJldHVybiB2YWx1ZSAmJiAodHlwZW9mIHZhbHVlLnN1YnNjcmliZSA9PT0gJ2Z1bmN0aW9uJyB8fCB0eXBlb2YgdmFsdWUudGhlbiA9PT0gJ2Z1bmN0aW9uJyk7XG59XG5cbi8vIExpa2UgQmVoYXZpb3JTdWJqZWN0IGJ1dCB3YWl0cyBmb3IgYSBwcm9taXNlIHRvIHJlc29sdmVcbmV4cG9ydCBjbGFzcyBSZXNvbHZlZFN1YmplY3Q8VD4gZXh0ZW5kcyBTdWJqZWN0PFQ+IHtcbiAgcHJpdmF0ZSBfdmFsdWU6IFQ7XG4gIHByaXZhdGUgX3Jlc29sdmVkOiBib29sZWFuO1xuXG4gIGNvbnN0cnVjdG9yKHByb21pc2U6IFByb21pc2U8VD4pIHtcbiAgICBzdXBlcigpO1xuXG4gICAgcHJvbWlzZS50aGVuKHZhbCA9PiB7XG4gICAgICB0aGlzLl9yZXNvbHZlZCA9IHRydWU7XG4gICAgICB0aGlzLm5leHQodmFsKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgdmFsdWUoKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0VmFsdWUoKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXRWYWx1ZSgpIHtcbiAgICBpZiAodGhpcy5oYXNFcnJvcikge1xuICAgICAgdGhyb3cgdGhpcy50aHJvd25FcnJvcjtcbiAgICB9IGVsc2UgaWYgKHRoaXMuY2xvc2VkKSB7XG4gICAgICB0aHJvdyBuZXcgT2JqZWN0VW5zdWJzY3JpYmVkRXJyb3IoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHRoaXMuX3ZhbHVlO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBuZXh0KHZhbHVlOiBUKSB7XG4gICAgaWYgKHRoaXMuX3Jlc29sdmVkKSB7XG4gICAgICB0aGlzLl92YWx1ZSA9IHZhbHVlO1xuICAgICAgc3VwZXIubmV4dCh2YWx1ZSk7XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIF9zdWJzY3JpYmUoc3Vic2NyaWJlcjogU3Vic2NyaWJlcjxUPik6IFN1YnNjcmlwdGlvbiB7XG4gICAgY29uc3Qgc3Vic2NyaXB0aW9uID0gc3VwZXIuX3N1YnNjcmliZShzdWJzY3JpYmVyKTtcbiAgICBpZiAodGhpcy5fcmVzb2x2ZWQgJiYgc3Vic2NyaXB0aW9uICYmICFzdWJzY3JpcHRpb24uY2xvc2VkKSB7XG4gICAgICAgIHN1YnNjcmliZXIubmV4dCh0aGlzLl92YWx1ZSk7XG4gICAgfVxuICAgIHJldHVybiBzdWJzY3JpcHRpb247XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNvbnZlcnRUb1Jlc29sdmVkU3ViamVjdDxUPihzdWJqZWN0OiBTdWJqZWN0PFQ+LCBwcm9taXNlOiBQcm9taXNlPFQ+KSB7XG4gIGxldCByZXNvbHZlZFN1YiA9IG5ldyBSZXNvbHZlZFN1YmplY3Q8VD4ocHJvbWlzZSk7XG4gIHN1YmplY3Quc3Vic2NyaWJlKHJlc29sdmVkU3ViKTtcbiAgcmV0dXJuIHJlc29sdmVkU3ViO1xufVxuIl19