Skip to content

Instantly share code, notes, and snippets.

@vorg
Last active November 9, 2016 15:49
Show Gist options
  • Select an option

  • Save vorg/bd641eadffff6ba6b8a6dca1835f3c2f to your computer and use it in GitHub Desktop.

Select an option

Save vorg/bd641eadffff6ba6b8a6dca1835f3c2f to your computer and use it in GitHub Desktop.
requirebin sketch
// Streams implementation for mouse events.
// Started based thinking in https://github.com/pex-gl/pex-gui/issues/8
// IMPORT DEPENDENCIES
// Flyd is "The less is more, modular, functional reactive programming library"
const flyd = require('flyd')
// emit events from one stream until another stream fires
const takeUntil = require('flyd/module/takeuntil')
// merge multiple streams into one
const mergeAll = require('flyd/module/mergeall')
// filter stream events based on predicate
const filterStream = require('flyd/module/filter')
// map events from a stream using a function
const mapStream = flyd.map
// check if point is inside a rectangle
const containsPoint = require('pex-geom/Rect').containsPoint
// UI
// Draw a red canvas with yellow "button" on the left
const btnRect = [[10, 10], [100, 100]]
const canvas = document.createElement('canvas')
canvas.style.background = 'red'
document.body.appendChild(canvas)
const ctx = canvas.getContext('2d')
ctx.fillStyle = '#FFFF00'
ctx.fillRect(btnRect[0][0], btnRect[0][1], btnRect[1][0] - btnRect[0][0], btnRect[1][1] - btnRect[0][1])
// crate streams for all mouse events
const mousedown = flyd.stream()
const mouseup = flyd.stream()
const mousemove = flyd.stream()
const windowmouseup = flyd.stream()
canvas.addEventListener('mousedown', mousedown)
canvas.addEventListener('mouseup', mouseup)
canvas.addEventListener('mousemove', mousemove)
window.addEventListener('mouseup', windowmouseup)
//flyd.on((e) => console.log('windowmouseup', e), windowmouseup)
// DRAG event stream implementation
// This shows how to combine streams (down, move, up) into a new stream
function createMouseDragStream (mousedown, mousemove, mouseup) {
const mousedrag = flyd.stream()
// on each mousedown event
flyd.on((e) => {
// create new stream that take events from mousemove
// until mouse up on canvas or window
const drag = takeUntil(mousemove, mergeAll([mouseup, windowmouseup]))
// then forward all events from drag to mousedrag
flyd.on(mousedrag, drag)
}, mousedown)
return mousedrag
}
const mousedrag = createMouseDragStream(mousedown, mousemove, mouseup)
// print mousedrag when dragging mouse over canvas
//flyd.on((e) => console.log('mousedrag', e), mousedrag)
// filter functon checking if mouse event is inside rectangle
function inRect (rect) {
return function (e) {
// TODO: curry this!
return containsPoint(rect, [e.clientX, e.clientY])
}
}
// we use preventDefault to mark handled streams
function markAsHandled (e) {
e.preventDefault()
return e
}
function notHandledYet (e) {
return !e.defaultPrevented
}
// we add background event listener first as we go from broad to more specific
const bgmousedown = filterStream(notHandledYet, mousedown)
flyd.on((e) => console.log('bg mousedown', e), bgmousedown)
/*
const bgmousedrag = mapStream(markAsHandled, createMouseDragStream(
bgmousedown,
mousemove,
mouseup
)
)
flyd.on((e) => console.log('bg mousedrag', e), bgmousedrag)
*/
// mouse clicks inside yellow rect
//const buttonmousedown = mapStream(markAsHandled, filterStream(inRect(btnRect), mousedown))
// mouse clicks outside yellow rect
//flyd.on((e) => console.log('button mousedown', e), buttonmousedown)
// crate drag event stream that happens only if we click inside button
const buttonmousedrag = createMouseDragStream(
mapStream(markAsHandled, filterStream(inRect(btnRect), mousedown)),
mousemove,
mouseup
)
//flyd.on((e) => console.log('button drag', e), buttonmousedrag)
/*
const a = flyd.stream()
const g = flyd.stream()
window.addEventListener('mousedown', a)
window.addEventListener('mousedown', g)
flyd.on((e) => console.log('a', e), a)
flyd.on((e) => console.log('g background', e), g)
flyd.on((e) => console.log('g slider', e), g)
*/
//const pointer = require('pointer-events-stream')(gl.canvas)
canvas.addEventListener('mousedown', (e) => {
e.preventDefault()
console.log('canvas down')
})
canvas.addEventListener('mouseup', (e) => {
console.log('canvas up', e.defaultPrevented)
})
window.addEventListener('mouseup', (e) => {
console.log('window up', e.defaultPrevented)
})
window.addEventListener('mouseout', (e) => {
console.log('window out', e.defaultPrevented)
})
/* Ideal scenario
var mouseclicks = stream()
var leftoferclicks = gui.addMouse(mouseclicks)
// inside gui
var click = mouseclicks.peak()
if (insideSlier(click)) {
mouseclicks.take()
}
*/
// PROBLEM
// - calling e.preventDefault in canvas.mousedown prevents window.mouseup released outside of browser bounds
// - gui and arcball / scene are using same canvas events. That wouldn't happen with canvas + dom dat.gui
// SCENARIOS
// gui vs arcball conflicks, picking bounding boxes vs arcball
// SOLUTIONS
// - keep using pex-sys/MouseEvent
// - flyd: add a handled flag to the Event object
// - create sepate window for gui
setTimeout(function(){
;require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
var _arity = require('./internal/_arity');
var _curry1 = require('./internal/_curry1');
var _curry2 = require('./internal/_curry2');
var _curryN = require('./internal/_curryN');
/**
* Returns a curried equivalent of the provided function, with the specified
* arity. The curried function has two unusual capabilities. First, its
* arguments needn't be provided one at a time. If `g` is `R.curryN(3, f)`, the
* following are equivalent:
*
* - `g(1)(2)(3)`
* - `g(1)(2, 3)`
* - `g(1, 2)(3)`
* - `g(1, 2, 3)`
*
* Secondly, the special placeholder value `R.__` may be used to specify
* "gaps", allowing partial application of any combination of arguments,
* regardless of their positions. If `g` is as above and `_` is `R.__`, the
* following are equivalent:
*
* - `g(1, 2, 3)`
* - `g(_, 2, 3)(1)`
* - `g(_, _, 3)(1)(2)`
* - `g(_, _, 3)(1, 2)`
* - `g(_, 2)(1)(3)`
* - `g(_, 2)(1, 3)`
* - `g(_, 2)(_, 3)(1)`
*
* @func
* @memberOf R
* @since v0.5.0
* @category Function
* @sig Number -> (* -> a) -> (* -> a)
* @param {Number} length The arity for the returned function.
* @param {Function} fn The function to curry.
* @return {Function} A new, curried function.
* @see R.curry
* @example
*
* var sumArgs = (...args) => R.sum(args);
*
* var curriedAddFourNumbers = R.curryN(4, sumArgs);
* var f = curriedAddFourNumbers(1, 2);
* var g = f(3);
* g(4); //=> 10
*/
module.exports = _curry2(function curryN(length, fn) {
if (length === 1) {
return _curry1(fn);
}
return _arity(length, _curryN(length, [], fn));
});
},{"./internal/_arity":2,"./internal/_curry1":3,"./internal/_curry2":4,"./internal/_curryN":5}],2:[function(require,module,exports){
module.exports = function _arity(n, fn) {
/* eslint-disable no-unused-vars */
switch (n) {
case 0: return function() { return fn.apply(this, arguments); };
case 1: return function(a0) { return fn.apply(this, arguments); };
case 2: return function(a0, a1) { return fn.apply(this, arguments); };
case 3: return function(a0, a1, a2) { return fn.apply(this, arguments); };
case 4: return function(a0, a1, a2, a3) { return fn.apply(this, arguments); };
case 5: return function(a0, a1, a2, a3, a4) { return fn.apply(this, arguments); };
case 6: return function(a0, a1, a2, a3, a4, a5) { return fn.apply(this, arguments); };
case 7: return function(a0, a1, a2, a3, a4, a5, a6) { return fn.apply(this, arguments); };
case 8: return function(a0, a1, a2, a3, a4, a5, a6, a7) { return fn.apply(this, arguments); };
case 9: return function(a0, a1, a2, a3, a4, a5, a6, a7, a8) { return fn.apply(this, arguments); };
case 10: return function(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) { return fn.apply(this, arguments); };
default: throw new Error('First argument to _arity must be a non-negative integer no greater than ten');
}
};
},{}],3:[function(require,module,exports){
var _isPlaceholder = require('./_isPlaceholder');
/**
* Optimized internal one-arity curry function.
*
* @private
* @category Function
* @param {Function} fn The function to curry.
* @return {Function} The curried function.
*/
module.exports = function _curry1(fn) {
return function f1(a) {
if (arguments.length === 0 || _isPlaceholder(a)) {
return f1;
} else {
return fn.apply(this, arguments);
}
};
};
},{"./_isPlaceholder":6}],4:[function(require,module,exports){
var _curry1 = require('./_curry1');
var _isPlaceholder = require('./_isPlaceholder');
/**
* Optimized internal two-arity curry function.
*
* @private
* @category Function
* @param {Function} fn The function to curry.
* @return {Function} The curried function.
*/
module.exports = function _curry2(fn) {
return function f2(a, b) {
switch (arguments.length) {
case 0:
return f2;
case 1:
return _isPlaceholder(a) ? f2
: _curry1(function(_b) { return fn(a, _b); });
default:
return _isPlaceholder(a) && _isPlaceholder(b) ? f2
: _isPlaceholder(a) ? _curry1(function(_a) { return fn(_a, b); })
: _isPlaceholder(b) ? _curry1(function(_b) { return fn(a, _b); })
: fn(a, b);
}
};
};
},{"./_curry1":3,"./_isPlaceholder":6}],5:[function(require,module,exports){
var _arity = require('./_arity');
var _isPlaceholder = require('./_isPlaceholder');
/**
* Internal curryN function.
*
* @private
* @category Function
* @param {Number} length The arity of the curried function.
* @param {Array} received An array of arguments received thus far.
* @param {Function} fn The function to curry.
* @return {Function} The curried function.
*/
module.exports = function _curryN(length, received, fn) {
return function() {
var combined = [];
var argsIdx = 0;
var left = length;
var combinedIdx = 0;
while (combinedIdx < received.length || argsIdx < arguments.length) {
var result;
if (combinedIdx < received.length &&
(!_isPlaceholder(received[combinedIdx]) ||
argsIdx >= arguments.length)) {
result = received[combinedIdx];
} else {
result = arguments[argsIdx];
argsIdx += 1;
}
combined[combinedIdx] = result;
if (!_isPlaceholder(result)) {
left -= 1;
}
combinedIdx += 1;
}
return left <= 0 ? fn.apply(this, combined)
: _arity(left, _curryN(length, combined, fn));
};
};
},{"./_arity":2,"./_isPlaceholder":6}],6:[function(require,module,exports){
module.exports = function _isPlaceholder(a) {
return a != null &&
typeof a === 'object' &&
a['@@functional/placeholder'] === true;
};
},{}],"flyd":[function(require,module,exports){
'use strict';
var curryN = require('ramda/src/curryN');
// Utility
function isFunction(obj) {
return !!(obj && obj.constructor && obj.call && obj.apply);
}
function trueFn() { return true; }
// Globals
var toUpdate = [];
var inStream;
var order = [];
var orderNextIdx = -1;
var flushing = false;
/** @namespace */
var flyd = {}
// /////////////////////////// API ///////////////////////////////// //
/**
* Creates a new stream
*
* __Signature__: `a -> Stream a`
*
* @name flyd.stream
* @param {*} initialValue - (Optional) the initial value of the stream
* @return {stream} the stream
*
* @example
* var n = flyd.stream(1); // Stream with initial value `1`
* var s = flyd.stream(); // Stream with no initial value
*/
flyd.stream = function(initialValue) {
var endStream = createDependentStream([], trueFn);
var s = createStream();
s.end = endStream;
s.fnArgs = [];
endStream.listeners.push(s);
if (arguments.length > 0) s(initialValue);
return s;
}
/**
* Create a new dependent stream
*
* __Signature__: `(...Stream * -> Stream b -> b) -> [Stream *] -> Stream b`
*
* @name flyd.combine
* @param {Function} fn - the function used to combine the streams
* @param {Array<stream>} dependencies - the streams that this one depends on
* @return {stream} the dependent stream
*
* @example
* var n1 = flyd.stream(0);
* var n2 = flyd.stream(0);
* var max = flyd.combine(function(n1, n2, self, changed) {
* return n1() > n2() ? n1() : n2();
* }, [n1, n2]);
*/
flyd.combine = curryN(2, combine);
function combine(fn, streams) {
var i, s, deps, depEndStreams;
var endStream = createDependentStream([], trueFn);
deps = []; depEndStreams = [];
for (i = 0; i < streams.length; ++i) {
if (streams[i] !== undefined) {
deps.push(streams[i]);
if (streams[i].end !== undefined) depEndStreams.push(streams[i].end);
}
}
s = createDependentStream(deps, fn);
s.depsChanged = [];
s.fnArgs = s.deps.concat([s, s.depsChanged]);
s.end = endStream;
endStream.listeners.push(s);
addListeners(depEndStreams, endStream);
endStream.deps = depEndStreams;
updateStream(s);
return s;
}
/**
* Returns `true` if the supplied argument is a Flyd stream and `false` otherwise.
*
* __Signature__: `* -> Boolean`
*
* @name flyd.isStream
* @param {*} value - the value to test
* @return {Boolean} `true` if is a Flyd streamn, `false` otherwise
*
* @example
* var s = flyd.stream(1);
* var n = 1;
* flyd.isStream(s); //=> true
* flyd.isStream(n); //=> false
*/
flyd.isStream = function(stream) {
return isFunction(stream) && 'hasVal' in stream;
}
/**
* Invokes the body (the function to calculate the value) of a dependent stream
*
* By default the body of a dependent stream is only called when all the streams
* upon which it depends has a value. `immediate` can circumvent this behaviour.
* It immediately invokes the body of a dependent stream.
*
* __Signature__: `Stream a -> Stream a`
*
* @name flyd.immediate
* @param {stream} stream - the dependent stream
* @return {stream} the same stream
*
* @example
* var s = flyd.stream();
* var hasItems = flyd.immediate(flyd.combine(function(s) {
* return s() !== undefined && s().length > 0;
* }, [s]);
* console.log(hasItems()); // logs `false`. Had `immediate` not been
* // used `hasItems()` would've returned `undefined`
* s([1]);
* console.log(hasItems()); // logs `true`.
* s([]);
* console.log(hasItems()); // logs `false`.
*/
flyd.immediate = function(s) {
if (s.depsMet === false) {
s.depsMet = true;
updateStream(s);
}
return s;
}
/**
* Changes which `endsStream` should trigger the ending of `s`.
*
* __Signature__: `Stream a -> Stream b -> Stream b`
*
* @name flyd.endsOn
* @param {stream} endStream - the stream to trigger the ending
* @param {stream} stream - the stream to be ended by the endStream
* @param {stream} the stream modified to be ended by endStream
*
* @example
* var n = flyd.stream(1);
* var killer = flyd.stream();
* // `double` ends when `n` ends or when `killer` emits any value
* var double = flyd.endsOn(flyd.merge(n.end, killer), flyd.combine(function(n) {
* return 2 * n();
* }, [n]);
*/
flyd.endsOn = function(endS, s) {
detachDeps(s.end);
endS.listeners.push(s.end);
s.end.deps.push(endS);
return s;
}
/**
* Map a stream
*
* Returns a new stream consisting of every value from `s` passed through
* `fn`. I.e. `map` creates a new stream that listens to `s` and
* applies `fn` to every new value.
* __Signature__: `(a -> result) -> Stream a -> Stream result`
*
* @name flyd.map
* @param {Function} fn - the function that produces the elements of the new stream
* @param {stream} stream - the stream to map
* @return {stream} a new stream with the mapped values
*
* @example
* var numbers = flyd.stream(0);
* var squaredNumbers = flyd.map(function(n) { return n*n; }, numbers);
*/
// Library functions use self callback to accept (null, undefined) update triggers.
flyd.map = curryN(2, function(f, s) {
return combine(function(s, self) { self(f(s.val)); }, [s]);
})
/**
* Listen to stream events
*
* Similar to `map` except that the returned stream is empty. Use `on` for doing
* side effects in reaction to stream changes. Use the returned stream only if you
* need to manually end it.
*
* __Signature__: `(a -> result) -> Stream a -> Stream undefined`
*
* @name flyd.on
* @param {Function} cb - the callback
* @param {stream} stream - the stream
* @return {stream} an empty stream (can be ended)
*/
flyd.on = curryN(2, function(f, s) {
return combine(function(s) { f(s.val); }, [s]);
})
/**
* Creates a new stream with the results of calling the function on every incoming
* stream with and accumulator and the incoming value.
*
* __Signature__: `(a -> b -> a) -> a -> Stream b -> Stream a`
*
* @name flyd.scan
* @param {Function} fn - the function to call
* @param {*} val - the initial value of the accumulator
* @param {stream} stream - the stream source
* @return {stream} the new stream
*
* @example
* var numbers = flyd.stream();
* var sum = flyd.scan(function(sum, n) { return sum+n; }, 0, numbers);
* numbers(2)(3)(5);
* sum(); // 10
*/
flyd.scan = curryN(3, function(f, acc, s) {
var ns = combine(function(s, self) {
self(acc = f(acc, s.val));
}, [s]);
if (!ns.hasVal) ns(acc);
return ns;
});
/**
* Creates a new stream down which all values from both `stream1` and `stream2`
* will be sent.
*
* __Signature__: `Stream a -> Stream a -> Stream a`
*
* @name flyd.merge
* @param {stream} source1 - one stream to be merged
* @param {stream} source2 - the other stream to be merged
* @return {stream} a stream with the values from both sources
*
* @example
* var btn1Clicks = flyd.stream();
* button1Elm.addEventListener(btn1Clicks);
* var btn2Clicks = flyd.stream();
* button2Elm.addEventListener(btn2Clicks);
* var allClicks = flyd.merge(btn1Clicks, btn2Clicks);
*/
flyd.merge = curryN(2, function(s1, s2) {
var s = flyd.immediate(combine(function(s1, s2, self, changed) {
if (changed[0]) {
self(changed[0]());
} else if (s1.hasVal) {
self(s1.val);
} else if (s2.hasVal) {
self(s2.val);
}
}, [s1, s2]));
flyd.endsOn(combine(function() {
return true;
}, [s1.end, s2.end]), s);
return s;
});
/**
* Creates a new stream resulting from applying `transducer` to `stream`.
*
* __Signature__: `Transducer -> Stream a -> Stream b`
*
* @name flyd.transduce
* @param {Transducer} xform - the transducer transformation
* @param {stream} source - the stream source
* @return {stream} the new stream
*
* @example
* var t = require('transducers.js');
*
* var results = [];
* var s1 = flyd.stream();
* var tx = t.compose(t.map(function(x) { return x * 2; }), t.dedupe());
* var s2 = flyd.transduce(tx, s1);
* flyd.combine(function(s2) { results.push(s2()); }, [s2]);
* s1(1)(1)(2)(3)(3)(3)(4);
* results; // => [2, 4, 6, 8]
*/
flyd.transduce = curryN(2, function(xform, source) {
xform = xform(new StreamTransformer());
return combine(function(source, self) {
var res = xform['@@transducer/step'](undefined, source.val);
if (res && res['@@transducer/reduced'] === true) {
self.end(true);
return res['@@transducer/value'];
} else {
return res;
}
}, [source]);
});
/**
* Returns `fn` curried to `n`. Use this function to curry functions exposed by
* modules for Flyd.
*
* @name flyd.curryN
* @function
* @param {Integer} arity - the function arity
* @param {Function} fn - the function to curry
* @return {Function} the curried function
*
* @example
* function add(x, y) { return x + y; };
* var a = flyd.curryN(2, add);
* a(2)(4) // => 6
*/
flyd.curryN = curryN
/**
* Returns a new stream identical to the original except every
* value will be passed through `f`.
*
* _Note:_ This function is included in order to support the fantasy land
* specification.
*
* __Signature__: Called bound to `Stream a`: `(a -> b) -> Stream b`
*
* @name stream.map
* @param {Function} function - the function to apply
* @return {stream} a new stream with the values mapped
*
* @example
* var numbers = flyd.stream(0);
* var squaredNumbers = numbers.map(function(n) { return n*n; });
*/
function boundMap(f) { return flyd.map(f, this); }
/**
* Returns a new stream which is the result of applying the
* functions from `this` stream to the values in `stream` parameter.
*
* `this` stream must be a stream of functions.
*
* _Note:_ This function is included in order to support the fantasy land
* specification.
*
* __Signature__: Called bound to `Stream (a -> b)`: `a -> Stream b`
*
* @name stream.ap
* @param {stream} stream - the values stream
* @return {stream} a new stram with the functions applied to values
*
* @example
* var add = flyd.curryN(2, function(x, y) { return x + y; });
* var numbers1 = flyd.stream();
* var numbers2 = flyd.stream();
* var addToNumbers1 = flyd.map(add, numbers1);
* var added = addToNumbers1.ap(numbers2);
*/
function ap(s2) {
var s1 = this;
return combine(function(s1, s2, self) { self(s1.val(s2.val)); }, [s1, s2]);
}
/**
* Get a human readable view of a stream
* @name stream.toString
* @return {String} the stream string representation
*/
function streamToString() {
return 'stream(' + this.val + ')';
}
/**
* @name stream.end
* @memberof stream
* A stream that emits `true` when the stream ends. If `true` is pushed down the
* stream the parent stream ends.
*/
/**
* @name stream.of
* @function
* @memberof stream
* Returns a new stream with `value` as its initial value. It is identical to
* calling `flyd.stream` with one argument.
*
* __Signature__: Called bound to `Stream (a)`: `b -> Stream b`
*
* @param {*} value - the initial value
* @return {stream} the new stream
*
* @example
* var n = flyd.stream(1);
* var m = n.of(1);
*/
// /////////////////////////// PRIVATE ///////////////////////////////// //
/**
* @private
* Create a stream with no dependencies and no value
* @return {Function} a flyd stream
*/
function createStream() {
function s(n) {
if (arguments.length === 0) return s.val
updateStreamValue(s, n)
return s
}
s.hasVal = false;
s.val = undefined;
s.vals = [];
s.listeners = [];
s.queued = false;
s.end = undefined;
s.map = boundMap;
s.ap = ap;
s.of = flyd.stream;
s.toString = streamToString;
return s;
}
/**
* @private
* Create a dependent stream
* @param {Array<stream>} dependencies - an array of the streams
* @param {Function} fn - the function used to calculate the new stream value
* from the dependencies
* @return {stream} the created stream
*/
function createDependentStream(deps, fn) {
var s = createStream();
s.fn = fn;
s.deps = deps;
s.depsMet = false;
s.depsChanged = deps.length > 0 ? [] : undefined;
s.shouldUpdate = false;
addListeners(deps, s);
return s;
}
/**
* @private
* Check if all the dependencies have values
* @param {stream} stream - the stream to check depencencies from
* @return {Boolean} `true` if all dependencies have vales, `false` otherwise
*/
function initialDepsNotMet(stream) {
stream.depsMet = stream.deps.every(function(s) {
return s.hasVal;
});
return !stream.depsMet;
}
/**
* @private
* Update a dependent stream using its dependencies in an atomic way
* @param {stream} stream - the stream to update
*/
function updateStream(s) {
if ((s.depsMet !== true && initialDepsNotMet(s)) ||
(s.end !== undefined && s.end.val === true)) return;
if (inStream !== undefined) {
toUpdate.push(s);
return;
}
inStream = s;
if (s.depsChanged) s.fnArgs[s.fnArgs.length - 1] = s.depsChanged;
var returnVal = s.fn.apply(s.fn, s.fnArgs);
if (returnVal !== undefined) {
s(returnVal);
}
inStream = undefined;
if (s.depsChanged !== undefined) s.depsChanged = [];
s.shouldUpdate = false;
if (flushing === false) flushUpdate();
}
/**
* @private
* Update the dependencies of a stream
* @param {stream} stream
*/
function updateDeps(s) {
var i, o, list
var listeners = s.listeners;
for (i = 0; i < listeners.length; ++i) {
list = listeners[i];
if (list.end === s) {
endStream(list);
} else {
if (list.depsChanged !== undefined) list.depsChanged.push(s);
list.shouldUpdate = true;
findDeps(list);
}
}
for (; orderNextIdx >= 0; --orderNextIdx) {
o = order[orderNextIdx];
if (o.shouldUpdate === true) updateStream(o);
o.queued = false;
}
}
/**
* @private
* Add stream dependencies to the global `order` queue.
* @param {stream} stream
* @see updateDeps
*/
function findDeps(s) {
var i
var listeners = s.listeners;
if (s.queued === false) {
s.queued = true;
for (i = 0; i < listeners.length; ++i) {
findDeps(listeners[i]);
}
order[++orderNextIdx] = s;
}
}
/**
* @private
*/
function flushUpdate() {
flushing = true;
while (toUpdate.length > 0) {
var s = toUpdate.shift();
if (s.vals.length > 0) s.val = s.vals.shift();
updateDeps(s);
}
flushing = false;
}
/**
* @private
* Push down a value into a stream
* @param {stream} stream
* @param {*} value
*/
function updateStreamValue(s, n) {
if (n !== undefined && n !== null && isFunction(n.then)) {
n.then(s);
return;
}
s.val = n;
s.hasVal = true;
if (inStream === undefined) {
flushing = true;
updateDeps(s);
if (toUpdate.length > 0) flushUpdate(); else flushing = false;
} else if (inStream === s) {
markListeners(s, s.listeners);
} else {
s.vals.push(n);
toUpdate.push(s);
}
}
/**
* @private
*/
function markListeners(s, lists) {
var i, list;
for (i = 0; i < lists.length; ++i) {
list = lists[i];
if (list.end !== s) {
if (list.depsChanged !== undefined) {
list.depsChanged.push(s);
}
list.shouldUpdate = true;
} else {
endStream(list);
}
}
}
/**
* @private
* Add dependencies to a stream
* @param {Array<stream>} dependencies
* @param {stream} stream
*/
function addListeners(deps, s) {
for (var i = 0; i < deps.length; ++i) {
deps[i].listeners.push(s);
}
}
/**
* @private
* Removes an stream from a dependency array
* @param {stream} stream
* @param {Array<stream>} dependencies
*/
function removeListener(s, listeners) {
var idx = listeners.indexOf(s);
listeners[idx] = listeners[listeners.length - 1];
listeners.length--;
}
/**
* @private
* Detach a stream from its dependencies
* @param {stream} stream
*/
function detachDeps(s) {
for (var i = 0; i < s.deps.length; ++i) {
removeListener(s, s.deps[i].listeners);
}
s.deps.length = 0;
}
/**
* @private
* Ends a stream
*/
function endStream(s) {
if (s.deps !== undefined) detachDeps(s);
if (s.end !== undefined) detachDeps(s.end);
}
/**
* @private
* transducer stream transformer
*/
function StreamTransformer() { }
StreamTransformer.prototype['@@transducer/init'] = function() { };
StreamTransformer.prototype['@@transducer/result'] = function() { };
StreamTransformer.prototype['@@transducer/step'] = function(s, v) { return v; };
module.exports = flyd;
},{"ramda/src/curryN":1}]},{},[])
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2hvbWUvYWRtaW4vYnJvd3NlcmlmeS1jZG4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXItcGFjay9fcHJlbHVkZS5qcyIsIm5vZGVfbW9kdWxlcy9yYW1kYS9zcmMvY3VycnlOLmpzIiwibm9kZV9tb2R1bGVzL3JhbWRhL3NyYy9pbnRlcm5hbC9fYXJpdHkuanMiLCJub2RlX21vZHVsZXMvcmFtZGEvc3JjL2ludGVybmFsL19jdXJyeTEuanMiLCJub2RlX21vZHVsZXMvcmFtZGEvc3JjL2ludGVybmFsL19jdXJyeTIuanMiLCJub2RlX21vZHVsZXMvcmFtZGEvc3JjL2ludGVybmFsL19jdXJyeU4uanMiLCJub2RlX21vZHVsZXMvcmFtZGEvc3JjL2ludGVybmFsL19pc1BsYWNlaG9sZGVyLmpzIiwibGliL2luZGV4LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsInZhciBfYXJpdHkgPSByZXF1aXJlKCcuL2ludGVybmFsL19hcml0eScpO1xudmFyIF9jdXJyeTEgPSByZXF1aXJlKCcuL2ludGVybmFsL19jdXJyeTEnKTtcbnZhciBfY3VycnkyID0gcmVxdWlyZSgnLi9pbnRlcm5hbC9fY3VycnkyJyk7XG52YXIgX2N1cnJ5TiA9IHJlcXVpcmUoJy4vaW50ZXJuYWwvX2N1cnJ5TicpO1xuXG5cbi8qKlxuICogUmV0dXJucyBhIGN1cnJpZWQgZXF1aXZhbGVudCBvZiB0aGUgcHJvdmlkZWQgZnVuY3Rpb24sIHdpdGggdGhlIHNwZWNpZmllZFxuICogYXJpdHkuIFRoZSBjdXJyaWVkIGZ1bmN0aW9uIGhhcyB0d28gdW51c3VhbCBjYXBhYmlsaXRpZXMuIEZpcnN0LCBpdHNcbiAqIGFyZ3VtZW50cyBuZWVkbid0IGJlIHByb3ZpZGVkIG9uZSBhdCBhIHRpbWUuIElmIGBnYCBpcyBgUi5jdXJyeU4oMywgZilgLCB0aGVcbiAqIGZvbGxvd2luZyBhcmUgZXF1aXZhbGVudDpcbiAqXG4gKiAgIC0gYGcoMSkoMikoMylgXG4gKiAgIC0gYGcoMSkoMiwgMylgXG4gKiAgIC0gYGcoMSwgMikoMylgXG4gKiAgIC0gYGcoMSwgMiwgMylgXG4gKlxuICogU2Vjb25kbHksIHRoZSBzcGVjaWFsIHBsYWNlaG9sZGVyIHZhbHVlIGBSLl9fYCBtYXkgYmUgdXNlZCB0byBzcGVjaWZ5XG4gKiBcImdhcHNcIiwgYWxsb3dpbmcgcGFydGlhbCBhcHBsaWNhdGlvbiBvZiBhbnkgY29tYmluYXRpb24gb2YgYXJndW1lbnRzLFxuICogcmVnYXJkbGVzcyBvZiB0aGVpciBwb3NpdGlvbnMuIElmIGBnYCBpcyBhcyBhYm92ZSBhbmQgYF9gIGlzIGBSLl9fYCwgdGhlXG4gKiBmb2xsb3dpbmcgYXJlIGVxdWl2YWxlbnQ6XG4gKlxuICogICAtIGBnKDEsIDIsIDMpYFxuICogICAtIGBnKF8sIDIsIDMpKDEpYFxuICogICAtIGBnKF8sIF8sIDMpKDEpKDIpYFxuICogICAtIGBnKF8sIF8sIDMpKDEsIDIpYFxuICogICAtIGBnKF8sIDIpKDEpKDMpYFxuICogICAtIGBnKF8sIDIpKDEsIDMpYFxuICogICAtIGBnKF8sIDIpKF8sIDMpKDEpYFxuICpcbiAqIEBmdW5jXG4gKiBAbWVtYmVyT2YgUlxuICogQHNpbmNlIHYwLjUuMFxuICogQGNhdGVnb3J5IEZ1bmN0aW9uXG4gKiBAc2lnIE51bWJlciAtPiAoKiAtPiBhKSAtPiAoKiAtPiBhKVxuICogQHBhcmFtIHtOdW1iZXJ9IGxlbmd0aCBUaGUgYXJpdHkgZm9yIHRoZSByZXR1cm5lZCBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIFRoZSBmdW5jdGlvbiB0byBjdXJyeS5cbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSBBIG5ldywgY3VycmllZCBmdW5jdGlvbi5cbiAqIEBzZWUgUi5jdXJyeVxuICogQGV4YW1wbGVcbiAqXG4gKiAgICAgIHZhciBzdW1BcmdzID0gKC4uLmFyZ3MpID0+IFIuc3VtKGFyZ3MpO1xuICpcbiAqICAgICAgdmFyIGN1cnJpZWRBZGRGb3VyTnVtYmVycyA9IFIuY3VycnlOKDQsIHN1bUFyZ3MpO1xuICogICAgICB2YXIgZiA9IGN1cnJpZWRBZGRGb3VyTnVtYmVycygxLCAyKTtcbiAqICAgICAgdmFyIGcgPSBmKDMpO1xuICogICAgICBnKDQpOyAvLz0+IDEwXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gX2N1cnJ5MihmdW5jdGlvbiBjdXJyeU4obGVuZ3RoLCBmbikge1xuICBpZiAobGVuZ3RoID09PSAxKSB7XG4gICAgcmV0dXJuIF9jdXJyeTEoZm4pO1xuICB9XG4gIHJldHVybiBfYXJpdHkobGVuZ3RoLCBfY3VycnlOKGxlbmd0aCwgW10sIGZuKSk7XG59KTtcbiIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gX2FyaXR5KG4sIGZuKSB7XG4gIC8qIGVzbGludC1kaXNhYmxlIG5vLXVudXNlZC12YXJzICovXG4gIHN3aXRjaCAobikge1xuICAgIGNhc2UgMDogcmV0dXJuIGZ1bmN0aW9uKCkgeyByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfTtcbiAgICBjYXNlIDE6IHJldHVybiBmdW5jdGlvbihhMCkgeyByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfTtcbiAgICBjYXNlIDI6IHJldHVybiBmdW5jdGlvbihhMCwgYTEpIHsgcmV0dXJuIGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7IH07XG4gICAgY2FzZSAzOiByZXR1cm4gZnVuY3Rpb24oYTAsIGExLCBhMikgeyByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfTtcbiAgICBjYXNlIDQ6IHJldHVybiBmdW5jdGlvbihhMCwgYTEsIGEyLCBhMykgeyByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfTtcbiAgICBjYXNlIDU6IHJldHVybiBmdW5jdGlvbihhMCwgYTEsIGEyLCBhMywgYTQpIHsgcmV0dXJuIGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7IH07XG4gICAgY2FzZSA2OiByZXR1cm4gZnVuY3Rpb24oYTAsIGExLCBhMiwgYTMsIGE0LCBhNSkgeyByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfTtcbiAgICBjYXNlIDc6IHJldHVybiBmdW5jdGlvbihhMCwgYTEsIGEyLCBhMywgYTQsIGE1LCBhNikgeyByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfTtcbiAgICBjYXNlIDg6IHJldHVybiBmdW5jdGlvbihhMCwgYTEsIGEyLCBhMywgYTQsIGE1LCBhNiwgYTcpIHsgcmV0dXJuIGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7IH07XG4gICAgY2FzZSA5OiByZXR1cm4gZnVuY3Rpb24oYTAsIGExLCBhMiwgYTMsIGE0LCBhNSwgYTYsIGE3LCBhOCkgeyByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfTtcbiAgICBjYXNlIDEwOiByZXR1cm4gZnVuY3Rpb24oYTAsIGExLCBhMiwgYTMsIGE0LCBhNSwgYTYsIGE3LCBhOCwgYTkpIHsgcmV0dXJuIGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7IH07XG4gICAgZGVmYXVsdDogdGhyb3cgbmV3IEVycm9yKCdGaXJzdCBhcmd1bWVudCB0byBfYXJpdHkgbXVzdCBiZSBhIG5vbi1uZWdhdGl2ZSBpbnRlZ2VyIG5vIGdyZWF0ZXIgdGhhbiB0ZW4nKTtcbiAgfVxufTtcbiIsInZhciBfaXNQbGFjZWhvbGRlciA9IHJlcXVpcmUoJy4vX2lzUGxhY2Vob2xkZXInKTtcblxuXG4vKipcbiAqIE9wdGltaXplZCBpbnRlcm5hbCBvbmUtYXJpdHkgY3VycnkgZnVuY3Rpb24uXG4gKlxuICogQHByaXZhdGVcbiAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm4gVGhlIGZ1bmN0aW9uIHRvIGN1cnJ5LlxuICogQHJldHVybiB7RnVuY3Rpb259IFRoZSBjdXJyaWVkIGZ1bmN0aW9uLlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIF9jdXJyeTEoZm4pIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIGYxKGEpIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCB8fCBfaXNQbGFjZWhvbGRlcihhKSkge1xuICAgICAgcmV0dXJuIGYxO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9XG4gIH07XG59O1xuIiwidmFyIF9jdXJyeTEgPSByZXF1aXJlKCcuL19jdXJyeTEnKTtcbnZhciBfaXNQbGFjZWhvbGRlciA9IHJlcXVpcmUoJy4vX2lzUGxhY2Vob2xkZXInKTtcblxuXG4vKipcbiAqIE9wdGltaXplZCBpbnRlcm5hbCB0d28tYXJpdHkgY3VycnkgZnVuY3Rpb24uXG4gKlxuICogQHByaXZhdGVcbiAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm4gVGhlIGZ1bmN0aW9uIHRvIGN1cnJ5LlxuICogQHJldHVybiB7RnVuY3Rpb259IFRoZSBjdXJyaWVkIGZ1bmN0aW9uLlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIF9jdXJyeTIoZm4pIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIGYyKGEsIGIpIHtcbiAgICBzd2l0Y2ggKGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgIGNhc2UgMDpcbiAgICAgICAgcmV0dXJuIGYyO1xuICAgICAgY2FzZSAxOlxuICAgICAgICByZXR1cm4gX2lzUGxhY2Vob2xkZXIoYSkgPyBmMlxuICAgICAgICAgICAgIDogX2N1cnJ5MShmdW5jdGlvbihfYikgeyByZXR1cm4gZm4oYSwgX2IpOyB9KTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiBfaXNQbGFjZWhvbGRlcihhKSAmJiBfaXNQbGFjZWhvbGRlcihiKSA/IGYyXG4gICAgICAgICAgICAgOiBfaXNQbGFjZWhvbGRlcihhKSA/IF9jdXJyeTEoZnVuY3Rpb24oX2EpIHsgcmV0dXJuIGZuKF9hLCBiKTsgfSlcbiAgICAgICAgICAgICA6IF9pc1BsYWNlaG9sZGVyKGIpID8gX2N1cnJ5MShmdW5jdGlvbihfYikgeyByZXR1cm4gZm4oYSwgX2IpOyB9KVxuICAgICAgICAgICAgIDogZm4oYSwgYik7XG4gICAgfVxuICB9O1xufTtcbiIsInZhciBfYXJpdHkgPSByZXF1aXJlKCcuL19hcml0eScpO1xudmFyIF9pc1BsYWNlaG9sZGVyID0gcmVxdWlyZSgnLi9faXNQbGFjZWhvbGRlcicpO1xuXG5cbi8qKlxuICogSW50ZXJuYWwgY3VycnlOIGZ1bmN0aW9uLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAqIEBwYXJhbSB7TnVtYmVyfSBsZW5ndGggVGhlIGFyaXR5IG9mIHRoZSBjdXJyaWVkIGZ1bmN0aW9uLlxuICogQHBhcmFtIHtBcnJheX0gcmVjZWl2ZWQgQW4gYXJyYXkgb2YgYXJndW1lbnRzIHJlY2VpdmVkIHRodXMgZmFyLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm4gVGhlIGZ1bmN0aW9uIHRvIGN1cnJ5LlxuICogQHJldHVybiB7RnVuY3Rpb259IFRoZSBjdXJyaWVkIGZ1bmN0aW9uLlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIF9jdXJyeU4obGVuZ3RoLCByZWNlaXZlZCwgZm4pIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHZhciBjb21iaW5lZCA9IFtdO1xuICAgIHZhciBhcmdzSWR4ID0gMDtcbiAgICB2YXIgbGVmdCA9IGxlbmd0aDtcbiAgICB2YXIgY29tYmluZWRJZHggPSAwO1xuICAgIHdoaWxlIChjb21iaW5lZElkeCA8IHJlY2VpdmVkLmxlbmd0aCB8fCBhcmdzSWR4IDwgYXJndW1lbnRzLmxlbmd0aCkge1xuICAgICAgdmFyIHJlc3VsdDtcbiAgICAgIGlmIChjb21iaW5lZElkeCA8IHJlY2VpdmVkLmxlbmd0aCAmJlxuICAgICAgICAgICghX2lzUGxhY2Vob2xkZXIocmVjZWl2ZWRbY29tYmluZWRJZHhdKSB8fFxuICAgICAgICAgICBhcmdzSWR4ID49IGFyZ3VtZW50cy5sZW5ndGgpKSB7XG4gICAgICAgIHJlc3VsdCA9IHJlY2VpdmVkW2NvbWJpbmVkSWR4XTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlc3VsdCA9IGFyZ3VtZW50c1thcmdzSWR4XTtcbiAgICAgICAgYXJnc0lkeCArPSAxO1xuICAgICAgfVxuICAgICAgY29tYmluZWRbY29tYmluZWRJZHhdID0gcmVzdWx0O1xuICAgICAgaWYgKCFfaXNQbGFjZWhvbGRlcihyZXN1bHQpKSB7XG4gICAgICAgIGxlZnQgLT0gMTtcbiAgICAgIH1cbiAgICAgIGNvbWJpbmVkSWR4ICs9IDE7XG4gICAgfVxuICAgIHJldHVybiBsZWZ0IDw9IDAgPyBmbi5hcHBseSh0aGlzLCBjb21iaW5lZClcbiAgICAgICAgICAgICAgICAgICAgIDogX2FyaXR5KGxlZnQsIF9jdXJyeU4obGVuZ3RoLCBjb21iaW5lZCwgZm4pKTtcbiAgfTtcbn07XG4iLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIF9pc1BsYWNlaG9sZGVyKGEpIHtcbiAgcmV0dXJuIGEgIT0gbnVsbCAmJlxuICAgICAgICAgdHlwZW9mIGEgPT09ICdvYmplY3QnICYmXG4gICAgICAgICBhWydAQGZ1bmN0aW9uYWwvcGxhY2Vob2xkZXInXSA9PT0gdHJ1ZTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBjdXJyeU4gPSByZXF1aXJlKCdyYW1kYS9zcmMvY3VycnlOJyk7XG5cbi8vIFV0aWxpdHlcbmZ1bmN0aW9uIGlzRnVuY3Rpb24ob2JqKSB7XG4gIHJldHVybiAhIShvYmogJiYgb2JqLmNvbnN0cnVjdG9yICYmIG9iai5jYWxsICYmIG9iai5hcHBseSk7XG59XG5mdW5jdGlvbiB0cnVlRm4oKSB7IHJldHVybiB0cnVlOyB9XG5cbi8vIEdsb2JhbHNcbnZhciB0b1VwZGF0ZSA9IFtdO1xudmFyIGluU3RyZWFtO1xudmFyIG9yZGVyID0gW107XG52YXIgb3JkZXJOZXh0SWR4ID0gLTE7XG52YXIgZmx1c2hpbmcgPSBmYWxzZTtcblxuLyoqIEBuYW1lc3BhY2UgKi9cbnZhciBmbHlkID0ge31cblxuLy8gLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vIEFQSSAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8gLy9cblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IHN0cmVhbVxuICpcbiAqIF9fU2lnbmF0dXJlX186IGBhIC0+IFN0cmVhbSBhYFxuICpcbiAqIEBuYW1lIGZseWQuc3RyZWFtXG4gKiBAcGFyYW0geyp9IGluaXRpYWxWYWx1ZSAtIChPcHRpb25hbCkgdGhlIGluaXRpYWwgdmFsdWUgb2YgdGhlIHN0cmVhbVxuICogQHJldHVybiB7c3RyZWFtfSB0aGUgc3RyZWFtXG4gKlxuICogQGV4YW1wbGVcbiAqIHZhciBuID0gZmx5ZC5zdHJlYW0oMSk7IC8vIFN0cmVhbSB3aXRoIGluaXRpYWwgdmFsdWUgYDFgXG4gKiB2YXIgcyA9IGZseWQuc3RyZWFtKCk7IC8vIFN0cmVhbSB3aXRoIG5vIGluaXRpYWwgdmFsdWVcbiAqL1xuZmx5ZC5zdHJlYW0gPSBmdW5jdGlvbihpbml0aWFsVmFsdWUpIHtcbiAgdmFyIGVuZFN0cmVhbSA9IGNyZWF0ZURlcGVuZGVudFN0cmVhbShbXSwgdHJ1ZUZuKTtcbiAgdmFyIHMgPSBjcmVhdGVTdHJlYW0oKTtcbiAgcy5lbmQgPSBlbmRTdHJlYW07XG4gIHMuZm5BcmdzID0gW107XG4gIGVuZFN0cmVhbS5saXN0ZW5lcnMucHVzaChzKTtcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAwKSBzKGluaXRpYWxWYWx1ZSk7XG4gIHJldHVybiBzO1xufVxuXG4vKipcbiAqIENyZWF0ZSBhIG5ldyBkZXBlbmRlbnQgc3RyZWFtXG4gKlxuICogX19TaWduYXR1cmVfXzogYCguLi5TdHJlYW0gKiAtPiBTdHJlYW0gYiAtPiBiKSAtPiBbU3RyZWFtICpdIC0+IFN0cmVhbSBiYFxuICpcbiAqIEBuYW1lIGZseWQuY29tYmluZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm4gLSB0aGUgZnVuY3Rpb24gdXNlZCB0byBjb21iaW5lIHRoZSBzdHJlYW1zXG4gKiBAcGFyYW0ge0FycmF5PHN0cmVhbT59IGRlcGVuZGVuY2llcyAtIHRoZSBzdHJlYW1zIHRoYXQgdGhpcyBvbmUgZGVwZW5kcyBvblxuICogQHJldHVybiB7c3RyZWFtfSB0aGUgZGVwZW5kZW50IHN0cmVhbVxuICpcbiAqIEBleGFtcGxlXG4gKiB2YXIgbjEgPSBmbHlkLnN0cmVhbSgwKTtcbiAqIHZhciBuMiA9IGZseWQuc3RyZWFtKDApO1xuICogdmFyIG1heCA9IGZseWQuY29tYmluZShmdW5jdGlvbihuMSwgbjIsIHNlbGYsIGNoYW5nZWQpIHtcbiAqICAgcmV0dXJuIG4xKCkgPiBuMigpID8gbjEoKSA6IG4yKCk7XG4gKiB9LCBbbjEsIG4yXSk7XG4gKi9cbmZseWQuY29tYmluZSA9IGN1cnJ5TigyLCBjb21iaW5lKTtcbmZ1bmN0aW9uIGNvbWJpbmUoZm4sIHN0cmVhbXMpIHtcbiAgdmFyIGksIHMsIGRlcHMsIGRlcEVuZFN0cmVhbXM7XG4gIHZhciBlbmRTdHJlYW0gPSBjcmVhdGVEZXBlbmRlbnRTdHJlYW0oW10sIHRydWVGbik7XG4gIGRlcHMgPSBbXTsgZGVwRW5kU3RyZWFtcyA9IFtdO1xuICBmb3IgKGkgPSAwOyBpIDwgc3RyZWFtcy5sZW5ndGg7ICsraSkge1xuICAgIGlmIChzdHJlYW1zW2ldICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGRlcHMucHVzaChzdHJlYW1zW2ldKTtcbiAgICAgIGlmIChzdHJlYW1zW2ldLmVuZCAhPT0gdW5kZWZpbmVkKSBkZXBFbmRTdHJlYW1zLnB1c2goc3RyZWFtc1tpXS5lbmQpO1xuICAgIH1cbiAgfVxuICBzID0gY3JlYXRlRGVwZW5kZW50U3RyZWFtKGRlcHMsIGZuKTtcbiAgcy5kZXBzQ2hhbmdlZCA9IFtdO1xuICBzLmZuQXJncyA9IHMuZGVwcy5jb25jYXQoW3MsIHMuZGVwc0NoYW5nZWRdKTtcbiAgcy5lbmQgPSBlbmRTdHJlYW07XG4gIGVuZFN0cmVhbS5saXN0ZW5lcnMucHVzaChzKTtcbiAgYWRkTGlzdGVuZXJzKGRlcEVuZFN0cmVhbXMsIGVuZFN0cmVhbSk7XG4gIGVuZFN0cmVhbS5kZXBzID0gZGVwRW5kU3RyZWFtcztcbiAgdXBkYXRlU3RyZWFtKHMpO1xuICByZXR1cm4gcztcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgc3VwcGxpZWQgYXJndW1lbnQgaXMgYSBGbHlkIHN0cmVhbSBhbmQgYGZhbHNlYCBvdGhlcndpc2UuXG4gKlxuICogX19TaWduYXR1cmVfXzogYCogLT4gQm9vbGVhbmBcbiAqXG4gKiBAbmFtZSBmbHlkLmlzU3RyZWFtXG4gKiBAcGFyYW0geyp9IHZhbHVlIC0gdGhlIHZhbHVlIHRvIHRlc3RcbiAqIEByZXR1cm4ge0Jvb2xlYW59IGB0cnVlYCBpZiBpcyBhIEZseWQgc3RyZWFtbiwgYGZhbHNlYCBvdGhlcndpc2VcbiAqXG4gKiBAZXhhbXBsZVxuICogdmFyIHMgPSBmbHlkLnN0cmVhbSgxKTtcbiAqIHZhciBuID0gMTtcbiAqIGZseWQuaXNTdHJlYW0ocyk7IC8vPT4gdHJ1ZVxuICogZmx5ZC5pc1N0cmVhbShuKTsgLy89PiBmYWxzZVxuICovXG5mbHlkLmlzU3RyZWFtID0gZnVuY3Rpb24oc3RyZWFtKSB7XG4gIHJldHVybiBpc0Z1bmN0aW9uKHN0cmVhbSkgJiYgJ2hhc1ZhbCcgaW4gc3RyZWFtO1xufVxuXG4vKipcbiAqIEludm9rZXMgdGhlIGJvZHkgKHRoZSBmdW5jdGlvbiB0byBjYWxjdWxhdGUgdGhlIHZhbHVlKSBvZiBhIGRlcGVuZGVudCBzdHJlYW1cbiAqXG4gKiBCeSBkZWZhdWx0IHRoZSBib2R5IG9mIGEgZGVwZW5kZW50IHN0cmVhbSBpcyBvbmx5IGNhbGxlZCB3aGVuIGFsbCB0aGUgc3RyZWFtc1xuICogdXBvbiB3aGljaCBpdCBkZXBlbmRzIGhhcyBhIHZhbHVlLiBgaW1tZWRpYXRlYCBjYW4gY2lyY3VtdmVudCB0aGlzIGJlaGF2aW91ci5cbiAqIEl0IGltbWVkaWF0ZWx5IGludm9rZXMgdGhlIGJvZHkgb2YgYSBkZXBlbmRlbnQgc3RyZWFtLlxuICpcbiAqIF9fU2lnbmF0dXJlX186IGBTdHJlYW0gYSAtPiBTdHJlYW0gYWBcbiAqXG4gKiBAbmFtZSBmbHlkLmltbWVkaWF0ZVxuICogQHBhcmFtIHtzdHJlYW19IHN0cmVhbSAtIHRoZSBkZXBlbmRlbnQgc3RyZWFtXG4gKiBAcmV0dXJuIHtzdHJlYW19IHRoZSBzYW1lIHN0cmVhbVxuICpcbiAqIEBleGFtcGxlXG4gKiB2YXIgcyA9IGZseWQuc3RyZWFtKCk7XG4gKiB2YXIgaGFzSXRlbXMgPSBmbHlkLmltbWVkaWF0ZShmbHlkLmNvbWJpbmUoZnVuY3Rpb24ocykge1xuICogICByZXR1cm4gcygpICE9PSB1bmRlZmluZWQgJiYgcygpLmxlbmd0aCA+IDA7XG4gKiB9LCBbc10pO1xuICogY29uc29sZS5sb2coaGFzSXRlbXMoKSk7IC8vIGxvZ3MgYGZhbHNlYC4gSGFkIGBpbW1lZGlhdGVgIG5vdCBiZWVuXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdXNlZCBgaGFzSXRlbXMoKWAgd291bGQndmUgcmV0dXJuZWQgYHVuZGVmaW5lZGBcbiAqIHMoWzFdKTtcbiAqIGNvbnNvbGUubG9nKGhhc0l0ZW1zKCkpOyAvLyBsb2dzIGB0cnVlYC5cbiAqIHMoW10pO1xuICogY29uc29sZS5sb2coaGFzSXRlbXMoKSk7IC8vIGxvZ3MgYGZhbHNlYC5cbiAqL1xuZmx5ZC5pbW1lZGlhdGUgPSBmdW5jdGlvbihzKSB7XG4gIGlmIChzLmRlcHNNZXQgPT09IGZhbHNlKSB7XG4gICAgcy5kZXBzTWV0ID0gdHJ1ZTtcbiAgICB1cGRhdGVTdHJlYW0ocyk7XG4gIH1cbiAgcmV0dXJuIHM7XG59XG5cbi8qKlxuICogQ2hhbmdlcyB3aGljaCBgZW5kc1N0cmVhbWAgc2hvdWxkIHRyaWdnZXIgdGhlIGVuZGluZyBvZiBgc2AuXG4gKlxuICogX19TaWduYXR1cmVfXzogYFN0cmVhbSBhIC0+IFN0cmVhbSBiIC0+IFN0cmVhbSBiYFxuICpcbiAqIEBuYW1lIGZseWQuZW5kc09uXG4gKiBAcGFyYW0ge3N0cmVhbX0gZW5kU3RyZWFtIC0gdGhlIHN0cmVhbSB0byB0cmlnZ2VyIHRoZSBlbmRpbmdcbiAqIEBwYXJhbSB7c3RyZWFtfSBzdHJlYW0gLSB0aGUgc3RyZWFtIHRvIGJlIGVuZGVkIGJ5IHRoZSBlbmRTdHJlYW1cbiAqIEBwYXJhbSB7c3RyZWFtfSB0aGUgc3RyZWFtIG1vZGlmaWVkIHRvIGJlIGVuZGVkIGJ5IGVuZFN0cmVhbVxuICpcbiAqIEBleGFtcGxlXG4gKiB2YXIgbiA9IGZseWQuc3RyZWFtKDEpO1xuICogdmFyIGtpbGxlciA9IGZseWQuc3RyZWFtKCk7XG4gKiAvLyBgZG91YmxlYCBlbmRzIHdoZW4gYG5gIGVuZHMgb3Igd2hlbiBga2lsbGVyYCBlbWl0cyBhbnkgdmFsdWVcbiAqIHZhciBkb3VibGUgPSBmbHlkLmVuZHNPbihmbHlkLm1lcmdlKG4uZW5kLCBraWxsZXIpLCBmbHlkLmNvbWJpbmUoZnVuY3Rpb24obikge1xuICogICByZXR1cm4gMiAqIG4oKTtcbiAqIH0sIFtuXSk7XG4qL1xuZmx5ZC5lbmRzT24gPSBmdW5jdGlvbihlbmRTLCBzKSB7XG4gIGRldGFjaERlcHMocy5lbmQpO1xuICBlbmRTLmxpc3RlbmVycy5wdXNoKHMuZW5kKTtcbiAgcy5lbmQuZGVwcy5wdXNoKGVuZFMpO1xuICByZXR1cm4gcztcbn1cblxuLyoqXG4gKiBNYXAgYSBzdHJlYW1cbiAqXG4gKiBSZXR1cm5zIGEgbmV3IHN0cmVhbSBjb25zaXN0aW5nIG9mIGV2ZXJ5IHZhbHVlIGZyb20gYHNgIHBhc3NlZCB0aHJvdWdoXG4gKiBgZm5gLiBJLmUuIGBtYXBgIGNyZWF0ZXMgYSBuZXcgc3RyZWFtIHRoYXQgbGlzdGVucyB0byBgc2AgYW5kXG4gKiBhcHBsaWVzIGBmbmAgdG8gZXZlcnkgbmV3IHZhbHVlLlxuICogX19TaWduYXR1cmVfXzogYChhIC0+IHJlc3VsdCkgLT4gU3RyZWFtIGEgLT4gU3RyZWFtIHJlc3VsdGBcbiAqXG4gKiBAbmFtZSBmbHlkLm1hcFxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm4gLSB0aGUgZnVuY3Rpb24gdGhhdCBwcm9kdWNlcyB0aGUgZWxlbWVudHMgb2YgdGhlIG5ldyBzdHJlYW1cbiAqIEBwYXJhbSB7c3RyZWFtfSBzdHJlYW0gLSB0aGUgc3RyZWFtIHRvIG1hcFxuICogQHJldHVybiB7c3RyZWFtfSBhIG5ldyBzdHJlYW0gd2l0aCB0aGUgbWFwcGVkIHZhbHVlc1xuICpcbiAqIEBleGFtcGxlXG4gKiB2YXIgbnVtYmVycyA9IGZseWQuc3RyZWFtKDApO1xuICogdmFyIHNxdWFyZWROdW1iZXJzID0gZmx5ZC5tYXAoZnVuY3Rpb24obikgeyByZXR1cm4gbipuOyB9LCBudW1iZXJzKTtcbiAqL1xuLy8gTGlicmFyeSBmdW5jdGlvbnMgdXNlIHNlbGYgY2FsbGJhY2sgdG8gYWNjZXB0IChudWxsLCB1bmRlZmluZWQpIHVwZGF0ZSB0cmlnZ2Vycy5cbmZseWQubWFwID0gY3VycnlOKDIsIGZ1bmN0aW9uKGYsIHMpIHtcbiAgcmV0dXJuIGNvbWJpbmUoZnVuY3Rpb24ocywgc2VsZikgeyBzZWxmKGYocy52YWwpKTsgfSwgW3NdKTtcbn0pXG5cbi8qKlxuICogTGlzdGVuIHRvIHN0cmVhbSBldmVudHNcbiAqXG4gKiBTaW1pbGFyIHRvIGBtYXBgIGV4Y2VwdCB0aGF0IHRoZSByZXR1cm5lZCBzdHJlYW0gaXMgZW1wdHkuIFVzZSBgb25gIGZvciBkb2luZ1xuICogc2lkZSBlZmZlY3RzIGluIHJlYWN0aW9uIHRvIHN0cmVhbSBjaGFuZ2VzLiBVc2UgdGhlIHJldHVybmVkIHN0cmVhbSBvbmx5IGlmIHlvdVxuICogbmVlZCB0byBtYW51YWxseSBlbmQgaXQuXG4gKlxuICogX19TaWduYXR1cmVfXzogYChhIC0+IHJlc3VsdCkgLT4gU3RyZWFtIGEgLT4gU3RyZWFtIHVuZGVmaW5lZGBcbiAqXG4gKiBAbmFtZSBmbHlkLm9uXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYiAtIHRoZSBjYWxsYmFja1xuICogQHBhcmFtIHtzdHJlYW19IHN0cmVhbSAtIHRoZSBzdHJlYW1cbiAqIEByZXR1cm4ge3N0cmVhbX0gYW4gZW1wdHkgc3RyZWFtIChjYW4gYmUgZW5kZWQpXG4gKi9cbmZseWQub24gPSBjdXJyeU4oMiwgZnVuY3Rpb24oZiwgcykge1xuICByZXR1cm4gY29tYmluZShmdW5jdGlvbihzKSB7IGYocy52YWwpOyB9LCBbc10pO1xufSlcblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IHN0cmVhbSB3aXRoIHRoZSByZXN1bHRzIG9mIGNhbGxpbmcgdGhlIGZ1bmN0aW9uIG9uIGV2ZXJ5IGluY29taW5nXG4gKiBzdHJlYW0gd2l0aCBhbmQgYWNjdW11bGF0b3IgYW5kIHRoZSBpbmNvbWluZyB2YWx1ZS5cbiAqXG4gKiBfX1NpZ25hdHVyZV9fOiBgKGEgLT4gYiAtPiBhKSAtPiBhIC0+IFN0cmVhbSBiIC0+IFN0cmVhbSBhYFxuICpcbiAqIEBuYW1lIGZseWQuc2NhblxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm4gLSB0aGUgZnVuY3Rpb24gdG8gY2FsbFxuICogQHBhcmFtIHsqfSB2YWwgLSB0aGUgaW5pdGlhbCB2YWx1ZSBvZiB0aGUgYWNjdW11bGF0b3JcbiAqIEBwYXJhbSB7c3RyZWFtfSBzdHJlYW0gLSB0aGUgc3RyZWFtIHNvdXJjZVxuICogQHJldHVybiB7c3RyZWFtfSB0aGUgbmV3IHN0cmVhbVxuICpcbiAqIEBleGFtcGxlXG4gKiB2YXIgbnVtYmVycyA9IGZseWQuc3RyZWFtKCk7XG4gKiB2YXIgc3VtID0gZmx5ZC5zY2FuKGZ1bmN0aW9uKHN1bSwgbikgeyByZXR1cm4gc3VtK247IH0sIDAsIG51bWJlcnMpO1xuICogbnVtYmVycygyKSgzKSg1KTtcbiAqIHN1bSgpOyAvLyAxMFxuICovXG5mbHlkLnNjYW4gPSBjdXJyeU4oMywgZnVuY3Rpb24oZiwgYWNjLCBzKSB7XG4gIHZhciBucyA9IGNvbWJpbmUoZnVuY3Rpb24ocywgc2VsZikge1xuICAgIHNlbGYoYWNjID0gZihhY2MsIHMudmFsKSk7XG4gIH0sIFtzXSk7XG4gIGlmICghbnMuaGFzVmFsKSBucyhhY2MpO1xuICByZXR1cm4gbnM7XG59KTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IHN0cmVhbSBkb3duIHdoaWNoIGFsbCB2YWx1ZXMgZnJvbSBib3RoIGBzdHJlYW0xYCBhbmQgYHN0cmVhbTJgXG4gKiB3aWxsIGJlIHNlbnQuXG4gKlxuICogX19TaWduYXR1cmVfXzogYFN0cmVhbSBhIC0+IFN0cmVhbSBhIC0+IFN0cmVhbSBhYFxuICpcbiAqIEBuYW1lIGZseWQubWVyZ2VcbiAqIEBwYXJhbSB7c3RyZWFtfSBzb3VyY2UxIC0gb25lIHN0cmVhbSB0byBiZSBtZXJnZWRcbiAqIEBwYXJhbSB7c3RyZWFtfSBzb3VyY2UyIC0gdGhlIG90aGVyIHN0cmVhbSB0byBiZSBtZXJnZWRcbiAqIEByZXR1cm4ge3N0cmVhbX0gYSBzdHJlYW0gd2l0aCB0aGUgdmFsdWVzIGZyb20gYm90aCBzb3VyY2VzXG4gKlxuICogQGV4YW1wbGVcbiAqIHZhciBidG4xQ2xpY2tzID0gZmx5ZC5zdHJlYW0oKTtcbiAqIGJ1dHRvbjFFbG0uYWRkRXZlbnRMaXN0ZW5lcihidG4xQ2xpY2tzKTtcbiAqIHZhciBidG4yQ2xpY2tzID0gZmx5ZC5zdHJlYW0oKTtcbiAqIGJ1dHRvbjJFbG0uYWRkRXZlbnRMaXN0ZW5lcihidG4yQ2xpY2tzKTtcbiAqIHZhciBhbGxDbGlja3MgPSBmbHlkLm1lcmdlKGJ0bjFDbGlja3MsIGJ0bjJDbGlja3MpO1xuICovXG5mbHlkLm1lcmdlID0gY3VycnlOKDIsIGZ1bmN0aW9uKHMxLCBzMikge1xuICB2YXIgcyA9IGZseWQuaW1tZWRpYXRlKGNvbWJpbmUoZnVuY3Rpb24oczEsIHMyLCBzZWxmLCBjaGFuZ2VkKSB7XG4gICAgaWYgKGNoYW5nZWRbMF0pIHtcbiAgICAgIHNlbGYoY2hhbmdlZFswXSgpKTtcbiAgICB9IGVsc2UgaWYgKHMxLmhhc1ZhbCkge1xuICAgICAgc2VsZihzMS52YWwpO1xuICAgIH0gZWxzZSBpZiAoczIuaGFzVmFsKSB7XG4gICAgICBzZWxmKHMyLnZhbCk7XG4gICAgfVxuICB9LCBbczEsIHMyXSkpO1xuICBmbHlkLmVuZHNPbihjb21iaW5lKGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0cnVlO1xuICB9LCBbczEuZW5kLCBzMi5lbmRdKSwgcyk7XG4gIHJldHVybiBzO1xufSk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIG5ldyBzdHJlYW0gcmVzdWx0aW5nIGZyb20gYXBwbHlpbmcgYHRyYW5zZHVjZXJgIHRvIGBzdHJlYW1gLlxuICpcbiAqIF9fU2lnbmF0dXJlX186IGBUcmFuc2R1Y2VyIC0+IFN0cmVhbSBhIC0+IFN0cmVhbSBiYFxuICpcbiAqIEBuYW1lIGZseWQudHJhbnNkdWNlXG4gKiBAcGFyYW0ge1RyYW5zZHVjZXJ9IHhmb3JtIC0gdGhlIHRyYW5zZHVjZXIgdHJhbnNmb3JtYXRpb25cbiAqIEBwYXJhbSB7c3RyZWFtfSBzb3VyY2UgLSB0aGUgc3RyZWFtIHNvdXJjZVxuICogQHJldHVybiB7c3RyZWFtfSB0aGUgbmV3IHN0cmVhbVxuICpcbiAqIEBleGFtcGxlXG4gKiB2YXIgdCA9IHJlcXVpcmUoJ3RyYW5zZHVjZXJzLmpzJyk7XG4gKlxuICogdmFyIHJlc3VsdHMgPSBbXTtcbiAqIHZhciBzMSA9IGZseWQuc3RyZWFtKCk7XG4gKiB2YXIgdHggPSB0LmNvbXBvc2UodC5tYXAoZnVuY3Rpb24oeCkgeyByZXR1cm4geCAqIDI7IH0pLCB0LmRlZHVwZSgpKTtcbiAqIHZhciBzMiA9IGZseWQudHJhbnNkdWNlKHR4LCBzMSk7XG4gKiBmbHlkLmNvbWJpbmUoZnVuY3Rpb24oczIpIHsgcmVzdWx0cy5wdXNoKHMyKCkpOyB9LCBbczJdKTtcbiAqIHMxKDEpKDEpKDIpKDMpKDMpKDMpKDQpO1xuICogcmVzdWx0czsgLy8gPT4gWzIsIDQsIDYsIDhdXG4gKi9cbmZseWQudHJhbnNkdWNlID0gY3VycnlOKDIsIGZ1bmN0aW9uKHhmb3JtLCBzb3VyY2UpIHtcbiAgeGZvcm0gPSB4Zm9ybShuZXcgU3RyZWFtVHJhbnNmb3JtZXIoKSk7XG4gIHJldHVybiBjb21iaW5lKGZ1bmN0aW9uKHNvdXJjZSwgc2VsZikge1xuICAgIHZhciByZXMgPSB4Zm9ybVsnQEB0cmFuc2R1Y2VyL3N0ZXAnXSh1bmRlZmluZWQsIHNvdXJjZS52YWwpO1xuICAgIGlmIChyZXMgJiYgcmVzWydAQHRyYW5zZHVjZXIvcmVkdWNlZCddID09PSB0cnVlKSB7XG4gICAgICBzZWxmLmVuZCh0cnVlKTtcbiAgICAgIHJldHVybiByZXNbJ0BAdHJhbnNkdWNlci92YWx1ZSddO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gcmVzO1xuICAgIH1cbiAgfSwgW3NvdXJjZV0pO1xufSk7XG5cbi8qKlxuICogUmV0dXJucyBgZm5gIGN1cnJpZWQgdG8gYG5gLiBVc2UgdGhpcyBmdW5jdGlvbiB0byBjdXJyeSBmdW5jdGlvbnMgZXhwb3NlZCBieVxuICogbW9kdWxlcyBmb3IgRmx5ZC5cbiAqXG4gKiBAbmFtZSBmbHlkLmN1cnJ5TlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge0ludGVnZXJ9IGFyaXR5IC0gdGhlIGZ1bmN0aW9uIGFyaXR5XG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiAtIHRoZSBmdW5jdGlvbiB0byBjdXJyeVxuICogQHJldHVybiB7RnVuY3Rpb259IHRoZSBjdXJyaWVkIGZ1bmN0aW9uXG4gKlxuICogQGV4YW1wbGVcbiAqIGZ1bmN0aW9uIGFkZCh4LCB5KSB7IHJldHVybiB4ICsgeTsgfTtcbiAqIHZhciBhID0gZmx5ZC5jdXJyeU4oMiwgYWRkKTtcbiAqIGEoMikoNCkgLy8gPT4gNlxuICovXG5mbHlkLmN1cnJ5TiA9IGN1cnJ5TlxuXG4vKipcbiAqIFJldHVybnMgYSBuZXcgc3RyZWFtIGlkZW50aWNhbCB0byB0aGUgb3JpZ2luYWwgZXhjZXB0IGV2ZXJ5XG4gKiB2YWx1ZSB3aWxsIGJlIHBhc3NlZCB0aHJvdWdoIGBmYC5cbiAqXG4gKiBfTm90ZTpfIFRoaXMgZnVuY3Rpb24gaXMgaW5jbHVkZWQgaW4gb3JkZXIgdG8gc3VwcG9ydCB0aGUgZmFudGFzeSBsYW5kXG4gKiBzcGVjaWZpY2F0aW9uLlxuICpcbiAqIF9fU2lnbmF0dXJlX186IENhbGxlZCBib3VuZCB0byBgU3RyZWFtIGFgOiBgKGEgLT4gYikgLT4gU3RyZWFtIGJgXG4gKlxuICogQG5hbWUgc3RyZWFtLm1hcFxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuY3Rpb24gLSB0aGUgZnVuY3Rpb24gdG8gYXBwbHlcbiAqIEByZXR1cm4ge3N0cmVhbX0gYSBuZXcgc3RyZWFtIHdpdGggdGhlIHZhbHVlcyBtYXBwZWRcbiAqXG4gKiBAZXhhbXBsZVxuICogdmFyIG51bWJlcnMgPSBmbHlkLnN0cmVhbSgwKTtcbiAqIHZhciBzcXVhcmVkTnVtYmVycyA9IG51bWJlcnMubWFwKGZ1bmN0aW9uKG4pIHsgcmV0dXJuIG4qbjsgfSk7XG4gKi9cbmZ1bmN0aW9uIGJvdW5kTWFwKGYpIHsgcmV0dXJuIGZseWQubWFwKGYsIHRoaXMpOyB9XG5cbi8qKlxuICogUmV0dXJucyBhIG5ldyBzdHJlYW0gd2hpY2ggaXMgdGhlIHJlc3VsdCBvZiBhcHBseWluZyB0aGVcbiAqIGZ1bmN0aW9ucyBmcm9tIGB0aGlzYCBzdHJlYW0gdG8gdGhlIHZhbHVlcyBpbiBgc3RyZWFtYCBwYXJhbWV0ZXIuXG4gKlxuICogYHRoaXNgIHN0cmVhbSBtdXN0IGJlIGEgc3RyZWFtIG9mIGZ1bmN0aW9ucy5cbiAqXG4gKiBfTm90ZTpfIFRoaXMgZnVuY3Rpb24gaXMgaW5jbHVkZWQgaW4gb3JkZXIgdG8gc3VwcG9ydCB0aGUgZmFudGFzeSBsYW5kXG4gKiBzcGVjaWZpY2F0aW9uLlxuICpcbiAqIF9fU2lnbmF0dXJlX186IENhbGxlZCBib3VuZCB0byBgU3RyZWFtIChhIC0+IGIpYDogYGEgLT4gU3RyZWFtIGJgXG4gKlxuICogQG5hbWUgc3RyZWFtLmFwXG4gKiBAcGFyYW0ge3N0cmVhbX0gc3RyZWFtIC0gdGhlIHZhbHVlcyBzdHJlYW1cbiAqIEByZXR1cm4ge3N0cmVhbX0gYSBuZXcgc3RyYW0gd2l0aCB0aGUgZnVuY3Rpb25zIGFwcGxpZWQgdG8gdmFsdWVzXG4gKlxuICogQGV4YW1wbGVcbiAqIHZhciBhZGQgPSBmbHlkLmN1cnJ5TigyLCBmdW5jdGlvbih4LCB5KSB7IHJldHVybiB4ICsgeTsgfSk7XG4gKiB2YXIgbnVtYmVyczEgPSBmbHlkLnN0cmVhbSgpO1xuICogdmFyIG51bWJlcnMyID0gZmx5ZC5zdHJlYW0oKTtcbiAqIHZhciBhZGRUb051bWJlcnMxID0gZmx5ZC5tYXAoYWRkLCBudW1iZXJzMSk7XG4gKiB2YXIgYWRkZWQgPSBhZGRUb051bWJlcnMxLmFwKG51bWJlcnMyKTtcbiAqL1xuZnVuY3Rpb24gYXAoczIpIHtcbiAgdmFyIHMxID0gdGhpcztcbiAgcmV0dXJuIGNvbWJpbmUoZnVuY3Rpb24oczEsIHMyLCBzZWxmKSB7IHNlbGYoczEudmFsKHMyLnZhbCkpOyB9LCBbczEsIHMyXSk7XG59XG5cbi8qKlxuICogR2V0IGEgaHVtYW4gcmVhZGFibGUgdmlldyBvZiBhIHN0cmVhbVxuICogQG5hbWUgc3RyZWFtLnRvU3RyaW5nXG4gKiBAcmV0dXJuIHtTdHJpbmd9IHRoZSBzdHJlYW0gc3RyaW5nIHJlcHJlc2VudGF0aW9uXG4gKi9cbmZ1bmN0aW9uIHN0cmVhbVRvU3RyaW5nKCkge1xuICByZXR1cm4gJ3N0cmVhbSgnICsgdGhpcy52YWwgKyAnKSc7XG59XG5cbi8qKlxuICogQG5hbWUgc3RyZWFtLmVuZFxuICogQG1lbWJlcm9mIHN0cmVhbVxuICogQSBzdHJlYW0gdGhhdCBlbWl0cyBgdHJ1ZWAgd2hlbiB0aGUgc3RyZWFtIGVuZHMuIElmIGB0cnVlYCBpcyBwdXNoZWQgZG93biB0aGVcbiAqIHN0cmVhbSB0aGUgcGFyZW50IHN0cmVhbSBlbmRzLlxuICovXG5cbi8qKlxuICogQG5hbWUgc3RyZWFtLm9mXG4gKiBAZnVuY3Rpb25cbiAqIEBtZW1iZXJvZiBzdHJlYW1cbiAqIFJldHVybnMgYSBuZXcgc3RyZWFtIHdpdGggYHZhbHVlYCBhcyBpdHMgaW5pdGlhbCB2YWx1ZS4gSXQgaXMgaWRlbnRpY2FsIHRvXG4gKiBjYWxsaW5nIGBmbHlkLnN0cmVhbWAgd2l0aCBvbmUgYXJndW1lbnQuXG4gKlxuICogX19TaWduYXR1cmVfXzogQ2FsbGVkIGJvdW5kIHRvIGBTdHJlYW0gKGEpYDogYGIgLT4gU3RyZWFtIGJgXG4gKlxuICogQHBhcmFtIHsqfSB2YWx1ZSAtIHRoZSBpbml0aWFsIHZhbHVlXG4gKiBAcmV0dXJuIHtzdHJlYW19IHRoZSBuZXcgc3RyZWFtXG4gKlxuICogQGV4YW1wbGVcbiAqIHZhciBuID0gZmx5ZC5zdHJlYW0oMSk7XG4gKiB2YXIgbSA9IG4ub2YoMSk7XG4gKi9cblxuLy8gLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vIFBSSVZBVEUgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vIC8vXG4vKipcbiAqIEBwcml2YXRlXG4gKiBDcmVhdGUgYSBzdHJlYW0gd2l0aCBubyBkZXBlbmRlbmNpZXMgYW5kIG5vIHZhbHVlXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gYSBmbHlkIHN0cmVhbVxuICovXG5mdW5jdGlvbiBjcmVhdGVTdHJlYW0oKSB7XG4gIGZ1bmN0aW9uIHMobikge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSByZXR1cm4gcy52YWxcbiAgICB1cGRhdGVTdHJlYW1WYWx1ZShzLCBuKVxuICAgIHJldHVybiBzXG4gIH1cbiAgcy5oYXNWYWwgPSBmYWxzZTtcbiAgcy52YWwgPSB1bmRlZmluZWQ7XG4gIHMudmFscyA9IFtdO1xuICBzLmxpc3RlbmVycyA9IFtdO1xuICBzLnF1ZXVlZCA9IGZhbHNlO1xuICBzLmVuZCA9IHVuZGVmaW5lZDtcbiAgcy5tYXAgPSBib3VuZE1hcDtcbiAgcy5hcCA9IGFwO1xuICBzLm9mID0gZmx5ZC5zdHJlYW07XG4gIHMudG9TdHJpbmcgPSBzdHJlYW1Ub1N0cmluZztcbiAgcmV0dXJuIHM7XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIENyZWF0ZSBhIGRlcGVuZGVudCBzdHJlYW1cbiAqIEBwYXJhbSB7QXJyYXk8c3RyZWFtPn0gZGVwZW5kZW5jaWVzIC0gYW4gYXJyYXkgb2YgdGhlIHN0cmVhbXNcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIC0gdGhlIGZ1bmN0aW9uIHVzZWQgdG8gY2FsY3VsYXRlIHRoZSBuZXcgc3RyZWFtIHZhbHVlXG4gKiBmcm9tIHRoZSBkZXBlbmRlbmNpZXNcbiAqIEByZXR1cm4ge3N0cmVhbX0gdGhlIGNyZWF0ZWQgc3RyZWFtXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZURlcGVuZGVudFN0cmVhbShkZXBzLCBmbikge1xuICB2YXIgcyA9IGNyZWF0ZVN0cmVhbSgpO1xuICBzLmZuID0gZm47XG4gIHMuZGVwcyA9IGRlcHM7XG4gIHMuZGVwc01ldCA9IGZhbHNlO1xuICBzLmRlcHNDaGFuZ2VkID0gZGVwcy5sZW5ndGggPiAwID8gW10gOiB1bmRlZmluZWQ7XG4gIHMuc2hvdWxkVXBkYXRlID0gZmFsc2U7XG4gIGFkZExpc3RlbmVycyhkZXBzLCBzKTtcbiAgcmV0dXJuIHM7XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIENoZWNrIGlmIGFsbCB0aGUgZGVwZW5kZW5jaWVzIGhhdmUgdmFsdWVzXG4gKiBAcGFyYW0ge3N0cmVhbX0gc3RyZWFtIC0gdGhlIHN0cmVhbSB0byBjaGVjayBkZXBlbmNlbmNpZXMgZnJvbVxuICogQHJldHVybiB7Qm9vbGVhbn0gYHRydWVgIGlmIGFsbCBkZXBlbmRlbmNpZXMgaGF2ZSB2YWxlcywgYGZhbHNlYCBvdGhlcndpc2VcbiAqL1xuZnVuY3Rpb24gaW5pdGlhbERlcHNOb3RNZXQoc3RyZWFtKSB7XG4gIHN0cmVhbS5kZXBzTWV0ID0gc3RyZWFtLmRlcHMuZXZlcnkoZnVuY3Rpb24ocykge1xuICAgIHJldHVybiBzLmhhc1ZhbDtcbiAgfSk7XG4gIHJldHVybiAhc3RyZWFtLmRlcHNNZXQ7XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIFVwZGF0ZSBhIGRlcGVuZGVudCBzdHJlYW0gdXNpbmcgaXRzIGRlcGVuZGVuY2llcyBpbiBhbiBhdG9taWMgd2F5XG4gKiBAcGFyYW0ge3N0cmVhbX0gc3RyZWFtIC0gdGhlIHN0cmVhbSB0byB1cGRhdGVcbiAqL1xuZnVuY3Rpb24gdXBkYXRlU3RyZWFtKHMpIHtcbiAgaWYgKChzLmRlcHNNZXQgIT09IHRydWUgJiYgaW5pdGlhbERlcHNOb3RNZXQocykpIHx8XG4gICAgICAocy5lbmQgIT09IHVuZGVmaW5lZCAmJiBzLmVuZC52YWwgPT09IHRydWUpKSByZXR1cm47XG4gIGlmIChpblN0cmVhbSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgdG9VcGRhdGUucHVzaChzKTtcbiAgICByZXR1cm47XG4gIH1cbiAgaW5TdHJlYW0gPSBzO1xuICBpZiAocy5kZXBzQ2hhbmdlZCkgcy5mbkFyZ3Nbcy5mbkFyZ3MubGVuZ3RoIC0gMV0gPSBzLmRlcHNDaGFuZ2VkO1xuICB2YXIgcmV0dXJuVmFsID0gcy5mbi5hcHBseShzLmZuLCBzLmZuQXJncyk7XG4gIGlmIChyZXR1cm5WYWwgIT09IHVuZGVmaW5lZCkge1xuICAgIHMocmV0dXJuVmFsKTtcbiAgfVxuICBpblN0cmVhbSA9IHVuZGVmaW5lZDtcbiAgaWYgKHMuZGVwc0NoYW5nZWQgIT09IHVuZGVmaW5lZCkgcy5kZXBzQ2hhbmdlZCA9IFtdO1xuICBzLnNob3VsZFVwZGF0ZSA9IGZhbHNlO1xuICBpZiAoZmx1c2hpbmcgPT09IGZhbHNlKSBmbHVzaFVwZGF0ZSgpO1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBVcGRhdGUgdGhlIGRlcGVuZGVuY2llcyBvZiBhIHN0cmVhbVxuICogQHBhcmFtIHtzdHJlYW19IHN0cmVhbVxuICovXG5mdW5jdGlvbiB1cGRhdGVEZXBzKHMpIHtcbiAgdmFyIGksIG8sIGxpc3RcbiAgdmFyIGxpc3RlbmVycyA9IHMubGlzdGVuZXJzO1xuICBmb3IgKGkgPSAwOyBpIDwgbGlzdGVuZXJzLmxlbmd0aDsgKytpKSB7XG4gICAgbGlzdCA9IGxpc3RlbmVyc1tpXTtcbiAgICBpZiAobGlzdC5lbmQgPT09IHMpIHtcbiAgICAgIGVuZFN0cmVhbShsaXN0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGxpc3QuZGVwc0NoYW5nZWQgIT09IHVuZGVmaW5lZCkgbGlzdC5kZXBzQ2hhbmdlZC5wdXNoKHMpO1xuICAgICAgbGlzdC5zaG91bGRVcGRhdGUgPSB0cnVlO1xuICAgICAgZmluZERlcHMobGlzdCk7XG4gICAgfVxuICB9XG4gIGZvciAoOyBvcmRlck5leHRJZHggPj0gMDsgLS1vcmRlck5leHRJZHgpIHtcbiAgICBvID0gb3JkZXJbb3JkZXJOZXh0SWR4XTtcbiAgICBpZiAoby5zaG91bGRVcGRhdGUgPT09IHRydWUpIHVwZGF0ZVN0cmVhbShvKTtcbiAgICBvLnF1ZXVlZCA9IGZhbHNlO1xuICB9XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEFkZCBzdHJlYW0gZGVwZW5kZW5jaWVzIHRvIHRoZSBnbG9iYWwgYG9yZGVyYCBxdWV1ZS5cbiAqIEBwYXJhbSB7c3RyZWFtfSBzdHJlYW1cbiAqIEBzZWUgdXBkYXRlRGVwc1xuICovXG5mdW5jdGlvbiBmaW5kRGVwcyhzKSB7XG4gIHZhciBpXG4gIHZhciBsaXN0ZW5lcnMgPSBzLmxpc3RlbmVycztcbiAgaWYgKHMucXVldWVkID09PSBmYWxzZSkge1xuICAgIHMucXVldWVkID0gdHJ1ZTtcbiAgICBmb3IgKGkgPSAwOyBpIDwgbGlzdGVuZXJzLmxlbmd0aDsgKytpKSB7XG4gICAgICBmaW5kRGVwcyhsaXN0ZW5lcnNbaV0pO1xuICAgIH1cbiAgICBvcmRlclsrK29yZGVyTmV4dElkeF0gPSBzO1xuICB9XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gZmx1c2hVcGRhdGUoKSB7XG4gIGZsdXNoaW5nID0gdHJ1ZTtcbiAgd2hpbGUgKHRvVXBkYXRlLmxlbmd0aCA+IDApIHtcbiAgICB2YXIgcyA9IHRvVXBkYXRlLnNoaWZ0KCk7XG4gICAgaWYgKHMudmFscy5sZW5ndGggPiAwKSBzLnZhbCA9IHMudmFscy5zaGlmdCgpO1xuICAgIHVwZGF0ZURlcHMocyk7XG4gIH1cbiAgZmx1c2hpbmcgPSBmYWxzZTtcbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogUHVzaCBkb3duIGEgdmFsdWUgaW50byBhIHN0cmVhbVxuICogQHBhcmFtIHtzdHJlYW19IHN0cmVhbVxuICogQHBhcmFtIHsqfSB2YWx1ZVxuICovXG5mdW5jdGlvbiB1cGRhdGVTdHJlYW1WYWx1ZShzLCBuKSB7XG4gIGlmIChuICE9PSB1bmRlZmluZWQgJiYgbiAhPT0gbnVsbCAmJiBpc0Z1bmN0aW9uKG4udGhlbikpIHtcbiAgICBuLnRoZW4ocyk7XG4gICAgcmV0dXJuO1xuICB9XG4gIHMudmFsID0gbjtcbiAgcy5oYXNWYWwgPSB0cnVlO1xuICBpZiAoaW5TdHJlYW0gPT09IHVuZGVmaW5lZCkge1xuICAgIGZsdXNoaW5nID0gdHJ1ZTtcbiAgICB1cGRhdGVEZXBzKHMpO1xuICAgIGlmICh0b1VwZGF0ZS5sZW5ndGggPiAwKSBmbHVzaFVwZGF0ZSgpOyBlbHNlIGZsdXNoaW5nID0gZmFsc2U7XG4gIH0gZWxzZSBpZiAoaW5TdHJlYW0gPT09IHMpIHtcbiAgICBtYXJrTGlzdGVuZXJzKHMsIHMubGlzdGVuZXJzKTtcbiAgfSBlbHNlIHtcbiAgICBzLnZhbHMucHVzaChuKTtcbiAgICB0b1VwZGF0ZS5wdXNoKHMpO1xuICB9XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gbWFya0xpc3RlbmVycyhzLCBsaXN0cykge1xuICB2YXIgaSwgbGlzdDtcbiAgZm9yIChpID0gMDsgaSA8IGxpc3RzLmxlbmd0aDsgKytpKSB7XG4gICAgbGlzdCA9IGxpc3RzW2ldO1xuICAgIGlmIChsaXN0LmVuZCAhPT0gcykge1xuICAgICAgaWYgKGxpc3QuZGVwc0NoYW5nZWQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBsaXN0LmRlcHNDaGFuZ2VkLnB1c2gocyk7XG4gICAgICB9XG4gICAgICBsaXN0LnNob3VsZFVwZGF0ZSA9IHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIGVuZFN0cmVhbShsaXN0KTtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQWRkIGRlcGVuZGVuY2llcyB0byBhIHN0cmVhbVxuICogQHBhcmFtIHtBcnJheTxzdHJlYW0+fSBkZXBlbmRlbmNpZXNcbiAqIEBwYXJhbSB7c3RyZWFtfSBzdHJlYW1cbiAqL1xuZnVuY3Rpb24gYWRkTGlzdGVuZXJzKGRlcHMsIHMpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBkZXBzLmxlbmd0aDsgKytpKSB7XG4gICAgZGVwc1tpXS5saXN0ZW5lcnMucHVzaChzKTtcbiAgfVxufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBSZW1vdmVzIGFuIHN0cmVhbSBmcm9tIGEgZGVwZW5kZW5jeSBhcnJheVxuICogQHBhcmFtIHtzdHJlYW19IHN0cmVhbVxuICogQHBhcmFtIHtBcnJheTxzdHJlYW0+fSBkZXBlbmRlbmNpZXNcbiAqL1xuZnVuY3Rpb24gcmVtb3ZlTGlzdGVuZXIocywgbGlzdGVuZXJzKSB7XG4gIHZhciBpZHggPSBsaXN0ZW5lcnMuaW5kZXhPZihzKTtcbiAgbGlzdGVuZXJzW2lkeF0gPSBsaXN0ZW5lcnNbbGlzdGVuZXJzLmxlbmd0aCAtIDFdO1xuICBsaXN0ZW5lcnMubGVuZ3RoLS07XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIERldGFjaCBhIHN0cmVhbSBmcm9tIGl0cyBkZXBlbmRlbmNpZXNcbiAqIEBwYXJhbSB7c3RyZWFtfSBzdHJlYW1cbiAqL1xuZnVuY3Rpb24gZGV0YWNoRGVwcyhzKSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcy5kZXBzLmxlbmd0aDsgKytpKSB7XG4gICAgcmVtb3ZlTGlzdGVuZXIocywgcy5kZXBzW2ldLmxpc3RlbmVycyk7XG4gIH1cbiAgcy5kZXBzLmxlbmd0aCA9IDA7XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEVuZHMgYSBzdHJlYW1cbiAqL1xuZnVuY3Rpb24gZW5kU3RyZWFtKHMpIHtcbiAgaWYgKHMuZGVwcyAhPT0gdW5kZWZpbmVkKSBkZXRhY2hEZXBzKHMpO1xuICBpZiAocy5lbmQgIT09IHVuZGVmaW5lZCkgZGV0YWNoRGVwcyhzLmVuZCk7XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIHRyYW5zZHVjZXIgc3RyZWFtIHRyYW5zZm9ybWVyXG4gKi9cbmZ1bmN0aW9uIFN0cmVhbVRyYW5zZm9ybWVyKCkgeyB9XG5TdHJlYW1UcmFuc2Zvcm1lci5wcm90b3R5cGVbJ0BAdHJhbnNkdWNlci9pbml0J10gPSBmdW5jdGlvbigpIHsgfTtcblN0cmVhbVRyYW5zZm9ybWVyLnByb3RvdHlwZVsnQEB0cmFuc2R1Y2VyL3Jlc3VsdCddID0gZnVuY3Rpb24oKSB7IH07XG5TdHJlYW1UcmFuc2Zvcm1lci5wcm90b3R5cGVbJ0BAdHJhbnNkdWNlci9zdGVwJ10gPSBmdW5jdGlvbihzLCB2KSB7IHJldHVybiB2OyB9O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZseWQ7XG4iXX0=
require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
'use strict';
var curryN = require('ramda/src/curryN');
// Utility
function isFunction(obj) {
return !!(obj && obj.constructor && obj.call && obj.apply);
}
function trueFn() { return true; }
// Globals
var toUpdate = [];
var inStream;
var order = [];
var orderNextIdx = -1;
var flushing = false;
/** @namespace */
var flyd = {}
// /////////////////////////// API ///////////////////////////////// //
/**
* Creates a new stream
*
* __Signature__: `a -> Stream a`
*
* @name flyd.stream
* @param {*} initialValue - (Optional) the initial value of the stream
* @return {stream} the stream
*
* @example
* var n = flyd.stream(1); // Stream with initial value `1`
* var s = flyd.stream(); // Stream with no initial value
*/
flyd.stream = function(initialValue) {
var endStream = createDependentStream([], trueFn);
var s = createStream();
s.end = endStream;
s.fnArgs = [];
endStream.listeners.push(s);
if (arguments.length > 0) s(initialValue);
return s;
}
/**
* Create a new dependent stream
*
* __Signature__: `(...Stream * -> Stream b -> b) -> [Stream *] -> Stream b`
*
* @name flyd.combine
* @param {Function} fn - the function used to combine the streams
* @param {Array<stream>} dependencies - the streams that this one depends on
* @return {stream} the dependent stream
*
* @example
* var n1 = flyd.stream(0);
* var n2 = flyd.stream(0);
* var max = flyd.combine(function(n1, n2, self, changed) {
* return n1() > n2() ? n1() : n2();
* }, [n1, n2]);
*/
flyd.combine = curryN(2, combine);
function combine(fn, streams) {
var i, s, deps, depEndStreams;
var endStream = createDependentStream([], trueFn);
deps = []; depEndStreams = [];
for (i = 0; i < streams.length; ++i) {
if (streams[i] !== undefined) {
deps.push(streams[i]);
if (streams[i].end !== undefined) depEndStreams.push(streams[i].end);
}
}
s = createDependentStream(deps, fn);
s.depsChanged = [];
s.fnArgs = s.deps.concat([s, s.depsChanged]);
s.end = endStream;
endStream.listeners.push(s);
addListeners(depEndStreams, endStream);
endStream.deps = depEndStreams;
updateStream(s);
return s;
}
/**
* Returns `true` if the supplied argument is a Flyd stream and `false` otherwise.
*
* __Signature__: `* -> Boolean`
*
* @name flyd.isStream
* @param {*} value - the value to test
* @return {Boolean} `true` if is a Flyd streamn, `false` otherwise
*
* @example
* var s = flyd.stream(1);
* var n = 1;
* flyd.isStream(s); //=> true
* flyd.isStream(n); //=> false
*/
flyd.isStream = function(stream) {
return isFunction(stream) && 'hasVal' in stream;
}
/**
* Invokes the body (the function to calculate the value) of a dependent stream
*
* By default the body of a dependent stream is only called when all the streams
* upon which it depends has a value. `immediate` can circumvent this behaviour.
* It immediately invokes the body of a dependent stream.
*
* __Signature__: `Stream a -> Stream a`
*
* @name flyd.immediate
* @param {stream} stream - the dependent stream
* @return {stream} the same stream
*
* @example
* var s = flyd.stream();
* var hasItems = flyd.immediate(flyd.combine(function(s) {
* return s() !== undefined && s().length > 0;
* }, [s]);
* console.log(hasItems()); // logs `false`. Had `immediate` not been
* // used `hasItems()` would've returned `undefined`
* s([1]);
* console.log(hasItems()); // logs `true`.
* s([]);
* console.log(hasItems()); // logs `false`.
*/
flyd.immediate = function(s) {
if (s.depsMet === false) {
s.depsMet = true;
updateStream(s);
}
return s;
}
/**
* Changes which `endsStream` should trigger the ending of `s`.
*
* __Signature__: `Stream a -> Stream b -> Stream b`
*
* @name flyd.endsOn
* @param {stream} endStream - the stream to trigger the ending
* @param {stream} stream - the stream to be ended by the endStream
* @param {stream} the stream modified to be ended by endStream
*
* @example
* var n = flyd.stream(1);
* var killer = flyd.stream();
* // `double` ends when `n` ends or when `killer` emits any value
* var double = flyd.endsOn(flyd.merge(n.end, killer), flyd.combine(function(n) {
* return 2 * n();
* }, [n]);
*/
flyd.endsOn = function(endS, s) {
detachDeps(s.end);
endS.listeners.push(s.end);
s.end.deps.push(endS);
return s;
}
/**
* Map a stream
*
* Returns a new stream consisting of every value from `s` passed through
* `fn`. I.e. `map` creates a new stream that listens to `s` and
* applies `fn` to every new value.
* __Signature__: `(a -> result) -> Stream a -> Stream result`
*
* @name flyd.map
* @param {Function} fn - the function that produces the elements of the new stream
* @param {stream} stream - the stream to map
* @return {stream} a new stream with the mapped values
*
* @example
* var numbers = flyd.stream(0);
* var squaredNumbers = flyd.map(function(n) { return n*n; }, numbers);
*/
// Library functions use self callback to accept (null, undefined) update triggers.
flyd.map = curryN(2, function(f, s) {
return combine(function(s, self) { self(f(s.val)); }, [s]);
})
/**
* Listen to stream events
*
* Similar to `map` except that the returned stream is empty. Use `on` for doing
* side effects in reaction to stream changes. Use the returned stream only if you
* need to manually end it.
*
* __Signature__: `(a -> result) -> Stream a -> Stream undefined`
*
* @name flyd.on
* @param {Function} cb - the callback
* @param {stream} stream - the stream
* @return {stream} an empty stream (can be ended)
*/
flyd.on = curryN(2, function(f, s) {
return combine(function(s) { f(s.val); }, [s]);
})
/**
* Creates a new stream with the results of calling the function on every incoming
* stream with and accumulator and the incoming value.
*
* __Signature__: `(a -> b -> a) -> a -> Stream b -> Stream a`
*
* @name flyd.scan
* @param {Function} fn - the function to call
* @param {*} val - the initial value of the accumulator
* @param {stream} stream - the stream source
* @return {stream} the new stream
*
* @example
* var numbers = flyd.stream();
* var sum = flyd.scan(function(sum, n) { return sum+n; }, 0, numbers);
* numbers(2)(3)(5);
* sum(); // 10
*/
flyd.scan = curryN(3, function(f, acc, s) {
var ns = combine(function(s, self) {
self(acc = f(acc, s.val));
}, [s]);
if (!ns.hasVal) ns(acc);
return ns;
});
/**
* Creates a new stream down which all values from both `stream1` and `stream2`
* will be sent.
*
* __Signature__: `Stream a -> Stream a -> Stream a`
*
* @name flyd.merge
* @param {stream} source1 - one stream to be merged
* @param {stream} source2 - the other stream to be merged
* @return {stream} a stream with the values from both sources
*
* @example
* var btn1Clicks = flyd.stream();
* button1Elm.addEventListener(btn1Clicks);
* var btn2Clicks = flyd.stream();
* button2Elm.addEventListener(btn2Clicks);
* var allClicks = flyd.merge(btn1Clicks, btn2Clicks);
*/
flyd.merge = curryN(2, function(s1, s2) {
var s = flyd.immediate(combine(function(s1, s2, self, changed) {
if (changed[0]) {
self(changed[0]());
} else if (s1.hasVal) {
self(s1.val);
} else if (s2.hasVal) {
self(s2.val);
}
}, [s1, s2]));
flyd.endsOn(combine(function() {
return true;
}, [s1.end, s2.end]), s);
return s;
});
/**
* Creates a new stream resulting from applying `transducer` to `stream`.
*
* __Signature__: `Transducer -> Stream a -> Stream b`
*
* @name flyd.transduce
* @param {Transducer} xform - the transducer transformation
* @param {stream} source - the stream source
* @return {stream} the new stream
*
* @example
* var t = require('transducers.js');
*
* var results = [];
* var s1 = flyd.stream();
* var tx = t.compose(t.map(function(x) { return x * 2; }), t.dedupe());
* var s2 = flyd.transduce(tx, s1);
* flyd.combine(function(s2) { results.push(s2()); }, [s2]);
* s1(1)(1)(2)(3)(3)(3)(4);
* results; // => [2, 4, 6, 8]
*/
flyd.transduce = curryN(2, function(xform, source) {
xform = xform(new StreamTransformer());
return combine(function(source, self) {
var res = xform['@@transducer/step'](undefined, source.val);
if (res && res['@@transducer/reduced'] === true) {
self.end(true);
return res['@@transducer/value'];
} else {
return res;
}
}, [source]);
});
/**
* Returns `fn` curried to `n`. Use this function to curry functions exposed by
* modules for Flyd.
*
* @name flyd.curryN
* @function
* @param {Integer} arity - the function arity
* @param {Function} fn - the function to curry
* @return {Function} the curried function
*
* @example
* function add(x, y) { return x + y; };
* var a = flyd.curryN(2, add);
* a(2)(4) // => 6
*/
flyd.curryN = curryN
/**
* Returns a new stream identical to the original except every
* value will be passed through `f`.
*
* _Note:_ This function is included in order to support the fantasy land
* specification.
*
* __Signature__: Called bound to `Stream a`: `(a -> b) -> Stream b`
*
* @name stream.map
* @param {Function} function - the function to apply
* @return {stream} a new stream with the values mapped
*
* @example
* var numbers = flyd.stream(0);
* var squaredNumbers = numbers.map(function(n) { return n*n; });
*/
function boundMap(f) { return flyd.map(f, this); }
/**
* Returns a new stream which is the result of applying the
* functions from `this` stream to the values in `stream` parameter.
*
* `this` stream must be a stream of functions.
*
* _Note:_ This function is included in order to support the fantasy land
* specification.
*
* __Signature__: Called bound to `Stream (a -> b)`: `a -> Stream b`
*
* @name stream.ap
* @param {stream} stream - the values stream
* @return {stream} a new stram with the functions applied to values
*
* @example
* var add = flyd.curryN(2, function(x, y) { return x + y; });
* var numbers1 = flyd.stream();
* var numbers2 = flyd.stream();
* var addToNumbers1 = flyd.map(add, numbers1);
* var added = addToNumbers1.ap(numbers2);
*/
function ap(s2) {
var s1 = this;
return combine(function(s1, s2, self) { self(s1.val(s2.val)); }, [s1, s2]);
}
/**
* Get a human readable view of a stream
* @name stream.toString
* @return {String} the stream string representation
*/
function streamToString() {
return 'stream(' + this.val + ')';
}
/**
* @name stream.end
* @memberof stream
* A stream that emits `true` when the stream ends. If `true` is pushed down the
* stream the parent stream ends.
*/
/**
* @name stream.of
* @function
* @memberof stream
* Returns a new stream with `value` as its initial value. It is identical to
* calling `flyd.stream` with one argument.
*
* __Signature__: Called bound to `Stream (a)`: `b -> Stream b`
*
* @param {*} value - the initial value
* @return {stream} the new stream
*
* @example
* var n = flyd.stream(1);
* var m = n.of(1);
*/
// /////////////////////////// PRIVATE ///////////////////////////////// //
/**
* @private
* Create a stream with no dependencies and no value
* @return {Function} a flyd stream
*/
function createStream() {
function s(n) {
if (arguments.length === 0) return s.val
updateStreamValue(s, n)
return s
}
s.hasVal = false;
s.val = undefined;
s.vals = [];
s.listeners = [];
s.queued = false;
s.end = undefined;
s.map = boundMap;
s.ap = ap;
s.of = flyd.stream;
s.toString = streamToString;
return s;
}
/**
* @private
* Create a dependent stream
* @param {Array<stream>} dependencies - an array of the streams
* @param {Function} fn - the function used to calculate the new stream value
* from the dependencies
* @return {stream} the created stream
*/
function createDependentStream(deps, fn) {
var s = createStream();
s.fn = fn;
s.deps = deps;
s.depsMet = false;
s.depsChanged = deps.length > 0 ? [] : undefined;
s.shouldUpdate = false;
addListeners(deps, s);
return s;
}
/**
* @private
* Check if all the dependencies have values
* @param {stream} stream - the stream to check depencencies from
* @return {Boolean} `true` if all dependencies have vales, `false` otherwise
*/
function initialDepsNotMet(stream) {
stream.depsMet = stream.deps.every(function(s) {
return s.hasVal;
});
return !stream.depsMet;
}
/**
* @private
* Update a dependent stream using its dependencies in an atomic way
* @param {stream} stream - the stream to update
*/
function updateStream(s) {
if ((s.depsMet !== true && initialDepsNotMet(s)) ||
(s.end !== undefined && s.end.val === true)) return;
if (inStream !== undefined) {
toUpdate.push(s);
return;
}
inStream = s;
if (s.depsChanged) s.fnArgs[s.fnArgs.length - 1] = s.depsChanged;
var returnVal = s.fn.apply(s.fn, s.fnArgs);
if (returnVal !== undefined) {
s(returnVal);
}
inStream = undefined;
if (s.depsChanged !== undefined) s.depsChanged = [];
s.shouldUpdate = false;
if (flushing === false) flushUpdate();
}
/**
* @private
* Update the dependencies of a stream
* @param {stream} stream
*/
function updateDeps(s) {
var i, o, list
var listeners = s.listeners;
for (i = 0; i < listeners.length; ++i) {
list = listeners[i];
if (list.end === s) {
endStream(list);
} else {
if (list.depsChanged !== undefined) list.depsChanged.push(s);
list.shouldUpdate = true;
findDeps(list);
}
}
for (; orderNextIdx >= 0; --orderNextIdx) {
o = order[orderNextIdx];
if (o.shouldUpdate === true) updateStream(o);
o.queued = false;
}
}
/**
* @private
* Add stream dependencies to the global `order` queue.
* @param {stream} stream
* @see updateDeps
*/
function findDeps(s) {
var i
var listeners = s.listeners;
if (s.queued === false) {
s.queued = true;
for (i = 0; i < listeners.length; ++i) {
findDeps(listeners[i]);
}
order[++orderNextIdx] = s;
}
}
/**
* @private
*/
function flushUpdate() {
flushing = true;
while (toUpdate.length > 0) {
var s = toUpdate.shift();
if (s.vals.length > 0) s.val = s.vals.shift();
updateDeps(s);
}
flushing = false;
}
/**
* @private
* Push down a value into a stream
* @param {stream} stream
* @param {*} value
*/
function updateStreamValue(s, n) {
if (n !== undefined && n !== null && isFunction(n.then)) {
n.then(s);
return;
}
s.val = n;
s.hasVal = true;
if (inStream === undefined) {
flushing = true;
updateDeps(s);
if (toUpdate.length > 0) flushUpdate(); else flushing = false;
} else if (inStream === s) {
markListeners(s, s.listeners);
} else {
s.vals.push(n);
toUpdate.push(s);
}
}
/**
* @private
*/
function markListeners(s, lists) {
var i, list;
for (i = 0; i < lists.length; ++i) {
list = lists[i];
if (list.end !== s) {
if (list.depsChanged !== undefined) {
list.depsChanged.push(s);
}
list.shouldUpdate = true;
} else {
endStream(list);
}
}
}
/**
* @private
* Add dependencies to a stream
* @param {Array<stream>} dependencies
* @param {stream} stream
*/
function addListeners(deps, s) {
for (var i = 0; i < deps.length; ++i) {
deps[i].listeners.push(s);
}
}
/**
* @private
* Removes an stream from a dependency array
* @param {stream} stream
* @param {Array<stream>} dependencies
*/
function removeListener(s, listeners) {
var idx = listeners.indexOf(s);
listeners[idx] = listeners[listeners.length - 1];
listeners.length--;
}
/**
* @private
* Detach a stream from its dependencies
* @param {stream} stream
*/
function detachDeps(s) {
for (var i = 0; i < s.deps.length; ++i) {
removeListener(s, s.deps[i].listeners);
}
s.deps.length = 0;
}
/**
* @private
* Ends a stream
*/
function endStream(s) {
if (s.deps !== undefined) detachDeps(s);
if (s.end !== undefined) detachDeps(s.end);
}
/**
* @private
* transducer stream transformer
*/
function StreamTransformer() { }
StreamTransformer.prototype['@@transducer/init'] = function() { };
StreamTransformer.prototype['@@transducer/result'] = function() { };
StreamTransformer.prototype['@@transducer/step'] = function(s, v) { return v; };
module.exports = flyd;
},{"ramda/src/curryN":2}],2:[function(require,module,exports){
var _arity = require('./internal/_arity');
var _curry1 = require('./internal/_curry1');
var _curry2 = require('./internal/_curry2');
var _curryN = require('./internal/_curryN');
/**
* Returns a curried equivalent of the provided function, with the specified
* arity. The curried function has two unusual capabilities. First, its
* arguments needn't be provided one at a time. If `g` is `R.curryN(3, f)`, the
* following are equivalent:
*
* - `g(1)(2)(3)`
* - `g(1)(2, 3)`
* - `g(1, 2)(3)`
* - `g(1, 2, 3)`
*
* Secondly, the special placeholder value `R.__` may be used to specify
* "gaps", allowing partial application of any combination of arguments,
* regardless of their positions. If `g` is as above and `_` is `R.__`, the
* following are equivalent:
*
* - `g(1, 2, 3)`
* - `g(_, 2, 3)(1)`
* - `g(_, _, 3)(1)(2)`
* - `g(_, _, 3)(1, 2)`
* - `g(_, 2)(1)(3)`
* - `g(_, 2)(1, 3)`
* - `g(_, 2)(_, 3)(1)`
*
* @func
* @memberOf R
* @since v0.5.0
* @category Function
* @sig Number -> (* -> a) -> (* -> a)
* @param {Number} length The arity for the returned function.
* @param {Function} fn The function to curry.
* @return {Function} A new, curried function.
* @see R.curry
* @example
*
* var sumArgs = (...args) => R.sum(args);
*
* var curriedAddFourNumbers = R.curryN(4, sumArgs);
* var f = curriedAddFourNumbers(1, 2);
* var g = f(3);
* g(4); //=> 10
*/
module.exports = _curry2(function curryN(length, fn) {
if (length === 1) {
return _curry1(fn);
}
return _arity(length, _curryN(length, [], fn));
});
},{"./internal/_arity":3,"./internal/_curry1":4,"./internal/_curry2":5,"./internal/_curryN":6}],3:[function(require,module,exports){
module.exports = function _arity(n, fn) {
/* eslint-disable no-unused-vars */
switch (n) {
case 0: return function() { return fn.apply(this, arguments); };
case 1: return function(a0) { return fn.apply(this, arguments); };
case 2: return function(a0, a1) { return fn.apply(this, arguments); };
case 3: return function(a0, a1, a2) { return fn.apply(this, arguments); };
case 4: return function(a0, a1, a2, a3) { return fn.apply(this, arguments); };
case 5: return function(a0, a1, a2, a3, a4) { return fn.apply(this, arguments); };
case 6: return function(a0, a1, a2, a3, a4, a5) { return fn.apply(this, arguments); };
case 7: return function(a0, a1, a2, a3, a4, a5, a6) { return fn.apply(this, arguments); };
case 8: return function(a0, a1, a2, a3, a4, a5, a6, a7) { return fn.apply(this, arguments); };
case 9: return function(a0, a1, a2, a3, a4, a5, a6, a7, a8) { return fn.apply(this, arguments); };
case 10: return function(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) { return fn.apply(this, arguments); };
default: throw new Error('First argument to _arity must be a non-negative integer no greater than ten');
}
};
},{}],4:[function(require,module,exports){
var _isPlaceholder = require('./_isPlaceholder');
/**
* Optimized internal one-arity curry function.
*
* @private
* @category Function
* @param {Function} fn The function to curry.
* @return {Function} The curried function.
*/
module.exports = function _curry1(fn) {
return function f1(a) {
if (arguments.length === 0 || _isPlaceholder(a)) {
return f1;
} else {
return fn.apply(this, arguments);
}
};
};
},{"./_isPlaceholder":7}],5:[function(require,module,exports){
var _curry1 = require('./_curry1');
var _isPlaceholder = require('./_isPlaceholder');
/**
* Optimized internal two-arity curry function.
*
* @private
* @category Function
* @param {Function} fn The function to curry.
* @return {Function} The curried function.
*/
module.exports = function _curry2(fn) {
return function f2(a, b) {
switch (arguments.length) {
case 0:
return f2;
case 1:
return _isPlaceholder(a) ? f2
: _curry1(function(_b) { return fn(a, _b); });
default:
return _isPlaceholder(a) && _isPlaceholder(b) ? f2
: _isPlaceholder(a) ? _curry1(function(_a) { return fn(_a, b); })
: _isPlaceholder(b) ? _curry1(function(_b) { return fn(a, _b); })
: fn(a, b);
}
};
};
},{"./_curry1":4,"./_isPlaceholder":7}],6:[function(require,module,exports){
var _arity = require('./_arity');
var _isPlaceholder = require('./_isPlaceholder');
/**
* Internal curryN function.
*
* @private
* @category Function
* @param {Number} length The arity of the curried function.
* @param {Array} received An array of arguments received thus far.
* @param {Function} fn The function to curry.
* @return {Function} The curried function.
*/
module.exports = function _curryN(length, received, fn) {
return function() {
var combined = [];
var argsIdx = 0;
var left = length;
var combinedIdx = 0;
while (combinedIdx < received.length || argsIdx < arguments.length) {
var result;
if (combinedIdx < received.length &&
(!_isPlaceholder(received[combinedIdx]) ||
argsIdx >= arguments.length)) {
result = received[combinedIdx];
} else {
result = arguments[argsIdx];
argsIdx += 1;
}
combined[combinedIdx] = result;
if (!_isPlaceholder(result)) {
left -= 1;
}
combinedIdx += 1;
}
return left <= 0 ? fn.apply(this, combined)
: _arity(left, _curryN(length, combined, fn));
};
};
},{"./_arity":3,"./_isPlaceholder":7}],7:[function(require,module,exports){
module.exports = function _isPlaceholder(a) {
return a != null &&
typeof a === 'object' &&
a['@@functional/placeholder'] === true;
};
},{}],"flyd/module/mergeall":[function(require,module,exports){
var flyd = require('../../lib');
module.exports = function mergeAll(streams) {
var s = flyd.immediate(flyd.combine(function() {
var self = arguments[arguments.length - 2];
if (arguments[arguments.length - 1][0]) {
self(arguments[arguments.length - 1][0]());
return;
}
[].slice.call(arguments, 0, arguments.length - 2)
.some(function(s1) {
if (s1.hasVal) {
self(s1.val);
return true;
}
});
}, streams));
flyd.endsOn(flyd.combine(function() {
return true;
}, streams.map(function(sm) { return sm.end; })), s);
return s;
};
},{"../../lib":1}]},{},[])
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2hvbWUvYWRtaW4vYnJvd3NlcmlmeS1jZG4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXItcGFjay9fcHJlbHVkZS5qcyIsImxpYi9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9yYW1kYS9zcmMvY3VycnlOLmpzIiwibm9kZV9tb2R1bGVzL3JhbWRhL3NyYy9pbnRlcm5hbC9fYXJpdHkuanMiLCJub2RlX21vZHVsZXMvcmFtZGEvc3JjL2ludGVybmFsL19jdXJyeTEuanMiLCJub2RlX21vZHVsZXMvcmFtZGEvc3JjL2ludGVybmFsL19jdXJyeTIuanMiLCJub2RlX21vZHVsZXMvcmFtZGEvc3JjL2ludGVybmFsL19jdXJyeU4uanMiLCJub2RlX21vZHVsZXMvcmFtZGEvc3JjL2ludGVybmFsL19pc1BsYWNlaG9sZGVyLmpzIiwibW9kdWxlL21lcmdlYWxsL2luZGV4LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsIid1c2Ugc3RyaWN0JztcblxudmFyIGN1cnJ5TiA9IHJlcXVpcmUoJ3JhbWRhL3NyYy9jdXJyeU4nKTtcblxuLy8gVXRpbGl0eVxuZnVuY3Rpb24gaXNGdW5jdGlvbihvYmopIHtcbiAgcmV0dXJuICEhKG9iaiAmJiBvYmouY29uc3RydWN0b3IgJiYgb2JqLmNhbGwgJiYgb2JqLmFwcGx5KTtcbn1cbmZ1bmN0aW9uIHRydWVGbigpIHsgcmV0dXJuIHRydWU7IH1cblxuLy8gR2xvYmFsc1xudmFyIHRvVXBkYXRlID0gW107XG52YXIgaW5TdHJlYW07XG52YXIgb3JkZXIgPSBbXTtcbnZhciBvcmRlck5leHRJZHggPSAtMTtcbnZhciBmbHVzaGluZyA9IGZhbHNlO1xuXG4vKiogQG5hbWVzcGFjZSAqL1xudmFyIGZseWQgPSB7fVxuXG4vLyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8gQVBJIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLyAvL1xuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgc3RyZWFtXG4gKlxuICogX19TaWduYXR1cmVfXzogYGEgLT4gU3RyZWFtIGFgXG4gKlxuICogQG5hbWUgZmx5ZC5zdHJlYW1cbiAqIEBwYXJhbSB7Kn0gaW5pdGlhbFZhbHVlIC0gKE9wdGlvbmFsKSB0aGUgaW5pdGlhbCB2YWx1ZSBvZiB0aGUgc3RyZWFtXG4gKiBAcmV0dXJuIHtzdHJlYW19IHRoZSBzdHJlYW1cbiAqXG4gKiBAZXhhbXBsZVxuICogdmFyIG4gPSBmbHlkLnN0cmVhbSgxKTsgLy8gU3RyZWFtIHdpdGggaW5pdGlhbCB2YWx1ZSBgMWBcbiAqIHZhciBzID0gZmx5ZC5zdHJlYW0oKTsgLy8gU3RyZWFtIHdpdGggbm8gaW5pdGlhbCB2YWx1ZVxuICovXG5mbHlkLnN0cmVhbSA9IGZ1bmN0aW9uKGluaXRpYWxWYWx1ZSkge1xuICB2YXIgZW5kU3RyZWFtID0gY3JlYXRlRGVwZW5kZW50U3RyZWFtKFtdLCB0cnVlRm4pO1xuICB2YXIgcyA9IGNyZWF0ZVN0cmVhbSgpO1xuICBzLmVuZCA9IGVuZFN0cmVhbTtcbiAgcy5mbkFyZ3MgPSBbXTtcbiAgZW5kU3RyZWFtLmxpc3RlbmVycy5wdXNoKHMpO1xuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDApIHMoaW5pdGlhbFZhbHVlKTtcbiAgcmV0dXJuIHM7XG59XG5cbi8qKlxuICogQ3JlYXRlIGEgbmV3IGRlcGVuZGVudCBzdHJlYW1cbiAqXG4gKiBfX1NpZ25hdHVyZV9fOiBgKC4uLlN0cmVhbSAqIC0+IFN0cmVhbSBiIC0+IGIpIC0+IFtTdHJlYW0gKl0gLT4gU3RyZWFtIGJgXG4gKlxuICogQG5hbWUgZmx5ZC5jb21iaW5lXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiAtIHRoZSBmdW5jdGlvbiB1c2VkIHRvIGNvbWJpbmUgdGhlIHN0cmVhbXNcbiAqIEBwYXJhbSB7QXJyYXk8c3RyZWFtPn0gZGVwZW5kZW5jaWVzIC0gdGhlIHN0cmVhbXMgdGhhdCB0aGlzIG9uZSBkZXBlbmRzIG9uXG4gKiBAcmV0dXJuIHtzdHJlYW19IHRoZSBkZXBlbmRlbnQgc3RyZWFtXG4gKlxuICogQGV4YW1wbGVcbiAqIHZhciBuMSA9IGZseWQuc3RyZWFtKDApO1xuICogdmFyIG4yID0gZmx5ZC5zdHJlYW0oMCk7XG4gKiB2YXIgbWF4ID0gZmx5ZC5jb21iaW5lKGZ1bmN0aW9uKG4xLCBuMiwgc2VsZiwgY2hhbmdlZCkge1xuICogICByZXR1cm4gbjEoKSA+IG4yKCkgPyBuMSgpIDogbjIoKTtcbiAqIH0sIFtuMSwgbjJdKTtcbiAqL1xuZmx5ZC5jb21iaW5lID0gY3VycnlOKDIsIGNvbWJpbmUpO1xuZnVuY3Rpb24gY29tYmluZShmbiwgc3RyZWFtcykge1xuICB2YXIgaSwgcywgZGVwcywgZGVwRW5kU3RyZWFtcztcbiAgdmFyIGVuZFN0cmVhbSA9IGNyZWF0ZURlcGVuZGVudFN0cmVhbShbXSwgdHJ1ZUZuKTtcbiAgZGVwcyA9IFtdOyBkZXBFbmRTdHJlYW1zID0gW107XG4gIGZvciAoaSA9IDA7IGkgPCBzdHJlYW1zLmxlbmd0aDsgKytpKSB7XG4gICAgaWYgKHN0cmVhbXNbaV0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgZGVwcy5wdXNoKHN0cmVhbXNbaV0pO1xuICAgICAgaWYgKHN0cmVhbXNbaV0uZW5kICE9PSB1bmRlZmluZWQpIGRlcEVuZFN0cmVhbXMucHVzaChzdHJlYW1zW2ldLmVuZCk7XG4gICAgfVxuICB9XG4gIHMgPSBjcmVhdGVEZXBlbmRlbnRTdHJlYW0oZGVwcywgZm4pO1xuICBzLmRlcHNDaGFuZ2VkID0gW107XG4gIHMuZm5BcmdzID0gcy5kZXBzLmNvbmNhdChbcywgcy5kZXBzQ2hhbmdlZF0pO1xuICBzLmVuZCA9IGVuZFN0cmVhbTtcbiAgZW5kU3RyZWFtLmxpc3RlbmVycy5wdXNoKHMpO1xuICBhZGRMaXN0ZW5lcnMoZGVwRW5kU3RyZWFtcywgZW5kU3RyZWFtKTtcbiAgZW5kU3RyZWFtLmRlcHMgPSBkZXBFbmRTdHJlYW1zO1xuICB1cGRhdGVTdHJlYW0ocyk7XG4gIHJldHVybiBzO1xufVxuXG4vKipcbiAqIFJldHVybnMgYHRydWVgIGlmIHRoZSBzdXBwbGllZCBhcmd1bWVudCBpcyBhIEZseWQgc3RyZWFtIGFuZCBgZmFsc2VgIG90aGVyd2lzZS5cbiAqXG4gKiBfX1NpZ25hdHVyZV9fOiBgKiAtPiBCb29sZWFuYFxuICpcbiAqIEBuYW1lIGZseWQuaXNTdHJlYW1cbiAqIEBwYXJhbSB7Kn0gdmFsdWUgLSB0aGUgdmFsdWUgdG8gdGVzdFxuICogQHJldHVybiB7Qm9vbGVhbn0gYHRydWVgIGlmIGlzIGEgRmx5ZCBzdHJlYW1uLCBgZmFsc2VgIG90aGVyd2lzZVxuICpcbiAqIEBleGFtcGxlXG4gKiB2YXIgcyA9IGZseWQuc3RyZWFtKDEpO1xuICogdmFyIG4gPSAxO1xuICogZmx5ZC5pc1N0cmVhbShzKTsgLy89PiB0cnVlXG4gKiBmbHlkLmlzU3RyZWFtKG4pOyAvLz0+IGZhbHNlXG4gKi9cbmZseWQuaXNTdHJlYW0gPSBmdW5jdGlvbihzdHJlYW0pIHtcbiAgcmV0dXJuIGlzRnVuY3Rpb24oc3RyZWFtKSAmJiAnaGFzVmFsJyBpbiBzdHJlYW07XG59XG5cbi8qKlxuICogSW52b2tlcyB0aGUgYm9keSAodGhlIGZ1bmN0aW9uIHRvIGNhbGN1bGF0ZSB0aGUgdmFsdWUpIG9mIGEgZGVwZW5kZW50IHN0cmVhbVxuICpcbiAqIEJ5IGRlZmF1bHQgdGhlIGJvZHkgb2YgYSBkZXBlbmRlbnQgc3RyZWFtIGlzIG9ubHkgY2FsbGVkIHdoZW4gYWxsIHRoZSBzdHJlYW1zXG4gKiB1cG9uIHdoaWNoIGl0IGRlcGVuZHMgaGFzIGEgdmFsdWUuIGBpbW1lZGlhdGVgIGNhbiBjaXJjdW12ZW50IHRoaXMgYmVoYXZpb3VyLlxuICogSXQgaW1tZWRpYXRlbHkgaW52b2tlcyB0aGUgYm9keSBvZiBhIGRlcGVuZGVudCBzdHJlYW0uXG4gKlxuICogX19TaWduYXR1cmVfXzogYFN0cmVhbSBhIC0+IFN0cmVhbSBhYFxuICpcbiAqIEBuYW1lIGZseWQuaW1tZWRpYXRlXG4gKiBAcGFyYW0ge3N0cmVhbX0gc3RyZWFtIC0gdGhlIGRlcGVuZGVudCBzdHJlYW1cbiAqIEByZXR1cm4ge3N0cmVhbX0gdGhlIHNhbWUgc3RyZWFtXG4gKlxuICogQGV4YW1wbGVcbiAqIHZhciBzID0gZmx5ZC5zdHJlYW0oKTtcbiAqIHZhciBoYXNJdGVtcyA9IGZseWQuaW1tZWRpYXRlKGZseWQuY29tYmluZShmdW5jdGlvbihzKSB7XG4gKiAgIHJldHVybiBzKCkgIT09IHVuZGVmaW5lZCAmJiBzKCkubGVuZ3RoID4gMDtcbiAqIH0sIFtzXSk7XG4gKiBjb25zb2xlLmxvZyhoYXNJdGVtcygpKTsgLy8gbG9ncyBgZmFsc2VgLiBIYWQgYGltbWVkaWF0ZWAgbm90IGJlZW5cbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB1c2VkIGBoYXNJdGVtcygpYCB3b3VsZCd2ZSByZXR1cm5lZCBgdW5kZWZpbmVkYFxuICogcyhbMV0pO1xuICogY29uc29sZS5sb2coaGFzSXRlbXMoKSk7IC8vIGxvZ3MgYHRydWVgLlxuICogcyhbXSk7XG4gKiBjb25zb2xlLmxvZyhoYXNJdGVtcygpKTsgLy8gbG9ncyBgZmFsc2VgLlxuICovXG5mbHlkLmltbWVkaWF0ZSA9IGZ1bmN0aW9uKHMpIHtcbiAgaWYgKHMuZGVwc01ldCA9PT0gZmFsc2UpIHtcbiAgICBzLmRlcHNNZXQgPSB0cnVlO1xuICAgIHVwZGF0ZVN0cmVhbShzKTtcbiAgfVxuICByZXR1cm4gcztcbn1cblxuLyoqXG4gKiBDaGFuZ2VzIHdoaWNoIGBlbmRzU3RyZWFtYCBzaG91bGQgdHJpZ2dlciB0aGUgZW5kaW5nIG9mIGBzYC5cbiAqXG4gKiBfX1NpZ25hdHVyZV9fOiBgU3RyZWFtIGEgLT4gU3RyZWFtIGIgLT4gU3RyZWFtIGJgXG4gKlxuICogQG5hbWUgZmx5ZC5lbmRzT25cbiAqIEBwYXJhbSB7c3RyZWFtfSBlbmRTdHJlYW0gLSB0aGUgc3RyZWFtIHRvIHRyaWdnZXIgdGhlIGVuZGluZ1xuICogQHBhcmFtIHtzdHJlYW19IHN0cmVhbSAtIHRoZSBzdHJlYW0gdG8gYmUgZW5kZWQgYnkgdGhlIGVuZFN0cmVhbVxuICogQHBhcmFtIHtzdHJlYW19IHRoZSBzdHJlYW0gbW9kaWZpZWQgdG8gYmUgZW5kZWQgYnkgZW5kU3RyZWFtXG4gKlxuICogQGV4YW1wbGVcbiAqIHZhciBuID0gZmx5ZC5zdHJlYW0oMSk7XG4gKiB2YXIga2lsbGVyID0gZmx5ZC5zdHJlYW0oKTtcbiAqIC8vIGBkb3VibGVgIGVuZHMgd2hlbiBgbmAgZW5kcyBvciB3aGVuIGBraWxsZXJgIGVtaXRzIGFueSB2YWx1ZVxuICogdmFyIGRvdWJsZSA9IGZseWQuZW5kc09uKGZseWQubWVyZ2Uobi5lbmQsIGtpbGxlciksIGZseWQuY29tYmluZShmdW5jdGlvbihuKSB7XG4gKiAgIHJldHVybiAyICogbigpO1xuICogfSwgW25dKTtcbiovXG5mbHlkLmVuZHNPbiA9IGZ1bmN0aW9uKGVuZFMsIHMpIHtcbiAgZGV0YWNoRGVwcyhzLmVuZCk7XG4gIGVuZFMubGlzdGVuZXJzLnB1c2gocy5lbmQpO1xuICBzLmVuZC5kZXBzLnB1c2goZW5kUyk7XG4gIHJldHVybiBzO1xufVxuXG4vKipcbiAqIE1hcCBhIHN0cmVhbVxuICpcbiAqIFJldHVybnMgYSBuZXcgc3RyZWFtIGNvbnNpc3Rpbmcgb2YgZXZlcnkgdmFsdWUgZnJvbSBgc2AgcGFzc2VkIHRocm91Z2hcbiAqIGBmbmAuIEkuZS4gYG1hcGAgY3JlYXRlcyBhIG5ldyBzdHJlYW0gdGhhdCBsaXN0ZW5zIHRvIGBzYCBhbmRcbiAqIGFwcGxpZXMgYGZuYCB0byBldmVyeSBuZXcgdmFsdWUuXG4gKiBfX1NpZ25hdHVyZV9fOiBgKGEgLT4gcmVzdWx0KSAtPiBTdHJlYW0gYSAtPiBTdHJlYW0gcmVzdWx0YFxuICpcbiAqIEBuYW1lIGZseWQubWFwXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiAtIHRoZSBmdW5jdGlvbiB0aGF0IHByb2R1Y2VzIHRoZSBlbGVtZW50cyBvZiB0aGUgbmV3IHN0cmVhbVxuICogQHBhcmFtIHtzdHJlYW19IHN0cmVhbSAtIHRoZSBzdHJlYW0gdG8gbWFwXG4gKiBAcmV0dXJuIHtzdHJlYW19IGEgbmV3IHN0cmVhbSB3aXRoIHRoZSBtYXBwZWQgdmFsdWVzXG4gKlxuICogQGV4YW1wbGVcbiAqIHZhciBudW1iZXJzID0gZmx5ZC5zdHJlYW0oMCk7XG4gKiB2YXIgc3F1YXJlZE51bWJlcnMgPSBmbHlkLm1hcChmdW5jdGlvbihuKSB7IHJldHVybiBuKm47IH0sIG51bWJlcnMpO1xuICovXG4vLyBMaWJyYXJ5IGZ1bmN0aW9ucyB1c2Ugc2VsZiBjYWxsYmFjayB0byBhY2NlcHQgKG51bGwsIHVuZGVmaW5lZCkgdXBkYXRlIHRyaWdnZXJzLlxuZmx5ZC5tYXAgPSBjdXJyeU4oMiwgZnVuY3Rpb24oZiwgcykge1xuICByZXR1cm4gY29tYmluZShmdW5jdGlvbihzLCBzZWxmKSB7IHNlbGYoZihzLnZhbCkpOyB9LCBbc10pO1xufSlcblxuLyoqXG4gKiBMaXN0ZW4gdG8gc3RyZWFtIGV2ZW50c1xuICpcbiAqIFNpbWlsYXIgdG8gYG1hcGAgZXhjZXB0IHRoYXQgdGhlIHJldHVybmVkIHN0cmVhbSBpcyBlbXB0eS4gVXNlIGBvbmAgZm9yIGRvaW5nXG4gKiBzaWRlIGVmZmVjdHMgaW4gcmVhY3Rpb24gdG8gc3RyZWFtIGNoYW5nZXMuIFVzZSB0aGUgcmV0dXJuZWQgc3RyZWFtIG9ubHkgaWYgeW91XG4gKiBuZWVkIHRvIG1hbnVhbGx5IGVuZCBpdC5cbiAqXG4gKiBfX1NpZ25hdHVyZV9fOiBgKGEgLT4gcmVzdWx0KSAtPiBTdHJlYW0gYSAtPiBTdHJlYW0gdW5kZWZpbmVkYFxuICpcbiAqIEBuYW1lIGZseWQub25cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNiIC0gdGhlIGNhbGxiYWNrXG4gKiBAcGFyYW0ge3N0cmVhbX0gc3RyZWFtIC0gdGhlIHN0cmVhbVxuICogQHJldHVybiB7c3RyZWFtfSBhbiBlbXB0eSBzdHJlYW0gKGNhbiBiZSBlbmRlZClcbiAqL1xuZmx5ZC5vbiA9IGN1cnJ5TigyLCBmdW5jdGlvbihmLCBzKSB7XG4gIHJldHVybiBjb21iaW5lKGZ1bmN0aW9uKHMpIHsgZihzLnZhbCk7IH0sIFtzXSk7XG59KVxuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgc3RyZWFtIHdpdGggdGhlIHJlc3VsdHMgb2YgY2FsbGluZyB0aGUgZnVuY3Rpb24gb24gZXZlcnkgaW5jb21pbmdcbiAqIHN0cmVhbSB3aXRoIGFuZCBhY2N1bXVsYXRvciBhbmQgdGhlIGluY29taW5nIHZhbHVlLlxuICpcbiAqIF9fU2lnbmF0dXJlX186IGAoYSAtPiBiIC0+IGEpIC0+IGEgLT4gU3RyZWFtIGIgLT4gU3RyZWFtIGFgXG4gKlxuICogQG5hbWUgZmx5ZC5zY2FuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiAtIHRoZSBmdW5jdGlvbiB0byBjYWxsXG4gKiBAcGFyYW0geyp9IHZhbCAtIHRoZSBpbml0aWFsIHZhbHVlIG9mIHRoZSBhY2N1bXVsYXRvclxuICogQHBhcmFtIHtzdHJlYW19IHN0cmVhbSAtIHRoZSBzdHJlYW0gc291cmNlXG4gKiBAcmV0dXJuIHtzdHJlYW19IHRoZSBuZXcgc3RyZWFtXG4gKlxuICogQGV4YW1wbGVcbiAqIHZhciBudW1iZXJzID0gZmx5ZC5zdHJlYW0oKTtcbiAqIHZhciBzdW0gPSBmbHlkLnNjYW4oZnVuY3Rpb24oc3VtLCBuKSB7IHJldHVybiBzdW0rbjsgfSwgMCwgbnVtYmVycyk7XG4gKiBudW1iZXJzKDIpKDMpKDUpO1xuICogc3VtKCk7IC8vIDEwXG4gKi9cbmZseWQuc2NhbiA9IGN1cnJ5TigzLCBmdW5jdGlvbihmLCBhY2MsIHMpIHtcbiAgdmFyIG5zID0gY29tYmluZShmdW5jdGlvbihzLCBzZWxmKSB7XG4gICAgc2VsZihhY2MgPSBmKGFjYywgcy52YWwpKTtcbiAgfSwgW3NdKTtcbiAgaWYgKCFucy5oYXNWYWwpIG5zKGFjYyk7XG4gIHJldHVybiBucztcbn0pO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgc3RyZWFtIGRvd24gd2hpY2ggYWxsIHZhbHVlcyBmcm9tIGJvdGggYHN0cmVhbTFgIGFuZCBgc3RyZWFtMmBcbiAqIHdpbGwgYmUgc2VudC5cbiAqXG4gKiBfX1NpZ25hdHVyZV9fOiBgU3RyZWFtIGEgLT4gU3RyZWFtIGEgLT4gU3RyZWFtIGFgXG4gKlxuICogQG5hbWUgZmx5ZC5tZXJnZVxuICogQHBhcmFtIHtzdHJlYW19IHNvdXJjZTEgLSBvbmUgc3RyZWFtIHRvIGJlIG1lcmdlZFxuICogQHBhcmFtIHtzdHJlYW19IHNvdXJjZTIgLSB0aGUgb3RoZXIgc3RyZWFtIHRvIGJlIG1lcmdlZFxuICogQHJldHVybiB7c3RyZWFtfSBhIHN0cmVhbSB3aXRoIHRoZSB2YWx1ZXMgZnJvbSBib3RoIHNvdXJjZXNcbiAqXG4gKiBAZXhhbXBsZVxuICogdmFyIGJ0bjFDbGlja3MgPSBmbHlkLnN0cmVhbSgpO1xuICogYnV0dG9uMUVsbS5hZGRFdmVudExpc3RlbmVyKGJ0bjFDbGlja3MpO1xuICogdmFyIGJ0bjJDbGlja3MgPSBmbHlkLnN0cmVhbSgpO1xuICogYnV0dG9uMkVsbS5hZGRFdmVudExpc3RlbmVyKGJ0bjJDbGlja3MpO1xuICogdmFyIGFsbENsaWNrcyA9IGZseWQubWVyZ2UoYnRuMUNsaWNrcywgYnRuMkNsaWNrcyk7XG4gKi9cbmZseWQubWVyZ2UgPSBjdXJyeU4oMiwgZnVuY3Rpb24oczEsIHMyKSB7XG4gIHZhciBzID0gZmx5ZC5pbW1lZGlhdGUoY29tYmluZShmdW5jdGlvbihzMSwgczIsIHNlbGYsIGNoYW5nZWQpIHtcbiAgICBpZiAoY2hhbmdlZFswXSkge1xuICAgICAgc2VsZihjaGFuZ2VkWzBdKCkpO1xuICAgIH0gZWxzZSBpZiAoczEuaGFzVmFsKSB7XG4gICAgICBzZWxmKHMxLnZhbCk7XG4gICAgfSBlbHNlIGlmIChzMi5oYXNWYWwpIHtcbiAgICAgIHNlbGYoczIudmFsKTtcbiAgICB9XG4gIH0sIFtzMSwgczJdKSk7XG4gIGZseWQuZW5kc09uKGNvbWJpbmUoZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH0sIFtzMS5lbmQsIHMyLmVuZF0pLCBzKTtcbiAgcmV0dXJuIHM7XG59KTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IHN0cmVhbSByZXN1bHRpbmcgZnJvbSBhcHBseWluZyBgdHJhbnNkdWNlcmAgdG8gYHN0cmVhbWAuXG4gKlxuICogX19TaWduYXR1cmVfXzogYFRyYW5zZHVjZXIgLT4gU3RyZWFtIGEgLT4gU3RyZWFtIGJgXG4gKlxuICogQG5hbWUgZmx5ZC50cmFuc2R1Y2VcbiAqIEBwYXJhbSB7VHJhbnNkdWNlcn0geGZvcm0gLSB0aGUgdHJhbnNkdWNlciB0cmFuc2Zvcm1hdGlvblxuICogQHBhcmFtIHtzdHJlYW19IHNvdXJjZSAtIHRoZSBzdHJlYW0gc291cmNlXG4gKiBAcmV0dXJuIHtzdHJlYW19IHRoZSBuZXcgc3RyZWFtXG4gKlxuICogQGV4YW1wbGVcbiAqIHZhciB0ID0gcmVxdWlyZSgndHJhbnNkdWNlcnMuanMnKTtcbiAqXG4gKiB2YXIgcmVzdWx0cyA9IFtdO1xuICogdmFyIHMxID0gZmx5ZC5zdHJlYW0oKTtcbiAqIHZhciB0eCA9IHQuY29tcG9zZSh0Lm1hcChmdW5jdGlvbih4KSB7IHJldHVybiB4ICogMjsgfSksIHQuZGVkdXBlKCkpO1xuICogdmFyIHMyID0gZmx5ZC50cmFuc2R1Y2UodHgsIHMxKTtcbiAqIGZseWQuY29tYmluZShmdW5jdGlvbihzMikgeyByZXN1bHRzLnB1c2goczIoKSk7IH0sIFtzMl0pO1xuICogczEoMSkoMSkoMikoMykoMykoMykoNCk7XG4gKiByZXN1bHRzOyAvLyA9PiBbMiwgNCwgNiwgOF1cbiAqL1xuZmx5ZC50cmFuc2R1Y2UgPSBjdXJyeU4oMiwgZnVuY3Rpb24oeGZvcm0sIHNvdXJjZSkge1xuICB4Zm9ybSA9IHhmb3JtKG5ldyBTdHJlYW1UcmFuc2Zvcm1lcigpKTtcbiAgcmV0dXJuIGNvbWJpbmUoZnVuY3Rpb24oc291cmNlLCBzZWxmKSB7XG4gICAgdmFyIHJlcyA9IHhmb3JtWydAQHRyYW5zZHVjZXIvc3RlcCddKHVuZGVmaW5lZCwgc291cmNlLnZhbCk7XG4gICAgaWYgKHJlcyAmJiByZXNbJ0BAdHJhbnNkdWNlci9yZWR1Y2VkJ10gPT09IHRydWUpIHtcbiAgICAgIHNlbGYuZW5kKHRydWUpO1xuICAgICAgcmV0dXJuIHJlc1snQEB0cmFuc2R1Y2VyL3ZhbHVlJ107XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiByZXM7XG4gICAgfVxuICB9LCBbc291cmNlXSk7XG59KTtcblxuLyoqXG4gKiBSZXR1cm5zIGBmbmAgY3VycmllZCB0byBgbmAuIFVzZSB0aGlzIGZ1bmN0aW9uIHRvIGN1cnJ5IGZ1bmN0aW9ucyBleHBvc2VkIGJ5XG4gKiBtb2R1bGVzIGZvciBGbHlkLlxuICpcbiAqIEBuYW1lIGZseWQuY3VycnlOXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7SW50ZWdlcn0gYXJpdHkgLSB0aGUgZnVuY3Rpb24gYXJpdHlcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIC0gdGhlIGZ1bmN0aW9uIHRvIGN1cnJ5XG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gdGhlIGN1cnJpZWQgZnVuY3Rpb25cbiAqXG4gKiBAZXhhbXBsZVxuICogZnVuY3Rpb24gYWRkKHgsIHkpIHsgcmV0dXJuIHggKyB5OyB9O1xuICogdmFyIGEgPSBmbHlkLmN1cnJ5TigyLCBhZGQpO1xuICogYSgyKSg0KSAvLyA9PiA2XG4gKi9cbmZseWQuY3VycnlOID0gY3VycnlOXG5cbi8qKlxuICogUmV0dXJucyBhIG5ldyBzdHJlYW0gaWRlbnRpY2FsIHRvIHRoZSBvcmlnaW5hbCBleGNlcHQgZXZlcnlcbiAqIHZhbHVlIHdpbGwgYmUgcGFzc2VkIHRocm91Z2ggYGZgLlxuICpcbiAqIF9Ob3RlOl8gVGhpcyBmdW5jdGlvbiBpcyBpbmNsdWRlZCBpbiBvcmRlciB0byBzdXBwb3J0IHRoZSBmYW50YXN5IGxhbmRcbiAqIHNwZWNpZmljYXRpb24uXG4gKlxuICogX19TaWduYXR1cmVfXzogQ2FsbGVkIGJvdW5kIHRvIGBTdHJlYW0gYWA6IGAoYSAtPiBiKSAtPiBTdHJlYW0gYmBcbiAqXG4gKiBAbmFtZSBzdHJlYW0ubWFwXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jdGlvbiAtIHRoZSBmdW5jdGlvbiB0byBhcHBseVxuICogQHJldHVybiB7c3RyZWFtfSBhIG5ldyBzdHJlYW0gd2l0aCB0aGUgdmFsdWVzIG1hcHBlZFxuICpcbiAqIEBleGFtcGxlXG4gKiB2YXIgbnVtYmVycyA9IGZseWQuc3RyZWFtKDApO1xuICogdmFyIHNxdWFyZWROdW1iZXJzID0gbnVtYmVycy5tYXAoZnVuY3Rpb24obikgeyByZXR1cm4gbipuOyB9KTtcbiAqL1xuZnVuY3Rpb24gYm91bmRNYXAoZikgeyByZXR1cm4gZmx5ZC5tYXAoZiwgdGhpcyk7IH1cblxuLyoqXG4gKiBSZXR1cm5zIGEgbmV3IHN0cmVhbSB3aGljaCBpcyB0aGUgcmVzdWx0IG9mIGFwcGx5aW5nIHRoZVxuICogZnVuY3Rpb25zIGZyb20gYHRoaXNgIHN0cmVhbSB0byB0aGUgdmFsdWVzIGluIGBzdHJlYW1gIHBhcmFtZXRlci5cbiAqXG4gKiBgdGhpc2Agc3RyZWFtIG11c3QgYmUgYSBzdHJlYW0gb2YgZnVuY3Rpb25zLlxuICpcbiAqIF9Ob3RlOl8gVGhpcyBmdW5jdGlvbiBpcyBpbmNsdWRlZCBpbiBvcmRlciB0byBzdXBwb3J0IHRoZSBmYW50YXN5IGxhbmRcbiAqIHNwZWNpZmljYXRpb24uXG4gKlxuICogX19TaWduYXR1cmVfXzogQ2FsbGVkIGJvdW5kIHRvIGBTdHJlYW0gKGEgLT4gYilgOiBgYSAtPiBTdHJlYW0gYmBcbiAqXG4gKiBAbmFtZSBzdHJlYW0uYXBcbiAqIEBwYXJhbSB7c3RyZWFtfSBzdHJlYW0gLSB0aGUgdmFsdWVzIHN0cmVhbVxuICogQHJldHVybiB7c3RyZWFtfSBhIG5ldyBzdHJhbSB3aXRoIHRoZSBmdW5jdGlvbnMgYXBwbGllZCB0byB2YWx1ZXNcbiAqXG4gKiBAZXhhbXBsZVxuICogdmFyIGFkZCA9IGZseWQuY3VycnlOKDIsIGZ1bmN0aW9uKHgsIHkpIHsgcmV0dXJuIHggKyB5OyB9KTtcbiAqIHZhciBudW1iZXJzMSA9IGZseWQuc3RyZWFtKCk7XG4gKiB2YXIgbnVtYmVyczIgPSBmbHlkLnN0cmVhbSgpO1xuICogdmFyIGFkZFRvTnVtYmVyczEgPSBmbHlkLm1hcChhZGQsIG51bWJlcnMxKTtcbiAqIHZhciBhZGRlZCA9IGFkZFRvTnVtYmVyczEuYXAobnVtYmVyczIpO1xuICovXG5mdW5jdGlvbiBhcChzMikge1xuICB2YXIgczEgPSB0aGlzO1xuICByZXR1cm4gY29tYmluZShmdW5jdGlvbihzMSwgczIsIHNlbGYpIHsgc2VsZihzMS52YWwoczIudmFsKSk7IH0sIFtzMSwgczJdKTtcbn1cblxuLyoqXG4gKiBHZXQgYSBodW1hbiByZWFkYWJsZSB2aWV3IG9mIGEgc3RyZWFtXG4gKiBAbmFtZSBzdHJlYW0udG9TdHJpbmdcbiAqIEByZXR1cm4ge1N0cmluZ30gdGhlIHN0cmVhbSBzdHJpbmcgcmVwcmVzZW50YXRpb25cbiAqL1xuZnVuY3Rpb24gc3RyZWFtVG9TdHJpbmcoKSB7XG4gIHJldHVybiAnc3RyZWFtKCcgKyB0aGlzLnZhbCArICcpJztcbn1cblxuLyoqXG4gKiBAbmFtZSBzdHJlYW0uZW5kXG4gKiBAbWVtYmVyb2Ygc3RyZWFtXG4gKiBBIHN0cmVhbSB0aGF0IGVtaXRzIGB0cnVlYCB3aGVuIHRoZSBzdHJlYW0gZW5kcy4gSWYgYHRydWVgIGlzIHB1c2hlZCBkb3duIHRoZVxuICogc3RyZWFtIHRoZSBwYXJlbnQgc3RyZWFtIGVuZHMuXG4gKi9cblxuLyoqXG4gKiBAbmFtZSBzdHJlYW0ub2ZcbiAqIEBmdW5jdGlvblxuICogQG1lbWJlcm9mIHN0cmVhbVxuICogUmV0dXJucyBhIG5ldyBzdHJlYW0gd2l0aCBgdmFsdWVgIGFzIGl0cyBpbml0aWFsIHZhbHVlLiBJdCBpcyBpZGVudGljYWwgdG9cbiAqIGNhbGxpbmcgYGZseWQuc3RyZWFtYCB3aXRoIG9uZSBhcmd1bWVudC5cbiAqXG4gKiBfX1NpZ25hdHVyZV9fOiBDYWxsZWQgYm91bmQgdG8gYFN0cmVhbSAoYSlgOiBgYiAtPiBTdHJlYW0gYmBcbiAqXG4gKiBAcGFyYW0geyp9IHZhbHVlIC0gdGhlIGluaXRpYWwgdmFsdWVcbiAqIEByZXR1cm4ge3N0cmVhbX0gdGhlIG5ldyBzdHJlYW1cbiAqXG4gKiBAZXhhbXBsZVxuICogdmFyIG4gPSBmbHlkLnN0cmVhbSgxKTtcbiAqIHZhciBtID0gbi5vZigxKTtcbiAqL1xuXG4vLyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8gUFJJVkFURSAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8gLy9cbi8qKlxuICogQHByaXZhdGVcbiAqIENyZWF0ZSBhIHN0cmVhbSB3aXRoIG5vIGRlcGVuZGVuY2llcyBhbmQgbm8gdmFsdWVcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSBhIGZseWQgc3RyZWFtXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZVN0cmVhbSgpIHtcbiAgZnVuY3Rpb24gcyhuKSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHJldHVybiBzLnZhbFxuICAgIHVwZGF0ZVN0cmVhbVZhbHVlKHMsIG4pXG4gICAgcmV0dXJuIHNcbiAgfVxuICBzLmhhc1ZhbCA9IGZhbHNlO1xuICBzLnZhbCA9IHVuZGVmaW5lZDtcbiAgcy52YWxzID0gW107XG4gIHMubGlzdGVuZXJzID0gW107XG4gIHMucXVldWVkID0gZmFsc2U7XG4gIHMuZW5kID0gdW5kZWZpbmVkO1xuICBzLm1hcCA9IGJvdW5kTWFwO1xuICBzLmFwID0gYXA7XG4gIHMub2YgPSBmbHlkLnN0cmVhbTtcbiAgcy50b1N0cmluZyA9IHN0cmVhbVRvU3RyaW5nO1xuICByZXR1cm4gcztcbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQ3JlYXRlIGEgZGVwZW5kZW50IHN0cmVhbVxuICogQHBhcmFtIHtBcnJheTxzdHJlYW0+fSBkZXBlbmRlbmNpZXMgLSBhbiBhcnJheSBvZiB0aGUgc3RyZWFtc1xuICogQHBhcmFtIHtGdW5jdGlvbn0gZm4gLSB0aGUgZnVuY3Rpb24gdXNlZCB0byBjYWxjdWxhdGUgdGhlIG5ldyBzdHJlYW0gdmFsdWVcbiAqIGZyb20gdGhlIGRlcGVuZGVuY2llc1xuICogQHJldHVybiB7c3RyZWFtfSB0aGUgY3JlYXRlZCBzdHJlYW1cbiAqL1xuZnVuY3Rpb24gY3JlYXRlRGVwZW5kZW50U3RyZWFtKGRlcHMsIGZuKSB7XG4gIHZhciBzID0gY3JlYXRlU3RyZWFtKCk7XG4gIHMuZm4gPSBmbjtcbiAgcy5kZXBzID0gZGVwcztcbiAgcy5kZXBzTWV0ID0gZmFsc2U7XG4gIHMuZGVwc0NoYW5nZWQgPSBkZXBzLmxlbmd0aCA+IDAgPyBbXSA6IHVuZGVmaW5lZDtcbiAgcy5zaG91bGRVcGRhdGUgPSBmYWxzZTtcbiAgYWRkTGlzdGVuZXJzKGRlcHMsIHMpO1xuICByZXR1cm4gcztcbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQ2hlY2sgaWYgYWxsIHRoZSBkZXBlbmRlbmNpZXMgaGF2ZSB2YWx1ZXNcbiAqIEBwYXJhbSB7c3RyZWFtfSBzdHJlYW0gLSB0aGUgc3RyZWFtIHRvIGNoZWNrIGRlcGVuY2VuY2llcyBmcm9tXG4gKiBAcmV0dXJuIHtCb29sZWFufSBgdHJ1ZWAgaWYgYWxsIGRlcGVuZGVuY2llcyBoYXZlIHZhbGVzLCBgZmFsc2VgIG90aGVyd2lzZVxuICovXG5mdW5jdGlvbiBpbml0aWFsRGVwc05vdE1ldChzdHJlYW0pIHtcbiAgc3RyZWFtLmRlcHNNZXQgPSBzdHJlYW0uZGVwcy5ldmVyeShmdW5jdGlvbihzKSB7XG4gICAgcmV0dXJuIHMuaGFzVmFsO1xuICB9KTtcbiAgcmV0dXJuICFzdHJlYW0uZGVwc01ldDtcbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogVXBkYXRlIGEgZGVwZW5kZW50IHN0cmVhbSB1c2luZyBpdHMgZGVwZW5kZW5jaWVzIGluIGFuIGF0b21pYyB3YXlcbiAqIEBwYXJhbSB7c3RyZWFtfSBzdHJlYW0gLSB0aGUgc3RyZWFtIHRvIHVwZGF0ZVxuICovXG5mdW5jdGlvbiB1cGRhdGVTdHJlYW0ocykge1xuICBpZiAoKHMuZGVwc01ldCAhPT0gdHJ1ZSAmJiBpbml0aWFsRGVwc05vdE1ldChzKSkgfHxcbiAgICAgIChzLmVuZCAhPT0gdW5kZWZpbmVkICYmIHMuZW5kLnZhbCA9PT0gdHJ1ZSkpIHJldHVybjtcbiAgaWYgKGluU3RyZWFtICE9PSB1bmRlZmluZWQpIHtcbiAgICB0b1VwZGF0ZS5wdXNoKHMpO1xuICAgIHJldHVybjtcbiAgfVxuICBpblN0cmVhbSA9IHM7XG4gIGlmIChzLmRlcHNDaGFuZ2VkKSBzLmZuQXJnc1tzLmZuQXJncy5sZW5ndGggLSAxXSA9IHMuZGVwc0NoYW5nZWQ7XG4gIHZhciByZXR1cm5WYWwgPSBzLmZuLmFwcGx5KHMuZm4sIHMuZm5BcmdzKTtcbiAgaWYgKHJldHVyblZhbCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgcyhyZXR1cm5WYWwpO1xuICB9XG4gIGluU3RyZWFtID0gdW5kZWZpbmVkO1xuICBpZiAocy5kZXBzQ2hhbmdlZCAhPT0gdW5kZWZpbmVkKSBzLmRlcHNDaGFuZ2VkID0gW107XG4gIHMuc2hvdWxkVXBkYXRlID0gZmFsc2U7XG4gIGlmIChmbHVzaGluZyA9PT0gZmFsc2UpIGZsdXNoVXBkYXRlKCk7XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIFVwZGF0ZSB0aGUgZGVwZW5kZW5jaWVzIG9mIGEgc3RyZWFtXG4gKiBAcGFyYW0ge3N0cmVhbX0gc3RyZWFtXG4gKi9cbmZ1bmN0aW9uIHVwZGF0ZURlcHMocykge1xuICB2YXIgaSwgbywgbGlzdFxuICB2YXIgbGlzdGVuZXJzID0gcy5saXN0ZW5lcnM7XG4gIGZvciAoaSA9IDA7IGkgPCBsaXN0ZW5lcnMubGVuZ3RoOyArK2kpIHtcbiAgICBsaXN0ID0gbGlzdGVuZXJzW2ldO1xuICAgIGlmIChsaXN0LmVuZCA9PT0gcykge1xuICAgICAgZW5kU3RyZWFtKGxpc3QpO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAobGlzdC5kZXBzQ2hhbmdlZCAhPT0gdW5kZWZpbmVkKSBsaXN0LmRlcHNDaGFuZ2VkLnB1c2gocyk7XG4gICAgICBsaXN0LnNob3VsZFVwZGF0ZSA9IHRydWU7XG4gICAgICBmaW5kRGVwcyhsaXN0KTtcbiAgICB9XG4gIH1cbiAgZm9yICg7IG9yZGVyTmV4dElkeCA+PSAwOyAtLW9yZGVyTmV4dElkeCkge1xuICAgIG8gPSBvcmRlcltvcmRlck5leHRJZHhdO1xuICAgIGlmIChvLnNob3VsZFVwZGF0ZSA9PT0gdHJ1ZSkgdXBkYXRlU3RyZWFtKG8pO1xuICAgIG8ucXVldWVkID0gZmFsc2U7XG4gIH1cbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQWRkIHN0cmVhbSBkZXBlbmRlbmNpZXMgdG8gdGhlIGdsb2JhbCBgb3JkZXJgIHF1ZXVlLlxuICogQHBhcmFtIHtzdHJlYW19IHN0cmVhbVxuICogQHNlZSB1cGRhdGVEZXBzXG4gKi9cbmZ1bmN0aW9uIGZpbmREZXBzKHMpIHtcbiAgdmFyIGlcbiAgdmFyIGxpc3RlbmVycyA9IHMubGlzdGVuZXJzO1xuICBpZiAocy5xdWV1ZWQgPT09IGZhbHNlKSB7XG4gICAgcy5xdWV1ZWQgPSB0cnVlO1xuICAgIGZvciAoaSA9IDA7IGkgPCBsaXN0ZW5lcnMubGVuZ3RoOyArK2kpIHtcbiAgICAgIGZpbmREZXBzKGxpc3RlbmVyc1tpXSk7XG4gICAgfVxuICAgIG9yZGVyWysrb3JkZXJOZXh0SWR4XSA9IHM7XG4gIH1cbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBmbHVzaFVwZGF0ZSgpIHtcbiAgZmx1c2hpbmcgPSB0cnVlO1xuICB3aGlsZSAodG9VcGRhdGUubGVuZ3RoID4gMCkge1xuICAgIHZhciBzID0gdG9VcGRhdGUuc2hpZnQoKTtcbiAgICBpZiAocy52YWxzLmxlbmd0aCA+IDApIHMudmFsID0gcy52YWxzLnNoaWZ0KCk7XG4gICAgdXBkYXRlRGVwcyhzKTtcbiAgfVxuICBmbHVzaGluZyA9IGZhbHNlO1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBQdXNoIGRvd24gYSB2YWx1ZSBpbnRvIGEgc3RyZWFtXG4gKiBAcGFyYW0ge3N0cmVhbX0gc3RyZWFtXG4gKiBAcGFyYW0geyp9IHZhbHVlXG4gKi9cbmZ1bmN0aW9uIHVwZGF0ZVN0cmVhbVZhbHVlKHMsIG4pIHtcbiAgaWYgKG4gIT09IHVuZGVmaW5lZCAmJiBuICE9PSBudWxsICYmIGlzRnVuY3Rpb24obi50aGVuKSkge1xuICAgIG4udGhlbihzKTtcbiAgICByZXR1cm47XG4gIH1cbiAgcy52YWwgPSBuO1xuICBzLmhhc1ZhbCA9IHRydWU7XG4gIGlmIChpblN0cmVhbSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgZmx1c2hpbmcgPSB0cnVlO1xuICAgIHVwZGF0ZURlcHMocyk7XG4gICAgaWYgKHRvVXBkYXRlLmxlbmd0aCA+IDApIGZsdXNoVXBkYXRlKCk7IGVsc2UgZmx1c2hpbmcgPSBmYWxzZTtcbiAgfSBlbHNlIGlmIChpblN0cmVhbSA9PT0gcykge1xuICAgIG1hcmtMaXN0ZW5lcnMocywgcy5saXN0ZW5lcnMpO1xuICB9IGVsc2Uge1xuICAgIHMudmFscy5wdXNoKG4pO1xuICAgIHRvVXBkYXRlLnB1c2gocyk7XG4gIH1cbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBtYXJrTGlzdGVuZXJzKHMsIGxpc3RzKSB7XG4gIHZhciBpLCBsaXN0O1xuICBmb3IgKGkgPSAwOyBpIDwgbGlzdHMubGVuZ3RoOyArK2kpIHtcbiAgICBsaXN0ID0gbGlzdHNbaV07XG4gICAgaWYgKGxpc3QuZW5kICE9PSBzKSB7XG4gICAgICBpZiAobGlzdC5kZXBzQ2hhbmdlZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGxpc3QuZGVwc0NoYW5nZWQucHVzaChzKTtcbiAgICAgIH1cbiAgICAgIGxpc3Quc2hvdWxkVXBkYXRlID0gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgZW5kU3RyZWFtKGxpc3QpO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBBZGQgZGVwZW5kZW5jaWVzIHRvIGEgc3RyZWFtXG4gKiBAcGFyYW0ge0FycmF5PHN0cmVhbT59IGRlcGVuZGVuY2llc1xuICogQHBhcmFtIHtzdHJlYW19IHN0cmVhbVxuICovXG5mdW5jdGlvbiBhZGRMaXN0ZW5lcnMoZGVwcywgcykge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGRlcHMubGVuZ3RoOyArK2kpIHtcbiAgICBkZXBzW2ldLmxpc3RlbmVycy5wdXNoKHMpO1xuICB9XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIFJlbW92ZXMgYW4gc3RyZWFtIGZyb20gYSBkZXBlbmRlbmN5IGFycmF5XG4gKiBAcGFyYW0ge3N0cmVhbX0gc3RyZWFtXG4gKiBAcGFyYW0ge0FycmF5PHN0cmVhbT59IGRlcGVuZGVuY2llc1xuICovXG5mdW5jdGlvbiByZW1vdmVMaXN0ZW5lcihzLCBsaXN0ZW5lcnMpIHtcbiAgdmFyIGlkeCA9IGxpc3RlbmVycy5pbmRleE9mKHMpO1xuICBsaXN0ZW5lcnNbaWR4XSA9IGxpc3RlbmVyc1tsaXN0ZW5lcnMubGVuZ3RoIC0gMV07XG4gIGxpc3RlbmVycy5sZW5ndGgtLTtcbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogRGV0YWNoIGEgc3RyZWFtIGZyb20gaXRzIGRlcGVuZGVuY2llc1xuICogQHBhcmFtIHtzdHJlYW19IHN0cmVhbVxuICovXG5mdW5jdGlvbiBkZXRhY2hEZXBzKHMpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzLmRlcHMubGVuZ3RoOyArK2kpIHtcbiAgICByZW1vdmVMaXN0ZW5lcihzLCBzLmRlcHNbaV0ubGlzdGVuZXJzKTtcbiAgfVxuICBzLmRlcHMubGVuZ3RoID0gMDtcbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogRW5kcyBhIHN0cmVhbVxuICovXG5mdW5jdGlvbiBlbmRTdHJlYW0ocykge1xuICBpZiAocy5kZXBzICE9PSB1bmRlZmluZWQpIGRldGFjaERlcHMocyk7XG4gIGlmIChzLmVuZCAhPT0gdW5kZWZpbmVkKSBkZXRhY2hEZXBzKHMuZW5kKTtcbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogdHJhbnNkdWNlciBzdHJlYW0gdHJhbnNmb3JtZXJcbiAqL1xuZnVuY3Rpb24gU3RyZWFtVHJhbnNmb3JtZXIoKSB7IH1cblN0cmVhbVRyYW5zZm9ybWVyLnByb3RvdHlwZVsnQEB0cmFuc2R1Y2VyL2luaXQnXSA9IGZ1bmN0aW9uKCkgeyB9O1xuU3RyZWFtVHJhbnNmb3JtZXIucHJvdG90eXBlWydAQHRyYW5zZHVjZXIvcmVzdWx0J10gPSBmdW5jdGlvbigpIHsgfTtcblN0cmVhbVRyYW5zZm9ybWVyLnByb3RvdHlwZVsnQEB0cmFuc2R1Y2VyL3N0ZXAnXSA9IGZ1bmN0aW9uKHMsIHYpIHsgcmV0dXJuIHY7IH07XG5cbm1vZHVsZS5leHBvcnRzID0gZmx5ZDtcbiIsInZhciBfYXJpdHkgPSByZXF1aXJlKCcuL2ludGVybmFsL19hcml0eScpO1xudmFyIF9jdXJyeTEgPSByZXF1aXJlKCcuL2ludGVybmFsL19jdXJyeTEnKTtcbnZhciBfY3VycnkyID0gcmVxdWlyZSgnLi9pbnRlcm5hbC9fY3VycnkyJyk7XG52YXIgX2N1cnJ5TiA9IHJlcXVpcmUoJy4vaW50ZXJuYWwvX2N1cnJ5TicpO1xuXG5cbi8qKlxuICogUmV0dXJucyBhIGN1cnJpZWQgZXF1aXZhbGVudCBvZiB0aGUgcHJvdmlkZWQgZnVuY3Rpb24sIHdpdGggdGhlIHNwZWNpZmllZFxuICogYXJpdHkuIFRoZSBjdXJyaWVkIGZ1bmN0aW9uIGhhcyB0d28gdW51c3VhbCBjYXBhYmlsaXRpZXMuIEZpcnN0LCBpdHNcbiAqIGFyZ3VtZW50cyBuZWVkbid0IGJlIHByb3ZpZGVkIG9uZSBhdCBhIHRpbWUuIElmIGBnYCBpcyBgUi5jdXJyeU4oMywgZilgLCB0aGVcbiAqIGZvbGxvd2luZyBhcmUgZXF1aXZhbGVudDpcbiAqXG4gKiAgIC0gYGcoMSkoMikoMylgXG4gKiAgIC0gYGcoMSkoMiwgMylgXG4gKiAgIC0gYGcoMSwgMikoMylgXG4gKiAgIC0gYGcoMSwgMiwgMylgXG4gKlxuICogU2Vjb25kbHksIHRoZSBzcGVjaWFsIHBsYWNlaG9sZGVyIHZhbHVlIGBSLl9fYCBtYXkgYmUgdXNlZCB0byBzcGVjaWZ5XG4gKiBcImdhcHNcIiwgYWxsb3dpbmcgcGFydGlhbCBhcHBsaWNhdGlvbiBvZiBhbnkgY29tYmluYXRpb24gb2YgYXJndW1lbnRzLFxuICogcmVnYXJkbGVzcyBvZiB0aGVpciBwb3NpdGlvbnMuIElmIGBnYCBpcyBhcyBhYm92ZSBhbmQgYF9gIGlzIGBSLl9fYCwgdGhlXG4gKiBmb2xsb3dpbmcgYXJlIGVxdWl2YWxlbnQ6XG4gKlxuICogICAtIGBnKDEsIDIsIDMpYFxuICogICAtIGBnKF8sIDIsIDMpKDEpYFxuICogICAtIGBnKF8sIF8sIDMpKDEpKDIpYFxuICogICAtIGBnKF8sIF8sIDMpKDEsIDIpYFxuICogICAtIGBnKF8sIDIpKDEpKDMpYFxuICogICAtIGBnKF8sIDIpKDEsIDMpYFxuICogICAtIGBnKF8sIDIpKF8sIDMpKDEpYFxuICpcbiAqIEBmdW5jXG4gKiBAbWVtYmVyT2YgUlxuICogQHNpbmNlIHYwLjUuMFxuICogQGNhdGVnb3J5IEZ1bmN0aW9uXG4gKiBAc2lnIE51bWJlciAtPiAoKiAtPiBhKSAtPiAoKiAtPiBhKVxuICogQHBhcmFtIHtOdW1iZXJ9IGxlbmd0aCBUaGUgYXJpdHkgZm9yIHRoZSByZXR1cm5lZCBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIFRoZSBmdW5jdGlvbiB0byBjdXJyeS5cbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSBBIG5ldywgY3VycmllZCBmdW5jdGlvbi5cbiAqIEBzZWUgUi5jdXJyeVxuICogQGV4YW1wbGVcbiAqXG4gKiAgICAgIHZhciBzdW1BcmdzID0gKC4uLmFyZ3MpID0+IFIuc3VtKGFyZ3MpO1xuICpcbiAqICAgICAgdmFyIGN1cnJpZWRBZGRGb3VyTnVtYmVycyA9IFIuY3VycnlOKDQsIHN1bUFyZ3MpO1xuICogICAgICB2YXIgZiA9IGN1cnJpZWRBZGRGb3VyTnVtYmVycygxLCAyKTtcbiAqICAgICAgdmFyIGcgPSBmKDMpO1xuICogICAgICBnKDQpOyAvLz0+IDEwXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gX2N1cnJ5MihmdW5jdGlvbiBjdXJyeU4obGVuZ3RoLCBmbikge1xuICBpZiAobGVuZ3RoID09PSAxKSB7XG4gICAgcmV0dXJuIF9jdXJyeTEoZm4pO1xuICB9XG4gIHJldHVybiBfYXJpdHkobGVuZ3RoLCBfY3VycnlOKGxlbmd0aCwgW10sIGZuKSk7XG59KTtcbiIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gX2FyaXR5KG4sIGZuKSB7XG4gIC8qIGVzbGludC1kaXNhYmxlIG5vLXVudXNlZC12YXJzICovXG4gIHN3aXRjaCAobikge1xuICAgIGNhc2UgMDogcmV0dXJuIGZ1bmN0aW9uKCkgeyByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfTtcbiAgICBjYXNlIDE6IHJldHVybiBmdW5jdGlvbihhMCkgeyByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfTtcbiAgICBjYXNlIDI6IHJldHVybiBmdW5jdGlvbihhMCwgYTEpIHsgcmV0dXJuIGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7IH07XG4gICAgY2FzZSAzOiByZXR1cm4gZnVuY3Rpb24oYTAsIGExLCBhMikgeyByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfTtcbiAgICBjYXNlIDQ6IHJldHVybiBmdW5jdGlvbihhMCwgYTEsIGEyLCBhMykgeyByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfTtcbiAgICBjYXNlIDU6IHJldHVybiBmdW5jdGlvbihhMCwgYTEsIGEyLCBhMywgYTQpIHsgcmV0dXJuIGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7IH07XG4gICAgY2FzZSA2OiByZXR1cm4gZnVuY3Rpb24oYTAsIGExLCBhMiwgYTMsIGE0LCBhNSkgeyByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfTtcbiAgICBjYXNlIDc6IHJldHVybiBmdW5jdGlvbihhMCwgYTEsIGEyLCBhMywgYTQsIGE1LCBhNikgeyByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfTtcbiAgICBjYXNlIDg6IHJldHVybiBmdW5jdGlvbihhMCwgYTEsIGEyLCBhMywgYTQsIGE1LCBhNiwgYTcpIHsgcmV0dXJuIGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7IH07XG4gICAgY2FzZSA5OiByZXR1cm4gZnVuY3Rpb24oYTAsIGExLCBhMiwgYTMsIGE0LCBhNSwgYTYsIGE3LCBhOCkgeyByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfTtcbiAgICBjYXNlIDEwOiByZXR1cm4gZnVuY3Rpb24oYTAsIGExLCBhMiwgYTMsIGE0LCBhNSwgYTYsIGE3LCBhOCwgYTkpIHsgcmV0dXJuIGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7IH07XG4gICAgZGVmYXVsdDogdGhyb3cgbmV3IEVycm9yKCdGaXJzdCBhcmd1bWVudCB0byBfYXJpdHkgbXVzdCBiZSBhIG5vbi1uZWdhdGl2ZSBpbnRlZ2VyIG5vIGdyZWF0ZXIgdGhhbiB0ZW4nKTtcbiAgfVxufTtcbiIsInZhciBfaXNQbGFjZWhvbGRlciA9IHJlcXVpcmUoJy4vX2lzUGxhY2Vob2xkZXInKTtcblxuXG4vKipcbiAqIE9wdGltaXplZCBpbnRlcm5hbCBvbmUtYXJpdHkgY3VycnkgZnVuY3Rpb24uXG4gKlxuICogQHByaXZhdGVcbiAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm4gVGhlIGZ1bmN0aW9uIHRvIGN1cnJ5LlxuICogQHJldHVybiB7RnVuY3Rpb259IFRoZSBjdXJyaWVkIGZ1bmN0aW9uLlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIF9jdXJyeTEoZm4pIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIGYxKGEpIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCB8fCBfaXNQbGFjZWhvbGRlcihhKSkge1xuICAgICAgcmV0dXJuIGYxO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9XG4gIH07XG59O1xuIiwidmFyIF9jdXJyeTEgPSByZXF1aXJlKCcuL19jdXJyeTEnKTtcbnZhciBfaXNQbGFjZWhvbGRlciA9IHJlcXVpcmUoJy4vX2lzUGxhY2Vob2xkZXInKTtcblxuXG4vKipcbiAqIE9wdGltaXplZCBpbnRlcm5hbCB0d28tYXJpdHkgY3VycnkgZnVuY3Rpb24uXG4gKlxuICogQHByaXZhdGVcbiAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm4gVGhlIGZ1bmN0aW9uIHRvIGN1cnJ5LlxuICogQHJldHVybiB7RnVuY3Rpb259IFRoZSBjdXJyaWVkIGZ1bmN0aW9uLlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIF9jdXJyeTIoZm4pIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIGYyKGEsIGIpIHtcbiAgICBzd2l0Y2ggKGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgIGNhc2UgMDpcbiAgICAgICAgcmV0dXJuIGYyO1xuICAgICAgY2FzZSAxOlxuICAgICAgICByZXR1cm4gX2lzUGxhY2Vob2xkZXIoYSkgPyBmMlxuICAgICAgICAgICAgIDogX2N1cnJ5MShmdW5jdGlvbihfYikgeyByZXR1cm4gZm4oYSwgX2IpOyB9KTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiBfaXNQbGFjZWhvbGRlcihhKSAmJiBfaXNQbGFjZWhvbGRlcihiKSA/IGYyXG4gICAgICAgICAgICAgOiBfaXNQbGFjZWhvbGRlcihhKSA/IF9jdXJyeTEoZnVuY3Rpb24oX2EpIHsgcmV0dXJuIGZuKF9hLCBiKTsgfSlcbiAgICAgICAgICAgICA6IF9pc1BsYWNlaG9sZGVyKGIpID8gX2N1cnJ5MShmdW5jdGlvbihfYikgeyByZXR1cm4gZm4oYSwgX2IpOyB9KVxuICAgICAgICAgICAgIDogZm4oYSwgYik7XG4gICAgfVxuICB9O1xufTtcbiIsInZhciBfYXJpdHkgPSByZXF1aXJlKCcuL19hcml0eScpO1xudmFyIF9pc1BsYWNlaG9sZGVyID0gcmVxdWlyZSgnLi9faXNQbGFjZWhvbGRlcicpO1xuXG5cbi8qKlxuICogSW50ZXJuYWwgY3VycnlOIGZ1bmN0aW9uLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAqIEBwYXJhbSB7TnVtYmVyfSBsZW5ndGggVGhlIGFyaXR5IG9mIHRoZSBjdXJyaWVkIGZ1bmN0aW9uLlxuICogQHBhcmFtIHtBcnJheX0gcmVjZWl2ZWQgQW4gYXJyYXkgb2YgYXJndW1lbnRzIHJlY2VpdmVkIHRodXMgZmFyLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm4gVGhlIGZ1bmN0aW9uIHRvIGN1cnJ5LlxuICogQHJldHVybiB7RnVuY3Rpb259IFRoZSBjdXJyaWVkIGZ1bmN0aW9uLlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIF9jdXJyeU4obGVuZ3RoLCByZWNlaXZlZCwgZm4pIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHZhciBjb21iaW5lZCA9IFtdO1xuICAgIHZhciBhcmdzSWR4ID0gMDtcbiAgICB2YXIgbGVmdCA9IGxlbmd0aDtcbiAgICB2YXIgY29tYmluZWRJZHggPSAwO1xuICAgIHdoaWxlIChjb21iaW5lZElkeCA8IHJlY2VpdmVkLmxlbmd0aCB8fCBhcmdzSWR4IDwgYXJndW1lbnRzLmxlbmd0aCkge1xuICAgICAgdmFyIHJlc3VsdDtcbiAgICAgIGlmIChjb21iaW5lZElkeCA8IHJlY2VpdmVkLmxlbmd0aCAmJlxuICAgICAgICAgICghX2lzUGxhY2Vob2xkZXIocmVjZWl2ZWRbY29tYmluZWRJZHhdKSB8fFxuICAgICAgICAgICBhcmdzSWR4ID49IGFyZ3VtZW50cy5sZW5ndGgpKSB7XG4gICAgICAgIHJlc3VsdCA9IHJlY2VpdmVkW2NvbWJpbmVkSWR4XTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlc3VsdCA9IGFyZ3VtZW50c1thcmdzSWR4XTtcbiAgICAgICAgYXJnc0lkeCArPSAxO1xuICAgICAgfVxuICAgICAgY29tYmluZWRbY29tYmluZWRJZHhdID0gcmVzdWx0O1xuICAgICAgaWYgKCFfaXNQbGFjZWhvbGRlcihyZXN1bHQpKSB7XG4gICAgICAgIGxlZnQgLT0gMTtcbiAgICAgIH1cbiAgICAgIGNvbWJpbmVkSWR4ICs9IDE7XG4gICAgfVxuICAgIHJldHVybiBsZWZ0IDw9IDAgPyBmbi5hcHBseSh0aGlzLCBjb21iaW5lZClcbiAgICAgICAgICAgICAgICAgICAgIDogX2FyaXR5KGxlZnQsIF9jdXJyeU4obGVuZ3RoLCBjb21iaW5lZCwgZm4pKTtcbiAgfTtcbn07XG4iLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIF9pc1BsYWNlaG9sZGVyKGEpIHtcbiAgcmV0dXJuIGEgIT0gbnVsbCAmJlxuICAgICAgICAgdHlwZW9mIGEgPT09ICdvYmplY3QnICYmXG4gICAgICAgICBhWydAQGZ1bmN0aW9uYWwvcGxhY2Vob2xkZXInXSA9PT0gdHJ1ZTtcbn07XG4iLCJ2YXIgZmx5ZCA9IHJlcXVpcmUoJy4uLy4uL2xpYicpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIG1lcmdlQWxsKHN0cmVhbXMpIHtcbiAgdmFyIHMgPSBmbHlkLmltbWVkaWF0ZShmbHlkLmNvbWJpbmUoZnVuY3Rpb24oKSB7XG4gICAgdmFyIHNlbGYgPSBhcmd1bWVudHNbYXJndW1lbnRzLmxlbmd0aCAtIDJdO1xuICAgIGlmIChhcmd1bWVudHNbYXJndW1lbnRzLmxlbmd0aCAtIDFdWzBdKSB7XG4gICAgICBzZWxmKGFyZ3VtZW50c1thcmd1bWVudHMubGVuZ3RoIC0gMV1bMF0oKSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwLCBhcmd1bWVudHMubGVuZ3RoIC0gMilcbiAgICAuc29tZShmdW5jdGlvbihzMSkge1xuICAgICAgaWYgKHMxLmhhc1ZhbCkge1xuICAgICAgICBzZWxmKHMxLnZhbCk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH0pO1xuICB9LCBzdHJlYW1zKSk7XG4gIGZseWQuZW5kc09uKGZseWQuY29tYmluZShmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSwgc3RyZWFtcy5tYXAoZnVuY3Rpb24oc20pIHsgcmV0dXJuIHNtLmVuZDsgfSkpLCBzKTtcbiAgcmV0dXJuIHM7XG59O1xuXG4iXX0=
require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
'use strict';
var curryN = require('ramda/src/curryN');
// Utility
function isFunction(obj) {
return !!(obj && obj.constructor && obj.call && obj.apply);
}
function trueFn() { return true; }
// Globals
var toUpdate = [];
var inStream;
var order = [];
var orderNextIdx = -1;
var flushing = false;
/** @namespace */
var flyd = {}
// /////////////////////////// API ///////////////////////////////// //
/**
* Creates a new stream
*
* __Signature__: `a -> Stream a`
*
* @name flyd.stream
* @param {*} initialValue - (Optional) the initial value of the stream
* @return {stream} the stream
*
* @example
* var n = flyd.stream(1); // Stream with initial value `1`
* var s = flyd.stream(); // Stream with no initial value
*/
flyd.stream = function(initialValue) {
var endStream = createDependentStream([], trueFn);
var s = createStream();
s.end = endStream;
s.fnArgs = [];
endStream.listeners.push(s);
if (arguments.length > 0) s(initialValue);
return s;
}
/**
* Create a new dependent stream
*
* __Signature__: `(...Stream * -> Stream b -> b) -> [Stream *] -> Stream b`
*
* @name flyd.combine
* @param {Function} fn - the function used to combine the streams
* @param {Array<stream>} dependencies - the streams that this one depends on
* @return {stream} the dependent stream
*
* @example
* var n1 = flyd.stream(0);
* var n2 = flyd.stream(0);
* var max = flyd.combine(function(n1, n2, self, changed) {
* return n1() > n2() ? n1() : n2();
* }, [n1, n2]);
*/
flyd.combine = curryN(2, combine);
function combine(fn, streams) {
var i, s, deps, depEndStreams;
var endStream = createDependentStream([], trueFn);
deps = []; depEndStreams = [];
for (i = 0; i < streams.length; ++i) {
if (streams[i] !== undefined) {
deps.push(streams[i]);
if (streams[i].end !== undefined) depEndStreams.push(streams[i].end);
}
}
s = createDependentStream(deps, fn);
s.depsChanged = [];
s.fnArgs = s.deps.concat([s, s.depsChanged]);
s.end = endStream;
endStream.listeners.push(s);
addListeners(depEndStreams, endStream);
endStream.deps = depEndStreams;
updateStream(s);
return s;
}
/**
* Returns `true` if the supplied argument is a Flyd stream and `false` otherwise.
*
* __Signature__: `* -> Boolean`
*
* @name flyd.isStream
* @param {*} value - the value to test
* @return {Boolean} `true` if is a Flyd streamn, `false` otherwise
*
* @example
* var s = flyd.stream(1);
* var n = 1;
* flyd.isStream(s); //=> true
* flyd.isStream(n); //=> false
*/
flyd.isStream = function(stream) {
return isFunction(stream) && 'hasVal' in stream;
}
/**
* Invokes the body (the function to calculate the value) of a dependent stream
*
* By default the body of a dependent stream is only called when all the streams
* upon which it depends has a value. `immediate` can circumvent this behaviour.
* It immediately invokes the body of a dependent stream.
*
* __Signature__: `Stream a -> Stream a`
*
* @name flyd.immediate
* @param {stream} stream - the dependent stream
* @return {stream} the same stream
*
* @example
* var s = flyd.stream();
* var hasItems = flyd.immediate(flyd.combine(function(s) {
* return s() !== undefined && s().length > 0;
* }, [s]);
* console.log(hasItems()); // logs `false`. Had `immediate` not been
* // used `hasItems()` would've returned `undefined`
* s([1]);
* console.log(hasItems()); // logs `true`.
* s([]);
* console.log(hasItems()); // logs `false`.
*/
flyd.immediate = function(s) {
if (s.depsMet === false) {
s.depsMet = true;
updateStream(s);
}
return s;
}
/**
* Changes which `endsStream` should trigger the ending of `s`.
*
* __Signature__: `Stream a -> Stream b -> Stream b`
*
* @name flyd.endsOn
* @param {stream} endStream - the stream to trigger the ending
* @param {stream} stream - the stream to be ended by the endStream
* @param {stream} the stream modified to be ended by endStream
*
* @example
* var n = flyd.stream(1);
* var killer = flyd.stream();
* // `double` ends when `n` ends or when `killer` emits any value
* var double = flyd.endsOn(flyd.merge(n.end, killer), flyd.combine(function(n) {
* return 2 * n();
* }, [n]);
*/
flyd.endsOn = function(endS, s) {
detachDeps(s.end);
endS.listeners.push(s.end);
s.end.deps.push(endS);
return s;
}
/**
* Map a stream
*
* Returns a new stream consisting of every value from `s` passed through
* `fn`. I.e. `map` creates a new stream that listens to `s` and
* applies `fn` to every new value.
* __Signature__: `(a -> result) -> Stream a -> Stream result`
*
* @name flyd.map
* @param {Function} fn - the function that produces the elements of the new stream
* @param {stream} stream - the stream to map
* @return {stream} a new stream with the mapped values
*
* @example
* var numbers = flyd.stream(0);
* var squaredNumbers = flyd.map(function(n) { return n*n; }, numbers);
*/
// Library functions use self callback to accept (null, undefined) update triggers.
flyd.map = curryN(2, function(f, s) {
return combine(function(s, self) { self(f(s.val)); }, [s]);
})
/**
* Listen to stream events
*
* Similar to `map` except that the returned stream is empty. Use `on` for doing
* side effects in reaction to stream changes. Use the returned stream only if you
* need to manually end it.
*
* __Signature__: `(a -> result) -> Stream a -> Stream undefined`
*
* @name flyd.on
* @param {Function} cb - the callback
* @param {stream} stream - the stream
* @return {stream} an empty stream (can be ended)
*/
flyd.on = curryN(2, function(f, s) {
return combine(function(s) { f(s.val); }, [s]);
})
/**
* Creates a new stream with the results of calling the function on every incoming
* stream with and accumulator and the incoming value.
*
* __Signature__: `(a -> b -> a) -> a -> Stream b -> Stream a`
*
* @name flyd.scan
* @param {Function} fn - the function to call
* @param {*} val - the initial value of the accumulator
* @param {stream} stream - the stream source
* @return {stream} the new stream
*
* @example
* var numbers = flyd.stream();
* var sum = flyd.scan(function(sum, n) { return sum+n; }, 0, numbers);
* numbers(2)(3)(5);
* sum(); // 10
*/
flyd.scan = curryN(3, function(f, acc, s) {
var ns = combine(function(s, self) {
self(acc = f(acc, s.val));
}, [s]);
if (!ns.hasVal) ns(acc);
return ns;
});
/**
* Creates a new stream down which all values from both `stream1` and `stream2`
* will be sent.
*
* __Signature__: `Stream a -> Stream a -> Stream a`
*
* @name flyd.merge
* @param {stream} source1 - one stream to be merged
* @param {stream} source2 - the other stream to be merged
* @return {stream} a stream with the values from both sources
*
* @example
* var btn1Clicks = flyd.stream();
* button1Elm.addEventListener(btn1Clicks);
* var btn2Clicks = flyd.stream();
* button2Elm.addEventListener(btn2Clicks);
* var allClicks = flyd.merge(btn1Clicks, btn2Clicks);
*/
flyd.merge = curryN(2, function(s1, s2) {
var s = flyd.immediate(combine(function(s1, s2, self, changed) {
if (changed[0]) {
self(changed[0]());
} else if (s1.hasVal) {
self(s1.val);
} else if (s2.hasVal) {
self(s2.val);
}
}, [s1, s2]));
flyd.endsOn(combine(function() {
return true;
}, [s1.end, s2.end]), s);
return s;
});
/**
* Creates a new stream resulting from applying `transducer` to `stream`.
*
* __Signature__: `Transducer -> Stream a -> Stream b`
*
* @name flyd.transduce
* @param {Transducer} xform - the transducer transformation
* @param {stream} source - the stream source
* @return {stream} the new stream
*
* @example
* var t = require('transducers.js');
*
* var results = [];
* var s1 = flyd.stream();
* var tx = t.compose(t.map(function(x) { return x * 2; }), t.dedupe());
* var s2 = flyd.transduce(tx, s1);
* flyd.combine(function(s2) { results.push(s2()); }, [s2]);
* s1(1)(1)(2)(3)(3)(3)(4);
* results; // => [2, 4, 6, 8]
*/
flyd.transduce = curryN(2, function(xform, source) {
xform = xform(new StreamTransformer());
return combine(function(source, self) {
var res = xform['@@transducer/step'](undefined, source.val);
if (res && res['@@transducer/reduced'] === true) {
self.end(true);
return res['@@transducer/value'];
} else {
return res;
}
}, [source]);
});
/**
* Returns `fn` curried to `n`. Use this function to curry functions exposed by
* modules for Flyd.
*
* @name flyd.curryN
* @function
* @param {Integer} arity - the function arity
* @param {Function} fn - the function to curry
* @return {Function} the curried function
*
* @example
* function add(x, y) { return x + y; };
* var a = flyd.curryN(2, add);
* a(2)(4) // => 6
*/
flyd.curryN = curryN
/**
* Returns a new stream identical to the original except every
* value will be passed through `f`.
*
* _Note:_ This function is included in order to support the fantasy land
* specification.
*
* __Signature__: Called bound to `Stream a`: `(a -> b) -> Stream b`
*
* @name stream.map
* @param {Function} function - the function to apply
* @return {stream} a new stream with the values mapped
*
* @example
* var numbers = flyd.stream(0);
* var squaredNumbers = numbers.map(function(n) { return n*n; });
*/
function boundMap(f) { return flyd.map(f, this); }
/**
* Returns a new stream which is the result of applying the
* functions from `this` stream to the values in `stream` parameter.
*
* `this` stream must be a stream of functions.
*
* _Note:_ This function is included in order to support the fantasy land
* specification.
*
* __Signature__: Called bound to `Stream (a -> b)`: `a -> Stream b`
*
* @name stream.ap
* @param {stream} stream - the values stream
* @return {stream} a new stram with the functions applied to values
*
* @example
* var add = flyd.curryN(2, function(x, y) { return x + y; });
* var numbers1 = flyd.stream();
* var numbers2 = flyd.stream();
* var addToNumbers1 = flyd.map(add, numbers1);
* var added = addToNumbers1.ap(numbers2);
*/
function ap(s2) {
var s1 = this;
return combine(function(s1, s2, self) { self(s1.val(s2.val)); }, [s1, s2]);
}
/**
* Get a human readable view of a stream
* @name stream.toString
* @return {String} the stream string representation
*/
function streamToString() {
return 'stream(' + this.val + ')';
}
/**
* @name stream.end
* @memberof stream
* A stream that emits `true` when the stream ends. If `true` is pushed down the
* stream the parent stream ends.
*/
/**
* @name stream.of
* @function
* @memberof stream
* Returns a new stream with `value` as its initial value. It is identical to
* calling `flyd.stream` with one argument.
*
* __Signature__: Called bound to `Stream (a)`: `b -> Stream b`
*
* @param {*} value - the initial value
* @return {stream} the new stream
*
* @example
* var n = flyd.stream(1);
* var m = n.of(1);
*/
// /////////////////////////// PRIVATE ///////////////////////////////// //
/**
* @private
* Create a stream with no dependencies and no value
* @return {Function} a flyd stream
*/
function createStream() {
function s(n) {
if (arguments.length === 0) return s.val
updateStreamValue(s, n)
return s
}
s.hasVal = false;
s.val = undefined;
s.vals = [];
s.listeners = [];
s.queued = false;
s.end = undefined;
s.map = boundMap;
s.ap = ap;
s.of = flyd.stream;
s.toString = streamToString;
return s;
}
/**
* @private
* Create a dependent stream
* @param {Array<stream>} dependencies - an array of the streams
* @param {Function} fn - the function used to calculate the new stream value
* from the dependencies
* @return {stream} the created stream
*/
function createDependentStream(deps, fn) {
var s = createStream();
s.fn = fn;
s.deps = deps;
s.depsMet = false;
s.depsChanged = deps.length > 0 ? [] : undefined;
s.shouldUpdate = false;
addListeners(deps, s);
return s;
}
/**
* @private
* Check if all the dependencies have values
* @param {stream} stream - the stream to check depencencies from
* @return {Boolean} `true` if all dependencies have vales, `false` otherwise
*/
function initialDepsNotMet(stream) {
stream.depsMet = stream.deps.every(function(s) {
return s.hasVal;
});
return !stream.depsMet;
}
/**
* @private
* Update a dependent stream using its dependencies in an atomic way
* @param {stream} stream - the stream to update
*/
function updateStream(s) {
if ((s.depsMet !== true && initialDepsNotMet(s)) ||
(s.end !== undefined && s.end.val === true)) return;
if (inStream !== undefined) {
toUpdate.push(s);
return;
}
inStream = s;
if (s.depsChanged) s.fnArgs[s.fnArgs.length - 1] = s.depsChanged;
var returnVal = s.fn.apply(s.fn, s.fnArgs);
if (returnVal !== undefined) {
s(returnVal);
}
inStream = undefined;
if (s.depsChanged !== undefined) s.depsChanged = [];
s.shouldUpdate = false;
if (flushing === false) flushUpdate();
}
/**
* @private
* Update the dependencies of a stream
* @param {stream} stream
*/
function updateDeps(s) {
var i, o, list
var listeners = s.listeners;
for (i = 0; i < listeners.length; ++i) {
list = listeners[i];
if (list.end === s) {
endStream(list);
} else {
if (list.depsChanged !== undefined) list.depsChanged.push(s);
list.shouldUpdate = true;
findDeps(list);
}
}
for (; orderNextIdx >= 0; --orderNextIdx) {
o = order[orderNextIdx];
if (o.shouldUpdate === true) updateStream(o);
o.queued = false;
}
}
/**
* @private
* Add stream dependencies to the global `order` queue.
* @param {stream} stream
* @see updateDeps
*/
function findDeps(s) {
var i
var listeners = s.listeners;
if (s.queued === false) {
s.queued = true;
for (i = 0; i < listeners.length; ++i) {
findDeps(listeners[i]);
}
order[++orderNextIdx] = s;
}
}
/**
* @private
*/
function flushUpdate() {
flushing = true;
while (toUpdate.length > 0) {
var s = toUpdate.shift();
if (s.vals.length > 0) s.val = s.vals.shift();
updateDeps(s);
}
flushing = false;
}
/**
* @private
* Push down a value into a stream
* @param {stream} stream
* @param {*} value
*/
function updateStreamValue(s, n) {
if (n !== undefined && n !== null && isFunction(n.then)) {
n.then(s);
return;
}
s.val = n;
s.hasVal = true;
if (inStream === undefined) {
flushing = true;
updateDeps(s);
if (toUpdate.length > 0) flushUpdate(); else flushing = false;
} else if (inStream === s) {
markListeners(s, s.listeners);
} else {
s.vals.push(n);
toUpdate.push(s);
}
}
/**
* @private
*/
function markListeners(s, lists) {
var i, list;
for (i = 0; i < lists.length; ++i) {
list = lists[i];
if (list.end !== s) {
if (list.depsChanged !== undefined) {
list.depsChanged.push(s);
}
list.shouldUpdate = true;
} else {
endStream(list);
}
}
}
/**
* @private
* Add dependencies to a stream
* @param {Array<stream>} dependencies
* @param {stream} stream
*/
function addListeners(deps, s) {
for (var i = 0; i < deps.length; ++i) {
deps[i].listeners.push(s);
}
}
/**
* @private
* Removes an stream from a dependency array
* @param {stream} stream
* @param {Array<stream>} dependencies
*/
function removeListener(s, listeners) {
var idx = listeners.indexOf(s);
listeners[idx] = listeners[listeners.length - 1];
listeners.length--;
}
/**
* @private
* Detach a stream from its dependencies
* @param {stream} stream
*/
function detachDeps(s) {
for (var i = 0; i < s.deps.length; ++i) {
removeListener(s, s.deps[i].listeners);
}
s.deps.length = 0;
}
/**
* @private
* Ends a stream
*/
function endStream(s) {
if (s.deps !== undefined) detachDeps(s);
if (s.end !== undefined) detachDeps(s.end);
}
/**
* @private
* transducer stream transformer
*/
function StreamTransformer() { }
StreamTransformer.prototype['@@transducer/init'] = function() { };
StreamTransformer.prototype['@@transducer/result'] = function() { };
StreamTransformer.prototype['@@transducer/step'] = function(s, v) { return v; };
module.exports = flyd;
},{"ramda/src/curryN":2}],2:[function(require,module,exports){
var _arity = require('./internal/_arity');
var _curry1 = require('./internal/_curry1');
var _curry2 = require('./internal/_curry2');
var _curryN = require('./internal/_curryN');
/**
* Returns a curried equivalent of the provided function, with the specified
* arity. The curried function has two unusual capabilities. First, its
* arguments needn't be provided one at a time. If `g` is `R.curryN(3, f)`, the
* following are equivalent:
*
* - `g(1)(2)(3)`
* - `g(1)(2, 3)`
* - `g(1, 2)(3)`
* - `g(1, 2, 3)`
*
* Secondly, the special placeholder value `R.__` may be used to specify
* "gaps", allowing partial application of any combination of arguments,
* regardless of their positions. If `g` is as above and `_` is `R.__`, the
* following are equivalent:
*
* - `g(1, 2, 3)`
* - `g(_, 2, 3)(1)`
* - `g(_, _, 3)(1)(2)`
* - `g(_, _, 3)(1, 2)`
* - `g(_, 2)(1)(3)`
* - `g(_, 2)(1, 3)`
* - `g(_, 2)(_, 3)(1)`
*
* @func
* @memberOf R
* @since v0.5.0
* @category Function
* @sig Number -> (* -> a) -> (* -> a)
* @param {Number} length The arity for the returned function.
* @param {Function} fn The function to curry.
* @return {Function} A new, curried function.
* @see R.curry
* @example
*
* var sumArgs = (...args) => R.sum(args);
*
* var curriedAddFourNumbers = R.curryN(4, sumArgs);
* var f = curriedAddFourNumbers(1, 2);
* var g = f(3);
* g(4); //=> 10
*/
module.exports = _curry2(function curryN(length, fn) {
if (length === 1) {
return _curry1(fn);
}
return _arity(length, _curryN(length, [], fn));
});
},{"./internal/_arity":3,"./internal/_curry1":4,"./internal/_curry2":5,"./internal/_curryN":6}],3:[function(require,module,exports){
module.exports = function _arity(n, fn) {
/* eslint-disable no-unused-vars */
switch (n) {
case 0: return function() { return fn.apply(this, arguments); };
case 1: return function(a0) { return fn.apply(this, arguments); };
case 2: return function(a0, a1) { return fn.apply(this, arguments); };
case 3: return function(a0, a1, a2) { return fn.apply(this, arguments); };
case 4: return function(a0, a1, a2, a3) { return fn.apply(this, arguments); };
case 5: return function(a0, a1, a2, a3, a4) { return fn.apply(this, arguments); };
case 6: return function(a0, a1, a2, a3, a4, a5) { return fn.apply(this, arguments); };
case 7: return function(a0, a1, a2, a3, a4, a5, a6) { return fn.apply(this, arguments); };
case 8: return function(a0, a1, a2, a3, a4, a5, a6, a7) { return fn.apply(this, arguments); };
case 9: return function(a0, a1, a2, a3, a4, a5, a6, a7, a8) { return fn.apply(this, arguments); };
case 10: return function(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) { return fn.apply(this, arguments); };
default: throw new Error('First argument to _arity must be a non-negative integer no greater than ten');
}
};
},{}],4:[function(require,module,exports){
var _isPlaceholder = require('./_isPlaceholder');
/**
* Optimized internal one-arity curry function.
*
* @private
* @category Function
* @param {Function} fn The function to curry.
* @return {Function} The curried function.
*/
module.exports = function _curry1(fn) {
return function f1(a) {
if (arguments.length === 0 || _isPlaceholder(a)) {
return f1;
} else {
return fn.apply(this, arguments);
}
};
};
},{"./_isPlaceholder":7}],5:[function(require,module,exports){
var _curry1 = require('./_curry1');
var _isPlaceholder = require('./_isPlaceholder');
/**
* Optimized internal two-arity curry function.
*
* @private
* @category Function
* @param {Function} fn The function to curry.
* @return {Function} The curried function.
*/
module.exports = function _curry2(fn) {
return function f2(a, b) {
switch (arguments.length) {
case 0:
return f2;
case 1:
return _isPlaceholder(a) ? f2
: _curry1(function(_b) { return fn(a, _b); });
default:
return _isPlaceholder(a) && _isPlaceholder(b) ? f2
: _isPlaceholder(a) ? _curry1(function(_a) { return fn(_a, b); })
: _isPlaceholder(b) ? _curry1(function(_b) { return fn(a, _b); })
: fn(a, b);
}
};
};
},{"./_curry1":4,"./_isPlaceholder":7}],6:[function(require,module,exports){
var _arity = require('./_arity');
var _isPlaceholder = require('./_isPlaceholder');
/**
* Internal curryN function.
*
* @private
* @category Function
* @param {Number} length The arity of the curried function.
* @param {Array} received An array of arguments received thus far.
* @param {Function} fn The function to curry.
* @return {Function} The curried function.
*/
module.exports = function _curryN(length, received, fn) {
return function() {
var combined = [];
var argsIdx = 0;
var left = length;
var combinedIdx = 0;
while (combinedIdx < received.length || argsIdx < arguments.length) {
var result;
if (combinedIdx < received.length &&
(!_isPlaceholder(received[combinedIdx]) ||
argsIdx >= arguments.length)) {
result = received[combinedIdx];
} else {
result = arguments[argsIdx];
argsIdx += 1;
}
combined[combinedIdx] = result;
if (!_isPlaceholder(result)) {
left -= 1;
}
combinedIdx += 1;
}
return left <= 0 ? fn.apply(this, combined)
: _arity(left, _curryN(length, combined, fn));
};
};
},{"./_arity":3,"./_isPlaceholder":7}],7:[function(require,module,exports){
module.exports = function _isPlaceholder(a) {
return a != null &&
typeof a === 'object' &&
a['@@functional/placeholder'] === true;
};
},{}],"flyd/module/takeuntil":[function(require,module,exports){
var flyd = require('../../lib');
module.exports = function(src, term) {
return flyd.endsOn(flyd.merge(term, src.end), flyd.combine(function(src, self) {
self(src());
}, [src]));
};
},{"../../lib":1}]},{},[])
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2hvbWUvYWRtaW4vYnJvd3NlcmlmeS1jZG4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXItcGFjay9fcHJlbHVkZS5qcyIsImxpYi9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9yYW1kYS9zcmMvY3VycnlOLmpzIiwibm9kZV9tb2R1bGVzL3JhbWRhL3NyYy9pbnRlcm5hbC9fYXJpdHkuanMiLCJub2RlX21vZHVsZXMvcmFtZGEvc3JjL2ludGVybmFsL19jdXJyeTEuanMiLCJub2RlX21vZHVsZXMvcmFtZGEvc3JjL2ludGVybmFsL19jdXJyeTIuanMiLCJub2RlX21vZHVsZXMvcmFtZGEvc3JjL2ludGVybmFsL19jdXJyeU4uanMiLCJub2RlX21vZHVsZXMvcmFtZGEvc3JjL2ludGVybmFsL19pc1BsYWNlaG9sZGVyLmpzIiwibW9kdWxlL3Rha2V1bnRpbC9pbmRleC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsbkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3REQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dmFyIGY9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKTt0aHJvdyBmLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsZn12YXIgbD1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwobC5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxsLGwuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc30pIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgY3VycnlOID0gcmVxdWlyZSgncmFtZGEvc3JjL2N1cnJ5TicpO1xuXG4vLyBVdGlsaXR5XG5mdW5jdGlvbiBpc0Z1bmN0aW9uKG9iaikge1xuICByZXR1cm4gISEob2JqICYmIG9iai5jb25zdHJ1Y3RvciAmJiBvYmouY2FsbCAmJiBvYmouYXBwbHkpO1xufVxuZnVuY3Rpb24gdHJ1ZUZuKCkgeyByZXR1cm4gdHJ1ZTsgfVxuXG4vLyBHbG9iYWxzXG52YXIgdG9VcGRhdGUgPSBbXTtcbnZhciBpblN0cmVhbTtcbnZhciBvcmRlciA9IFtdO1xudmFyIG9yZGVyTmV4dElkeCA9IC0xO1xudmFyIGZsdXNoaW5nID0gZmFsc2U7XG5cbi8qKiBAbmFtZXNwYWNlICovXG52YXIgZmx5ZCA9IHt9XG5cbi8vIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLyBBUEkgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vIC8vXG5cbi8qKlxuICogQ3JlYXRlcyBhIG5ldyBzdHJlYW1cbiAqXG4gKiBfX1NpZ25hdHVyZV9fOiBgYSAtPiBTdHJlYW0gYWBcbiAqXG4gKiBAbmFtZSBmbHlkLnN0cmVhbVxuICogQHBhcmFtIHsqfSBpbml0aWFsVmFsdWUgLSAoT3B0aW9uYWwpIHRoZSBpbml0aWFsIHZhbHVlIG9mIHRoZSBzdHJlYW1cbiAqIEByZXR1cm4ge3N0cmVhbX0gdGhlIHN0cmVhbVxuICpcbiAqIEBleGFtcGxlXG4gKiB2YXIgbiA9IGZseWQuc3RyZWFtKDEpOyAvLyBTdHJlYW0gd2l0aCBpbml0aWFsIHZhbHVlIGAxYFxuICogdmFyIHMgPSBmbHlkLnN0cmVhbSgpOyAvLyBTdHJlYW0gd2l0aCBubyBpbml0aWFsIHZhbHVlXG4gKi9cbmZseWQuc3RyZWFtID0gZnVuY3Rpb24oaW5pdGlhbFZhbHVlKSB7XG4gIHZhciBlbmRTdHJlYW0gPSBjcmVhdGVEZXBlbmRlbnRTdHJlYW0oW10sIHRydWVGbik7XG4gIHZhciBzID0gY3JlYXRlU3RyZWFtKCk7XG4gIHMuZW5kID0gZW5kU3RyZWFtO1xuICBzLmZuQXJncyA9IFtdO1xuICBlbmRTdHJlYW0ubGlzdGVuZXJzLnB1c2gocyk7XG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMCkgcyhpbml0aWFsVmFsdWUpO1xuICByZXR1cm4gcztcbn1cblxuLyoqXG4gKiBDcmVhdGUgYSBuZXcgZGVwZW5kZW50IHN0cmVhbVxuICpcbiAqIF9fU2lnbmF0dXJlX186IGAoLi4uU3RyZWFtICogLT4gU3RyZWFtIGIgLT4gYikgLT4gW1N0cmVhbSAqXSAtPiBTdHJlYW0gYmBcbiAqXG4gKiBAbmFtZSBmbHlkLmNvbWJpbmVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIC0gdGhlIGZ1bmN0aW9uIHVzZWQgdG8gY29tYmluZSB0aGUgc3RyZWFtc1xuICogQHBhcmFtIHtBcnJheTxzdHJlYW0+fSBkZXBlbmRlbmNpZXMgLSB0aGUgc3RyZWFtcyB0aGF0IHRoaXMgb25lIGRlcGVuZHMgb25cbiAqIEByZXR1cm4ge3N0cmVhbX0gdGhlIGRlcGVuZGVudCBzdHJlYW1cbiAqXG4gKiBAZXhhbXBsZVxuICogdmFyIG4xID0gZmx5ZC5zdHJlYW0oMCk7XG4gKiB2YXIgbjIgPSBmbHlkLnN0cmVhbSgwKTtcbiAqIHZhciBtYXggPSBmbHlkLmNvbWJpbmUoZnVuY3Rpb24objEsIG4yLCBzZWxmLCBjaGFuZ2VkKSB7XG4gKiAgIHJldHVybiBuMSgpID4gbjIoKSA/IG4xKCkgOiBuMigpO1xuICogfSwgW24xLCBuMl0pO1xuICovXG5mbHlkLmNvbWJpbmUgPSBjdXJyeU4oMiwgY29tYmluZSk7XG5mdW5jdGlvbiBjb21iaW5lKGZuLCBzdHJlYW1zKSB7XG4gIHZhciBpLCBzLCBkZXBzLCBkZXBFbmRTdHJlYW1zO1xuICB2YXIgZW5kU3RyZWFtID0gY3JlYXRlRGVwZW5kZW50U3RyZWFtKFtdLCB0cnVlRm4pO1xuICBkZXBzID0gW107IGRlcEVuZFN0cmVhbXMgPSBbXTtcbiAgZm9yIChpID0gMDsgaSA8IHN0cmVhbXMubGVuZ3RoOyArK2kpIHtcbiAgICBpZiAoc3RyZWFtc1tpXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBkZXBzLnB1c2goc3RyZWFtc1tpXSk7XG4gICAgICBpZiAoc3RyZWFtc1tpXS5lbmQgIT09IHVuZGVmaW5lZCkgZGVwRW5kU3RyZWFtcy5wdXNoKHN0cmVhbXNbaV0uZW5kKTtcbiAgICB9XG4gIH1cbiAgcyA9IGNyZWF0ZURlcGVuZGVudFN0cmVhbShkZXBzLCBmbik7XG4gIHMuZGVwc0NoYW5nZWQgPSBbXTtcbiAgcy5mbkFyZ3MgPSBzLmRlcHMuY29uY2F0KFtzLCBzLmRlcHNDaGFuZ2VkXSk7XG4gIHMuZW5kID0gZW5kU3RyZWFtO1xuICBlbmRTdHJlYW0ubGlzdGVuZXJzLnB1c2gocyk7XG4gIGFkZExpc3RlbmVycyhkZXBFbmRTdHJlYW1zLCBlbmRTdHJlYW0pO1xuICBlbmRTdHJlYW0uZGVwcyA9IGRlcEVuZFN0cmVhbXM7XG4gIHVwZGF0ZVN0cmVhbShzKTtcbiAgcmV0dXJuIHM7XG59XG5cbi8qKlxuICogUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIHN1cHBsaWVkIGFyZ3VtZW50IGlzIGEgRmx5ZCBzdHJlYW0gYW5kIGBmYWxzZWAgb3RoZXJ3aXNlLlxuICpcbiAqIF9fU2lnbmF0dXJlX186IGAqIC0+IEJvb2xlYW5gXG4gKlxuICogQG5hbWUgZmx5ZC5pc1N0cmVhbVxuICogQHBhcmFtIHsqfSB2YWx1ZSAtIHRoZSB2YWx1ZSB0byB0ZXN0XG4gKiBAcmV0dXJuIHtCb29sZWFufSBgdHJ1ZWAgaWYgaXMgYSBGbHlkIHN0cmVhbW4sIGBmYWxzZWAgb3RoZXJ3aXNlXG4gKlxuICogQGV4YW1wbGVcbiAqIHZhciBzID0gZmx5ZC5zdHJlYW0oMSk7XG4gKiB2YXIgbiA9IDE7XG4gKiBmbHlkLmlzU3RyZWFtKHMpOyAvLz0+IHRydWVcbiAqIGZseWQuaXNTdHJlYW0obik7IC8vPT4gZmFsc2VcbiAqL1xuZmx5ZC5pc1N0cmVhbSA9IGZ1bmN0aW9uKHN0cmVhbSkge1xuICByZXR1cm4gaXNGdW5jdGlvbihzdHJlYW0pICYmICdoYXNWYWwnIGluIHN0cmVhbTtcbn1cblxuLyoqXG4gKiBJbnZva2VzIHRoZSBib2R5ICh0aGUgZnVuY3Rpb24gdG8gY2FsY3VsYXRlIHRoZSB2YWx1ZSkgb2YgYSBkZXBlbmRlbnQgc3RyZWFtXG4gKlxuICogQnkgZGVmYXVsdCB0aGUgYm9keSBvZiBhIGRlcGVuZGVudCBzdHJlYW0gaXMgb25seSBjYWxsZWQgd2hlbiBhbGwgdGhlIHN0cmVhbXNcbiAqIHVwb24gd2hpY2ggaXQgZGVwZW5kcyBoYXMgYSB2YWx1ZS4gYGltbWVkaWF0ZWAgY2FuIGNpcmN1bXZlbnQgdGhpcyBiZWhhdmlvdXIuXG4gKiBJdCBpbW1lZGlhdGVseSBpbnZva2VzIHRoZSBib2R5IG9mIGEgZGVwZW5kZW50IHN0cmVhbS5cbiAqXG4gKiBfX1NpZ25hdHVyZV9fOiBgU3RyZWFtIGEgLT4gU3RyZWFtIGFgXG4gKlxuICogQG5hbWUgZmx5ZC5pbW1lZGlhdGVcbiAqIEBwYXJhbSB7c3RyZWFtfSBzdHJlYW0gLSB0aGUgZGVwZW5kZW50IHN0cmVhbVxuICogQHJldHVybiB7c3RyZWFtfSB0aGUgc2FtZSBzdHJlYW1cbiAqXG4gKiBAZXhhbXBsZVxuICogdmFyIHMgPSBmbHlkLnN0cmVhbSgpO1xuICogdmFyIGhhc0l0ZW1zID0gZmx5ZC5pbW1lZGlhdGUoZmx5ZC5jb21iaW5lKGZ1bmN0aW9uKHMpIHtcbiAqICAgcmV0dXJuIHMoKSAhPT0gdW5kZWZpbmVkICYmIHMoKS5sZW5ndGggPiAwO1xuICogfSwgW3NdKTtcbiAqIGNvbnNvbGUubG9nKGhhc0l0ZW1zKCkpOyAvLyBsb2dzIGBmYWxzZWAuIEhhZCBgaW1tZWRpYXRlYCBub3QgYmVlblxuICogICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHVzZWQgYGhhc0l0ZW1zKClgIHdvdWxkJ3ZlIHJldHVybmVkIGB1bmRlZmluZWRgXG4gKiBzKFsxXSk7XG4gKiBjb25zb2xlLmxvZyhoYXNJdGVtcygpKTsgLy8gbG9ncyBgdHJ1ZWAuXG4gKiBzKFtdKTtcbiAqIGNvbnNvbGUubG9nKGhhc0l0ZW1zKCkpOyAvLyBsb2dzIGBmYWxzZWAuXG4gKi9cbmZseWQuaW1tZWRpYXRlID0gZnVuY3Rpb24ocykge1xuICBpZiAocy5kZXBzTWV0ID09PSBmYWxzZSkge1xuICAgIHMuZGVwc01ldCA9IHRydWU7XG4gICAgdXBkYXRlU3RyZWFtKHMpO1xuICB9XG4gIHJldHVybiBzO1xufVxuXG4vKipcbiAqIENoYW5nZXMgd2hpY2ggYGVuZHNTdHJlYW1gIHNob3VsZCB0cmlnZ2VyIHRoZSBlbmRpbmcgb2YgYHNgLlxuICpcbiAqIF9fU2lnbmF0dXJlX186IGBTdHJlYW0gYSAtPiBTdHJlYW0gYiAtPiBTdHJlYW0gYmBcbiAqXG4gKiBAbmFtZSBmbHlkLmVuZHNPblxuICogQHBhcmFtIHtzdHJlYW19IGVuZFN0cmVhbSAtIHRoZSBzdHJlYW0gdG8gdHJpZ2dlciB0aGUgZW5kaW5nXG4gKiBAcGFyYW0ge3N0cmVhbX0gc3RyZWFtIC0gdGhlIHN0cmVhbSB0byBiZSBlbmRlZCBieSB0aGUgZW5kU3RyZWFtXG4gKiBAcGFyYW0ge3N0cmVhbX0gdGhlIHN0cmVhbSBtb2RpZmllZCB0byBiZSBlbmRlZCBieSBlbmRTdHJlYW1cbiAqXG4gKiBAZXhhbXBsZVxuICogdmFyIG4gPSBmbHlkLnN0cmVhbSgxKTtcbiAqIHZhciBraWxsZXIgPSBmbHlkLnN0cmVhbSgpO1xuICogLy8gYGRvdWJsZWAgZW5kcyB3aGVuIGBuYCBlbmRzIG9yIHdoZW4gYGtpbGxlcmAgZW1pdHMgYW55IHZhbHVlXG4gKiB2YXIgZG91YmxlID0gZmx5ZC5lbmRzT24oZmx5ZC5tZXJnZShuLmVuZCwga2lsbGVyKSwgZmx5ZC5jb21iaW5lKGZ1bmN0aW9uKG4pIHtcbiAqICAgcmV0dXJuIDIgKiBuKCk7XG4gKiB9LCBbbl0pO1xuKi9cbmZseWQuZW5kc09uID0gZnVuY3Rpb24oZW5kUywgcykge1xuICBkZXRhY2hEZXBzKHMuZW5kKTtcbiAgZW5kUy5saXN0ZW5lcnMucHVzaChzLmVuZCk7XG4gIHMuZW5kLmRlcHMucHVzaChlbmRTKTtcbiAgcmV0dXJuIHM7XG59XG5cbi8qKlxuICogTWFwIGEgc3RyZWFtXG4gKlxuICogUmV0dXJucyBhIG5ldyBzdHJlYW0gY29uc2lzdGluZyBvZiBldmVyeSB2YWx1ZSBmcm9tIGBzYCBwYXNzZWQgdGhyb3VnaFxuICogYGZuYC4gSS5lLiBgbWFwYCBjcmVhdGVzIGEgbmV3IHN0cmVhbSB0aGF0IGxpc3RlbnMgdG8gYHNgIGFuZFxuICogYXBwbGllcyBgZm5gIHRvIGV2ZXJ5IG5ldyB2YWx1ZS5cbiAqIF9fU2lnbmF0dXJlX186IGAoYSAtPiByZXN1bHQpIC0+IFN0cmVhbSBhIC0+IFN0cmVhbSByZXN1bHRgXG4gKlxuICogQG5hbWUgZmx5ZC5tYXBcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIC0gdGhlIGZ1bmN0aW9uIHRoYXQgcHJvZHVjZXMgdGhlIGVsZW1lbnRzIG9mIHRoZSBuZXcgc3RyZWFtXG4gKiBAcGFyYW0ge3N0cmVhbX0gc3RyZWFtIC0gdGhlIHN0cmVhbSB0byBtYXBcbiAqIEByZXR1cm4ge3N0cmVhbX0gYSBuZXcgc3RyZWFtIHdpdGggdGhlIG1hcHBlZCB2YWx1ZXNcbiAqXG4gKiBAZXhhbXBsZVxuICogdmFyIG51bWJlcnMgPSBmbHlkLnN0cmVhbSgwKTtcbiAqIHZhciBzcXVhcmVkTnVtYmVycyA9IGZseWQubWFwKGZ1bmN0aW9uKG4pIHsgcmV0dXJuIG4qbjsgfSwgbnVtYmVycyk7XG4gKi9cbi8vIExpYnJhcnkgZnVuY3Rpb25zIHVzZSBzZWxmIGNhbGxiYWNrIHRvIGFjY2VwdCAobnVsbCwgdW5kZWZpbmVkKSB1cGRhdGUgdHJpZ2dlcnMuXG5mbHlkLm1hcCA9IGN1cnJ5TigyLCBmdW5jdGlvbihmLCBzKSB7XG4gIHJldHVybiBjb21iaW5lKGZ1bmN0aW9uKHMsIHNlbGYpIHsgc2VsZihmKHMudmFsKSk7IH0sIFtzXSk7XG59KVxuXG4vKipcbiAqIExpc3RlbiB0byBzdHJlYW0gZXZlbnRzXG4gKlxuICogU2ltaWxhciB0byBgbWFwYCBleGNlcHQgdGhhdCB0aGUgcmV0dXJuZWQgc3RyZWFtIGlzIGVtcHR5LiBVc2UgYG9uYCBmb3IgZG9pbmdcbiAqIHNpZGUgZWZmZWN0cyBpbiByZWFjdGlvbiB0byBzdHJlYW0gY2hhbmdlcy4gVXNlIHRoZSByZXR1cm5lZCBzdHJlYW0gb25seSBpZiB5b3VcbiAqIG5lZWQgdG8gbWFudWFsbHkgZW5kIGl0LlxuICpcbiAqIF9fU2lnbmF0dXJlX186IGAoYSAtPiByZXN1bHQpIC0+IFN0cmVhbSBhIC0+IFN0cmVhbSB1bmRlZmluZWRgXG4gKlxuICogQG5hbWUgZmx5ZC5vblxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2IgLSB0aGUgY2FsbGJhY2tcbiAqIEBwYXJhbSB7c3RyZWFtfSBzdHJlYW0gLSB0aGUgc3RyZWFtXG4gKiBAcmV0dXJuIHtzdHJlYW19IGFuIGVtcHR5IHN0cmVhbSAoY2FuIGJlIGVuZGVkKVxuICovXG5mbHlkLm9uID0gY3VycnlOKDIsIGZ1bmN0aW9uKGYsIHMpIHtcbiAgcmV0dXJuIGNvbWJpbmUoZnVuY3Rpb24ocykgeyBmKHMudmFsKTsgfSwgW3NdKTtcbn0pXG5cbi8qKlxuICogQ3JlYXRlcyBhIG5ldyBzdHJlYW0gd2l0aCB0aGUgcmVzdWx0cyBvZiBjYWxsaW5nIHRoZSBmdW5jdGlvbiBvbiBldmVyeSBpbmNvbWluZ1xuICogc3RyZWFtIHdpdGggYW5kIGFjY3VtdWxhdG9yIGFuZCB0aGUgaW5jb21pbmcgdmFsdWUuXG4gKlxuICogX19TaWduYXR1cmVfXzogYChhIC0+IGIgLT4gYSkgLT4gYSAtPiBTdHJlYW0gYiAtPiBTdHJlYW0gYWBcbiAqXG4gKiBAbmFtZSBmbHlkLnNjYW5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIC0gdGhlIGZ1bmN0aW9uIHRvIGNhbGxcbiAqIEBwYXJhbSB7Kn0gdmFsIC0gdGhlIGluaXRpYWwgdmFsdWUgb2YgdGhlIGFjY3VtdWxhdG9yXG4gKiBAcGFyYW0ge3N0cmVhbX0gc3RyZWFtIC0gdGhlIHN0cmVhbSBzb3VyY2VcbiAqIEByZXR1cm4ge3N0cmVhbX0gdGhlIG5ldyBzdHJlYW1cbiAqXG4gKiBAZXhhbXBsZVxuICogdmFyIG51bWJlcnMgPSBmbHlkLnN0cmVhbSgpO1xuICogdmFyIHN1bSA9IGZseWQuc2NhbihmdW5jdGlvbihzdW0sIG4pIHsgcmV0dXJuIHN1bStuOyB9LCAwLCBudW1iZXJzKTtcbiAqIG51bWJlcnMoMikoMykoNSk7XG4gKiBzdW0oKTsgLy8gMTBcbiAqL1xuZmx5ZC5zY2FuID0gY3VycnlOKDMsIGZ1bmN0aW9uKGYsIGFjYywgcykge1xuICB2YXIgbnMgPSBjb21iaW5lKGZ1bmN0aW9uKHMsIHNlbGYpIHtcbiAgICBzZWxmKGFjYyA9IGYoYWNjLCBzLnZhbCkpO1xuICB9LCBbc10pO1xuICBpZiAoIW5zLmhhc1ZhbCkgbnMoYWNjKTtcbiAgcmV0dXJuIG5zO1xufSk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIG5ldyBzdHJlYW0gZG93biB3aGljaCBhbGwgdmFsdWVzIGZyb20gYm90aCBgc3RyZWFtMWAgYW5kIGBzdHJlYW0yYFxuICogd2lsbCBiZSBzZW50LlxuICpcbiAqIF9fU2lnbmF0dXJlX186IGBTdHJlYW0gYSAtPiBTdHJlYW0gYSAtPiBTdHJlYW0gYWBcbiAqXG4gKiBAbmFtZSBmbHlkLm1lcmdlXG4gKiBAcGFyYW0ge3N0cmVhbX0gc291cmNlMSAtIG9uZSBzdHJlYW0gdG8gYmUgbWVyZ2VkXG4gKiBAcGFyYW0ge3N0cmVhbX0gc291cmNlMiAtIHRoZSBvdGhlciBzdHJlYW0gdG8gYmUgbWVyZ2VkXG4gKiBAcmV0dXJuIHtzdHJlYW19IGEgc3RyZWFtIHdpdGggdGhlIHZhbHVlcyBmcm9tIGJvdGggc291cmNlc1xuICpcbiAqIEBleGFtcGxlXG4gKiB2YXIgYnRuMUNsaWNrcyA9IGZseWQuc3RyZWFtKCk7XG4gKiBidXR0b24xRWxtLmFkZEV2ZW50TGlzdGVuZXIoYnRuMUNsaWNrcyk7XG4gKiB2YXIgYnRuMkNsaWNrcyA9IGZseWQuc3RyZWFtKCk7XG4gKiBidXR0b24yRWxtLmFkZEV2ZW50TGlzdGVuZXIoYnRuMkNsaWNrcyk7XG4gKiB2YXIgYWxsQ2xpY2tzID0gZmx5ZC5tZXJnZShidG4xQ2xpY2tzLCBidG4yQ2xpY2tzKTtcbiAqL1xuZmx5ZC5tZXJnZSA9IGN1cnJ5TigyLCBmdW5jdGlvbihzMSwgczIpIHtcbiAgdmFyIHMgPSBmbHlkLmltbWVkaWF0ZShjb21iaW5lKGZ1bmN0aW9uKHMxLCBzMiwgc2VsZiwgY2hhbmdlZCkge1xuICAgIGlmIChjaGFuZ2VkWzBdKSB7XG4gICAgICBzZWxmKGNoYW5nZWRbMF0oKSk7XG4gICAgfSBlbHNlIGlmIChzMS5oYXNWYWwpIHtcbiAgICAgIHNlbGYoczEudmFsKTtcbiAgICB9IGVsc2UgaWYgKHMyLmhhc1ZhbCkge1xuICAgICAgc2VsZihzMi52YWwpO1xuICAgIH1cbiAgfSwgW3MxLCBzMl0pKTtcbiAgZmx5ZC5lbmRzT24oY29tYmluZShmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSwgW3MxLmVuZCwgczIuZW5kXSksIHMpO1xuICByZXR1cm4gcztcbn0pO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgc3RyZWFtIHJlc3VsdGluZyBmcm9tIGFwcGx5aW5nIGB0cmFuc2R1Y2VyYCB0byBgc3RyZWFtYC5cbiAqXG4gKiBfX1NpZ25hdHVyZV9fOiBgVHJhbnNkdWNlciAtPiBTdHJlYW0gYSAtPiBTdHJlYW0gYmBcbiAqXG4gKiBAbmFtZSBmbHlkLnRyYW5zZHVjZVxuICogQHBhcmFtIHtUcmFuc2R1Y2VyfSB4Zm9ybSAtIHRoZSB0cmFuc2R1Y2VyIHRyYW5zZm9ybWF0aW9uXG4gKiBAcGFyYW0ge3N0cmVhbX0gc291cmNlIC0gdGhlIHN0cmVhbSBzb3VyY2VcbiAqIEByZXR1cm4ge3N0cmVhbX0gdGhlIG5ldyBzdHJlYW1cbiAqXG4gKiBAZXhhbXBsZVxuICogdmFyIHQgPSByZXF1aXJlKCd0cmFuc2R1Y2Vycy5qcycpO1xuICpcbiAqIHZhciByZXN1bHRzID0gW107XG4gKiB2YXIgczEgPSBmbHlkLnN0cmVhbSgpO1xuICogdmFyIHR4ID0gdC5jb21wb3NlKHQubWFwKGZ1bmN0aW9uKHgpIHsgcmV0dXJuIHggKiAyOyB9KSwgdC5kZWR1cGUoKSk7XG4gKiB2YXIgczIgPSBmbHlkLnRyYW5zZHVjZSh0eCwgczEpO1xuICogZmx5ZC5jb21iaW5lKGZ1bmN0aW9uKHMyKSB7IHJlc3VsdHMucHVzaChzMigpKTsgfSwgW3MyXSk7XG4gKiBzMSgxKSgxKSgyKSgzKSgzKSgzKSg0KTtcbiAqIHJlc3VsdHM7IC8vID0+IFsyLCA0LCA2LCA4XVxuICovXG5mbHlkLnRyYW5zZHVjZSA9IGN1cnJ5TigyLCBmdW5jdGlvbih4Zm9ybSwgc291cmNlKSB7XG4gIHhmb3JtID0geGZvcm0obmV3IFN0cmVhbVRyYW5zZm9ybWVyKCkpO1xuICByZXR1cm4gY29tYmluZShmdW5jdGlvbihzb3VyY2UsIHNlbGYpIHtcbiAgICB2YXIgcmVzID0geGZvcm1bJ0BAdHJhbnNkdWNlci9zdGVwJ10odW5kZWZpbmVkLCBzb3VyY2UudmFsKTtcbiAgICBpZiAocmVzICYmIHJlc1snQEB0cmFuc2R1Y2VyL3JlZHVjZWQnXSA9PT0gdHJ1ZSkge1xuICAgICAgc2VsZi5lbmQodHJ1ZSk7XG4gICAgICByZXR1cm4gcmVzWydAQHRyYW5zZHVjZXIvdmFsdWUnXTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG4gIH0sIFtzb3VyY2VdKTtcbn0pO1xuXG4vKipcbiAqIFJldHVybnMgYGZuYCBjdXJyaWVkIHRvIGBuYC4gVXNlIHRoaXMgZnVuY3Rpb24gdG8gY3VycnkgZnVuY3Rpb25zIGV4cG9zZWQgYnlcbiAqIG1vZHVsZXMgZm9yIEZseWQuXG4gKlxuICogQG5hbWUgZmx5ZC5jdXJyeU5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtJbnRlZ2VyfSBhcml0eSAtIHRoZSBmdW5jdGlvbiBhcml0eVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm4gLSB0aGUgZnVuY3Rpb24gdG8gY3VycnlcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSB0aGUgY3VycmllZCBmdW5jdGlvblxuICpcbiAqIEBleGFtcGxlXG4gKiBmdW5jdGlvbiBhZGQoeCwgeSkgeyByZXR1cm4geCArIHk7IH07XG4gKiB2YXIgYSA9IGZseWQuY3VycnlOKDIsIGFkZCk7XG4gKiBhKDIpKDQpIC8vID0+IDZcbiAqL1xuZmx5ZC5jdXJyeU4gPSBjdXJyeU5cblxuLyoqXG4gKiBSZXR1cm5zIGEgbmV3IHN0cmVhbSBpZGVudGljYWwgdG8gdGhlIG9yaWdpbmFsIGV4Y2VwdCBldmVyeVxuICogdmFsdWUgd2lsbCBiZSBwYXNzZWQgdGhyb3VnaCBgZmAuXG4gKlxuICogX05vdGU6XyBUaGlzIGZ1bmN0aW9uIGlzIGluY2x1ZGVkIGluIG9yZGVyIHRvIHN1cHBvcnQgdGhlIGZhbnRhc3kgbGFuZFxuICogc3BlY2lmaWNhdGlvbi5cbiAqXG4gKiBfX1NpZ25hdHVyZV9fOiBDYWxsZWQgYm91bmQgdG8gYFN0cmVhbSBhYDogYChhIC0+IGIpIC0+IFN0cmVhbSBiYFxuICpcbiAqIEBuYW1lIHN0cmVhbS5tYXBcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmN0aW9uIC0gdGhlIGZ1bmN0aW9uIHRvIGFwcGx5XG4gKiBAcmV0dXJuIHtzdHJlYW19IGEgbmV3IHN0cmVhbSB3aXRoIHRoZSB2YWx1ZXMgbWFwcGVkXG4gKlxuICogQGV4YW1wbGVcbiAqIHZhciBudW1iZXJzID0gZmx5ZC5zdHJlYW0oMCk7XG4gKiB2YXIgc3F1YXJlZE51bWJlcnMgPSBudW1iZXJzLm1hcChmdW5jdGlvbihuKSB7IHJldHVybiBuKm47IH0pO1xuICovXG5mdW5jdGlvbiBib3VuZE1hcChmKSB7IHJldHVybiBmbHlkLm1hcChmLCB0aGlzKTsgfVxuXG4vKipcbiAqIFJldHVybnMgYSBuZXcgc3RyZWFtIHdoaWNoIGlzIHRoZSByZXN1bHQgb2YgYXBwbHlpbmcgdGhlXG4gKiBmdW5jdGlvbnMgZnJvbSBgdGhpc2Agc3RyZWFtIHRvIHRoZSB2YWx1ZXMgaW4gYHN0cmVhbWAgcGFyYW1ldGVyLlxuICpcbiAqIGB0aGlzYCBzdHJlYW0gbXVzdCBiZSBhIHN0cmVhbSBvZiBmdW5jdGlvbnMuXG4gKlxuICogX05vdGU6XyBUaGlzIGZ1bmN0aW9uIGlzIGluY2x1ZGVkIGluIG9yZGVyIHRvIHN1cHBvcnQgdGhlIGZhbnRhc3kgbGFuZFxuICogc3BlY2lmaWNhdGlvbi5cbiAqXG4gKiBfX1NpZ25hdHVyZV9fOiBDYWxsZWQgYm91bmQgdG8gYFN0cmVhbSAoYSAtPiBiKWA6IGBhIC0+IFN0cmVhbSBiYFxuICpcbiAqIEBuYW1lIHN0cmVhbS5hcFxuICogQHBhcmFtIHtzdHJlYW19IHN0cmVhbSAtIHRoZSB2YWx1ZXMgc3RyZWFtXG4gKiBAcmV0dXJuIHtzdHJlYW19IGEgbmV3IHN0cmFtIHdpdGggdGhlIGZ1bmN0aW9ucyBhcHBsaWVkIHRvIHZhbHVlc1xuICpcbiAqIEBleGFtcGxlXG4gKiB2YXIgYWRkID0gZmx5ZC5jdXJyeU4oMiwgZnVuY3Rpb24oeCwgeSkgeyByZXR1cm4geCArIHk7IH0pO1xuICogdmFyIG51bWJlcnMxID0gZmx5ZC5zdHJlYW0oKTtcbiAqIHZhciBudW1iZXJzMiA9IGZseWQuc3RyZWFtKCk7XG4gKiB2YXIgYWRkVG9OdW1iZXJzMSA9IGZseWQubWFwKGFkZCwgbnVtYmVyczEpO1xuICogdmFyIGFkZGVkID0gYWRkVG9OdW1iZXJzMS5hcChudW1iZXJzMik7XG4gKi9cbmZ1bmN0aW9uIGFwKHMyKSB7XG4gIHZhciBzMSA9IHRoaXM7XG4gIHJldHVybiBjb21iaW5lKGZ1bmN0aW9uKHMxLCBzMiwgc2VsZikgeyBzZWxmKHMxLnZhbChzMi52YWwpKTsgfSwgW3MxLCBzMl0pO1xufVxuXG4vKipcbiAqIEdldCBhIGh1bWFuIHJlYWRhYmxlIHZpZXcgb2YgYSBzdHJlYW1cbiAqIEBuYW1lIHN0cmVhbS50b1N0cmluZ1xuICogQHJldHVybiB7U3RyaW5nfSB0aGUgc3RyZWFtIHN0cmluZyByZXByZXNlbnRhdGlvblxuICovXG5mdW5jdGlvbiBzdHJlYW1Ub1N0cmluZygpIHtcbiAgcmV0dXJuICdzdHJlYW0oJyArIHRoaXMudmFsICsgJyknO1xufVxuXG4vKipcbiAqIEBuYW1lIHN0cmVhbS5lbmRcbiAqIEBtZW1iZXJvZiBzdHJlYW1cbiAqIEEgc3RyZWFtIHRoYXQgZW1pdHMgYHRydWVgIHdoZW4gdGhlIHN0cmVhbSBlbmRzLiBJZiBgdHJ1ZWAgaXMgcHVzaGVkIGRvd24gdGhlXG4gKiBzdHJlYW0gdGhlIHBhcmVudCBzdHJlYW0gZW5kcy5cbiAqL1xuXG4vKipcbiAqIEBuYW1lIHN0cmVhbS5vZlxuICogQGZ1bmN0aW9uXG4gKiBAbWVtYmVyb2Ygc3RyZWFtXG4gKiBSZXR1cm5zIGEgbmV3IHN0cmVhbSB3aXRoIGB2YWx1ZWAgYXMgaXRzIGluaXRpYWwgdmFsdWUuIEl0IGlzIGlkZW50aWNhbCB0b1xuICogY2FsbGluZyBgZmx5ZC5zdHJlYW1gIHdpdGggb25lIGFyZ3VtZW50LlxuICpcbiAqIF9fU2lnbmF0dXJlX186IENhbGxlZCBib3VuZCB0byBgU3RyZWFtIChhKWA6IGBiIC0+IFN0cmVhbSBiYFxuICpcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgLSB0aGUgaW5pdGlhbCB2YWx1ZVxuICogQHJldHVybiB7c3RyZWFtfSB0aGUgbmV3IHN0cmVhbVxuICpcbiAqIEBleGFtcGxlXG4gKiB2YXIgbiA9IGZseWQuc3RyZWFtKDEpO1xuICogdmFyIG0gPSBuLm9mKDEpO1xuICovXG5cbi8vIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLyBQUklWQVRFIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLyAvL1xuLyoqXG4gKiBAcHJpdmF0ZVxuICogQ3JlYXRlIGEgc3RyZWFtIHdpdGggbm8gZGVwZW5kZW5jaWVzIGFuZCBubyB2YWx1ZVxuICogQHJldHVybiB7RnVuY3Rpb259IGEgZmx5ZCBzdHJlYW1cbiAqL1xuZnVuY3Rpb24gY3JlYXRlU3RyZWFtKCkge1xuICBmdW5jdGlvbiBzKG4pIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIHMudmFsXG4gICAgdXBkYXRlU3RyZWFtVmFsdWUocywgbilcbiAgICByZXR1cm4gc1xuICB9XG4gIHMuaGFzVmFsID0gZmFsc2U7XG4gIHMudmFsID0gdW5kZWZpbmVkO1xuICBzLnZhbHMgPSBbXTtcbiAgcy5saXN0ZW5lcnMgPSBbXTtcbiAgcy5xdWV1ZWQgPSBmYWxzZTtcbiAgcy5lbmQgPSB1bmRlZmluZWQ7XG4gIHMubWFwID0gYm91bmRNYXA7XG4gIHMuYXAgPSBhcDtcbiAgcy5vZiA9IGZseWQuc3RyZWFtO1xuICBzLnRvU3RyaW5nID0gc3RyZWFtVG9TdHJpbmc7XG4gIHJldHVybiBzO1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBDcmVhdGUgYSBkZXBlbmRlbnQgc3RyZWFtXG4gKiBAcGFyYW0ge0FycmF5PHN0cmVhbT59IGRlcGVuZGVuY2llcyAtIGFuIGFycmF5IG9mIHRoZSBzdHJlYW1zXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiAtIHRoZSBmdW5jdGlvbiB1c2VkIHRvIGNhbGN1bGF0ZSB0aGUgbmV3IHN0cmVhbSB2YWx1ZVxuICogZnJvbSB0aGUgZGVwZW5kZW5jaWVzXG4gKiBAcmV0dXJuIHtzdHJlYW19IHRoZSBjcmVhdGVkIHN0cmVhbVxuICovXG5mdW5jdGlvbiBjcmVhdGVEZXBlbmRlbnRTdHJlYW0oZGVwcywgZm4pIHtcbiAgdmFyIHMgPSBjcmVhdGVTdHJlYW0oKTtcbiAgcy5mbiA9IGZuO1xuICBzLmRlcHMgPSBkZXBzO1xuICBzLmRlcHNNZXQgPSBmYWxzZTtcbiAgcy5kZXBzQ2hhbmdlZCA9IGRlcHMubGVuZ3RoID4gMCA/IFtdIDogdW5kZWZpbmVkO1xuICBzLnNob3VsZFVwZGF0ZSA9IGZhbHNlO1xuICBhZGRMaXN0ZW5lcnMoZGVwcywgcyk7XG4gIHJldHVybiBzO1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBDaGVjayBpZiBhbGwgdGhlIGRlcGVuZGVuY2llcyBoYXZlIHZhbHVlc1xuICogQHBhcmFtIHtzdHJlYW19IHN0cmVhbSAtIHRoZSBzdHJlYW0gdG8gY2hlY2sgZGVwZW5jZW5jaWVzIGZyb21cbiAqIEByZXR1cm4ge0Jvb2xlYW59IGB0cnVlYCBpZiBhbGwgZGVwZW5kZW5jaWVzIGhhdmUgdmFsZXMsIGBmYWxzZWAgb3RoZXJ3aXNlXG4gKi9cbmZ1bmN0aW9uIGluaXRpYWxEZXBzTm90TWV0KHN0cmVhbSkge1xuICBzdHJlYW0uZGVwc01ldCA9IHN0cmVhbS5kZXBzLmV2ZXJ5KGZ1bmN0aW9uKHMpIHtcbiAgICByZXR1cm4gcy5oYXNWYWw7XG4gIH0pO1xuICByZXR1cm4gIXN0cmVhbS5kZXBzTWV0O1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBVcGRhdGUgYSBkZXBlbmRlbnQgc3RyZWFtIHVzaW5nIGl0cyBkZXBlbmRlbmNpZXMgaW4gYW4gYXRvbWljIHdheVxuICogQHBhcmFtIHtzdHJlYW19IHN0cmVhbSAtIHRoZSBzdHJlYW0gdG8gdXBkYXRlXG4gKi9cbmZ1bmN0aW9uIHVwZGF0ZVN0cmVhbShzKSB7XG4gIGlmICgocy5kZXBzTWV0ICE9PSB0cnVlICYmIGluaXRpYWxEZXBzTm90TWV0KHMpKSB8fFxuICAgICAgKHMuZW5kICE9PSB1bmRlZmluZWQgJiYgcy5lbmQudmFsID09PSB0cnVlKSkgcmV0dXJuO1xuICBpZiAoaW5TdHJlYW0gIT09IHVuZGVmaW5lZCkge1xuICAgIHRvVXBkYXRlLnB1c2gocyk7XG4gICAgcmV0dXJuO1xuICB9XG4gIGluU3RyZWFtID0gcztcbiAgaWYgKHMuZGVwc0NoYW5nZWQpIHMuZm5BcmdzW3MuZm5BcmdzLmxlbmd0aCAtIDFdID0gcy5kZXBzQ2hhbmdlZDtcbiAgdmFyIHJldHVyblZhbCA9IHMuZm4uYXBwbHkocy5mbiwgcy5mbkFyZ3MpO1xuICBpZiAocmV0dXJuVmFsICE9PSB1bmRlZmluZWQpIHtcbiAgICBzKHJldHVyblZhbCk7XG4gIH1cbiAgaW5TdHJlYW0gPSB1bmRlZmluZWQ7XG4gIGlmIChzLmRlcHNDaGFuZ2VkICE9PSB1bmRlZmluZWQpIHMuZGVwc0NoYW5nZWQgPSBbXTtcbiAgcy5zaG91bGRVcGRhdGUgPSBmYWxzZTtcbiAgaWYgKGZsdXNoaW5nID09PSBmYWxzZSkgZmx1c2hVcGRhdGUoKTtcbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogVXBkYXRlIHRoZSBkZXBlbmRlbmNpZXMgb2YgYSBzdHJlYW1cbiAqIEBwYXJhbSB7c3RyZWFtfSBzdHJlYW1cbiAqL1xuZnVuY3Rpb24gdXBkYXRlRGVwcyhzKSB7XG4gIHZhciBpLCBvLCBsaXN0XG4gIHZhciBsaXN0ZW5lcnMgPSBzLmxpc3RlbmVycztcbiAgZm9yIChpID0gMDsgaSA8IGxpc3RlbmVycy5sZW5ndGg7ICsraSkge1xuICAgIGxpc3QgPSBsaXN0ZW5lcnNbaV07XG4gICAgaWYgKGxpc3QuZW5kID09PSBzKSB7XG4gICAgICBlbmRTdHJlYW0obGlzdCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChsaXN0LmRlcHNDaGFuZ2VkICE9PSB1bmRlZmluZWQpIGxpc3QuZGVwc0NoYW5nZWQucHVzaChzKTtcbiAgICAgIGxpc3Quc2hvdWxkVXBkYXRlID0gdHJ1ZTtcbiAgICAgIGZpbmREZXBzKGxpc3QpO1xuICAgIH1cbiAgfVxuICBmb3IgKDsgb3JkZXJOZXh0SWR4ID49IDA7IC0tb3JkZXJOZXh0SWR4KSB7XG4gICAgbyA9IG9yZGVyW29yZGVyTmV4dElkeF07XG4gICAgaWYgKG8uc2hvdWxkVXBkYXRlID09PSB0cnVlKSB1cGRhdGVTdHJlYW0obyk7XG4gICAgby5xdWV1ZWQgPSBmYWxzZTtcbiAgfVxufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBBZGQgc3RyZWFtIGRlcGVuZGVuY2llcyB0byB0aGUgZ2xvYmFsIGBvcmRlcmAgcXVldWUuXG4gKiBAcGFyYW0ge3N0cmVhbX0gc3RyZWFtXG4gKiBAc2VlIHVwZGF0ZURlcHNcbiAqL1xuZnVuY3Rpb24gZmluZERlcHMocykge1xuICB2YXIgaVxuICB2YXIgbGlzdGVuZXJzID0gcy5saXN0ZW5lcnM7XG4gIGlmIChzLnF1ZXVlZCA9PT0gZmFsc2UpIHtcbiAgICBzLnF1ZXVlZCA9IHRydWU7XG4gICAgZm9yIChpID0gMDsgaSA8IGxpc3RlbmVycy5sZW5ndGg7ICsraSkge1xuICAgICAgZmluZERlcHMobGlzdGVuZXJzW2ldKTtcbiAgICB9XG4gICAgb3JkZXJbKytvcmRlck5leHRJZHhdID0gcztcbiAgfVxufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIGZsdXNoVXBkYXRlKCkge1xuICBmbHVzaGluZyA9IHRydWU7XG4gIHdoaWxlICh0b1VwZGF0ZS5sZW5ndGggPiAwKSB7XG4gICAgdmFyIHMgPSB0b1VwZGF0ZS5zaGlmdCgpO1xuICAgIGlmIChzLnZhbHMubGVuZ3RoID4gMCkgcy52YWwgPSBzLnZhbHMuc2hpZnQoKTtcbiAgICB1cGRhdGVEZXBzKHMpO1xuICB9XG4gIGZsdXNoaW5nID0gZmFsc2U7XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIFB1c2ggZG93biBhIHZhbHVlIGludG8gYSBzdHJlYW1cbiAqIEBwYXJhbSB7c3RyZWFtfSBzdHJlYW1cbiAqIEBwYXJhbSB7Kn0gdmFsdWVcbiAqL1xuZnVuY3Rpb24gdXBkYXRlU3RyZWFtVmFsdWUocywgbikge1xuICBpZiAobiAhPT0gdW5kZWZpbmVkICYmIG4gIT09IG51bGwgJiYgaXNGdW5jdGlvbihuLnRoZW4pKSB7XG4gICAgbi50aGVuKHMpO1xuICAgIHJldHVybjtcbiAgfVxuICBzLnZhbCA9IG47XG4gIHMuaGFzVmFsID0gdHJ1ZTtcbiAgaWYgKGluU3RyZWFtID09PSB1bmRlZmluZWQpIHtcbiAgICBmbHVzaGluZyA9IHRydWU7XG4gICAgdXBkYXRlRGVwcyhzKTtcbiAgICBpZiAodG9VcGRhdGUubGVuZ3RoID4gMCkgZmx1c2hVcGRhdGUoKTsgZWxzZSBmbHVzaGluZyA9IGZhbHNlO1xuICB9IGVsc2UgaWYgKGluU3RyZWFtID09PSBzKSB7XG4gICAgbWFya0xpc3RlbmVycyhzLCBzLmxpc3RlbmVycyk7XG4gIH0gZWxzZSB7XG4gICAgcy52YWxzLnB1c2gobik7XG4gICAgdG9VcGRhdGUucHVzaChzKTtcbiAgfVxufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIG1hcmtMaXN0ZW5lcnMocywgbGlzdHMpIHtcbiAgdmFyIGksIGxpc3Q7XG4gIGZvciAoaSA9IDA7IGkgPCBsaXN0cy5sZW5ndGg7ICsraSkge1xuICAgIGxpc3QgPSBsaXN0c1tpXTtcbiAgICBpZiAobGlzdC5lbmQgIT09IHMpIHtcbiAgICAgIGlmIChsaXN0LmRlcHNDaGFuZ2VkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgbGlzdC5kZXBzQ2hhbmdlZC5wdXNoKHMpO1xuICAgICAgfVxuICAgICAgbGlzdC5zaG91bGRVcGRhdGUgPSB0cnVlO1xuICAgIH0gZWxzZSB7XG4gICAgICBlbmRTdHJlYW0obGlzdCk7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEFkZCBkZXBlbmRlbmNpZXMgdG8gYSBzdHJlYW1cbiAqIEBwYXJhbSB7QXJyYXk8c3RyZWFtPn0gZGVwZW5kZW5jaWVzXG4gKiBAcGFyYW0ge3N0cmVhbX0gc3RyZWFtXG4gKi9cbmZ1bmN0aW9uIGFkZExpc3RlbmVycyhkZXBzLCBzKSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgZGVwcy5sZW5ndGg7ICsraSkge1xuICAgIGRlcHNbaV0ubGlzdGVuZXJzLnB1c2gocyk7XG4gIH1cbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogUmVtb3ZlcyBhbiBzdHJlYW0gZnJvbSBhIGRlcGVuZGVuY3kgYXJyYXlcbiAqIEBwYXJhbSB7c3RyZWFtfSBzdHJlYW1cbiAqIEBwYXJhbSB7QXJyYXk8c3RyZWFtPn0gZGVwZW5kZW5jaWVzXG4gKi9cbmZ1bmN0aW9uIHJlbW92ZUxpc3RlbmVyKHMsIGxpc3RlbmVycykge1xuICB2YXIgaWR4ID0gbGlzdGVuZXJzLmluZGV4T2Yocyk7XG4gIGxpc3RlbmVyc1tpZHhdID0gbGlzdGVuZXJzW2xpc3RlbmVycy5sZW5ndGggLSAxXTtcbiAgbGlzdGVuZXJzLmxlbmd0aC0tO1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBEZXRhY2ggYSBzdHJlYW0gZnJvbSBpdHMgZGVwZW5kZW5jaWVzXG4gKiBAcGFyYW0ge3N0cmVhbX0gc3RyZWFtXG4gKi9cbmZ1bmN0aW9uIGRldGFjaERlcHMocykge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHMuZGVwcy5sZW5ndGg7ICsraSkge1xuICAgIHJlbW92ZUxpc3RlbmVyKHMsIHMuZGVwc1tpXS5saXN0ZW5lcnMpO1xuICB9XG4gIHMuZGVwcy5sZW5ndGggPSAwO1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBFbmRzIGEgc3RyZWFtXG4gKi9cbmZ1bmN0aW9uIGVuZFN0cmVhbShzKSB7XG4gIGlmIChzLmRlcHMgIT09IHVuZGVmaW5lZCkgZGV0YWNoRGVwcyhzKTtcbiAgaWYgKHMuZW5kICE9PSB1bmRlZmluZWQpIGRldGFjaERlcHMocy5lbmQpO1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiB0cmFuc2R1Y2VyIHN0cmVhbSB0cmFuc2Zvcm1lclxuICovXG5mdW5jdGlvbiBTdHJlYW1UcmFuc2Zvcm1lcigpIHsgfVxuU3RyZWFtVHJhbnNmb3JtZXIucHJvdG90eXBlWydAQHRyYW5zZHVjZXIvaW5pdCddID0gZnVuY3Rpb24oKSB7IH07XG5TdHJlYW1UcmFuc2Zvcm1lci5wcm90b3R5cGVbJ0BAdHJhbnNkdWNlci9yZXN1bHQnXSA9IGZ1bmN0aW9uKCkgeyB9O1xuU3RyZWFtVHJhbnNmb3JtZXIucHJvdG90eXBlWydAQHRyYW5zZHVjZXIvc3RlcCddID0gZnVuY3Rpb24ocywgdikgeyByZXR1cm4gdjsgfTtcblxubW9kdWxlLmV4cG9ydHMgPSBmbHlkO1xuIiwidmFyIF9hcml0eSA9IHJlcXVpcmUoJy4vaW50ZXJuYWwvX2FyaXR5Jyk7XG52YXIgX2N1cnJ5MSA9IHJlcXVpcmUoJy4vaW50ZXJuYWwvX2N1cnJ5MScpO1xudmFyIF9jdXJyeTIgPSByZXF1aXJlKCcuL2ludGVybmFsL19jdXJyeTInKTtcbnZhciBfY3VycnlOID0gcmVxdWlyZSgnLi9pbnRlcm5hbC9fY3VycnlOJyk7XG5cblxuLyoqXG4gKiBSZXR1cm5zIGEgY3VycmllZCBlcXVpdmFsZW50IG9mIHRoZSBwcm92aWRlZCBmdW5jdGlvbiwgd2l0aCB0aGUgc3BlY2lmaWVkXG4gKiBhcml0eS4gVGhlIGN1cnJpZWQgZnVuY3Rpb24gaGFzIHR3byB1bnVzdWFsIGNhcGFiaWxpdGllcy4gRmlyc3QsIGl0c1xuICogYXJndW1lbnRzIG5lZWRuJ3QgYmUgcHJvdmlkZWQgb25lIGF0IGEgdGltZS4gSWYgYGdgIGlzIGBSLmN1cnJ5TigzLCBmKWAsIHRoZVxuICogZm9sbG93aW5nIGFyZSBlcXVpdmFsZW50OlxuICpcbiAqICAgLSBgZygxKSgyKSgzKWBcbiAqICAgLSBgZygxKSgyLCAzKWBcbiAqICAgLSBgZygxLCAyKSgzKWBcbiAqICAgLSBgZygxLCAyLCAzKWBcbiAqXG4gKiBTZWNvbmRseSwgdGhlIHNwZWNpYWwgcGxhY2Vob2xkZXIgdmFsdWUgYFIuX19gIG1heSBiZSB1c2VkIHRvIHNwZWNpZnlcbiAqIFwiZ2Fwc1wiLCBhbGxvd2luZyBwYXJ0aWFsIGFwcGxpY2F0aW9uIG9mIGFueSBjb21iaW5hdGlvbiBvZiBhcmd1bWVudHMsXG4gKiByZWdhcmRsZXNzIG9mIHRoZWlyIHBvc2l0aW9ucy4gSWYgYGdgIGlzIGFzIGFib3ZlIGFuZCBgX2AgaXMgYFIuX19gLCB0aGVcbiAqIGZvbGxvd2luZyBhcmUgZXF1aXZhbGVudDpcbiAqXG4gKiAgIC0gYGcoMSwgMiwgMylgXG4gKiAgIC0gYGcoXywgMiwgMykoMSlgXG4gKiAgIC0gYGcoXywgXywgMykoMSkoMilgXG4gKiAgIC0gYGcoXywgXywgMykoMSwgMilgXG4gKiAgIC0gYGcoXywgMikoMSkoMylgXG4gKiAgIC0gYGcoXywgMikoMSwgMylgXG4gKiAgIC0gYGcoXywgMikoXywgMykoMSlgXG4gKlxuICogQGZ1bmNcbiAqIEBtZW1iZXJPZiBSXG4gKiBAc2luY2UgdjAuNS4wXG4gKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAqIEBzaWcgTnVtYmVyIC0+ICgqIC0+IGEpIC0+ICgqIC0+IGEpXG4gKiBAcGFyYW0ge051bWJlcn0gbGVuZ3RoIFRoZSBhcml0eSBmb3IgdGhlIHJldHVybmVkIGZ1bmN0aW9uLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm4gVGhlIGZ1bmN0aW9uIHRvIGN1cnJ5LlxuICogQHJldHVybiB7RnVuY3Rpb259IEEgbmV3LCBjdXJyaWVkIGZ1bmN0aW9uLlxuICogQHNlZSBSLmN1cnJ5XG4gKiBAZXhhbXBsZVxuICpcbiAqICAgICAgdmFyIHN1bUFyZ3MgPSAoLi4uYXJncykgPT4gUi5zdW0oYXJncyk7XG4gKlxuICogICAgICB2YXIgY3VycmllZEFkZEZvdXJOdW1iZXJzID0gUi5jdXJyeU4oNCwgc3VtQXJncyk7XG4gKiAgICAgIHZhciBmID0gY3VycmllZEFkZEZvdXJOdW1iZXJzKDEsIDIpO1xuICogICAgICB2YXIgZyA9IGYoMyk7XG4gKiAgICAgIGcoNCk7IC8vPT4gMTBcbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBfY3VycnkyKGZ1bmN0aW9uIGN1cnJ5TihsZW5ndGgsIGZuKSB7XG4gIGlmIChsZW5ndGggPT09IDEpIHtcbiAgICByZXR1cm4gX2N1cnJ5MShmbik7XG4gIH1cbiAgcmV0dXJuIF9hcml0eShsZW5ndGgsIF9jdXJyeU4obGVuZ3RoLCBbXSwgZm4pKTtcbn0pO1xuIiwibW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBfYXJpdHkobiwgZm4pIHtcbiAgLyogZXNsaW50LWRpc2FibGUgbm8tdW51c2VkLXZhcnMgKi9cbiAgc3dpdGNoIChuKSB7XG4gICAgY2FzZSAwOiByZXR1cm4gZnVuY3Rpb24oKSB7IHJldHVybiBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9O1xuICAgIGNhc2UgMTogcmV0dXJuIGZ1bmN0aW9uKGEwKSB7IHJldHVybiBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9O1xuICAgIGNhc2UgMjogcmV0dXJuIGZ1bmN0aW9uKGEwLCBhMSkgeyByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfTtcbiAgICBjYXNlIDM6IHJldHVybiBmdW5jdGlvbihhMCwgYTEsIGEyKSB7IHJldHVybiBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9O1xuICAgIGNhc2UgNDogcmV0dXJuIGZ1bmN0aW9uKGEwLCBhMSwgYTIsIGEzKSB7IHJldHVybiBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9O1xuICAgIGNhc2UgNTogcmV0dXJuIGZ1bmN0aW9uKGEwLCBhMSwgYTIsIGEzLCBhNCkgeyByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfTtcbiAgICBjYXNlIDY6IHJldHVybiBmdW5jdGlvbihhMCwgYTEsIGEyLCBhMywgYTQsIGE1KSB7IHJldHVybiBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9O1xuICAgIGNhc2UgNzogcmV0dXJuIGZ1bmN0aW9uKGEwLCBhMSwgYTIsIGEzLCBhNCwgYTUsIGE2KSB7IHJldHVybiBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9O1xuICAgIGNhc2UgODogcmV0dXJuIGZ1bmN0aW9uKGEwLCBhMSwgYTIsIGEzLCBhNCwgYTUsIGE2LCBhNykgeyByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfTtcbiAgICBjYXNlIDk6IHJldHVybiBmdW5jdGlvbihhMCwgYTEsIGEyLCBhMywgYTQsIGE1LCBhNiwgYTcsIGE4KSB7IHJldHVybiBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9O1xuICAgIGNhc2UgMTA6IHJldHVybiBmdW5jdGlvbihhMCwgYTEsIGEyLCBhMywgYTQsIGE1LCBhNiwgYTcsIGE4LCBhOSkgeyByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfTtcbiAgICBkZWZhdWx0OiB0aHJvdyBuZXcgRXJyb3IoJ0ZpcnN0IGFyZ3VtZW50IHRvIF9hcml0eSBtdXN0IGJlIGEgbm9uLW5lZ2F0aXZlIGludGVnZXIgbm8gZ3JlYXRlciB0aGFuIHRlbicpO1xuICB9XG59O1xuIiwidmFyIF9pc1BsYWNlaG9sZGVyID0gcmVxdWlyZSgnLi9faXNQbGFjZWhvbGRlcicpO1xuXG5cbi8qKlxuICogT3B0aW1pemVkIGludGVybmFsIG9uZS1hcml0eSBjdXJyeSBmdW5jdGlvbi5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQGNhdGVnb3J5IEZ1bmN0aW9uXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiBUaGUgZnVuY3Rpb24gdG8gY3VycnkuXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gVGhlIGN1cnJpZWQgZnVuY3Rpb24uXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gX2N1cnJ5MShmbikge1xuICByZXR1cm4gZnVuY3Rpb24gZjEoYSkge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwIHx8IF9pc1BsYWNlaG9sZGVyKGEpKSB7XG4gICAgICByZXR1cm4gZjE7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH1cbiAgfTtcbn07XG4iLCJ2YXIgX2N1cnJ5MSA9IHJlcXVpcmUoJy4vX2N1cnJ5MScpO1xudmFyIF9pc1BsYWNlaG9sZGVyID0gcmVxdWlyZSgnLi9faXNQbGFjZWhvbGRlcicpO1xuXG5cbi8qKlxuICogT3B0aW1pemVkIGludGVybmFsIHR3by1hcml0eSBjdXJyeSBmdW5jdGlvbi5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQGNhdGVnb3J5IEZ1bmN0aW9uXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiBUaGUgZnVuY3Rpb24gdG8gY3VycnkuXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gVGhlIGN1cnJpZWQgZnVuY3Rpb24uXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gX2N1cnJ5Mihmbikge1xuICByZXR1cm4gZnVuY3Rpb24gZjIoYSwgYikge1xuICAgIHN3aXRjaCAoYXJndW1lbnRzLmxlbmd0aCkge1xuICAgICAgY2FzZSAwOlxuICAgICAgICByZXR1cm4gZjI7XG4gICAgICBjYXNlIDE6XG4gICAgICAgIHJldHVybiBfaXNQbGFjZWhvbGRlcihhKSA/IGYyXG4gICAgICAgICAgICAgOiBfY3VycnkxKGZ1bmN0aW9uKF9iKSB7IHJldHVybiBmbihhLCBfYik7IH0pO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIF9pc1BsYWNlaG9sZGVyKGEpICYmIF9pc1BsYWNlaG9sZGVyKGIpID8gZjJcbiAgICAgICAgICAgICA6IF9pc1BsYWNlaG9sZGVyKGEpID8gX2N1cnJ5MShmdW5jdGlvbihfYSkgeyByZXR1cm4gZm4oX2EsIGIpOyB9KVxuICAgICAgICAgICAgIDogX2lzUGxhY2Vob2xkZXIoYikgPyBfY3VycnkxKGZ1bmN0aW9uKF9iKSB7IHJldHVybiBmbihhLCBfYik7IH0pXG4gICAgICAgICAgICAgOiBmbihhLCBiKTtcbiAgICB9XG4gIH07XG59O1xuIiwidmFyIF9hcml0eSA9IHJlcXVpcmUoJy4vX2FyaXR5Jyk7XG52YXIgX2lzUGxhY2Vob2xkZXIgPSByZXF1aXJlKCcuL19pc1BsYWNlaG9sZGVyJyk7XG5cblxuLyoqXG4gKiBJbnRlcm5hbCBjdXJyeU4gZnVuY3Rpb24uXG4gKlxuICogQHByaXZhdGVcbiAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICogQHBhcmFtIHtOdW1iZXJ9IGxlbmd0aCBUaGUgYXJpdHkgb2YgdGhlIGN1cnJpZWQgZnVuY3Rpb24uXG4gKiBAcGFyYW0ge0FycmF5fSByZWNlaXZlZCBBbiBhcnJheSBvZiBhcmd1bWVudHMgcmVjZWl2ZWQgdGh1cyBmYXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiBUaGUgZnVuY3Rpb24gdG8gY3VycnkuXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gVGhlIGN1cnJpZWQgZnVuY3Rpb24uXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gX2N1cnJ5TihsZW5ndGgsIHJlY2VpdmVkLCBmbikge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGNvbWJpbmVkID0gW107XG4gICAgdmFyIGFyZ3NJZHggPSAwO1xuICAgIHZhciBsZWZ0ID0gbGVuZ3RoO1xuICAgIHZhciBjb21iaW5lZElkeCA9IDA7XG4gICAgd2hpbGUgKGNvbWJpbmVkSWR4IDwgcmVjZWl2ZWQubGVuZ3RoIHx8IGFyZ3NJZHggPCBhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICB2YXIgcmVzdWx0O1xuICAgICAgaWYgKGNvbWJpbmVkSWR4IDwgcmVjZWl2ZWQubGVuZ3RoICYmXG4gICAgICAgICAgKCFfaXNQbGFjZWhvbGRlcihyZWNlaXZlZFtjb21iaW5lZElkeF0pIHx8XG4gICAgICAgICAgIGFyZ3NJZHggPj0gYXJndW1lbnRzLmxlbmd0aCkpIHtcbiAgICAgICAgcmVzdWx0ID0gcmVjZWl2ZWRbY29tYmluZWRJZHhdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzdWx0ID0gYXJndW1lbnRzW2FyZ3NJZHhdO1xuICAgICAgICBhcmdzSWR4ICs9IDE7XG4gICAgICB9XG4gICAgICBjb21iaW5lZFtjb21iaW5lZElkeF0gPSByZXN1bHQ7XG4gICAgICBpZiAoIV9pc1BsYWNlaG9sZGVyKHJlc3VsdCkpIHtcbiAgICAgICAgbGVmdCAtPSAxO1xuICAgICAgfVxuICAgICAgY29tYmluZWRJZHggKz0gMTtcbiAgICB9XG4gICAgcmV0dXJuIGxlZnQgPD0gMCA/IGZuLmFwcGx5KHRoaXMsIGNvbWJpbmVkKVxuICAgICAgICAgICAgICAgICAgICAgOiBfYXJpdHkobGVmdCwgX2N1cnJ5TihsZW5ndGgsIGNvbWJpbmVkLCBmbikpO1xuICB9O1xufTtcbiIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gX2lzUGxhY2Vob2xkZXIoYSkge1xuICByZXR1cm4gYSAhPSBudWxsICYmXG4gICAgICAgICB0eXBlb2YgYSA9PT0gJ29iamVjdCcgJiZcbiAgICAgICAgIGFbJ0BAZnVuY3Rpb25hbC9wbGFjZWhvbGRlciddID09PSB0cnVlO1xufTtcbiIsInZhciBmbHlkID0gcmVxdWlyZSgnLi4vLi4vbGliJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oc3JjLCB0ZXJtKSB7XG4gIHJldHVybiBmbHlkLmVuZHNPbihmbHlkLm1lcmdlKHRlcm0sIHNyYy5lbmQpLCBmbHlkLmNvbWJpbmUoZnVuY3Rpb24oc3JjLCBzZWxmKSB7XG4gICAgc2VsZihzcmMoKSk7XG4gIH0sIFtzcmNdKSk7XG59O1xuIl19
require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
'use strict';
var curryN = require('ramda/src/curryN');
// Utility
function isFunction(obj) {
return !!(obj && obj.constructor && obj.call && obj.apply);
}
function trueFn() { return true; }
// Globals
var toUpdate = [];
var inStream;
var order = [];
var orderNextIdx = -1;
var flushing = false;
/** @namespace */
var flyd = {}
// /////////////////////////// API ///////////////////////////////// //
/**
* Creates a new stream
*
* __Signature__: `a -> Stream a`
*
* @name flyd.stream
* @param {*} initialValue - (Optional) the initial value of the stream
* @return {stream} the stream
*
* @example
* var n = flyd.stream(1); // Stream with initial value `1`
* var s = flyd.stream(); // Stream with no initial value
*/
flyd.stream = function(initialValue) {
var endStream = createDependentStream([], trueFn);
var s = createStream();
s.end = endStream;
s.fnArgs = [];
endStream.listeners.push(s);
if (arguments.length > 0) s(initialValue);
return s;
}
/**
* Create a new dependent stream
*
* __Signature__: `(...Stream * -> Stream b -> b) -> [Stream *] -> Stream b`
*
* @name flyd.combine
* @param {Function} fn - the function used to combine the streams
* @param {Array<stream>} dependencies - the streams that this one depends on
* @return {stream} the dependent stream
*
* @example
* var n1 = flyd.stream(0);
* var n2 = flyd.stream(0);
* var max = flyd.combine(function(n1, n2, self, changed) {
* return n1() > n2() ? n1() : n2();
* }, [n1, n2]);
*/
flyd.combine = curryN(2, combine);
function combine(fn, streams) {
var i, s, deps, depEndStreams;
var endStream = createDependentStream([], trueFn);
deps = []; depEndStreams = [];
for (i = 0; i < streams.length; ++i) {
if (streams[i] !== undefined) {
deps.push(streams[i]);
if (streams[i].end !== undefined) depEndStreams.push(streams[i].end);
}
}
s = createDependentStream(deps, fn);
s.depsChanged = [];
s.fnArgs = s.deps.concat([s, s.depsChanged]);
s.end = endStream;
endStream.listeners.push(s);
addListeners(depEndStreams, endStream);
endStream.deps = depEndStreams;
updateStream(s);
return s;
}
/**
* Returns `true` if the supplied argument is a Flyd stream and `false` otherwise.
*
* __Signature__: `* -> Boolean`
*
* @name flyd.isStream
* @param {*} value - the value to test
* @return {Boolean} `true` if is a Flyd streamn, `false` otherwise
*
* @example
* var s = flyd.stream(1);
* var n = 1;
* flyd.isStream(s); //=> true
* flyd.isStream(n); //=> false
*/
flyd.isStream = function(stream) {
return isFunction(stream) && 'hasVal' in stream;
}
/**
* Invokes the body (the function to calculate the value) of a dependent stream
*
* By default the body of a dependent stream is only called when all the streams
* upon which it depends has a value. `immediate` can circumvent this behaviour.
* It immediately invokes the body of a dependent stream.
*
* __Signature__: `Stream a -> Stream a`
*
* @name flyd.immediate
* @param {stream} stream - the dependent stream
* @return {stream} the same stream
*
* @example
* var s = flyd.stream();
* var hasItems = flyd.immediate(flyd.combine(function(s) {
* return s() !== undefined && s().length > 0;
* }, [s]);
* console.log(hasItems()); // logs `false`. Had `immediate` not been
* // used `hasItems()` would've returned `undefined`
* s([1]);
* console.log(hasItems()); // logs `true`.
* s([]);
* console.log(hasItems()); // logs `false`.
*/
flyd.immediate = function(s) {
if (s.depsMet === false) {
s.depsMet = true;
updateStream(s);
}
return s;
}
/**
* Changes which `endsStream` should trigger the ending of `s`.
*
* __Signature__: `Stream a -> Stream b -> Stream b`
*
* @name flyd.endsOn
* @param {stream} endStream - the stream to trigger the ending
* @param {stream} stream - the stream to be ended by the endStream
* @param {stream} the stream modified to be ended by endStream
*
* @example
* var n = flyd.stream(1);
* var killer = flyd.stream();
* // `double` ends when `n` ends or when `killer` emits any value
* var double = flyd.endsOn(flyd.merge(n.end, killer), flyd.combine(function(n) {
* return 2 * n();
* }, [n]);
*/
flyd.endsOn = function(endS, s) {
detachDeps(s.end);
endS.listeners.push(s.end);
s.end.deps.push(endS);
return s;
}
/**
* Map a stream
*
* Returns a new stream consisting of every value from `s` passed through
* `fn`. I.e. `map` creates a new stream that listens to `s` and
* applies `fn` to every new value.
* __Signature__: `(a -> result) -> Stream a -> Stream result`
*
* @name flyd.map
* @param {Function} fn - the function that produces the elements of the new stream
* @param {stream} stream - the stream to map
* @return {stream} a new stream with the mapped values
*
* @example
* var numbers = flyd.stream(0);
* var squaredNumbers = flyd.map(function(n) { return n*n; }, numbers);
*/
// Library functions use self callback to accept (null, undefined) update triggers.
flyd.map = curryN(2, function(f, s) {
return combine(function(s, self) { self(f(s.val)); }, [s]);
})
/**
* Listen to stream events
*
* Similar to `map` except that the returned stream is empty. Use `on` for doing
* side effects in reaction to stream changes. Use the returned stream only if you
* need to manually end it.
*
* __Signature__: `(a -> result) -> Stream a -> Stream undefined`
*
* @name flyd.on
* @param {Function} cb - the callback
* @param {stream} stream - the stream
* @return {stream} an empty stream (can be ended)
*/
flyd.on = curryN(2, function(f, s) {
return combine(function(s) { f(s.val); }, [s]);
})
/**
* Creates a new stream with the results of calling the function on every incoming
* stream with and accumulator and the incoming value.
*
* __Signature__: `(a -> b -> a) -> a -> Stream b -> Stream a`
*
* @name flyd.scan
* @param {Function} fn - the function to call
* @param {*} val - the initial value of the accumulator
* @param {stream} stream - the stream source
* @return {stream} the new stream
*
* @example
* var numbers = flyd.stream();
* var sum = flyd.scan(function(sum, n) { return sum+n; }, 0, numbers);
* numbers(2)(3)(5);
* sum(); // 10
*/
flyd.scan = curryN(3, function(f, acc, s) {
var ns = combine(function(s, self) {
self(acc = f(acc, s.val));
}, [s]);
if (!ns.hasVal) ns(acc);
return ns;
});
/**
* Creates a new stream down which all values from both `stream1` and `stream2`
* will be sent.
*
* __Signature__: `Stream a -> Stream a -> Stream a`
*
* @name flyd.merge
* @param {stream} source1 - one stream to be merged
* @param {stream} source2 - the other stream to be merged
* @return {stream} a stream with the values from both sources
*
* @example
* var btn1Clicks = flyd.stream();
* button1Elm.addEventListener(btn1Clicks);
* var btn2Clicks = flyd.stream();
* button2Elm.addEventListener(btn2Clicks);
* var allClicks = flyd.merge(btn1Clicks, btn2Clicks);
*/
flyd.merge = curryN(2, function(s1, s2) {
var s = flyd.immediate(combine(function(s1, s2, self, changed) {
if (changed[0]) {
self(changed[0]());
} else if (s1.hasVal) {
self(s1.val);
} else if (s2.hasVal) {
self(s2.val);
}
}, [s1, s2]));
flyd.endsOn(combine(function() {
return true;
}, [s1.end, s2.end]), s);
return s;
});
/**
* Creates a new stream resulting from applying `transducer` to `stream`.
*
* __Signature__: `Transducer -> Stream a -> Stream b`
*
* @name flyd.transduce
* @param {Transducer} xform - the transducer transformation
* @param {stream} source - the stream source
* @return {stream} the new stream
*
* @example
* var t = require('transducers.js');
*
* var results = [];
* var s1 = flyd.stream();
* var tx = t.compose(t.map(function(x) { return x * 2; }), t.dedupe());
* var s2 = flyd.transduce(tx, s1);
* flyd.combine(function(s2) { results.push(s2()); }, [s2]);
* s1(1)(1)(2)(3)(3)(3)(4);
* results; // => [2, 4, 6, 8]
*/
flyd.transduce = curryN(2, function(xform, source) {
xform = xform(new StreamTransformer());
return combine(function(source, self) {
var res = xform['@@transducer/step'](undefined, source.val);
if (res && res['@@transducer/reduced'] === true) {
self.end(true);
return res['@@transducer/value'];
} else {
return res;
}
}, [source]);
});
/**
* Returns `fn` curried to `n`. Use this function to curry functions exposed by
* modules for Flyd.
*
* @name flyd.curryN
* @function
* @param {Integer} arity - the function arity
* @param {Function} fn - the function to curry
* @return {Function} the curried function
*
* @example
* function add(x, y) { return x + y; };
* var a = flyd.curryN(2, add);
* a(2)(4) // => 6
*/
flyd.curryN = curryN
/**
* Returns a new stream identical to the original except every
* value will be passed through `f`.
*
* _Note:_ This function is included in order to support the fantasy land
* specification.
*
* __Signature__: Called bound to `Stream a`: `(a -> b) -> Stream b`
*
* @name stream.map
* @param {Function} function - the function to apply
* @return {stream} a new stream with the values mapped
*
* @example
* var numbers = flyd.stream(0);
* var squaredNumbers = numbers.map(function(n) { return n*n; });
*/
function boundMap(f) { return flyd.map(f, this); }
/**
* Returns a new stream which is the result of applying the
* functions from `this` stream to the values in `stream` parameter.
*
* `this` stream must be a stream of functions.
*
* _Note:_ This function is included in order to support the fantasy land
* specification.
*
* __Signature__: Called bound to `Stream (a -> b)`: `a -> Stream b`
*
* @name stream.ap
* @param {stream} stream - the values stream
* @return {stream} a new stram with the functions applied to values
*
* @example
* var add = flyd.curryN(2, function(x, y) { return x + y; });
* var numbers1 = flyd.stream();
* var numbers2 = flyd.stream();
* var addToNumbers1 = flyd.map(add, numbers1);
* var added = addToNumbers1.ap(numbers2);
*/
function ap(s2) {
var s1 = this;
return combine(function(s1, s2, self) { self(s1.val(s2.val)); }, [s1, s2]);
}
/**
* Get a human readable view of a stream
* @name stream.toString
* @return {String} the stream string representation
*/
function streamToString() {
return 'stream(' + this.val + ')';
}
/**
* @name stream.end
* @memberof stream
* A stream that emits `true` when the stream ends. If `true` is pushed down the
* stream the parent stream ends.
*/
/**
* @name stream.of
* @function
* @memberof stream
* Returns a new stream with `value` as its initial value. It is identical to
* calling `flyd.stream` with one argument.
*
* __Signature__: Called bound to `Stream (a)`: `b -> Stream b`
*
* @param {*} value - the initial value
* @return {stream} the new stream
*
* @example
* var n = flyd.stream(1);
* var m = n.of(1);
*/
// /////////////////////////// PRIVATE ///////////////////////////////// //
/**
* @private
* Create a stream with no dependencies and no value
* @return {Function} a flyd stream
*/
function createStream() {
function s(n) {
if (arguments.length === 0) return s.val
updateStreamValue(s, n)
return s
}
s.hasVal = false;
s.val = undefined;
s.vals = [];
s.listeners = [];
s.queued = false;
s.end = undefined;
s.map = boundMap;
s.ap = ap;
s.of = flyd.stream;
s.toString = streamToString;
return s;
}
/**
* @private
* Create a dependent stream
* @param {Array<stream>} dependencies - an array of the streams
* @param {Function} fn - the function used to calculate the new stream value
* from the dependencies
* @return {stream} the created stream
*/
function createDependentStream(deps, fn) {
var s = createStream();
s.fn = fn;
s.deps = deps;
s.depsMet = false;
s.depsChanged = deps.length > 0 ? [] : undefined;
s.shouldUpdate = false;
addListeners(deps, s);
return s;
}
/**
* @private
* Check if all the dependencies have values
* @param {stream} stream - the stream to check depencencies from
* @return {Boolean} `true` if all dependencies have vales, `false` otherwise
*/
function initialDepsNotMet(stream) {
stream.depsMet = stream.deps.every(function(s) {
return s.hasVal;
});
return !stream.depsMet;
}
/**
* @private
* Update a dependent stream using its dependencies in an atomic way
* @param {stream} stream - the stream to update
*/
function updateStream(s) {
if ((s.depsMet !== true && initialDepsNotMet(s)) ||
(s.end !== undefined && s.end.val === true)) return;
if (inStream !== undefined) {
toUpdate.push(s);
return;
}
inStream = s;
if (s.depsChanged) s.fnArgs[s.fnArgs.length - 1] = s.depsChanged;
var returnVal = s.fn.apply(s.fn, s.fnArgs);
if (returnVal !== undefined) {
s(returnVal);
}
inStream = undefined;
if (s.depsChanged !== undefined) s.depsChanged = [];
s.shouldUpdate = false;
if (flushing === false) flushUpdate();
}
/**
* @private
* Update the dependencies of a stream
* @param {stream} stream
*/
function updateDeps(s) {
var i, o, list
var listeners = s.listeners;
for (i = 0; i < listeners.length; ++i) {
list = listeners[i];
if (list.end === s) {
endStream(list);
} else {
if (list.depsChanged !== undefined) list.depsChanged.push(s);
list.shouldUpdate = true;
findDeps(list);
}
}
for (; orderNextIdx >= 0; --orderNextIdx) {
o = order[orderNextIdx];
if (o.shouldUpdate === true) updateStream(o);
o.queued = false;
}
}
/**
* @private
* Add stream dependencies to the global `order` queue.
* @param {stream} stream
* @see updateDeps
*/
function findDeps(s) {
var i
var listeners = s.listeners;
if (s.queued === false) {
s.queued = true;
for (i = 0; i < listeners.length; ++i) {
findDeps(listeners[i]);
}
order[++orderNextIdx] = s;
}
}
/**
* @private
*/
function flushUpdate() {
flushing = true;
while (toUpdate.length > 0) {
var s = toUpdate.shift();
if (s.vals.length > 0) s.val = s.vals.shift();
updateDeps(s);
}
flushing = false;
}
/**
* @private
* Push down a value into a stream
* @param {stream} stream
* @param {*} value
*/
function updateStreamValue(s, n) {
if (n !== undefined && n !== null && isFunction(n.then)) {
n.then(s);
return;
}
s.val = n;
s.hasVal = true;
if (inStream === undefined) {
flushing = true;
updateDeps(s);
if (toUpdate.length > 0) flushUpdate(); else flushing = false;
} else if (inStream === s) {
markListeners(s, s.listeners);
} else {
s.vals.push(n);
toUpdate.push(s);
}
}
/**
* @private
*/
function markListeners(s, lists) {
var i, list;
for (i = 0; i < lists.length; ++i) {
list = lists[i];
if (list.end !== s) {
if (list.depsChanged !== undefined) {
list.depsChanged.push(s);
}
list.shouldUpdate = true;
} else {
endStream(list);
}
}
}
/**
* @private
* Add dependencies to a stream
* @param {Array<stream>} dependencies
* @param {stream} stream
*/
function addListeners(deps, s) {
for (var i = 0; i < deps.length; ++i) {
deps[i].listeners.push(s);
}
}
/**
* @private
* Removes an stream from a dependency array
* @param {stream} stream
* @param {Array<stream>} dependencies
*/
function removeListener(s, listeners) {
var idx = listeners.indexOf(s);
listeners[idx] = listeners[listeners.length - 1];
listeners.length--;
}
/**
* @private
* Detach a stream from its dependencies
* @param {stream} stream
*/
function detachDeps(s) {
for (var i = 0; i < s.deps.length; ++i) {
removeListener(s, s.deps[i].listeners);
}
s.deps.length = 0;
}
/**
* @private
* Ends a stream
*/
function endStream(s) {
if (s.deps !== undefined) detachDeps(s);
if (s.end !== undefined) detachDeps(s.end);
}
/**
* @private
* transducer stream transformer
*/
function StreamTransformer() { }
StreamTransformer.prototype['@@transducer/init'] = function() { };
StreamTransformer.prototype['@@transducer/result'] = function() { };
StreamTransformer.prototype['@@transducer/step'] = function(s, v) { return v; };
module.exports = flyd;
},{"ramda/src/curryN":2}],2:[function(require,module,exports){
var _arity = require('./internal/_arity');
var _curry1 = require('./internal/_curry1');
var _curry2 = require('./internal/_curry2');
var _curryN = require('./internal/_curryN');
/**
* Returns a curried equivalent of the provided function, with the specified
* arity. The curried function has two unusual capabilities. First, its
* arguments needn't be provided one at a time. If `g` is `R.curryN(3, f)`, the
* following are equivalent:
*
* - `g(1)(2)(3)`
* - `g(1)(2, 3)`
* - `g(1, 2)(3)`
* - `g(1, 2, 3)`
*
* Secondly, the special placeholder value `R.__` may be used to specify
* "gaps", allowing partial application of any combination of arguments,
* regardless of their positions. If `g` is as above and `_` is `R.__`, the
* following are equivalent:
*
* - `g(1, 2, 3)`
* - `g(_, 2, 3)(1)`
* - `g(_, _, 3)(1)(2)`
* - `g(_, _, 3)(1, 2)`
* - `g(_, 2)(1)(3)`
* - `g(_, 2)(1, 3)`
* - `g(_, 2)(_, 3)(1)`
*
* @func
* @memberOf R
* @since v0.5.0
* @category Function
* @sig Number -> (* -> a) -> (* -> a)
* @param {Number} length The arity for the returned function.
* @param {Function} fn The function to curry.
* @return {Function} A new, curried function.
* @see R.curry
* @example
*
* var sumArgs = (...args) => R.sum(args);
*
* var curriedAddFourNumbers = R.curryN(4, sumArgs);
* var f = curriedAddFourNumbers(1, 2);
* var g = f(3);
* g(4); //=> 10
*/
module.exports = _curry2(function curryN(length, fn) {
if (length === 1) {
return _curry1(fn);
}
return _arity(length, _curryN(length, [], fn));
});
},{"./internal/_arity":3,"./internal/_curry1":4,"./internal/_curry2":5,"./internal/_curryN":6}],3:[function(require,module,exports){
module.exports = function _arity(n, fn) {
/* eslint-disable no-unused-vars */
switch (n) {
case 0: return function() { return fn.apply(this, arguments); };
case 1: return function(a0) { return fn.apply(this, arguments); };
case 2: return function(a0, a1) { return fn.apply(this, arguments); };
case 3: return function(a0, a1, a2) { return fn.apply(this, arguments); };
case 4: return function(a0, a1, a2, a3) { return fn.apply(this, arguments); };
case 5: return function(a0, a1, a2, a3, a4) { return fn.apply(this, arguments); };
case 6: return function(a0, a1, a2, a3, a4, a5) { return fn.apply(this, arguments); };
case 7: return function(a0, a1, a2, a3, a4, a5, a6) { return fn.apply(this, arguments); };
case 8: return function(a0, a1, a2, a3, a4, a5, a6, a7) { return fn.apply(this, arguments); };
case 9: return function(a0, a1, a2, a3, a4, a5, a6, a7, a8) { return fn.apply(this, arguments); };
case 10: return function(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) { return fn.apply(this, arguments); };
default: throw new Error('First argument to _arity must be a non-negative integer no greater than ten');
}
};
},{}],4:[function(require,module,exports){
var _isPlaceholder = require('./_isPlaceholder');
/**
* Optimized internal one-arity curry function.
*
* @private
* @category Function
* @param {Function} fn The function to curry.
* @return {Function} The curried function.
*/
module.exports = function _curry1(fn) {
return function f1(a) {
if (arguments.length === 0 || _isPlaceholder(a)) {
return f1;
} else {
return fn.apply(this, arguments);
}
};
};
},{"./_isPlaceholder":7}],5:[function(require,module,exports){
var _curry1 = require('./_curry1');
var _isPlaceholder = require('./_isPlaceholder');
/**
* Optimized internal two-arity curry function.
*
* @private
* @category Function
* @param {Function} fn The function to curry.
* @return {Function} The curried function.
*/
module.exports = function _curry2(fn) {
return function f2(a, b) {
switch (arguments.length) {
case 0:
return f2;
case 1:
return _isPlaceholder(a) ? f2
: _curry1(function(_b) { return fn(a, _b); });
default:
return _isPlaceholder(a) && _isPlaceholder(b) ? f2
: _isPlaceholder(a) ? _curry1(function(_a) { return fn(_a, b); })
: _isPlaceholder(b) ? _curry1(function(_b) { return fn(a, _b); })
: fn(a, b);
}
};
};
},{"./_curry1":4,"./_isPlaceholder":7}],6:[function(require,module,exports){
var _arity = require('./_arity');
var _isPlaceholder = require('./_isPlaceholder');
/**
* Internal curryN function.
*
* @private
* @category Function
* @param {Number} length The arity of the curried function.
* @param {Array} received An array of arguments received thus far.
* @param {Function} fn The function to curry.
* @return {Function} The curried function.
*/
module.exports = function _curryN(length, received, fn) {
return function() {
var combined = [];
var argsIdx = 0;
var left = length;
var combinedIdx = 0;
while (combinedIdx < received.length || argsIdx < arguments.length) {
var result;
if (combinedIdx < received.length &&
(!_isPlaceholder(received[combinedIdx]) ||
argsIdx >= arguments.length)) {
result = received[combinedIdx];
} else {
result = arguments[argsIdx];
argsIdx += 1;
}
combined[combinedIdx] = result;
if (!_isPlaceholder(result)) {
left -= 1;
}
combinedIdx += 1;
}
return left <= 0 ? fn.apply(this, combined)
: _arity(left, _curryN(length, combined, fn));
};
};
},{"./_arity":3,"./_isPlaceholder":7}],7:[function(require,module,exports){
module.exports = function _isPlaceholder(a) {
return a != null &&
typeof a === 'object' &&
a['@@functional/placeholder'] === true;
};
},{}],"flyd/module/filter":[function(require,module,exports){
var flyd = require('../../lib');
module.exports = flyd.curryN(2, function(fn, s) {
return flyd.combine(function(s, self) {
if (fn(s())) self(s.val);
}, [s]);
});
},{"../../lib":1}]},{},[])
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2hvbWUvYWRtaW4vYnJvd3NlcmlmeS1jZG4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXItcGFjay9fcHJlbHVkZS5qcyIsImxpYi9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9yYW1kYS9zcmMvY3VycnlOLmpzIiwibm9kZV9tb2R1bGVzL3JhbWRhL3NyYy9pbnRlcm5hbC9fYXJpdHkuanMiLCJub2RlX21vZHVsZXMvcmFtZGEvc3JjL2ludGVybmFsL19jdXJyeTEuanMiLCJub2RlX21vZHVsZXMvcmFtZGEvc3JjL2ludGVybmFsL19jdXJyeTIuanMiLCJub2RlX21vZHVsZXMvcmFtZGEvc3JjL2ludGVybmFsL19jdXJyeU4uanMiLCJub2RlX21vZHVsZXMvcmFtZGEvc3JjL2ludGVybmFsL19pc1BsYWNlaG9sZGVyLmpzIiwibW9kdWxlL2ZpbHRlci9pbmRleC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsbkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3REQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dmFyIGY9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKTt0aHJvdyBmLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsZn12YXIgbD1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwobC5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxsLGwuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc30pIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgY3VycnlOID0gcmVxdWlyZSgncmFtZGEvc3JjL2N1cnJ5TicpO1xuXG4vLyBVdGlsaXR5XG5mdW5jdGlvbiBpc0Z1bmN0aW9uKG9iaikge1xuICByZXR1cm4gISEob2JqICYmIG9iai5jb25zdHJ1Y3RvciAmJiBvYmouY2FsbCAmJiBvYmouYXBwbHkpO1xufVxuZnVuY3Rpb24gdHJ1ZUZuKCkgeyByZXR1cm4gdHJ1ZTsgfVxuXG4vLyBHbG9iYWxzXG52YXIgdG9VcGRhdGUgPSBbXTtcbnZhciBpblN0cmVhbTtcbnZhciBvcmRlciA9IFtdO1xudmFyIG9yZGVyTmV4dElkeCA9IC0xO1xudmFyIGZsdXNoaW5nID0gZmFsc2U7XG5cbi8qKiBAbmFtZXNwYWNlICovXG52YXIgZmx5ZCA9IHt9XG5cbi8vIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLyBBUEkgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vIC8vXG5cbi8qKlxuICogQ3JlYXRlcyBhIG5ldyBzdHJlYW1cbiAqXG4gKiBfX1NpZ25hdHVyZV9fOiBgYSAtPiBTdHJlYW0gYWBcbiAqXG4gKiBAbmFtZSBmbHlkLnN0cmVhbVxuICogQHBhcmFtIHsqfSBpbml0aWFsVmFsdWUgLSAoT3B0aW9uYWwpIHRoZSBpbml0aWFsIHZhbHVlIG9mIHRoZSBzdHJlYW1cbiAqIEByZXR1cm4ge3N0cmVhbX0gdGhlIHN0cmVhbVxuICpcbiAqIEBleGFtcGxlXG4gKiB2YXIgbiA9IGZseWQuc3RyZWFtKDEpOyAvLyBTdHJlYW0gd2l0aCBpbml0aWFsIHZhbHVlIGAxYFxuICogdmFyIHMgPSBmbHlkLnN0cmVhbSgpOyAvLyBTdHJlYW0gd2l0aCBubyBpbml0aWFsIHZhbHVlXG4gKi9cbmZseWQuc3RyZWFtID0gZnVuY3Rpb24oaW5pdGlhbFZhbHVlKSB7XG4gIHZhciBlbmRTdHJlYW0gPSBjcmVhdGVEZXBlbmRlbnRTdHJlYW0oW10sIHRydWVGbik7XG4gIHZhciBzID0gY3JlYXRlU3RyZWFtKCk7XG4gIHMuZW5kID0gZW5kU3RyZWFtO1xuICBzLmZuQXJncyA9IFtdO1xuICBlbmRTdHJlYW0ubGlzdGVuZXJzLnB1c2gocyk7XG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMCkgcyhpbml0aWFsVmFsdWUpO1xuICByZXR1cm4gcztcbn1cblxuLyoqXG4gKiBDcmVhdGUgYSBuZXcgZGVwZW5kZW50IHN0cmVhbVxuICpcbiAqIF9fU2lnbmF0dXJlX186IGAoLi4uU3RyZWFtICogLT4gU3RyZWFtIGIgLT4gYikgLT4gW1N0cmVhbSAqXSAtPiBTdHJlYW0gYmBcbiAqXG4gKiBAbmFtZSBmbHlkLmNvbWJpbmVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIC0gdGhlIGZ1bmN0aW9uIHVzZWQgdG8gY29tYmluZSB0aGUgc3RyZWFtc1xuICogQHBhcmFtIHtBcnJheTxzdHJlYW0+fSBkZXBlbmRlbmNpZXMgLSB0aGUgc3RyZWFtcyB0aGF0IHRoaXMgb25lIGRlcGVuZHMgb25cbiAqIEByZXR1cm4ge3N0cmVhbX0gdGhlIGRlcGVuZGVudCBzdHJlYW1cbiAqXG4gKiBAZXhhbXBsZVxuICogdmFyIG4xID0gZmx5ZC5zdHJlYW0oMCk7XG4gKiB2YXIgbjIgPSBmbHlkLnN0cmVhbSgwKTtcbiAqIHZhciBtYXggPSBmbHlkLmNvbWJpbmUoZnVuY3Rpb24objEsIG4yLCBzZWxmLCBjaGFuZ2VkKSB7XG4gKiAgIHJldHVybiBuMSgpID4gbjIoKSA/IG4xKCkgOiBuMigpO1xuICogfSwgW24xLCBuMl0pO1xuICovXG5mbHlkLmNvbWJpbmUgPSBjdXJyeU4oMiwgY29tYmluZSk7XG5mdW5jdGlvbiBjb21iaW5lKGZuLCBzdHJlYW1zKSB7XG4gIHZhciBpLCBzLCBkZXBzLCBkZXBFbmRTdHJlYW1zO1xuICB2YXIgZW5kU3RyZWFtID0gY3JlYXRlRGVwZW5kZW50U3RyZWFtKFtdLCB0cnVlRm4pO1xuICBkZXBzID0gW107IGRlcEVuZFN0cmVhbXMgPSBbXTtcbiAgZm9yIChpID0gMDsgaSA8IHN0cmVhbXMubGVuZ3RoOyArK2kpIHtcbiAgICBpZiAoc3RyZWFtc1tpXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBkZXBzLnB1c2goc3RyZWFtc1tpXSk7XG4gICAgICBpZiAoc3RyZWFtc1tpXS5lbmQgIT09IHVuZGVmaW5lZCkgZGVwRW5kU3RyZWFtcy5wdXNoKHN0cmVhbXNbaV0uZW5kKTtcbiAgICB9XG4gIH1cbiAgcyA9IGNyZWF0ZURlcGVuZGVudFN0cmVhbShkZXBzLCBmbik7XG4gIHMuZGVwc0NoYW5nZWQgPSBbXTtcbiAgcy5mbkFyZ3MgPSBzLmRlcHMuY29uY2F0KFtzLCBzLmRlcHNDaGFuZ2VkXSk7XG4gIHMuZW5kID0gZW5kU3RyZWFtO1xuICBlbmRTdHJlYW0ubGlzdGVuZXJzLnB1c2gocyk7XG4gIGFkZExpc3RlbmVycyhkZXBFbmRTdHJlYW1zLCBlbmRTdHJlYW0pO1xuICBlbmRTdHJlYW0uZGVwcyA9IGRlcEVuZFN0cmVhbXM7XG4gIHVwZGF0ZVN0cmVhbShzKTtcbiAgcmV0dXJuIHM7XG59XG5cbi8qKlxuICogUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIHN1cHBsaWVkIGFyZ3VtZW50IGlzIGEgRmx5ZCBzdHJlYW0gYW5kIGBmYWxzZWAgb3RoZXJ3aXNlLlxuICpcbiAqIF9fU2lnbmF0dXJlX186IGAqIC0+IEJvb2xlYW5gXG4gKlxuICogQG5hbWUgZmx5ZC5pc1N0cmVhbVxuICogQHBhcmFtIHsqfSB2YWx1ZSAtIHRoZSB2YWx1ZSB0byB0ZXN0XG4gKiBAcmV0dXJuIHtCb29sZWFufSBgdHJ1ZWAgaWYgaXMgYSBGbHlkIHN0cmVhbW4sIGBmYWxzZWAgb3RoZXJ3aXNlXG4gKlxuICogQGV4YW1wbGVcbiAqIHZhciBzID0gZmx5ZC5zdHJlYW0oMSk7XG4gKiB2YXIgbiA9IDE7XG4gKiBmbHlkLmlzU3RyZWFtKHMpOyAvLz0+IHRydWVcbiAqIGZseWQuaXNTdHJlYW0obik7IC8vPT4gZmFsc2VcbiAqL1xuZmx5ZC5pc1N0cmVhbSA9IGZ1bmN0aW9uKHN0cmVhbSkge1xuICByZXR1cm4gaXNGdW5jdGlvbihzdHJlYW0pICYmICdoYXNWYWwnIGluIHN0cmVhbTtcbn1cblxuLyoqXG4gKiBJbnZva2VzIHRoZSBib2R5ICh0aGUgZnVuY3Rpb24gdG8gY2FsY3VsYXRlIHRoZSB2YWx1ZSkgb2YgYSBkZXBlbmRlbnQgc3RyZWFtXG4gKlxuICogQnkgZGVmYXVsdCB0aGUgYm9keSBvZiBhIGRlcGVuZGVudCBzdHJlYW0gaXMgb25seSBjYWxsZWQgd2hlbiBhbGwgdGhlIHN0cmVhbXNcbiAqIHVwb24gd2hpY2ggaXQgZGVwZW5kcyBoYXMgYSB2YWx1ZS4gYGltbWVkaWF0ZWAgY2FuIGNpcmN1bXZlbnQgdGhpcyBiZWhhdmlvdXIuXG4gKiBJdCBpbW1lZGlhdGVseSBpbnZva2VzIHRoZSBib2R5IG9mIGEgZGVwZW5kZW50IHN0cmVhbS5cbiAqXG4gKiBfX1NpZ25hdHVyZV9fOiBgU3RyZWFtIGEgLT4gU3RyZWFtIGFgXG4gKlxuICogQG5hbWUgZmx5ZC5pbW1lZGlhdGVcbiAqIEBwYXJhbSB7c3RyZWFtfSBzdHJlYW0gLSB0aGUgZGVwZW5kZW50IHN0cmVhbVxuICogQHJldHVybiB7c3RyZWFtfSB0aGUgc2FtZSBzdHJlYW1cbiAqXG4gKiBAZXhhbXBsZVxuICogdmFyIHMgPSBmbHlkLnN0cmVhbSgpO1xuICogdmFyIGhhc0l0ZW1zID0gZmx5ZC5pbW1lZGlhdGUoZmx5ZC5jb21iaW5lKGZ1bmN0aW9uKHMpIHtcbiAqICAgcmV0dXJuIHMoKSAhPT0gdW5kZWZpbmVkICYmIHMoKS5sZW5ndGggPiAwO1xuICogfSwgW3NdKTtcbiAqIGNvbnNvbGUubG9nKGhhc0l0ZW1zKCkpOyAvLyBsb2dzIGBmYWxzZWAuIEhhZCBgaW1tZWRpYXRlYCBub3QgYmVlblxuICogICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHVzZWQgYGhhc0l0ZW1zKClgIHdvdWxkJ3ZlIHJldHVybmVkIGB1bmRlZmluZWRgXG4gKiBzKFsxXSk7XG4gKiBjb25zb2xlLmxvZyhoYXNJdGVtcygpKTsgLy8gbG9ncyBgdHJ1ZWAuXG4gKiBzKFtdKTtcbiAqIGNvbnNvbGUubG9nKGhhc0l0ZW1zKCkpOyAvLyBsb2dzIGBmYWxzZWAuXG4gKi9cbmZseWQuaW1tZWRpYXRlID0gZnVuY3Rpb24ocykge1xuICBpZiAocy5kZXBzTWV0ID09PSBmYWxzZSkge1xuICAgIHMuZGVwc01ldCA9IHRydWU7XG4gICAgdXBkYXRlU3RyZWFtKHMpO1xuICB9XG4gIHJldHVybiBzO1xufVxuXG4vKipcbiAqIENoYW5nZXMgd2hpY2ggYGVuZHNTdHJlYW1gIHNob3VsZCB0cmlnZ2VyIHRoZSBlbmRpbmcgb2YgYHNgLlxuICpcbiAqIF9fU2lnbmF0dXJlX186IGBTdHJlYW0gYSAtPiBTdHJlYW0gYiAtPiBTdHJlYW0gYmBcbiAqXG4gKiBAbmFtZSBmbHlkLmVuZHNPblxuICogQHBhcmFtIHtzdHJlYW19IGVuZFN0cmVhbSAtIHRoZSBzdHJlYW0gdG8gdHJpZ2dlciB0aGUgZW5kaW5nXG4gKiBAcGFyYW0ge3N0cmVhbX0gc3RyZWFtIC0gdGhlIHN0cmVhbSB0byBiZSBlbmRlZCBieSB0aGUgZW5kU3RyZWFtXG4gKiBAcGFyYW0ge3N0cmVhbX0gdGhlIHN0cmVhbSBtb2RpZmllZCB0byBiZSBlbmRlZCBieSBlbmRTdHJlYW1cbiAqXG4gKiBAZXhhbXBsZVxuICogdmFyIG4gPSBmbHlkLnN0cmVhbSgxKTtcbiAqIHZhciBraWxsZXIgPSBmbHlkLnN0cmVhbSgpO1xuICogLy8gYGRvdWJsZWAgZW5kcyB3aGVuIGBuYCBlbmRzIG9yIHdoZW4gYGtpbGxlcmAgZW1pdHMgYW55IHZhbHVlXG4gKiB2YXIgZG91YmxlID0gZmx5ZC5lbmRzT24oZmx5ZC5tZXJnZShuLmVuZCwga2lsbGVyKSwgZmx5ZC5jb21iaW5lKGZ1bmN0aW9uKG4pIHtcbiAqICAgcmV0dXJuIDIgKiBuKCk7XG4gKiB9LCBbbl0pO1xuKi9cbmZseWQuZW5kc09uID0gZnVuY3Rpb24oZW5kUywgcykge1xuICBkZXRhY2hEZXBzKHMuZW5kKTtcbiAgZW5kUy5saXN0ZW5lcnMucHVzaChzLmVuZCk7XG4gIHMuZW5kLmRlcHMucHVzaChlbmRTKTtcbiAgcmV0dXJuIHM7XG59XG5cbi8qKlxuICogTWFwIGEgc3RyZWFtXG4gKlxuICogUmV0dXJucyBhIG5ldyBzdHJlYW0gY29uc2lzdGluZyBvZiBldmVyeSB2YWx1ZSBmcm9tIGBzYCBwYXNzZWQgdGhyb3VnaFxuICogYGZuYC4gSS5lLiBgbWFwYCBjcmVhdGVzIGEgbmV3IHN0cmVhbSB0aGF0IGxpc3RlbnMgdG8gYHNgIGFuZFxuICogYXBwbGllcyBgZm5gIHRvIGV2ZXJ5IG5ldyB2YWx1ZS5cbiAqIF9fU2lnbmF0dXJlX186IGAoYSAtPiByZXN1bHQpIC0+IFN0cmVhbSBhIC0+IFN0cmVhbSByZXN1bHRgXG4gKlxuICogQG5hbWUgZmx5ZC5tYXBcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIC0gdGhlIGZ1bmN0aW9uIHRoYXQgcHJvZHVjZXMgdGhlIGVsZW1lbnRzIG9mIHRoZSBuZXcgc3RyZWFtXG4gKiBAcGFyYW0ge3N0cmVhbX0gc3RyZWFtIC0gdGhlIHN0cmVhbSB0byBtYXBcbiAqIEByZXR1cm4ge3N0cmVhbX0gYSBuZXcgc3RyZWFtIHdpdGggdGhlIG1hcHBlZCB2YWx1ZXNcbiAqXG4gKiBAZXhhbXBsZVxuICogdmFyIG51bWJlcnMgPSBmbHlkLnN0cmVhbSgwKTtcbiAqIHZhciBzcXVhcmVkTnVtYmVycyA9IGZseWQubWFwKGZ1bmN0aW9uKG4pIHsgcmV0dXJuIG4qbjsgfSwgbnVtYmVycyk7XG4gKi9cbi8vIExpYnJhcnkgZnVuY3Rpb25zIHVzZSBzZWxmIGNhbGxiYWNrIHRvIGFjY2VwdCAobnVsbCwgdW5kZWZpbmVkKSB1cGRhdGUgdHJpZ2dlcnMuXG5mbHlkLm1hcCA9IGN1cnJ5TigyLCBmdW5jdGlvbihmLCBzKSB7XG4gIHJldHVybiBjb21iaW5lKGZ1bmN0aW9uKHMsIHNlbGYpIHsgc2VsZihmKHMudmFsKSk7IH0sIFtzXSk7XG59KVxuXG4vKipcbiAqIExpc3RlbiB0byBzdHJlYW0gZXZlbnRzXG4gKlxuICogU2ltaWxhciB0byBgbWFwYCBleGNlcHQgdGhhdCB0aGUgcmV0dXJuZWQgc3RyZWFtIGlzIGVtcHR5LiBVc2UgYG9uYCBmb3IgZG9pbmdcbiAqIHNpZGUgZWZmZWN0cyBpbiByZWFjdGlvbiB0byBzdHJlYW0gY2hhbmdlcy4gVXNlIHRoZSByZXR1cm5lZCBzdHJlYW0gb25seSBpZiB5b3VcbiAqIG5lZWQgdG8gbWFudWFsbHkgZW5kIGl0LlxuICpcbiAqIF9fU2lnbmF0dXJlX186IGAoYSAtPiByZXN1bHQpIC0+IFN0cmVhbSBhIC0+IFN0cmVhbSB1bmRlZmluZWRgXG4gKlxuICogQG5hbWUgZmx5ZC5vblxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2IgLSB0aGUgY2FsbGJhY2tcbiAqIEBwYXJhbSB7c3RyZWFtfSBzdHJlYW0gLSB0aGUgc3RyZWFtXG4gKiBAcmV0dXJuIHtzdHJlYW19IGFuIGVtcHR5IHN0cmVhbSAoY2FuIGJlIGVuZGVkKVxuICovXG5mbHlkLm9uID0gY3VycnlOKDIsIGZ1bmN0aW9uKGYsIHMpIHtcbiAgcmV0dXJuIGNvbWJpbmUoZnVuY3Rpb24ocykgeyBmKHMudmFsKTsgfSwgW3NdKTtcbn0pXG5cbi8qKlxuICogQ3JlYXRlcyBhIG5ldyBzdHJlYW0gd2l0aCB0aGUgcmVzdWx0cyBvZiBjYWxsaW5nIHRoZSBmdW5jdGlvbiBvbiBldmVyeSBpbmNvbWluZ1xuICogc3RyZWFtIHdpdGggYW5kIGFjY3VtdWxhdG9yIGFuZCB0aGUgaW5jb21pbmcgdmFsdWUuXG4gKlxuICogX19TaWduYXR1cmVfXzogYChhIC0+IGIgLT4gYSkgLT4gYSAtPiBTdHJlYW0gYiAtPiBTdHJlYW0gYWBcbiAqXG4gKiBAbmFtZSBmbHlkLnNjYW5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIC0gdGhlIGZ1bmN0aW9uIHRvIGNhbGxcbiAqIEBwYXJhbSB7Kn0gdmFsIC0gdGhlIGluaXRpYWwgdmFsdWUgb2YgdGhlIGFjY3VtdWxhdG9yXG4gKiBAcGFyYW0ge3N0cmVhbX0gc3RyZWFtIC0gdGhlIHN0cmVhbSBzb3VyY2VcbiAqIEByZXR1cm4ge3N0cmVhbX0gdGhlIG5ldyBzdHJlYW1cbiAqXG4gKiBAZXhhbXBsZVxuICogdmFyIG51bWJlcnMgPSBmbHlkLnN0cmVhbSgpO1xuICogdmFyIHN1bSA9IGZseWQuc2NhbihmdW5jdGlvbihzdW0sIG4pIHsgcmV0dXJuIHN1bStuOyB9LCAwLCBudW1iZXJzKTtcbiAqIG51bWJlcnMoMikoMykoNSk7XG4gKiBzdW0oKTsgLy8gMTBcbiAqL1xuZmx5ZC5zY2FuID0gY3VycnlOKDMsIGZ1bmN0aW9uKGYsIGFjYywgcykge1xuICB2YXIgbnMgPSBjb21iaW5lKGZ1bmN0aW9uKHMsIHNlbGYpIHtcbiAgICBzZWxmKGFjYyA9IGYoYWNjLCBzLnZhbCkpO1xuICB9LCBbc10pO1xuICBpZiAoIW5zLmhhc1ZhbCkgbnMoYWNjKTtcbiAgcmV0dXJuIG5zO1xufSk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIG5ldyBzdHJlYW0gZG93biB3aGljaCBhbGwgdmFsdWVzIGZyb20gYm90aCBgc3RyZWFtMWAgYW5kIGBzdHJlYW0yYFxuICogd2lsbCBiZSBzZW50LlxuICpcbiAqIF9fU2lnbmF0dXJlX186IGBTdHJlYW0gYSAtPiBTdHJlYW0gYSAtPiBTdHJlYW0gYWBcbiAqXG4gKiBAbmFtZSBmbHlkLm1lcmdlXG4gKiBAcGFyYW0ge3N0cmVhbX0gc291cmNlMSAtIG9uZSBzdHJlYW0gdG8gYmUgbWVyZ2VkXG4gKiBAcGFyYW0ge3N0cmVhbX0gc291cmNlMiAtIHRoZSBvdGhlciBzdHJlYW0gdG8gYmUgbWVyZ2VkXG4gKiBAcmV0dXJuIHtzdHJlYW19IGEgc3RyZWFtIHdpdGggdGhlIHZhbHVlcyBmcm9tIGJvdGggc291cmNlc1xuICpcbiAqIEBleGFtcGxlXG4gKiB2YXIgYnRuMUNsaWNrcyA9IGZseWQuc3RyZWFtKCk7XG4gKiBidXR0b24xRWxtLmFkZEV2ZW50TGlzdGVuZXIoYnRuMUNsaWNrcyk7XG4gKiB2YXIgYnRuMkNsaWNrcyA9IGZseWQuc3RyZWFtKCk7XG4gKiBidXR0b24yRWxtLmFkZEV2ZW50TGlzdGVuZXIoYnRuMkNsaWNrcyk7XG4gKiB2YXIgYWxsQ2xpY2tzID0gZmx5ZC5tZXJnZShidG4xQ2xpY2tzLCBidG4yQ2xpY2tzKTtcbiAqL1xuZmx5ZC5tZXJnZSA9IGN1cnJ5TigyLCBmdW5jdGlvbihzMSwgczIpIHtcbiAgdmFyIHMgPSBmbHlkLmltbWVkaWF0ZShjb21iaW5lKGZ1bmN0aW9uKHMxLCBzMiwgc2VsZiwgY2hhbmdlZCkge1xuICAgIGlmIChjaGFuZ2VkWzBdKSB7XG4gICAgICBzZWxmKGNoYW5nZWRbMF0oKSk7XG4gICAgfSBlbHNlIGlmIChzMS5oYXNWYWwpIHtcbiAgICAgIHNlbGYoczEudmFsKTtcbiAgICB9IGVsc2UgaWYgKHMyLmhhc1ZhbCkge1xuICAgICAgc2VsZihzMi52YWwpO1xuICAgIH1cbiAgfSwgW3MxLCBzMl0pKTtcbiAgZmx5ZC5lbmRzT24oY29tYmluZShmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSwgW3MxLmVuZCwgczIuZW5kXSksIHMpO1xuICByZXR1cm4gcztcbn0pO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgc3RyZWFtIHJlc3VsdGluZyBmcm9tIGFwcGx5aW5nIGB0cmFuc2R1Y2VyYCB0byBgc3RyZWFtYC5cbiAqXG4gKiBfX1NpZ25hdHVyZV9fOiBgVHJhbnNkdWNlciAtPiBTdHJlYW0gYSAtPiBTdHJlYW0gYmBcbiAqXG4gKiBAbmFtZSBmbHlkLnRyYW5zZHVjZVxuICogQHBhcmFtIHtUcmFuc2R1Y2VyfSB4Zm9ybSAtIHRoZSB0cmFuc2R1Y2VyIHRyYW5zZm9ybWF0aW9uXG4gKiBAcGFyYW0ge3N0cmVhbX0gc291cmNlIC0gdGhlIHN0cmVhbSBzb3VyY2VcbiAqIEByZXR1cm4ge3N0cmVhbX0gdGhlIG5ldyBzdHJlYW1cbiAqXG4gKiBAZXhhbXBsZVxuICogdmFyIHQgPSByZXF1aXJlKCd0cmFuc2R1Y2Vycy5qcycpO1xuICpcbiAqIHZhciByZXN1bHRzID0gW107XG4gKiB2YXIgczEgPSBmbHlkLnN0cmVhbSgpO1xuICogdmFyIHR4ID0gdC5jb21wb3NlKHQubWFwKGZ1bmN0aW9uKHgpIHsgcmV0dXJuIHggKiAyOyB9KSwgdC5kZWR1cGUoKSk7XG4gKiB2YXIgczIgPSBmbHlkLnRyYW5zZHVjZSh0eCwgczEpO1xuICogZmx5ZC5jb21iaW5lKGZ1bmN0aW9uKHMyKSB7IHJlc3VsdHMucHVzaChzMigpKTsgfSwgW3MyXSk7XG4gKiBzMSgxKSgxKSgyKSgzKSgzKSgzKSg0KTtcbiAqIHJlc3VsdHM7IC8vID0+IFsyLCA0LCA2LCA4XVxuICovXG5mbHlkLnRyYW5zZHVjZSA9IGN1cnJ5TigyLCBmdW5jdGlvbih4Zm9ybSwgc291cmNlKSB7XG4gIHhmb3JtID0geGZvcm0obmV3IFN0cmVhbVRyYW5zZm9ybWVyKCkpO1xuICByZXR1cm4gY29tYmluZShmdW5jdGlvbihzb3VyY2UsIHNlbGYpIHtcbiAgICB2YXIgcmVzID0geGZvcm1bJ0BAdHJhbnNkdWNlci9zdGVwJ10odW5kZWZpbmVkLCBzb3VyY2UudmFsKTtcbiAgICBpZiAocmVzICYmIHJlc1snQEB0cmFuc2R1Y2VyL3JlZHVjZWQnXSA9PT0gdHJ1ZSkge1xuICAgICAgc2VsZi5lbmQodHJ1ZSk7XG4gICAgICByZXR1cm4gcmVzWydAQHRyYW5zZHVjZXIvdmFsdWUnXTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG4gIH0sIFtzb3VyY2VdKTtcbn0pO1xuXG4vKipcbiAqIFJldHVybnMgYGZuYCBjdXJyaWVkIHRvIGBuYC4gVXNlIHRoaXMgZnVuY3Rpb24gdG8gY3VycnkgZnVuY3Rpb25zIGV4cG9zZWQgYnlcbiAqIG1vZHVsZXMgZm9yIEZseWQuXG4gKlxuICogQG5hbWUgZmx5ZC5jdXJyeU5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtJbnRlZ2VyfSBhcml0eSAtIHRoZSBmdW5jdGlvbiBhcml0eVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm4gLSB0aGUgZnVuY3Rpb24gdG8gY3VycnlcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSB0aGUgY3VycmllZCBmdW5jdGlvblxuICpcbiAqIEBleGFtcGxlXG4gKiBmdW5jdGlvbiBhZGQoeCwgeSkgeyByZXR1cm4geCArIHk7IH07XG4gKiB2YXIgYSA9IGZseWQuY3VycnlOKDIsIGFkZCk7XG4gKiBhKDIpKDQpIC8vID0+IDZcbiAqL1xuZmx5ZC5jdXJyeU4gPSBjdXJyeU5cblxuLyoqXG4gKiBSZXR1cm5zIGEgbmV3IHN0cmVhbSBpZGVudGljYWwgdG8gdGhlIG9yaWdpbmFsIGV4Y2VwdCBldmVyeVxuICogdmFsdWUgd2lsbCBiZSBwYXNzZWQgdGhyb3VnaCBgZmAuXG4gKlxuICogX05vdGU6XyBUaGlzIGZ1bmN0aW9uIGlzIGluY2x1ZGVkIGluIG9yZGVyIHRvIHN1cHBvcnQgdGhlIGZhbnRhc3kgbGFuZFxuICogc3BlY2lmaWNhdGlvbi5cbiAqXG4gKiBfX1NpZ25hdHVyZV9fOiBDYWxsZWQgYm91bmQgdG8gYFN0cmVhbSBhYDogYChhIC0+IGIpIC0+IFN0cmVhbSBiYFxuICpcbiAqIEBuYW1lIHN0cmVhbS5tYXBcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmN0aW9uIC0gdGhlIGZ1bmN0aW9uIHRvIGFwcGx5XG4gKiBAcmV0dXJuIHtzdHJlYW19IGEgbmV3IHN0cmVhbSB3aXRoIHRoZSB2YWx1ZXMgbWFwcGVkXG4gKlxuICogQGV4YW1wbGVcbiAqIHZhciBudW1iZXJzID0gZmx5ZC5zdHJlYW0oMCk7XG4gKiB2YXIgc3F1YXJlZE51bWJlcnMgPSBudW1iZXJzLm1hcChmdW5jdGlvbihuKSB7IHJldHVybiBuKm47IH0pO1xuICovXG5mdW5jdGlvbiBib3VuZE1hcChmKSB7IHJldHVybiBmbHlkLm1hcChmLCB0aGlzKTsgfVxuXG4vKipcbiAqIFJldHVybnMgYSBuZXcgc3RyZWFtIHdoaWNoIGlzIHRoZSByZXN1bHQgb2YgYXBwbHlpbmcgdGhlXG4gKiBmdW5jdGlvbnMgZnJvbSBgdGhpc2Agc3RyZWFtIHRvIHRoZSB2YWx1ZXMgaW4gYHN0cmVhbWAgcGFyYW1ldGVyLlxuICpcbiAqIGB0aGlzYCBzdHJlYW0gbXVzdCBiZSBhIHN0cmVhbSBvZiBmdW5jdGlvbnMuXG4gKlxuICogX05vdGU6XyBUaGlzIGZ1bmN0aW9uIGlzIGluY2x1ZGVkIGluIG9yZGVyIHRvIHN1cHBvcnQgdGhlIGZhbnRhc3kgbGFuZFxuICogc3BlY2lmaWNhdGlvbi5cbiAqXG4gKiBfX1NpZ25hdHVyZV9fOiBDYWxsZWQgYm91bmQgdG8gYFN0cmVhbSAoYSAtPiBiKWA6IGBhIC0+IFN0cmVhbSBiYFxuICpcbiAqIEBuYW1lIHN0cmVhbS5hcFxuICogQHBhcmFtIHtzdHJlYW19IHN0cmVhbSAtIHRoZSB2YWx1ZXMgc3RyZWFtXG4gKiBAcmV0dXJuIHtzdHJlYW19IGEgbmV3IHN0cmFtIHdpdGggdGhlIGZ1bmN0aW9ucyBhcHBsaWVkIHRvIHZhbHVlc1xuICpcbiAqIEBleGFtcGxlXG4gKiB2YXIgYWRkID0gZmx5ZC5jdXJyeU4oMiwgZnVuY3Rpb24oeCwgeSkgeyByZXR1cm4geCArIHk7IH0pO1xuICogdmFyIG51bWJlcnMxID0gZmx5ZC5zdHJlYW0oKTtcbiAqIHZhciBudW1iZXJzMiA9IGZseWQuc3RyZWFtKCk7XG4gKiB2YXIgYWRkVG9OdW1iZXJzMSA9IGZseWQubWFwKGFkZCwgbnVtYmVyczEpO1xuICogdmFyIGFkZGVkID0gYWRkVG9OdW1iZXJzMS5hcChudW1iZXJzMik7XG4gKi9cbmZ1bmN0aW9uIGFwKHMyKSB7XG4gIHZhciBzMSA9IHRoaXM7XG4gIHJldHVybiBjb21iaW5lKGZ1bmN0aW9uKHMxLCBzMiwgc2VsZikgeyBzZWxmKHMxLnZhbChzMi52YWwpKTsgfSwgW3MxLCBzMl0pO1xufVxuXG4vKipcbiAqIEdldCBhIGh1bWFuIHJlYWRhYmxlIHZpZXcgb2YgYSBzdHJlYW1cbiAqIEBuYW1lIHN0cmVhbS50b1N0cmluZ1xuICogQHJldHVybiB7U3RyaW5nfSB0aGUgc3RyZWFtIHN0cmluZyByZXByZXNlbnRhdGlvblxuICovXG5mdW5jdGlvbiBzdHJlYW1Ub1N0cmluZygpIHtcbiAgcmV0dXJuICdzdHJlYW0oJyArIHRoaXMudmFsICsgJyknO1xufVxuXG4vKipcbiAqIEBuYW1lIHN0cmVhbS5lbmRcbiAqIEBtZW1iZXJvZiBzdHJlYW1cbiAqIEEgc3RyZWFtIHRoYXQgZW1pdHMgYHRydWVgIHdoZW4gdGhlIHN0cmVhbSBlbmRzLiBJZiBgdHJ1ZWAgaXMgcHVzaGVkIGRvd24gdGhlXG4gKiBzdHJlYW0gdGhlIHBhcmVudCBzdHJlYW0gZW5kcy5cbiAqL1xuXG4vKipcbiAqIEBuYW1lIHN0cmVhbS5vZlxuICogQGZ1bmN0aW9uXG4gKiBAbWVtYmVyb2Ygc3RyZWFtXG4gKiBSZXR1cm5zIGEgbmV3IHN0cmVhbSB3aXRoIGB2YWx1ZWAgYXMgaXRzIGluaXRpYWwgdmFsdWUuIEl0IGlzIGlkZW50aWNhbCB0b1xuICogY2FsbGluZyBgZmx5ZC5zdHJlYW1gIHdpdGggb25lIGFyZ3VtZW50LlxuICpcbiAqIF9fU2lnbmF0dXJlX186IENhbGxlZCBib3VuZCB0byBgU3RyZWFtIChhKWA6IGBiIC0+IFN0cmVhbSBiYFxuICpcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgLSB0aGUgaW5pdGlhbCB2YWx1ZVxuICogQHJldHVybiB7c3RyZWFtfSB0aGUgbmV3IHN0cmVhbVxuICpcbiAqIEBleGFtcGxlXG4gKiB2YXIgbiA9IGZseWQuc3RyZWFtKDEpO1xuICogdmFyIG0gPSBuLm9mKDEpO1xuICovXG5cbi8vIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLyBQUklWQVRFIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLyAvL1xuLyoqXG4gKiBAcHJpdmF0ZVxuICogQ3JlYXRlIGEgc3RyZWFtIHdpdGggbm8gZGVwZW5kZW5jaWVzIGFuZCBubyB2YWx1ZVxuICogQHJldHVybiB7RnVuY3Rpb259IGEgZmx5ZCBzdHJlYW1cbiAqL1xuZnVuY3Rpb24gY3JlYXRlU3RyZWFtKCkge1xuICBmdW5jdGlvbiBzKG4pIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIHMudmFsXG4gICAgdXBkYXRlU3RyZWFtVmFsdWUocywgbilcbiAgICByZXR1cm4gc1xuICB9XG4gIHMuaGFzVmFsID0gZmFsc2U7XG4gIHMudmFsID0gdW5kZWZpbmVkO1xuICBzLnZhbHMgPSBbXTtcbiAgcy5saXN0ZW5lcnMgPSBbXTtcbiAgcy5xdWV1ZWQgPSBmYWxzZTtcbiAgcy5lbmQgPSB1bmRlZmluZWQ7XG4gIHMubWFwID0gYm91bmRNYXA7XG4gIHMuYXAgPSBhcDtcbiAgcy5vZiA9IGZseWQuc3RyZWFtO1xuICBzLnRvU3RyaW5nID0gc3RyZWFtVG9TdHJpbmc7XG4gIHJldHVybiBzO1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBDcmVhdGUgYSBkZXBlbmRlbnQgc3RyZWFtXG4gKiBAcGFyYW0ge0FycmF5PHN0cmVhbT59IGRlcGVuZGVuY2llcyAtIGFuIGFycmF5IG9mIHRoZSBzdHJlYW1zXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiAtIHRoZSBmdW5jdGlvbiB1c2VkIHRvIGNhbGN1bGF0ZSB0aGUgbmV3IHN0cmVhbSB2YWx1ZVxuICogZnJvbSB0aGUgZGVwZW5kZW5jaWVzXG4gKiBAcmV0dXJuIHtzdHJlYW19IHRoZSBjcmVhdGVkIHN0cmVhbVxuICovXG5mdW5jdGlvbiBjcmVhdGVEZXBlbmRlbnRTdHJlYW0oZGVwcywgZm4pIHtcbiAgdmFyIHMgPSBjcmVhdGVTdHJlYW0oKTtcbiAgcy5mbiA9IGZuO1xuICBzLmRlcHMgPSBkZXBzO1xuICBzLmRlcHNNZXQgPSBmYWxzZTtcbiAgcy5kZXBzQ2hhbmdlZCA9IGRlcHMubGVuZ3RoID4gMCA/IFtdIDogdW5kZWZpbmVkO1xuICBzLnNob3VsZFVwZGF0ZSA9IGZhbHNlO1xuICBhZGRMaXN0ZW5lcnMoZGVwcywgcyk7XG4gIHJldHVybiBzO1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBDaGVjayBpZiBhbGwgdGhlIGRlcGVuZGVuY2llcyBoYXZlIHZhbHVlc1xuICogQHBhcmFtIHtzdHJlYW19IHN0cmVhbSAtIHRoZSBzdHJlYW0gdG8gY2hlY2sgZGVwZW5jZW5jaWVzIGZyb21cbiAqIEByZXR1cm4ge0Jvb2xlYW59IGB0cnVlYCBpZiBhbGwgZGVwZW5kZW5jaWVzIGhhdmUgdmFsZXMsIGBmYWxzZWAgb3RoZXJ3aXNlXG4gKi9cbmZ1bmN0aW9uIGluaXRpYWxEZXBzTm90TWV0KHN0cmVhbSkge1xuICBzdHJlYW0uZGVwc01ldCA9IHN0cmVhbS5kZXBzLmV2ZXJ5KGZ1bmN0aW9uKHMpIHtcbiAgICByZXR1cm4gcy5oYXNWYWw7XG4gIH0pO1xuICByZXR1cm4gIXN0cmVhbS5kZXBzTWV0O1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBVcGRhdGUgYSBkZXBlbmRlbnQgc3RyZWFtIHVzaW5nIGl0cyBkZXBlbmRlbmNpZXMgaW4gYW4gYXRvbWljIHdheVxuICogQHBhcmFtIHtzdHJlYW19IHN0cmVhbSAtIHRoZSBzdHJlYW0gdG8gdXBkYXRlXG4gKi9cbmZ1bmN0aW9uIHVwZGF0ZVN0cmVhbShzKSB7XG4gIGlmICgocy5kZXBzTWV0ICE9PSB0cnVlICYmIGluaXRpYWxEZXBzTm90TWV0KHMpKSB8fFxuICAgICAgKHMuZW5kICE9PSB1bmRlZmluZWQgJiYgcy5lbmQudmFsID09PSB0cnVlKSkgcmV0dXJuO1xuICBpZiAoaW5TdHJlYW0gIT09IHVuZGVmaW5lZCkge1xuICAgIHRvVXBkYXRlLnB1c2gocyk7XG4gICAgcmV0dXJuO1xuICB9XG4gIGluU3RyZWFtID0gcztcbiAgaWYgKHMuZGVwc0NoYW5nZWQpIHMuZm5BcmdzW3MuZm5BcmdzLmxlbmd0aCAtIDFdID0gcy5kZXBzQ2hhbmdlZDtcbiAgdmFyIHJldHVyblZhbCA9IHMuZm4uYXBwbHkocy5mbiwgcy5mbkFyZ3MpO1xuICBpZiAocmV0dXJuVmFsICE9PSB1bmRlZmluZWQpIHtcbiAgICBzKHJldHVyblZhbCk7XG4gIH1cbiAgaW5TdHJlYW0gPSB1bmRlZmluZWQ7XG4gIGlmIChzLmRlcHNDaGFuZ2VkICE9PSB1bmRlZmluZWQpIHMuZGVwc0NoYW5nZWQgPSBbXTtcbiAgcy5zaG91bGRVcGRhdGUgPSBmYWxzZTtcbiAgaWYgKGZsdXNoaW5nID09PSBmYWxzZSkgZmx1c2hVcGRhdGUoKTtcbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogVXBkYXRlIHRoZSBkZXBlbmRlbmNpZXMgb2YgYSBzdHJlYW1cbiAqIEBwYXJhbSB7c3RyZWFtfSBzdHJlYW1cbiAqL1xuZnVuY3Rpb24gdXBkYXRlRGVwcyhzKSB7XG4gIHZhciBpLCBvLCBsaXN0XG4gIHZhciBsaXN0ZW5lcnMgPSBzLmxpc3RlbmVycztcbiAgZm9yIChpID0gMDsgaSA8IGxpc3RlbmVycy5sZW5ndGg7ICsraSkge1xuICAgIGxpc3QgPSBsaXN0ZW5lcnNbaV07XG4gICAgaWYgKGxpc3QuZW5kID09PSBzKSB7XG4gICAgICBlbmRTdHJlYW0obGlzdCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChsaXN0LmRlcHNDaGFuZ2VkICE9PSB1bmRlZmluZWQpIGxpc3QuZGVwc0NoYW5nZWQucHVzaChzKTtcbiAgICAgIGxpc3Quc2hvdWxkVXBkYXRlID0gdHJ1ZTtcbiAgICAgIGZpbmREZXBzKGxpc3QpO1xuICAgIH1cbiAgfVxuICBmb3IgKDsgb3JkZXJOZXh0SWR4ID49IDA7IC0tb3JkZXJOZXh0SWR4KSB7XG4gICAgbyA9IG9yZGVyW29yZGVyTmV4dElkeF07XG4gICAgaWYgKG8uc2hvdWxkVXBkYXRlID09PSB0cnVlKSB1cGRhdGVTdHJlYW0obyk7XG4gICAgby5xdWV1ZWQgPSBmYWxzZTtcbiAgfVxufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBBZGQgc3RyZWFtIGRlcGVuZGVuY2llcyB0byB0aGUgZ2xvYmFsIGBvcmRlcmAgcXVldWUuXG4gKiBAcGFyYW0ge3N0cmVhbX0gc3RyZWFtXG4gKiBAc2VlIHVwZGF0ZURlcHNcbiAqL1xuZnVuY3Rpb24gZmluZERlcHMocykge1xuICB2YXIgaVxuICB2YXIgbGlzdGVuZXJzID0gcy5saXN0ZW5lcnM7XG4gIGlmIChzLnF1ZXVlZCA9PT0gZmFsc2UpIHtcbiAgICBzLnF1ZXVlZCA9IHRydWU7XG4gICAgZm9yIChpID0gMDsgaSA8IGxpc3RlbmVycy5sZW5ndGg7ICsraSkge1xuICAgICAgZmluZERlcHMobGlzdGVuZXJzW2ldKTtcbiAgICB9XG4gICAgb3JkZXJbKytvcmRlck5leHRJZHhdID0gcztcbiAgfVxufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIGZsdXNoVXBkYXRlKCkge1xuICBmbHVzaGluZyA9IHRydWU7XG4gIHdoaWxlICh0b1VwZGF0ZS5sZW5ndGggPiAwKSB7XG4gICAgdmFyIHMgPSB0b1VwZGF0ZS5zaGlmdCgpO1xuICAgIGlmIChzLnZhbHMubGVuZ3RoID4gMCkgcy52YWwgPSBzLnZhbHMuc2hpZnQoKTtcbiAgICB1cGRhdGVEZXBzKHMpO1xuICB9XG4gIGZsdXNoaW5nID0gZmFsc2U7XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIFB1c2ggZG93biBhIHZhbHVlIGludG8gYSBzdHJlYW1cbiAqIEBwYXJhbSB7c3RyZWFtfSBzdHJlYW1cbiAqIEBwYXJhbSB7Kn0gdmFsdWVcbiAqL1xuZnVuY3Rpb24gdXBkYXRlU3RyZWFtVmFsdWUocywgbikge1xuICBpZiAobiAhPT0gdW5kZWZpbmVkICYmIG4gIT09IG51bGwgJiYgaXNGdW5jdGlvbihuLnRoZW4pKSB7XG4gICAgbi50aGVuKHMpO1xuICAgIHJldHVybjtcbiAgfVxuICBzLnZhbCA9IG47XG4gIHMuaGFzVmFsID0gdHJ1ZTtcbiAgaWYgKGluU3RyZWFtID09PSB1bmRlZmluZWQpIHtcbiAgICBmbHVzaGluZyA9IHRydWU7XG4gICAgdXBkYXRlRGVwcyhzKTtcbiAgICBpZiAodG9VcGRhdGUubGVuZ3RoID4gMCkgZmx1c2hVcGRhdGUoKTsgZWxzZSBmbHVzaGluZyA9IGZhbHNlO1xuICB9IGVsc2UgaWYgKGluU3RyZWFtID09PSBzKSB7XG4gICAgbWFya0xpc3RlbmVycyhzLCBzLmxpc3RlbmVycyk7XG4gIH0gZWxzZSB7XG4gICAgcy52YWxzLnB1c2gobik7XG4gICAgdG9VcGRhdGUucHVzaChzKTtcbiAgfVxufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIG1hcmtMaXN0ZW5lcnMocywgbGlzdHMpIHtcbiAgdmFyIGksIGxpc3Q7XG4gIGZvciAoaSA9IDA7IGkgPCBsaXN0cy5sZW5ndGg7ICsraSkge1xuICAgIGxpc3QgPSBsaXN0c1tpXTtcbiAgICBpZiAobGlzdC5lbmQgIT09IHMpIHtcbiAgICAgIGlmIChsaXN0LmRlcHNDaGFuZ2VkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgbGlzdC5kZXBzQ2hhbmdlZC5wdXNoKHMpO1xuICAgICAgfVxuICAgICAgbGlzdC5zaG91bGRVcGRhdGUgPSB0cnVlO1xuICAgIH0gZWxzZSB7XG4gICAgICBlbmRTdHJlYW0obGlzdCk7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEFkZCBkZXBlbmRlbmNpZXMgdG8gYSBzdHJlYW1cbiAqIEBwYXJhbSB7QXJyYXk8c3RyZWFtPn0gZGVwZW5kZW5jaWVzXG4gKiBAcGFyYW0ge3N0cmVhbX0gc3RyZWFtXG4gKi9cbmZ1bmN0aW9uIGFkZExpc3RlbmVycyhkZXBzLCBzKSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgZGVwcy5sZW5ndGg7ICsraSkge1xuICAgIGRlcHNbaV0ubGlzdGVuZXJzLnB1c2gocyk7XG4gIH1cbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogUmVtb3ZlcyBhbiBzdHJlYW0gZnJvbSBhIGRlcGVuZGVuY3kgYXJyYXlcbiAqIEBwYXJhbSB7c3RyZWFtfSBzdHJlYW1cbiAqIEBwYXJhbSB7QXJyYXk8c3RyZWFtPn0gZGVwZW5kZW5jaWVzXG4gKi9cbmZ1bmN0aW9uIHJlbW92ZUxpc3RlbmVyKHMsIGxpc3RlbmVycykge1xuICB2YXIgaWR4ID0gbGlzdGVuZXJzLmluZGV4T2Yocyk7XG4gIGxpc3RlbmVyc1tpZHhdID0gbGlzdGVuZXJzW2xpc3RlbmVycy5sZW5ndGggLSAxXTtcbiAgbGlzdGVuZXJzLmxlbmd0aC0tO1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBEZXRhY2ggYSBzdHJlYW0gZnJvbSBpdHMgZGVwZW5kZW5jaWVzXG4gKiBAcGFyYW0ge3N0cmVhbX0gc3RyZWFtXG4gKi9cbmZ1bmN0aW9uIGRldGFjaERlcHMocykge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHMuZGVwcy5sZW5ndGg7ICsraSkge1xuICAgIHJlbW92ZUxpc3RlbmVyKHMsIHMuZGVwc1tpXS5saXN0ZW5lcnMpO1xuICB9XG4gIHMuZGVwcy5sZW5ndGggPSAwO1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBFbmRzIGEgc3RyZWFtXG4gKi9cbmZ1bmN0aW9uIGVuZFN0cmVhbShzKSB7XG4gIGlmIChzLmRlcHMgIT09IHVuZGVmaW5lZCkgZGV0YWNoRGVwcyhzKTtcbiAgaWYgKHMuZW5kICE9PSB1bmRlZmluZWQpIGRldGFjaERlcHMocy5lbmQpO1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiB0cmFuc2R1Y2VyIHN0cmVhbSB0cmFuc2Zvcm1lclxuICovXG5mdW5jdGlvbiBTdHJlYW1UcmFuc2Zvcm1lcigpIHsgfVxuU3RyZWFtVHJhbnNmb3JtZXIucHJvdG90eXBlWydAQHRyYW5zZHVjZXIvaW5pdCddID0gZnVuY3Rpb24oKSB7IH07XG5TdHJlYW1UcmFuc2Zvcm1lci5wcm90b3R5cGVbJ0BAdHJhbnNkdWNlci9yZXN1bHQnXSA9IGZ1bmN0aW9uKCkgeyB9O1xuU3RyZWFtVHJhbnNmb3JtZXIucHJvdG90eXBlWydAQHRyYW5zZHVjZXIvc3RlcCddID0gZnVuY3Rpb24ocywgdikgeyByZXR1cm4gdjsgfTtcblxubW9kdWxlLmV4cG9ydHMgPSBmbHlkO1xuIiwidmFyIF9hcml0eSA9IHJlcXVpcmUoJy4vaW50ZXJuYWwvX2FyaXR5Jyk7XG52YXIgX2N1cnJ5MSA9IHJlcXVpcmUoJy4vaW50ZXJuYWwvX2N1cnJ5MScpO1xudmFyIF9jdXJyeTIgPSByZXF1aXJlKCcuL2ludGVybmFsL19jdXJyeTInKTtcbnZhciBfY3VycnlOID0gcmVxdWlyZSgnLi9pbnRlcm5hbC9fY3VycnlOJyk7XG5cblxuLyoqXG4gKiBSZXR1cm5zIGEgY3VycmllZCBlcXVpdmFsZW50IG9mIHRoZSBwcm92aWRlZCBmdW5jdGlvbiwgd2l0aCB0aGUgc3BlY2lmaWVkXG4gKiBhcml0eS4gVGhlIGN1cnJpZWQgZnVuY3Rpb24gaGFzIHR3byB1bnVzdWFsIGNhcGFiaWxpdGllcy4gRmlyc3QsIGl0c1xuICogYXJndW1lbnRzIG5lZWRuJ3QgYmUgcHJvdmlkZWQgb25lIGF0IGEgdGltZS4gSWYgYGdgIGlzIGBSLmN1cnJ5TigzLCBmKWAsIHRoZVxuICogZm9sbG93aW5nIGFyZSBlcXVpdmFsZW50OlxuICpcbiAqICAgLSBgZygxKSgyKSgzKWBcbiAqICAgLSBgZygxKSgyLCAzKWBcbiAqICAgLSBgZygxLCAyKSgzKWBcbiAqICAgLSBgZygxLCAyLCAzKWBcbiAqXG4gKiBTZWNvbmRseSwgdGhlIHNwZWNpYWwgcGxhY2Vob2xkZXIgdmFsdWUgYFIuX19gIG1heSBiZSB1c2VkIHRvIHNwZWNpZnlcbiAqIFwiZ2Fwc1wiLCBhbGxvd2luZyBwYXJ0aWFsIGFwcGxpY2F0aW9uIG9mIGFueSBjb21iaW5hdGlvbiBvZiBhcmd1bWVudHMsXG4gKiByZWdhcmRsZXNzIG9mIHRoZWlyIHBvc2l0aW9ucy4gSWYgYGdgIGlzIGFzIGFib3ZlIGFuZCBgX2AgaXMgYFIuX19gLCB0aGVcbiAqIGZvbGxvd2luZyBhcmUgZXF1aXZhbGVudDpcbiAqXG4gKiAgIC0gYGcoMSwgMiwgMylgXG4gKiAgIC0gYGcoXywgMiwgMykoMSlgXG4gKiAgIC0gYGcoXywgXywgMykoMSkoMilgXG4gKiAgIC0gYGcoXywgXywgMykoMSwgMilgXG4gKiAgIC0gYGcoXywgMikoMSkoMylgXG4gKiAgIC0gYGcoXywgMikoMSwgMylgXG4gKiAgIC0gYGcoXywgMikoXywgMykoMSlgXG4gKlxuICogQGZ1bmNcbiAqIEBtZW1iZXJPZiBSXG4gKiBAc2luY2UgdjAuNS4wXG4gKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAqIEBzaWcgTnVtYmVyIC0+ICgqIC0+IGEpIC0+ICgqIC0+IGEpXG4gKiBAcGFyYW0ge051bWJlcn0gbGVuZ3RoIFRoZSBhcml0eSBmb3IgdGhlIHJldHVybmVkIGZ1bmN0aW9uLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm4gVGhlIGZ1bmN0aW9uIHRvIGN1cnJ5LlxuICogQHJldHVybiB7RnVuY3Rpb259IEEgbmV3LCBjdXJyaWVkIGZ1bmN0aW9uLlxuICogQHNlZSBSLmN1cnJ5XG4gKiBAZXhhbXBsZVxuICpcbiAqICAgICAgdmFyIHN1bUFyZ3MgPSAoLi4uYXJncykgPT4gUi5zdW0oYXJncyk7XG4gKlxuICogICAgICB2YXIgY3VycmllZEFkZEZvdXJOdW1iZXJzID0gUi5jdXJyeU4oNCwgc3VtQXJncyk7XG4gKiAgICAgIHZhciBmID0gY3VycmllZEFkZEZvdXJOdW1iZXJzKDEsIDIpO1xuICogICAgICB2YXIgZyA9IGYoMyk7XG4gKiAgICAgIGcoNCk7IC8vPT4gMTBcbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBfY3VycnkyKGZ1bmN0aW9uIGN1cnJ5TihsZW5ndGgsIGZuKSB7XG4gIGlmIChsZW5ndGggPT09IDEpIHtcbiAgICByZXR1cm4gX2N1cnJ5MShmbik7XG4gIH1cbiAgcmV0dXJuIF9hcml0eShsZW5ndGgsIF9jdXJyeU4obGVuZ3RoLCBbXSwgZm4pKTtcbn0pO1xuIiwibW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBfYXJpdHkobiwgZm4pIHtcbiAgLyogZXNsaW50LWRpc2FibGUgbm8tdW51c2VkLXZhcnMgKi9cbiAgc3dpdGNoIChuKSB7XG4gICAgY2FzZSAwOiByZXR1cm4gZnVuY3Rpb24oKSB7IHJldHVybiBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9O1xuICAgIGNhc2UgMTogcmV0dXJuIGZ1bmN0aW9uKGEwKSB7IHJldHVybiBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9O1xuICAgIGNhc2UgMjogcmV0dXJuIGZ1bmN0aW9uKGEwLCBhMSkgeyByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfTtcbiAgICBjYXNlIDM6IHJldHVybiBmdW5jdGlvbihhMCwgYTEsIGEyKSB7IHJldHVybiBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9O1xuICAgIGNhc2UgNDogcmV0dXJuIGZ1bmN0aW9uKGEwLCBhMSwgYTIsIGEzKSB7IHJldHVybiBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9O1xuICAgIGNhc2UgNTogcmV0dXJuIGZ1bmN0aW9uKGEwLCBhMSwgYTIsIGEzLCBhNCkgeyByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfTtcbiAgICBjYXNlIDY6IHJldHVybiBmdW5jdGlvbihhMCwgYTEsIGEyLCBhMywgYTQsIGE1KSB7IHJldHVybiBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9O1xuICAgIGNhc2UgNzogcmV0dXJuIGZ1bmN0aW9uKGEwLCBhMSwgYTIsIGEzLCBhNCwgYTUsIGE2KSB7IHJldHVybiBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9O1xuICAgIGNhc2UgODogcmV0dXJuIGZ1bmN0aW9uKGEwLCBhMSwgYTIsIGEzLCBhNCwgYTUsIGE2LCBhNykgeyByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfTtcbiAgICBjYXNlIDk6IHJldHVybiBmdW5jdGlvbihhMCwgYTEsIGEyLCBhMywgYTQsIGE1LCBhNiwgYTcsIGE4KSB7IHJldHVybiBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9O1xuICAgIGNhc2UgMTA6IHJldHVybiBmdW5jdGlvbihhMCwgYTEsIGEyLCBhMywgYTQsIGE1LCBhNiwgYTcsIGE4LCBhOSkgeyByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfTtcbiAgICBkZWZhdWx0OiB0aHJvdyBuZXcgRXJyb3IoJ0ZpcnN0IGFyZ3VtZW50IHRvIF9hcml0eSBtdXN0IGJlIGEgbm9uLW5lZ2F0aXZlIGludGVnZXIgbm8gZ3JlYXRlciB0aGFuIHRlbicpO1xuICB9XG59O1xuIiwidmFyIF9pc1BsYWNlaG9sZGVyID0gcmVxdWlyZSgnLi9faXNQbGFjZWhvbGRlcicpO1xuXG5cbi8qKlxuICogT3B0aW1pemVkIGludGVybmFsIG9uZS1hcml0eSBjdXJyeSBmdW5jdGlvbi5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQGNhdGVnb3J5IEZ1bmN0aW9uXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiBUaGUgZnVuY3Rpb24gdG8gY3VycnkuXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gVGhlIGN1cnJpZWQgZnVuY3Rpb24uXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gX2N1cnJ5MShmbikge1xuICByZXR1cm4gZnVuY3Rpb24gZjEoYSkge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwIHx8IF9pc1BsYWNlaG9sZGVyKGEpKSB7XG4gICAgICByZXR1cm4gZjE7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH1cbiAgfTtcbn07XG4iLCJ2YXIgX2N1cnJ5MSA9IHJlcXVpcmUoJy4vX2N1cnJ5MScpO1xudmFyIF9pc1BsYWNlaG9sZGVyID0gcmVxdWlyZSgnLi9faXNQbGFjZWhvbGRlcicpO1xuXG5cbi8qKlxuICogT3B0aW1pemVkIGludGVybmFsIHR3by1hcml0eSBjdXJyeSBmdW5jdGlvbi5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQGNhdGVnb3J5IEZ1bmN0aW9uXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiBUaGUgZnVuY3Rpb24gdG8gY3VycnkuXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gVGhlIGN1cnJpZWQgZnVuY3Rpb24uXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gX2N1cnJ5Mihmbikge1xuICByZXR1cm4gZnVuY3Rpb24gZjIoYSwgYikge1xuICAgIHN3aXRjaCAoYXJndW1lbnRzLmxlbmd0aCkge1xuICAgICAgY2FzZSAwOlxuICAgICAgICByZXR1cm4gZjI7XG4gICAgICBjYXNlIDE6XG4gICAgICAgIHJldHVybiBfaXNQbGFjZWhvbGRlcihhKSA/IGYyXG4gICAgICAgICAgICAgOiBfY3VycnkxKGZ1bmN0aW9uKF9iKSB7IHJldHVybiBmbihhLCBfYik7IH0pO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIF9pc1BsYWNlaG9sZGVyKGEpICYmIF9pc1BsYWNlaG9sZGVyKGIpID8gZjJcbiAgICAgICAgICAgICA6IF9pc1BsYWNlaG9sZGVyKGEpID8gX2N1cnJ5MShmdW5jdGlvbihfYSkgeyByZXR1cm4gZm4oX2EsIGIpOyB9KVxuICAgICAgICAgICAgIDogX2lzUGxhY2Vob2xkZXIoYikgPyBfY3VycnkxKGZ1bmN0aW9uKF9iKSB7IHJldHVybiBmbihhLCBfYik7IH0pXG4gICAgICAgICAgICAgOiBmbihhLCBiKTtcbiAgICB9XG4gIH07XG59O1xuIiwidmFyIF9hcml0eSA9IHJlcXVpcmUoJy4vX2FyaXR5Jyk7XG52YXIgX2lzUGxhY2Vob2xkZXIgPSByZXF1aXJlKCcuL19pc1BsYWNlaG9sZGVyJyk7XG5cblxuLyoqXG4gKiBJbnRlcm5hbCBjdXJyeU4gZnVuY3Rpb24uXG4gKlxuICogQHByaXZhdGVcbiAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICogQHBhcmFtIHtOdW1iZXJ9IGxlbmd0aCBUaGUgYXJpdHkgb2YgdGhlIGN1cnJpZWQgZnVuY3Rpb24uXG4gKiBAcGFyYW0ge0FycmF5fSByZWNlaXZlZCBBbiBhcnJheSBvZiBhcmd1bWVudHMgcmVjZWl2ZWQgdGh1cyBmYXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiBUaGUgZnVuY3Rpb24gdG8gY3VycnkuXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gVGhlIGN1cnJpZWQgZnVuY3Rpb24uXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gX2N1cnJ5TihsZW5ndGgsIHJlY2VpdmVkLCBmbikge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGNvbWJpbmVkID0gW107XG4gICAgdmFyIGFyZ3NJZHggPSAwO1xuICAgIHZhciBsZWZ0ID0gbGVuZ3RoO1xuICAgIHZhciBjb21iaW5lZElkeCA9IDA7XG4gICAgd2hpbGUgKGNvbWJpbmVkSWR4IDwgcmVjZWl2ZWQubGVuZ3RoIHx8IGFyZ3NJZHggPCBhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICB2YXIgcmVzdWx0O1xuICAgICAgaWYgKGNvbWJpbmVkSWR4IDwgcmVjZWl2ZWQubGVuZ3RoICYmXG4gICAgICAgICAgKCFfaXNQbGFjZWhvbGRlcihyZWNlaXZlZFtjb21iaW5lZElkeF0pIHx8XG4gICAgICAgICAgIGFyZ3NJZHggPj0gYXJndW1lbnRzLmxlbmd0aCkpIHtcbiAgICAgICAgcmVzdWx0ID0gcmVjZWl2ZWRbY29tYmluZWRJZHhdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzdWx0ID0gYXJndW1lbnRzW2FyZ3NJZHhdO1xuICAgICAgICBhcmdzSWR4ICs9IDE7XG4gICAgICB9XG4gICAgICBjb21iaW5lZFtjb21iaW5lZElkeF0gPSByZXN1bHQ7XG4gICAgICBpZiAoIV9pc1BsYWNlaG9sZGVyKHJlc3VsdCkpIHtcbiAgICAgICAgbGVmdCAtPSAxO1xuICAgICAgfVxuICAgICAgY29tYmluZWRJZHggKz0gMTtcbiAgICB9XG4gICAgcmV0dXJuIGxlZnQgPD0gMCA/IGZuLmFwcGx5KHRoaXMsIGNvbWJpbmVkKVxuICAgICAgICAgICAgICAgICAgICAgOiBfYXJpdHkobGVmdCwgX2N1cnJ5TihsZW5ndGgsIGNvbWJpbmVkLCBmbikpO1xuICB9O1xufTtcbiIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gX2lzUGxhY2Vob2xkZXIoYSkge1xuICByZXR1cm4gYSAhPSBudWxsICYmXG4gICAgICAgICB0eXBlb2YgYSA9PT0gJ29iamVjdCcgJiZcbiAgICAgICAgIGFbJ0BAZnVuY3Rpb25hbC9wbGFjZWhvbGRlciddID09PSB0cnVlO1xufTtcbiIsInZhciBmbHlkID0gcmVxdWlyZSgnLi4vLi4vbGliJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZmx5ZC5jdXJyeU4oMiwgZnVuY3Rpb24oZm4sIHMpIHtcbiAgcmV0dXJuIGZseWQuY29tYmluZShmdW5jdGlvbihzLCBzZWxmKSB7XG4gICAgaWYgKGZuKHMoKSkpIHNlbGYocy52YWwpO1xuICB9LCBbc10pO1xufSk7XG4iXX0=
require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({"pex-geom/Rect":[function(require,module,exports){
function create(){
return [[Infinity,Infinity],[-Infinity,-Infinity]];
}
function zero(){
return [[0,0],[0,0]];
}
function copy(a){
return [a[0].slice(0),a[1].slice()];
}
function set(a,b){
a[0][0] = b[0][0];
a[0][1] = b[0][1];
a[1][0] = b[1][0];
a[1][1] = b[1][1];
return a;
}
function set4(a,x,y,w,h){
a[0][0] = x;
a[0][1] = y;
a[1][0] = x + w;
a[1][1] = y + h;
return a;
}
function scale(a,n){
a[0][0] *= n;
a[0][1] *= n;
a[1][0] *= n;
a[1][1] *= n;
return a;
}
function setMinMax(a,min,max){
a[0][0] = min[0];
a[0][1] = min[1];
a[1][0] = max[0];
a[1][1] = max[1];
return a;
}
function setMinMax4(a,minx,miny,maxx,maxy){
a[0][0] = minx;
a[0][1] = miny;
a[1][0] = maxx;
a[1][1] = maxy;
return a;
}
function getMin(a,out){
if(out === undefined){
return [a[0][0],a[0][1]];
}
out[0] = a[0][0];
out[1] = a[0][1];
return out;
}
function getMax(a,out){
if(out === undefined){
return [a[1][0],a[1][1]];
}
out[0] = a[1][0];
out[1] = a[1][1];
return out;
}
function setSize2(a,width,height){
a[1][0] = a[0][0] + width;
a[1][1] = a[0][1] + height;
return a;
}
function setSize(a,size){
a[1][0] = a[0][0] + size[0];
a[1][1] = a[0][1] + size[1];
return a;
}
function getSize(a,out){
var width = getWidth(a);
var height = getHeight(a);
if(out === undefined){
return [width,height];
}
out[0] = width;
out[1] = height;
return out;
}
function setWidth(a,width){
a[1][0] = a[0][0] + width;
return a;
}
function setHeight(a,height){
a[1][1] = a[0][1] + height;
return a;
}
function getWidth(a){
return a[1][0] - a[0][0];
}
function getHeight(a){
return a[1][1] - a[0][1];
}
function getAspectRatio(a){
return getWidth(a) / getHeight(a);
}
function setPosition(a,position){
return setPosition2(a,position[0],position[1]);
}
function setPosition2(a,x,y){
a[0][0] = x;
a[0][1] = y;
a[1][0] = x + getWidth(a);
a[1][1] = y + getHeight(a);
return a;
}
function getTR(a,out){
if(out === undefined){
return [a[1][0],a[1]];
}
out[0] = a[1][0];
out[1] = a[0][1];
return out;
}
function getBL(a,out){
if(out === undefined){
return [a[0][0],a[1][1]];
}
out[0] = a[0][0];
out[1] = a[1][1];
return out;
}
function getCenter(a,out){
var x = getWidth(a) * 0.5;
var y = getHeight(a) * 0.5;
if(out === undefined){
return [x,y];
}
out[0] = x;
out[1] = y;
return out;
}
function containsPoint(a,point){
return containsPoint2(a,point[0],point[1]);
}
function containsPoint2(a,x,y){
return x >= a[0][0] && x <= a[1][0] && y >= a[0][1] && y <= a[1][1];
}
function containsRect(a,b){
return containsPoint2(a,b[0][0],b[0][1]) && containsPoint2(a,b[1][0],b[1][1]);
}
function includePoint(a,point){
return includePoint2(a,point[0],point[1]);
}
function includePoint2(a,x,y){
var minx = a[0][0];
var miny = a[0][1];
var maxx = a[1][0];
var maxy = a[1][1];
a[0][0] = minx > x ? x : minx;
a[0][1] = miny > y ? y : miny;
a[1][0] = maxx < x ? x : maxx;
a[1][1] = maxy < y ? y : maxy;
return a;
}
function includePoints(a,points){
var minx = a[0][0];
var miny = a[0][1];
var maxx = a[1][0];
var maxy = a[1][1];
for(var i = 0, l = points.length, x, y; i < l; ++i){
x = points[i][0];
y = points[i][1];
minx = minx > x ? x : minx;
miny = miny > y ? y : miny;
maxx = maxx < x ? x : maxx;
maxy = maxy < y ? y : maxy;
}
a[0][0] = minx;
a[0][1] = miny;
a[1][0] = maxx;
a[1][1] = maxy;
return a;
}
function includePointsFlat(a,points){
var minx = a[0][0];
var miny = a[0][1];
var maxx = a[1][0];
var maxy = a[1][1];
for(var i = 0, l = points.length, x, y; i < l; i+=2){
x = points[i ];
y = points[i+1];
minx = minx > x ? x : minx;
miny = miny > y ? y : miny;
maxx = maxx < x ? x : maxx;
maxy = maxy < y ? y : maxy;
}
a[0][0] = minx;
a[0][1] = miny;
a[1][0] = maxx;
a[1][1] = maxy;
return a;
}
function includeRect(a,rect){
includePoint(a,rect[0]);
includePoint(a,rect[1]);
return a;
}
function includeRects(a,rects){
for(var i = 0, l = rects.length; i < l; ++i){
includeRect(a,rects[i]);
}
return a;
}
function mapPoint(a,point){
var minx = a[0][0];
var miny = a[0][1];
var maxx = a[1][0];
var maxy = a[1][1];
var x = point[0];
var y = point[1];
point[0] = Math.max(minx,Math.min(x,maxx)) - minx;
point[1] = Math.max(miny,Math.min(y,maxy)) - miny;
return point;
}
function clampPoint(a,point){
var minx = a[0][0];
var miny = a[0][1];
var maxx = a[1][0];
var maxy = a[1][1];
point[0] = Math.max(minx,Math.min(point[0],maxx));
point[1] = Math.max(miny,Math.min(point[1],maxy));
return point;
}
function toMax(a){
a[0][0] = a[1][0] = -Number.MAX_VALUE;
a[0][1] = a[1][1] = Number.MAX_VALUE;
}
function setEmpty(a){
a[0][0] = a[0][1] = Infinity;
a[1][0] = a[1][1] = -Infinity;
return a;
}
function isEmpty(a){
return (a[0][0] > a[1][0]) || (a[0][1] > a[1][1]);
}
function isZero(a){
return a[0][0] == 0 && a[0][1] == 0 && a[1][0] == 0 && a[1][1] == 0;
}
function setZero(a){
a[0][0] = a[0][1] = a[1][0] = a[1][1] = 0;
return a;
}
function createFromPoints(points){
return includePoints(create(),points);
}
function createFromPointsFlat(points){
return includePointsFlat(create(),points);
}
function createFromRects(rects){
return includeRects(create(),rects);
}
/**
* [Rect description]
* @type {Object}
*/
var Rect = {
/**
* [create description]
* @type {[type]}
*/
create : create,
/**
* [zero description]
* @type {[type]}
*/
zero : zero,
/**
* [copy description]
* @type {[type]}
*/
copy : copy,
/**
* [set description]
* @type {[type]}
*/
set : set,
/**
* [set4 description]
* @type {[type]}
*/
set4 : set4,
/**
* [scale description]
* @type {[type]}
*/
scale : scale,
/**
* [setMinMax description]
* @type {[type]}
*/
setMinMax : setMinMax,
/**
* [setMinMax4 description]
* @type {[type]}
*/
setMinMax4 : setMinMax4,
/**
* [getMin description]
* @type {[type]}
*/
getMin : getMin,
/**
* [getMax description]
* @type {[type]}
*/
getMax : getMax,
/**
* [setSize2 description]
* @type {[type]}
*/
setSize2 : setSize2,
/**
* [setSize description]
* @type {[type]}
*/
setSize : setSize,
/**
* [getSize description]
* @type {[type]}
*/
getSize : getSize,
/**
* [setWidth description]
* @type {[type]}
*/
setWidth : setWidth,
/**
* [getWidth description]
* @type {[type]}
*/
getWidth : getWidth,
/**
* [setHeight description]
* @type {[type]}
*/
setHeight : setHeight,
/**
* [getHeight description]
* @type {[type]}
*/
getHeight : getHeight,
/**
* [getAspectRatio description]
* @type {[type]}
*/
getAspectRatio : getAspectRatio,
/**
* [setPosition description]
* @type {[type]}
*/
setPosition : setPosition,
/**
* [setPosition2 description]
* @type {[type]}
*/
setPosition2 : setPosition2,
/**
* [getPosition description]
* @type {[type]}
*/
getPosition : getMin,
/**
* [getTL description]
* @type {[type]}
*/
getTL : getMin,
/**
* [getTR description]
* @type {[type]}
*/
getTR : getTR,
/**
* [getBL description]
* @type {[type]}
*/
getBL : getBL,
/**
* [getBR description]
* @type {[type]}
*/
getBR : getMax,
/**
* [getCenter description]
* @type {[type]}
*/
getCenter : getCenter,
/**
* [containsPoint description]
* @type {[type]}
*/
containsPoint : containsPoint,
/**
* [containsPoint2 description]
* @type {[type]}
*/
containsPoint2 : containsPoint2,
/**
* [containsRect description]
* @type {[type]}
*/
containsRect : containsRect,
/**
* [includePoint description]
* @type {[type]}
*/
includePoint : includePoint,
/**
* [includePoint2 description]
* @type {[type]}
*/
includePoint2 : includePoint2,
/**
* [includePoints description]
* @type {[type]}
*/
includePoints : includePoints,
/**
* [includePointsFlat description]
* @type {[type]}
*/
includePointsFlat : includePointsFlat,
/**
* [includeRect description]
* @type {[type]}
*/
includeRect : includeRect,
/**
* [includeRects description]
* @type {[type]}
*/
includeRects : includeRects,
/**
* [mapPoint description]
* @type {[type]}
*/
mapPoint : mapPoint,
/**
* [clampPoint description]
* @type {[type]}
*/
clampPoint : clampPoint,
/**
* [isZero description]
* @type {Boolean}
*/
isZero : isZero,
/**
* [isEmpty description]
* @type {Boolean}
*/
isEmpty : isEmpty,
/**
* [setEmpty description]
* @type {[type]}
*/
setEmpty : setEmpty,
/**
* [toMax description]
* @type {[type]}
*/
toMax : toMax,
/**
* [setZero description]
* @type {[type]}
*/
setZero : setZero,
/**
* [createFromPoints description]
* @type {[type]}
*/
createFromPoints : createFromPoints,
/**
* [createFromPointsFlat description]
* @type {[type]}
*/
createFromPointsFlat : createFromPointsFlat,
/**
* [createFromRects description]
* @type {[type]}
*/
createFromRects : createFromRects
};
module.exports = Rect;
},{}]},{},[])
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2hvbWUvYWRtaW4vYnJvd3NlcmlmeS1jZG4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXItcGFjay9fcHJlbHVkZS5qcyIsIlJlY3QuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsImZ1bmN0aW9uIGNyZWF0ZSgpe1xuICAgIHJldHVybiBbW0luZmluaXR5LEluZmluaXR5XSxbLUluZmluaXR5LC1JbmZpbml0eV1dO1xufVxuXG5mdW5jdGlvbiB6ZXJvKCl7XG4gICAgcmV0dXJuIFtbMCwwXSxbMCwwXV07XG59XG5cbmZ1bmN0aW9uIGNvcHkoYSl7XG4gICAgcmV0dXJuIFthWzBdLnNsaWNlKDApLGFbMV0uc2xpY2UoKV07XG59XG5cbmZ1bmN0aW9uIHNldChhLGIpe1xuICAgIGFbMF1bMF0gPSBiWzBdWzBdO1xuICAgIGFbMF1bMV0gPSBiWzBdWzFdO1xuICAgIGFbMV1bMF0gPSBiWzFdWzBdO1xuICAgIGFbMV1bMV0gPSBiWzFdWzFdO1xuICAgIHJldHVybiBhO1xufVxuXG5mdW5jdGlvbiBzZXQ0KGEseCx5LHcsaCl7XG4gICAgYVswXVswXSA9IHg7XG4gICAgYVswXVsxXSA9IHk7XG4gICAgYVsxXVswXSA9IHggKyB3O1xuICAgIGFbMV1bMV0gPSB5ICsgaDtcbiAgICByZXR1cm4gYTtcbn1cblxuZnVuY3Rpb24gc2NhbGUoYSxuKXtcbiAgICBhWzBdWzBdICo9IG47XG4gICAgYVswXVsxXSAqPSBuO1xuICAgIGFbMV1bMF0gKj0gbjtcbiAgICBhWzFdWzFdICo9IG47XG4gICAgcmV0dXJuIGE7XG59XG5cbmZ1bmN0aW9uIHNldE1pbk1heChhLG1pbixtYXgpe1xuICAgIGFbMF1bMF0gPSBtaW5bMF07XG4gICAgYVswXVsxXSA9IG1pblsxXTtcbiAgICBhWzFdWzBdID0gbWF4WzBdO1xuICAgIGFbMV1bMV0gPSBtYXhbMV07XG4gICAgcmV0dXJuIGE7XG59XG5cbmZ1bmN0aW9uIHNldE1pbk1heDQoYSxtaW54LG1pbnksbWF4eCxtYXh5KXtcbiAgICBhWzBdWzBdID0gbWlueDtcbiAgICBhWzBdWzFdID0gbWlueTtcbiAgICBhWzFdWzBdID0gbWF4eDtcbiAgICBhWzFdWzFdID0gbWF4eTtcbiAgICByZXR1cm4gYTtcbn1cblxuZnVuY3Rpb24gZ2V0TWluKGEsb3V0KXtcbiAgICBpZihvdXQgPT09IHVuZGVmaW5lZCl7XG4gICAgICAgIHJldHVybiBbYVswXVswXSxhWzBdWzFdXTtcbiAgICB9XG4gICAgb3V0WzBdID0gYVswXVswXTtcbiAgICBvdXRbMV0gPSBhWzBdWzFdO1xuICAgIHJldHVybiBvdXQ7XG59XG5cbmZ1bmN0aW9uIGdldE1heChhLG91dCl7XG4gICAgaWYob3V0ID09PSB1bmRlZmluZWQpe1xuICAgICAgICByZXR1cm4gW2FbMV1bMF0sYVsxXVsxXV07XG4gICAgfVxuICAgIG91dFswXSA9IGFbMV1bMF07XG4gICAgb3V0WzFdID0gYVsxXVsxXTtcbiAgICByZXR1cm4gb3V0O1xufVxuXG5mdW5jdGlvbiBzZXRTaXplMihhLHdpZHRoLGhlaWdodCl7XG4gICAgYVsxXVswXSA9IGFbMF1bMF0gKyB3aWR0aDtcbiAgICBhWzFdWzFdID0gYVswXVsxXSArIGhlaWdodDtcbiAgICByZXR1cm4gYTtcbn1cblxuZnVuY3Rpb24gc2V0U2l6ZShhLHNpemUpe1xuICAgIGFbMV1bMF0gPSBhWzBdWzBdICsgc2l6ZVswXTtcbiAgICBhWzFdWzFdID0gYVswXVsxXSArIHNpemVbMV07XG4gICAgcmV0dXJuIGE7XG59XG5cbmZ1bmN0aW9uIGdldFNpemUoYSxvdXQpe1xuICAgIHZhciB3aWR0aCAgPSBnZXRXaWR0aChhKTtcbiAgICB2YXIgaGVpZ2h0ID0gZ2V0SGVpZ2h0KGEpO1xuICAgIGlmKG91dCA9PT0gdW5kZWZpbmVkKXtcbiAgICAgICAgcmV0dXJuIFt3aWR0aCxoZWlnaHRdO1xuICAgIH1cbiAgICBvdXRbMF0gPSB3aWR0aDtcbiAgICBvdXRbMV0gPSBoZWlnaHQ7XG4gICAgcmV0dXJuIG91dDtcbn1cblxuZnVuY3Rpb24gc2V0V2lkdGgoYSx3aWR0aCl7XG4gICAgYVsxXVswXSA9IGFbMF1bMF0gKyB3aWR0aDtcbiAgICByZXR1cm4gYTtcbn1cblxuZnVuY3Rpb24gc2V0SGVpZ2h0KGEsaGVpZ2h0KXtcbiAgICBhWzFdWzFdID0gYVswXVsxXSArIGhlaWdodDtcbiAgICByZXR1cm4gYTtcbn1cblxuZnVuY3Rpb24gZ2V0V2lkdGgoYSl7XG4gICAgcmV0dXJuIGFbMV1bMF0gLSBhWzBdWzBdO1xufVxuXG5mdW5jdGlvbiBnZXRIZWlnaHQoYSl7XG4gICAgcmV0dXJuIGFbMV1bMV0gLSBhWzBdWzFdO1xufVxuXG5mdW5jdGlvbiBnZXRBc3BlY3RSYXRpbyhhKXtcbiAgICByZXR1cm4gZ2V0V2lkdGgoYSkgLyBnZXRIZWlnaHQoYSk7XG59XG5cbmZ1bmN0aW9uIHNldFBvc2l0aW9uKGEscG9zaXRpb24pe1xuICAgIHJldHVybiBzZXRQb3NpdGlvbjIoYSxwb3NpdGlvblswXSxwb3NpdGlvblsxXSk7XG59XG5cbmZ1bmN0aW9uIHNldFBvc2l0aW9uMihhLHgseSl7XG4gICAgYVswXVswXSA9IHg7XG4gICAgYVswXVsxXSA9IHk7XG4gICAgYVsxXVswXSA9IHggKyBnZXRXaWR0aChhKTtcbiAgICBhWzFdWzFdID0geSArIGdldEhlaWdodChhKTtcbiAgICByZXR1cm4gYTtcbn1cblxuZnVuY3Rpb24gZ2V0VFIoYSxvdXQpe1xuICAgIGlmKG91dCA9PT0gdW5kZWZpbmVkKXtcbiAgICAgICAgcmV0dXJuIFthWzFdWzBdLGFbMV1dO1xuICAgIH1cbiAgICBvdXRbMF0gPSBhWzFdWzBdO1xuICAgIG91dFsxXSA9IGFbMF1bMV07XG4gICAgcmV0dXJuIG91dDtcbn1cblxuZnVuY3Rpb24gZ2V0QkwoYSxvdXQpe1xuICAgIGlmKG91dCA9PT0gdW5kZWZpbmVkKXtcbiAgICAgICAgcmV0dXJuIFthWzBdWzBdLGFbMV1bMV1dO1xuICAgIH1cbiAgICBvdXRbMF0gPSBhWzBdWzBdO1xuICAgIG91dFsxXSA9IGFbMV1bMV07XG4gICAgcmV0dXJuIG91dDtcbn1cblxuZnVuY3Rpb24gZ2V0Q2VudGVyKGEsb3V0KXtcbiAgICB2YXIgeCA9IGdldFdpZHRoKGEpICogMC41O1xuICAgIHZhciB5ID0gZ2V0SGVpZ2h0KGEpICogMC41O1xuICAgIGlmKG91dCA9PT0gdW5kZWZpbmVkKXtcbiAgICAgICAgcmV0dXJuIFt4LHldO1xuICAgIH1cbiAgICBvdXRbMF0gPSB4O1xuICAgIG91dFsxXSA9IHk7XG4gICAgcmV0dXJuIG91dDtcbn1cblxuZnVuY3Rpb24gY29udGFpbnNQb2ludChhLHBvaW50KXtcbiAgICByZXR1cm4gY29udGFpbnNQb2ludDIoYSxwb2ludFswXSxwb2ludFsxXSk7XG59XG5cbmZ1bmN0aW9uIGNvbnRhaW5zUG9pbnQyKGEseCx5KXtcbiAgICByZXR1cm4geCA+PSBhWzBdWzBdICYmIHggPD0gYVsxXVswXSAmJiB5ID49IGFbMF1bMV0gJiYgeSA8PSBhWzFdWzFdO1xufVxuXG5mdW5jdGlvbiBjb250YWluc1JlY3QoYSxiKXtcbiAgICByZXR1cm4gY29udGFpbnNQb2ludDIoYSxiWzBdWzBdLGJbMF1bMV0pICYmIGNvbnRhaW5zUG9pbnQyKGEsYlsxXVswXSxiWzFdWzFdKTtcbn1cblxuZnVuY3Rpb24gaW5jbHVkZVBvaW50KGEscG9pbnQpe1xuICAgIHJldHVybiBpbmNsdWRlUG9pbnQyKGEscG9pbnRbMF0scG9pbnRbMV0pO1xufVxuXG5mdW5jdGlvbiBpbmNsdWRlUG9pbnQyKGEseCx5KXtcbiAgICB2YXIgbWlueCA9IGFbMF1bMF07XG4gICAgdmFyIG1pbnkgPSBhWzBdWzFdO1xuICAgIHZhciBtYXh4ID0gYVsxXVswXTtcbiAgICB2YXIgbWF4eSA9IGFbMV1bMV07XG5cbiAgICBhWzBdWzBdID0gbWlueCA+IHggPyB4IDogbWlueDtcbiAgICBhWzBdWzFdID0gbWlueSA+IHkgPyB5IDogbWlueTtcbiAgICBhWzFdWzBdID0gbWF4eCA8IHggPyB4IDogbWF4eDtcbiAgICBhWzFdWzFdID0gbWF4eSA8IHkgPyB5IDogbWF4eTtcblxuICAgIHJldHVybiBhO1xufVxuXG5mdW5jdGlvbiBpbmNsdWRlUG9pbnRzKGEscG9pbnRzKXtcbiAgICB2YXIgbWlueCA9IGFbMF1bMF07XG4gICAgdmFyIG1pbnkgPSBhWzBdWzFdO1xuICAgIHZhciBtYXh4ID0gYVsxXVswXTtcbiAgICB2YXIgbWF4eSA9IGFbMV1bMV07XG5cbiAgICBmb3IodmFyIGkgPSAwLCBsID0gcG9pbnRzLmxlbmd0aCwgeCwgeTsgaSA8IGw7ICsraSl7XG4gICAgICAgIHggPSBwb2ludHNbaV1bMF07XG4gICAgICAgIHkgPSBwb2ludHNbaV1bMV07XG5cbiAgICAgICAgbWlueCA9IG1pbnggPiB4ID8geCA6IG1pbng7XG4gICAgICAgIG1pbnkgPSBtaW55ID4geSA/IHkgOiBtaW55O1xuICAgICAgICBtYXh4ID0gbWF4eCA8IHggPyB4IDogbWF4eDtcbiAgICAgICAgbWF4eSA9IG1heHkgPCB5ID8geSA6IG1heHk7XG4gICAgfVxuXG4gICAgYVswXVswXSA9IG1pbng7XG4gICAgYVswXVsxXSA9IG1pbnk7XG4gICAgYVsxXVswXSA9IG1heHg7XG4gICAgYVsxXVsxXSA9IG1heHk7XG5cbiAgICByZXR1cm4gYTtcbn1cblxuZnVuY3Rpb24gaW5jbHVkZVBvaW50c0ZsYXQoYSxwb2ludHMpe1xuICAgIHZhciBtaW54ID0gYVswXVswXTtcbiAgICB2YXIgbWlueSA9IGFbMF1bMV07XG4gICAgdmFyIG1heHggPSBhWzFdWzBdO1xuICAgIHZhciBtYXh5ID0gYVsxXVsxXTtcblxuICAgIGZvcih2YXIgaSA9IDAsIGwgPSBwb2ludHMubGVuZ3RoLCB4LCB5OyBpIDwgbDsgaSs9Mil7XG4gICAgICAgIHggPSBwb2ludHNbaSAgXTtcbiAgICAgICAgeSA9IHBvaW50c1tpKzFdO1xuXG4gICAgICAgIG1pbnggPSBtaW54ID4geCA/IHggOiBtaW54O1xuICAgICAgICBtaW55ID0gbWlueSA+IHkgPyB5IDogbWlueTtcbiAgICAgICAgbWF4eCA9IG1heHggPCB4ID8geCA6IG1heHg7XG4gICAgICAgIG1heHkgPSBtYXh5IDwgeSA/IHkgOiBtYXh5O1xuICAgIH1cblxuICAgIGFbMF1bMF0gPSBtaW54O1xuICAgIGFbMF1bMV0gPSBtaW55O1xuICAgIGFbMV1bMF0gPSBtYXh4O1xuICAgIGFbMV1bMV0gPSBtYXh5O1xuXG4gICAgcmV0dXJuIGE7XG59XG5cbmZ1bmN0aW9uIGluY2x1ZGVSZWN0KGEscmVjdCl7XG4gICAgaW5jbHVkZVBvaW50KGEscmVjdFswXSk7XG4gICAgaW5jbHVkZVBvaW50KGEscmVjdFsxXSk7XG4gICAgcmV0dXJuIGE7XG59XG5cbmZ1bmN0aW9uIGluY2x1ZGVSZWN0cyhhLHJlY3RzKXtcbiAgICBmb3IodmFyIGkgPSAwLCBsID0gcmVjdHMubGVuZ3RoOyBpIDwgbDsgKytpKXtcbiAgICAgICAgaW5jbHVkZVJlY3QoYSxyZWN0c1tpXSk7XG4gICAgfVxuICAgIHJldHVybiBhO1xufVxuXG5mdW5jdGlvbiBtYXBQb2ludChhLHBvaW50KXtcbiAgICB2YXIgbWlueCA9IGFbMF1bMF07XG4gICAgdmFyIG1pbnkgPSBhWzBdWzFdO1xuICAgIHZhciBtYXh4ID0gYVsxXVswXTtcbiAgICB2YXIgbWF4eSA9IGFbMV1bMV07XG4gICAgdmFyIHggPSBwb2ludFswXTtcbiAgICB2YXIgeSA9IHBvaW50WzFdO1xuXG4gICAgcG9pbnRbMF0gPSBNYXRoLm1heChtaW54LE1hdGgubWluKHgsbWF4eCkpIC0gbWlueDtcbiAgICBwb2ludFsxXSA9IE1hdGgubWF4KG1pbnksTWF0aC5taW4oeSxtYXh5KSkgLSBtaW55O1xuICAgIHJldHVybiBwb2ludDtcbn1cblxuZnVuY3Rpb24gY2xhbXBQb2ludChhLHBvaW50KXtcblxuICAgIHZhciBtaW54ID0gYVswXVswXTtcbiAgICB2YXIgbWlueSA9IGFbMF1bMV07XG4gICAgdmFyIG1heHggPSBhWzFdWzBdO1xuICAgIHZhciBtYXh5ID0gYVsxXVsxXTtcblxuICAgIHBvaW50WzBdID0gTWF0aC5tYXgobWlueCxNYXRoLm1pbihwb2ludFswXSxtYXh4KSk7XG4gICAgcG9pbnRbMV0gPSBNYXRoLm1heChtaW55LE1hdGgubWluKHBvaW50WzFdLG1heHkpKTtcbiAgICByZXR1cm4gcG9pbnQ7XG59XG5cbmZ1bmN0aW9uIHRvTWF4KGEpe1xuICAgIGFbMF1bMF0gPSBhWzFdWzBdID0gLU51bWJlci5NQVhfVkFMVUU7XG4gICAgYVswXVsxXSA9IGFbMV1bMV0gPSAgTnVtYmVyLk1BWF9WQUxVRTtcbn1cblxuZnVuY3Rpb24gc2V0RW1wdHkoYSl7XG4gICAgYVswXVswXSA9IGFbMF1bMV0gPSAgSW5maW5pdHk7XG4gICAgYVsxXVswXSA9IGFbMV1bMV0gPSAtSW5maW5pdHk7XG4gICAgcmV0dXJuIGE7XG59XG5cbmZ1bmN0aW9uIGlzRW1wdHkoYSl7XG4gICAgcmV0dXJuIChhWzBdWzBdID4gYVsxXVswXSkgfHwgKGFbMF1bMV0gPiBhWzFdWzFdKTtcbn1cblxuZnVuY3Rpb24gaXNaZXJvKGEpe1xuICAgIHJldHVybiBhWzBdWzBdID09IDAgJiYgYVswXVsxXSA9PSAwICYmIGFbMV1bMF0gPT0gMCAmJiBhWzFdWzFdID09IDA7XG59XG5cbmZ1bmN0aW9uIHNldFplcm8oYSl7XG4gICAgYVswXVswXSA9IGFbMF1bMV0gPSBhWzFdWzBdID0gYVsxXVsxXSA9IDA7XG4gICAgcmV0dXJuIGE7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUZyb21Qb2ludHMocG9pbnRzKXtcbiAgICByZXR1cm4gaW5jbHVkZVBvaW50cyhjcmVhdGUoKSxwb2ludHMpO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVGcm9tUG9pbnRzRmxhdChwb2ludHMpe1xuICAgIHJldHVybiBpbmNsdWRlUG9pbnRzRmxhdChjcmVhdGUoKSxwb2ludHMpO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVGcm9tUmVjdHMocmVjdHMpe1xuICAgIHJldHVybiBpbmNsdWRlUmVjdHMoY3JlYXRlKCkscmVjdHMpO1xufVxuXG4vKipcbiAqIFtSZWN0IGRlc2NyaXB0aW9uXVxuICogQHR5cGUge09iamVjdH1cbiAqL1xudmFyIFJlY3QgPSB7XG4gICAgLyoqXG4gICAgICogW2NyZWF0ZSBkZXNjcmlwdGlvbl1cbiAgICAgKiBAdHlwZSB7W3R5cGVdfVxuICAgICAqL1xuICAgIGNyZWF0ZSA6IGNyZWF0ZSxcbiAgICAvKipcbiAgICAgKiBbemVybyBkZXNjcmlwdGlvbl1cbiAgICAgKiBAdHlwZSB7W3R5cGVdfVxuICAgICAqL1xuICAgIHplcm8gICA6IHplcm8sXG4gICAgLyoqXG4gICAgICogW2NvcHkgZGVzY3JpcHRpb25dXG4gICAgICogQHR5cGUge1t0eXBlXX1cbiAgICAgKi9cbiAgICBjb3B5ICAgOiBjb3B5LFxuICAgIC8qKlxuICAgICAqIFtzZXQgZGVzY3JpcHRpb25dXG4gICAgICogQHR5cGUge1t0eXBlXX1cbiAgICAgKi9cbiAgICBzZXQgIDogc2V0LFxuICAgIC8qKlxuICAgICAqIFtzZXQ0IGRlc2NyaXB0aW9uXVxuICAgICAqIEB0eXBlIHtbdHlwZV19XG4gICAgICovXG4gICAgc2V0NCA6IHNldDQsXG4gICAgLyoqXG4gICAgICogW3NjYWxlIGRlc2NyaXB0aW9uXVxuICAgICAqIEB0eXBlIHtbdHlwZV19XG4gICAgICovXG4gICAgc2NhbGUgOiBzY2FsZSxcbiAgICAvKipcbiAgICAgKiBbc2V0TWluTWF4IGRlc2NyaXB0aW9uXVxuICAgICAqIEB0eXBlIHtbdHlwZV19XG4gICAgICovXG4gICAgc2V0TWluTWF4IDogc2V0TWluTWF4LFxuICAgIC8qKlxuICAgICAqIFtzZXRNaW5NYXg0IGRlc2NyaXB0aW9uXVxuICAgICAqIEB0eXBlIHtbdHlwZV19XG4gICAgICovXG4gICAgc2V0TWluTWF4NCA6IHNldE1pbk1heDQsXG4gICAgLyoqXG4gICAgICogW2dldE1pbiBkZXNjcmlwdGlvbl1cbiAgICAgKiBAdHlwZSB7W3R5cGVdfVxuICAgICAqL1xuICAgIGdldE1pbiA6IGdldE1pbixcbiAgICAvKipcbiAgICAgKiBbZ2V0TWF4IGRlc2NyaXB0aW9uXVxuICAgICAqIEB0eXBlIHtbdHlwZV19XG4gICAgICovXG4gICAgZ2V0TWF4IDogZ2V0TWF4LFxuICAgIC8qKlxuICAgICAqIFtzZXRTaXplMiBkZXNjcmlwdGlvbl1cbiAgICAgKiBAdHlwZSB7W3R5cGVdfVxuICAgICAqL1xuICAgIHNldFNpemUyICA6IHNldFNpemUyLFxuICAgIC8qKlxuICAgICAqIFtzZXRTaXplIGRlc2NyaXB0aW9uXVxuICAgICAqIEB0eXBlIHtbdHlwZV19XG4gICAgICovXG4gICAgc2V0U2l6ZSAgIDogc2V0U2l6ZSxcbiAgICAvKipcbiAgICAgKiBbZ2V0U2l6ZSBkZXNjcmlwdGlvbl1cbiAgICAgKiBAdHlwZSB7W3R5cGVdfVxuICAgICAqL1xuICAgIGdldFNpemUgICA6IGdldFNpemUsXG4gICAgLyoqXG4gICAgICogW3NldFdpZHRoIGRlc2NyaXB0aW9uXVxuICAgICAqIEB0eXBlIHtbdHlwZV19XG4gICAgICovXG4gICAgc2V0V2lkdGggIDogc2V0V2lkdGgsXG4gICAgLyoqXG4gICAgICogW2dldFdpZHRoIGRlc2NyaXB0aW9uXVxuICAgICAqIEB0eXBlIHtbdHlwZV19XG4gICAgICovXG4gICAgZ2V0V2lkdGggIDogZ2V0V2lkdGgsXG4gICAgLyoqXG4gICAgICogW3NldEhlaWdodCBkZXNjcmlwdGlvbl1cbiAgICAgKiBAdHlwZSB7W3R5cGVdfVxuICAgICAqL1xuICAgIHNldEhlaWdodCA6IHNldEhlaWdodCxcbiAgICAvKipcbiAgICAgKiBbZ2V0SGVpZ2h0IGRlc2NyaXB0aW9uXVxuICAgICAqIEB0eXBlIHtbdHlwZV19XG4gICAgICovXG4gICAgZ2V0SGVpZ2h0IDogZ2V0SGVpZ2h0LFxuICAgIC8qKlxuICAgICAqIFtnZXRBc3BlY3RSYXRpbyBkZXNjcmlwdGlvbl1cbiAgICAgKiBAdHlwZSB7W3R5cGVdfVxuICAgICAqL1xuICAgIGdldEFzcGVjdFJhdGlvIDogZ2V0QXNwZWN0UmF0aW8sXG4gICAgLyoqXG4gICAgICogW3NldFBvc2l0aW9uIGRlc2NyaXB0aW9uXVxuICAgICAqIEB0eXBlIHtbdHlwZV19XG4gICAgICovXG4gICAgc2V0UG9zaXRpb24gIDogc2V0UG9zaXRpb24sXG4gICAgLyoqXG4gICAgICogW3NldFBvc2l0aW9uMiBkZXNjcmlwdGlvbl1cbiAgICAgKiBAdHlwZSB7W3R5cGVdfVxuICAgICAqL1xuICAgIHNldFBvc2l0aW9uMiA6IHNldFBvc2l0aW9uMixcbiAgICAvKipcbiAgICAgKiBbZ2V0UG9zaXRpb24gZGVzY3JpcHRpb25dXG4gICAgICogQHR5cGUge1t0eXBlXX1cbiAgICAgKi9cbiAgICBnZXRQb3NpdGlvbiAgOiBnZXRNaW4sXG4gICAgLyoqXG4gICAgICogW2dldFRMIGRlc2NyaXB0aW9uXVxuICAgICAqIEB0eXBlIHtbdHlwZV19XG4gICAgICovXG4gICAgZ2V0VEwgOiBnZXRNaW4sXG4gICAgLyoqXG4gICAgICogW2dldFRSIGRlc2NyaXB0aW9uXVxuICAgICAqIEB0eXBlIHtbdHlwZV19XG4gICAgICovXG4gICAgZ2V0VFIgOiBnZXRUUixcbiAgICAvKipcbiAgICAgKiBbZ2V0QkwgZGVzY3JpcHRpb25dXG4gICAgICogQHR5cGUge1t0eXBlXX1cbiAgICAgKi9cbiAgICBnZXRCTCA6IGdldEJMLFxuICAgIC8qKlxuICAgICAqIFtnZXRCUiBkZXNjcmlwdGlvbl1cbiAgICAgKiBAdHlwZSB7W3R5cGVdfVxuICAgICAqL1xuICAgIGdldEJSIDogZ2V0TWF4LFxuICAgIC8qKlxuICAgICAqIFtnZXRDZW50ZXIgZGVzY3JpcHRpb25dXG4gICAgICogQHR5cGUge1t0eXBlXX1cbiAgICAgKi9cbiAgICBnZXRDZW50ZXIgOiBnZXRDZW50ZXIsXG4gICAgLyoqXG4gICAgICogW2NvbnRhaW5zUG9pbnQgZGVzY3JpcHRpb25dXG4gICAgICogQHR5cGUge1t0eXBlXX1cbiAgICAgKi9cbiAgICBjb250YWluc1BvaW50IDogY29udGFpbnNQb2ludCxcbiAgICAvKipcbiAgICAgKiBbY29udGFpbnNQb2ludDIgZGVzY3JpcHRpb25dXG4gICAgICogQHR5cGUge1t0eXBlXX1cbiAgICAgKi9cbiAgICBjb250YWluc1BvaW50MiA6IGNvbnRhaW5zUG9pbnQyLFxuICAgIC8qKlxuICAgICAqIFtjb250YWluc1JlY3QgZGVzY3JpcHRpb25dXG4gICAgICogQHR5cGUge1t0eXBlXX1cbiAgICAgKi9cbiAgICBjb250YWluc1JlY3QgICA6IGNvbnRhaW5zUmVjdCxcbiAgICAvKipcbiAgICAgKiBbaW5jbHVkZVBvaW50IGRlc2NyaXB0aW9uXVxuICAgICAqIEB0eXBlIHtbdHlwZV19XG4gICAgICovXG4gICAgaW5jbHVkZVBvaW50ICAgICAgOiBpbmNsdWRlUG9pbnQsXG4gICAgLyoqXG4gICAgICogW2luY2x1ZGVQb2ludDIgZGVzY3JpcHRpb25dXG4gICAgICogQHR5cGUge1t0eXBlXX1cbiAgICAgKi9cbiAgICBpbmNsdWRlUG9pbnQyICAgICA6IGluY2x1ZGVQb2ludDIsXG4gICAgLyoqXG4gICAgICogW2luY2x1ZGVQb2ludHMgZGVzY3JpcHRpb25dXG4gICAgICogQHR5cGUge1t0eXBlXX1cbiAgICAgKi9cbiAgICBpbmNsdWRlUG9pbnRzICAgICA6IGluY2x1ZGVQb2ludHMsXG4gICAgLyoqXG4gICAgICogW2luY2x1ZGVQb2ludHNGbGF0IGRlc2NyaXB0aW9uXVxuICAgICAqIEB0eXBlIHtbdHlwZV19XG4gICAgICovXG4gICAgaW5jbHVkZVBvaW50c0ZsYXQgOiBpbmNsdWRlUG9pbnRzRmxhdCxcbiAgICAvKipcbiAgICAgKiBbaW5jbHVkZVJlY3QgZGVzY3JpcHRpb25dXG4gICAgICogQHR5cGUge1t0eXBlXX1cbiAgICAgKi9cbiAgICBpbmNsdWRlUmVjdCAgIDogaW5jbHVkZVJlY3QsXG4gICAgLyoqXG4gICAgICogW2luY2x1ZGVSZWN0cyBkZXNjcmlwdGlvbl1cbiAgICAgKiBAdHlwZSB7W3R5cGVdfVxuICAgICAqL1xuICAgIGluY2x1ZGVSZWN0cyAgOiBpbmNsdWRlUmVjdHMsXG4gICAgLyoqXG4gICAgICogW21hcFBvaW50IGRlc2NyaXB0aW9uXVxuICAgICAqIEB0eXBlIHtbdHlwZV19XG4gICAgICovXG4gICAgbWFwUG9pbnQgICA6IG1hcFBvaW50LFxuICAgIC8qKlxuICAgICAqIFtjbGFtcFBvaW50IGRlc2NyaXB0aW9uXVxuICAgICAqIEB0eXBlIHtbdHlwZV19XG4gICAgICovXG4gICAgY2xhbXBQb2ludCA6IGNsYW1wUG9pbnQsXG4gICAgLyoqXG4gICAgICogW2lzWmVybyBkZXNjcmlwdGlvbl1cbiAgICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBpc1plcm8gICA6IGlzWmVybyxcbiAgICAvKipcbiAgICAgKiBbaXNFbXB0eSBkZXNjcmlwdGlvbl1cbiAgICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBpc0VtcHR5ICA6IGlzRW1wdHksXG4gICAgLyoqXG4gICAgICogW3NldEVtcHR5IGRlc2NyaXB0aW9uXVxuICAgICAqIEB0eXBlIHtbdHlwZV19XG4gICAgICovXG4gICAgc2V0RW1wdHkgOiBzZXRFbXB0eSxcbiAgICAvKipcbiAgICAgKiBbdG9NYXggZGVzY3JpcHRpb25dXG4gICAgICogQHR5cGUge1t0eXBlXX1cbiAgICAgKi9cbiAgICB0b01heCAgOiB0b01heCxcbiAgICAvKipcbiAgICAgKiBbc2V0WmVybyBkZXNjcmlwdGlvbl1cbiAgICAgKiBAdHlwZSB7W3R5cGVdfVxuICAgICAqL1xuICAgIHNldFplcm8gOiBzZXRaZXJvLFxuICAgIC8qKlxuICAgICAqIFtjcmVhdGVGcm9tUG9pbnRzIGRlc2NyaXB0aW9uXVxuICAgICAqIEB0eXBlIHtbdHlwZV19XG4gICAgICovXG4gICAgY3JlYXRlRnJvbVBvaW50cyAgICAgOiBjcmVhdGVGcm9tUG9pbnRzLFxuICAgIC8qKlxuICAgICAqIFtjcmVhdGVGcm9tUG9pbnRzRmxhdCBkZXNjcmlwdGlvbl1cbiAgICAgKiBAdHlwZSB7W3R5cGVdfVxuICAgICAqL1xuICAgIGNyZWF0ZUZyb21Qb2ludHNGbGF0IDogY3JlYXRlRnJvbVBvaW50c0ZsYXQsXG4gICAgLyoqXG4gICAgICogW2NyZWF0ZUZyb21SZWN0cyBkZXNjcmlwdGlvbl1cbiAgICAgKiBAdHlwZSB7W3R5cGVdfVxuICAgICAqL1xuICAgIGNyZWF0ZUZyb21SZWN0cyAgICAgIDogY3JlYXRlRnJvbVJlY3RzXG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFJlY3Q7XG4iXX0=
// Streams implementation for mouse events.
// Started based thinking in https://github.com/pex-gl/pex-gui/issues/8
// IMPORT DEPENDENCIES
// Flyd is "The less is more, modular, functional reactive programming library"
const flyd = require('flyd')
// emit events from one stream until another stream fires
const takeUntil = require('flyd/module/takeuntil')
// merge multiple streams into one
const mergeAll = require('flyd/module/mergeall')
// filter stream events based on predicate
const filterStream = require('flyd/module/filter')
// map events from a stream using a function
const mapStream = flyd.map
// check if point is inside a rectangle
const containsPoint = require('pex-geom/Rect').containsPoint
// UI
// Draw a red canvas with yellow "button" on the left
const btnRect = [[10, 10], [100, 100]]
const canvas = document.createElement('canvas')
canvas.style.background = 'red'
document.body.appendChild(canvas)
const ctx = canvas.getContext('2d')
ctx.fillStyle = '#FFFF00'
ctx.fillRect(btnRect[0][0], btnRect[0][1], btnRect[1][0] - btnRect[0][0], btnRect[1][1] - btnRect[0][1])
// crate streams for all mouse events
const mousedown = flyd.stream()
const mouseup = flyd.stream()
const mousemove = flyd.stream()
const windowmouseup = flyd.stream()
canvas.addEventListener('mousedown', mousedown)
canvas.addEventListener('mouseup', mouseup)
canvas.addEventListener('mousemove', mousemove)
window.addEventListener('mouseup', windowmouseup)
//flyd.on((e) => console.log('windowmouseup', e), windowmouseup)
// DRAG event stream implementation
// This shows how to combine streams (down, move, up) into a new stream
function createMouseDragStream (mousedown, mousemove, mouseup) {
const mousedrag = flyd.stream()
// on each mousedown event
flyd.on((e) => {
// create new stream that take events from mousemove
// until mouse up on canvas or window
const drag = takeUntil(mousemove, mergeAll([mouseup, windowmouseup]))
// then forward all events from drag to mousedrag
flyd.on(mousedrag, drag)
}, mousedown)
return mousedrag
}
const mousedrag = createMouseDragStream(mousedown, mousemove, mouseup)
// print mousedrag when dragging mouse over canvas
//flyd.on((e) => console.log('mousedrag', e), mousedrag)
// filter functon checking if mouse event is inside rectangle
function inRect (rect) {
return function (e) {
// TODO: curry this!
return containsPoint(rect, [e.clientX, e.clientY])
}
}
// we use preventDefault to mark handled streams
function markAsHandled (e) {
e.preventDefault()
return e
}
function notHandledYet (e) {
return !e.defaultPrevented
}
// we add background event listener first as we go from broad to more specific
const bgmousedown = filterStream(notHandledYet, mousedown)
flyd.on((e) => console.log('bg mousedown', e), bgmousedown)
/*
const bgmousedrag = mapStream(markAsHandled, createMouseDragStream(
bgmousedown,
mousemove,
mouseup
)
)
flyd.on((e) => console.log('bg mousedrag', e), bgmousedrag)
*/
// mouse clicks inside yellow rect
//const buttonmousedown = mapStream(markAsHandled, filterStream(inRect(btnRect), mousedown))
// mouse clicks outside yellow rect
//flyd.on((e) => console.log('button mousedown', e), buttonmousedown)
// crate drag event stream that happens only if we click inside button
const buttonmousedrag = createMouseDragStream(
mapStream(markAsHandled, filterStream(inRect(btnRect), mousedown)),
mousemove,
mouseup
)
//flyd.on((e) => console.log('button drag', e), buttonmousedrag)
/*
const a = flyd.stream()
const g = flyd.stream()
window.addEventListener('mousedown', a)
window.addEventListener('mousedown', g)
flyd.on((e) => console.log('a', e), a)
flyd.on((e) => console.log('g background', e), g)
flyd.on((e) => console.log('g slider', e), g)
*/
//const pointer = require('pointer-events-stream')(gl.canvas)
canvas.addEventListener('mousedown', (e) => {
e.preventDefault()
console.log('canvas down')
})
canvas.addEventListener('mouseup', (e) => {
console.log('canvas up', e.defaultPrevented)
})
window.addEventListener('mouseup', (e) => {
console.log('window up', e.defaultPrevented)
})
window.addEventListener('mouseout', (e) => {
console.log('window out', e.defaultPrevented)
})
/* Ideal scenario
var mouseclicks = stream()
var leftoferclicks = gui.addMouse(mouseclicks)
// inside gui
var click = mouseclicks.peak()
if (insideSlier(click)) {
mouseclicks.take()
}
*/
// PROBLEM
// - calling e.preventDefault in canvas.mousedown prevents window.mouseup released outside of browser bounds
// - gui and arcball / scene are using same canvas events. That wouldn't happen with canvas + dom dat.gui
// SCENARIOS
// gui vs arcball conflicks, picking bounding boxes vs arcball
// SOLUTIONS
// - keep using pex-sys/MouseEvent
// - flyd: add a handled flag to the Event object
// - create sepate window for gui
;}, 0)
{
"name": "requirebin-sketch",
"version": "1.0.0",
"dependencies": {
"flyd": "0.2.2",
"pex-geom": "1.0.0-beta.2"
}
}
<!-- contents of this file will be placed inside the <body> -->
<!-- contents of this file will be placed inside the <head> -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment