| /** |
| * rome - Customizable date (and time) picker. Opt-in UI, no jQuery! |
| * @version v2.1.0 |
| * @link https://github.com/bevacqua/rome |
| * @license MIT |
| */ |
| !function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.rome=e()}}(function(){var define,module,exports;return (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);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.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(_dereq_,module,exports){ |
| // shim for using process in browser |
| |
| var process = module.exports = {}; |
| |
| process.nextTick = (function () { |
| var canSetImmediate = typeof window !== 'undefined' |
| && window.setImmediate; |
| var canPost = typeof window !== 'undefined' |
| && window.postMessage && window.addEventListener |
| ; |
| |
| if (canSetImmediate) { |
| return function (f) { return window.setImmediate(f) }; |
| } |
| |
| if (canPost) { |
| var queue = []; |
| window.addEventListener('message', function (ev) { |
| var source = ev.source; |
| if ((source === window || source === null) && ev.data === 'process-tick') { |
| ev.stopPropagation(); |
| if (queue.length > 0) { |
| var fn = queue.shift(); |
| fn(); |
| } |
| } |
| }, true); |
| |
| return function nextTick(fn) { |
| queue.push(fn); |
| window.postMessage('process-tick', '*'); |
| }; |
| } |
| |
| return function nextTick(fn) { |
| setTimeout(fn, 0); |
| }; |
| })(); |
| |
| process.title = 'browser'; |
| process.browser = true; |
| process.env = {}; |
| process.argv = []; |
| |
| function noop() {} |
| |
| process.on = noop; |
| process.addListener = noop; |
| process.once = noop; |
| process.off = noop; |
| process.removeListener = noop; |
| process.removeAllListeners = noop; |
| process.emit = noop; |
| |
| process.binding = function (name) { |
| throw new Error('process.binding is not supported'); |
| } |
| |
| // TODO(shtylman) |
| process.cwd = function () { return '/' }; |
| process.chdir = function (dir) { |
| throw new Error('process.chdir is not supported'); |
| }; |
| |
| },{}],2:[function(_dereq_,module,exports){ |
| module.exports = _dereq_('./src/contra.emitter.js'); |
| |
| },{"./src/contra.emitter.js":3}],3:[function(_dereq_,module,exports){ |
| (function (process){ |
| (function (root, undefined) { |
| 'use strict'; |
| |
| var undef = '' + undefined; |
| function atoa (a, n) { return Array.prototype.slice.call(a, n); } |
| function debounce (fn, args, ctx) { if (!fn) { return; } tick(function run () { fn.apply(ctx || null, args || []); }); } |
| |
| // cross-platform ticker |
| var si = typeof setImmediate === 'function', tick; |
| if (si) { |
| tick = function (fn) { setImmediate(fn); }; |
| } else if (typeof process !== undef && process.nextTick) { |
| tick = process.nextTick; |
| } else { |
| tick = function (fn) { setTimeout(fn, 0); }; |
| } |
| |
| function _emitter (thing, options) { |
| var opts = options || {}; |
| var evt = {}; |
| if (thing === undefined) { thing = {}; } |
| thing.on = function (type, fn) { |
| if (!evt[type]) { |
| evt[type] = [fn]; |
| } else { |
| evt[type].push(fn); |
| } |
| return thing; |
| }; |
| thing.once = function (type, fn) { |
| fn._once = true; // thing.off(fn) still works! |
| thing.on(type, fn); |
| return thing; |
| }; |
| thing.off = function (type, fn) { |
| var c = arguments.length; |
| if (c === 1) { |
| delete evt[type]; |
| } else if (c === 0) { |
| evt = {}; |
| } else { |
| var et = evt[type]; |
| if (!et) { return thing; } |
| et.splice(et.indexOf(fn), 1); |
| } |
| return thing; |
| }; |
| thing.emit = function () { |
| var args = atoa(arguments); |
| return thing.emitterSnapshot(args.shift()).apply(this, args); |
| }; |
| thing.emitterSnapshot = function (type) { |
| var et = (evt[type] || []).slice(0); |
| return function () { |
| var args = atoa(arguments); |
| var ctx = this || thing; |
| if (type === 'error' && opts.throws !== false && !et.length) { throw args.length === 1 ? args[0] : args; } |
| evt[type] = et.filter(function emitter (listen) { |
| if (opts.async) { debounce(listen, args, ctx); } else { listen.apply(ctx, args); } |
| return !listen._once; |
| }); |
| return thing; |
| }; |
| } |
| return thing; |
| } |
| |
| // cross-platform export |
| if (typeof module !== undef && module.exports) { |
| module.exports = _emitter; |
| } else { |
| root.contra = root.contra || {}; |
| root.contra.emitter = _emitter; |
| } |
| })(this); |
| |
| }).call(this,_dereq_("FWaASH")) |
| },{"FWaASH":1}],4:[function(_dereq_,module,exports){ |
| var now = _dereq_('performance-now') |
| , global = typeof window === 'undefined' ? {} : window |
| , vendors = ['moz', 'webkit'] |
| , suffix = 'AnimationFrame' |
| , raf = global['request' + suffix] |
| , caf = global['cancel' + suffix] || global['cancelRequest' + suffix] |
| , isNative = true |
| |
| for(var i = 0; i < vendors.length && !raf; i++) { |
| raf = global[vendors[i] + 'Request' + suffix] |
| caf = global[vendors[i] + 'Cancel' + suffix] |
| || global[vendors[i] + 'CancelRequest' + suffix] |
| } |
| |
| // Some versions of FF have rAF but not cAF |
| if(!raf || !caf) { |
| isNative = false |
| |
| var last = 0 |
| , id = 0 |
| , queue = [] |
| , frameDuration = 1000 / 60 |
| |
| raf = function(callback) { |
| if(queue.length === 0) { |
| var _now = now() |
| , next = Math.max(0, frameDuration - (_now - last)) |
| last = next + _now |
| setTimeout(function() { |
| var cp = queue.slice(0) |
| // Clear queue here to prevent |
| // callbacks from appending listeners |
| // to the current frame's queue |
| queue.length = 0 |
| for(var i = 0; i < cp.length; i++) { |
| if(!cp[i].cancelled) { |
| try{ |
| cp[i].callback(last) |
| } catch(e) { |
| setTimeout(function() { throw e }, 0) |
| } |
| } |
| } |
| }, Math.round(next)) |
| } |
| queue.push({ |
| handle: ++id, |
| callback: callback, |
| cancelled: false |
| }) |
| return id |
| } |
| |
| caf = function(handle) { |
| for(var i = 0; i < queue.length; i++) { |
| if(queue[i].handle === handle) { |
| queue[i].cancelled = true |
| } |
| } |
| } |
| } |
| |
| module.exports = function(fn) { |
| // Wrap in a new function to prevent |
| // `cancel` potentially being assigned |
| // to the native rAF function |
| if(!isNative) { |
| return raf.call(global, fn) |
| } |
| return raf.call(global, function() { |
| try{ |
| fn.apply(this, arguments) |
| } catch(e) { |
| setTimeout(function() { throw e }, 0) |
| } |
| }) |
| } |
| module.exports.cancel = function() { |
| caf.apply(global, arguments) |
| } |
| |
| },{"performance-now":5}],5:[function(_dereq_,module,exports){ |
| (function (process){ |
| // Generated by CoffeeScript 1.6.3 |
| (function() { |
| var getNanoSeconds, hrtime, loadTime; |
| |
| if ((typeof performance !== "undefined" && performance !== null) && performance.now) { |
| module.exports = function() { |
| return performance.now(); |
| }; |
| } else if ((typeof process !== "undefined" && process !== null) && process.hrtime) { |
| module.exports = function() { |
| return (getNanoSeconds() - loadTime) / 1e6; |
| }; |
| hrtime = process.hrtime; |
| getNanoSeconds = function() { |
| var hr; |
| hr = hrtime(); |
| return hr[0] * 1e9 + hr[1]; |
| }; |
| loadTime = getNanoSeconds(); |
| } else if (Date.now) { |
| module.exports = function() { |
| return Date.now() - loadTime; |
| }; |
| loadTime = Date.now(); |
| } else { |
| module.exports = function() { |
| return new Date().getTime() - loadTime; |
| }; |
| loadTime = new Date().getTime(); |
| } |
| |
| }).call(this); |
| |
| /* |
| //@ sourceMappingURL=performance-now.map |
| */ |
| |
| }).call(this,_dereq_("FWaASH")) |
| },{"FWaASH":1}],6:[function(_dereq_,module,exports){ |
| 'use strict'; |
| |
| var isInput = _dereq_('./isInput'); |
| var bindings = {}; |
| |
| function has (source, target) { |
| var binding = bindings[source.id]; |
| return binding && binding[target.id]; |
| } |
| |
| function insert (source, target) { |
| var binding = bindings[source.id]; |
| if (!binding) { |
| binding = bindings[source.id] = {}; |
| } |
| var invalidate = invalidator(target); |
| binding[target.id] = invalidate; |
| source.on('data', invalidate); |
| source.on('destroyed', remove.bind(null, source, target)); |
| } |
| |
| function remove (source, target) { |
| var binding = bindings[source.id]; |
| if (!binding) { |
| return; |
| } |
| var invalidate = binding[target.id]; |
| source.off('data', invalidate); |
| delete binding[target.id]; |
| } |
| |
| function invalidator (target) { |
| return function invalidate () { |
| target.refresh(); |
| }; |
| } |
| |
| function add (source, target) { |
| if (isInput(target.associated) || has(source, target)) { |
| return; |
| } |
| insert(source, target); |
| } |
| |
| module.exports = { |
| add: add, |
| remove: remove |
| }; |
| |
| },{"./isInput":17}],7:[function(_dereq_,module,exports){ |
| 'use strict'; |
| |
| var emitter = _dereq_('contra.emitter'); |
| var raf = _dereq_('raf'); |
| var dom = _dereq_('./dom'); |
| var text = _dereq_('./text'); |
| var parse = _dereq_('./parse'); |
| var clone = _dereq_('./clone'); |
| var defaults = _dereq_('./defaults'); |
| var momentum = _dereq_('./momentum'); |
| var classes = _dereq_('./classes'); |
| var events = _dereq_('./events'); |
| var noop = _dereq_('./noop'); |
| var no; |
| |
| function calendar (calendarOptions) { |
| var o; |
| var api = emitter({}); |
| var ref; |
| var refCal; |
| var container; |
| var rendered = false; |
| |
| // date variables |
| var monthOffsetAttribute = 'data-rome-offset'; |
| var weekdays; |
| var weekdayCount; |
| var calendarMonths = []; |
| var lastYear; |
| var lastMonth; |
| var lastDay; |
| var lastDayElement; |
| var datewrapper; |
| var back; |
| var next; |
| |
| // time variables |
| var secondsInDay = 60 * 60 * 24; |
| var time; |
| var timelist; |
| |
| init(); |
| raf(ready); |
| |
| return api; |
| |
| function napi () { return api; } |
| |
| function init (initOptions) { |
| o = defaults(initOptions || calendarOptions, api); |
| if (!container) { container = dom({ className: o.styles.container }); } |
| weekdays = o.weekdayFormat; |
| weekdayCount = weekdays.length; |
| lastMonth = no; |
| lastYear = no; |
| lastDay = no; |
| lastDayElement = no; |
| o.appendTo.appendChild(container); |
| |
| removeChildren(container); |
| rendered = false; |
| ref = o.initialValue ? o.initialValue : momentum.moment(); |
| refCal = ref.clone(); |
| |
| api.container = container; |
| api.destroyed = false; |
| api.destroy = destroy.bind(api, false); |
| api.emitValues = emitValues; |
| api.getDate = getDate; |
| api.getDateString = getDateString; |
| api.getMoment = getMoment; |
| api.hide = hide; |
| api.options = changeOptions; |
| api.options.reset = resetOptions; |
| api.refresh = refresh; |
| api.restore = napi; |
| api.setValue = setValue; |
| api.show = show; |
| |
| show(); |
| eventListening(); |
| ready(); |
| |
| return api; |
| } |
| |
| function ready () { |
| api.emit('ready', clone(o)); |
| } |
| |
| function destroy (silent) { |
| if (container) { |
| container.parentNode.removeChild(container); |
| } |
| |
| if (o) { |
| eventListening(true); |
| } |
| |
| var destroyed = api.emitterSnapshot('destroyed'); |
| api.destroyed = true; |
| api.destroy = napi; |
| api.emitValues = napi; |
| api.getDate = noop; |
| api.getDateString = noop; |
| api.getMoment = noop; |
| api.hide = napi; |
| api.options = napi; |
| api.options.reset = napi; |
| api.refresh = napi; |
| api.restore = init; |
| api.setValue = napi; |
| api.show = napi; |
| api.off(); |
| |
| if (silent !== true) { |
| destroyed(); |
| } |
| |
| return api; |
| } |
| |
| function eventListening (remove) { |
| var op = remove ? 'remove' : 'add'; |
| if (o.autoHideOnBlur) { events[op](document.documentElement, 'focus', hideOnBlur, true); } |
| if (o.autoHideOnClick) { events[op](document, 'click', hideOnClick); } |
| } |
| |
| function changeOptions (options) { |
| if (arguments.length === 0) { |
| return clone(o); |
| } |
| destroy(); |
| init(options); |
| return api; |
| } |
| |
| function resetOptions () { |
| return changeOptions({ appendTo: o.appendTo }); |
| } |
| |
| function render () { |
| if (rendered) { |
| return; |
| } |
| rendered = true; |
| renderDates(); |
| renderTime(); |
| api.emit('render'); |
| } |
| |
| function renderDates () { |
| if (!o.date) { |
| return; |
| } |
| var i; |
| calendarMonths = []; |
| |
| datewrapper = dom({ className: o.styles.date, parent: container }); |
| |
| for (i = 0; i < o.monthsInCalendar; i++) { |
| renderMonth(i); |
| } |
| |
| events.add(back, 'click', subtractMonth); |
| events.add(next, 'click', addMonth); |
| events.add(datewrapper, 'click', pickDay); |
| |
| function renderMonth (i) { |
| var month = dom({ className: o.styles.month, parent: datewrapper }); |
| if (i === 0) { |
| back = dom({ type: 'button', className: o.styles.back, attributes: { type: 'button' }, parent: month }); |
| } |
| if (i === o.monthsInCalendar -1) { |
| next = dom({ type: 'button', className: o.styles.next, attributes: { type: 'button' }, parent: month }); |
| } |
| var label = dom({ className: o.styles.monthLabel, parent: month }); |
| var date = dom({ type: 'table', className: o.styles.dayTable, parent: month }); |
| var datehead = dom({ type: 'thead', className: o.styles.dayHead, parent: date }); |
| var dateheadrow = dom({ type: 'tr', className: o.styles.dayRow, parent: datehead }); |
| var datebody = dom({ type: 'tbody', className: o.styles.dayBody, parent: date }); |
| var j; |
| |
| for (j = 0; j < weekdayCount; j++) { |
| dom({ type: 'th', className: o.styles.dayHeadElem, parent: dateheadrow, text: weekdays[weekday(j)] }); |
| } |
| |
| datebody.setAttribute(monthOffsetAttribute, i); |
| calendarMonths.push({ |
| label: label, |
| body: datebody |
| }); |
| } |
| } |
| |
| function renderTime () { |
| if (!o.time || !o.timeInterval) { |
| return; |
| } |
| var timewrapper = dom({ className: o.styles.time, parent: container }); |
| time = dom({ className: o.styles.selectedTime, parent: timewrapper, text: ref.format(o.timeFormat) }); |
| events.add(time, 'click', toggleTimeList); |
| timelist = dom({ className: o.styles.timeList, parent: timewrapper }); |
| events.add(timelist, 'click', pickTime); |
| var next = momentum.moment('00:00:00', 'HH:mm:ss'); |
| var latest = next.clone().add(1, 'days'); |
| while (next.isBefore(latest)) { |
| dom({ className: o.styles.timeOption, parent: timelist, text: next.format(o.timeFormat) }); |
| next.add(o.timeInterval, 'seconds'); |
| } |
| } |
| |
| function weekday (index, backwards) { |
| var factor = backwards ? -1 : 1; |
| var offset = index + o.weekStart * factor; |
| if (offset >= weekdayCount || offset < 0) { |
| offset += weekdayCount * -factor; |
| } |
| return offset; |
| } |
| |
| function displayValidTimesOnly () { |
| if (!o.time || !rendered) { |
| return; |
| } |
| var times = timelist.children; |
| var length = times.length; |
| var date; |
| var time; |
| var item; |
| var i; |
| for (i = 0; i < length; i++) { |
| item = times[i]; |
| time = momentum.moment(text(item), o.timeFormat); |
| date = setTime(ref.clone(), time); |
| item.style.display = isInRange(date, false, o.timeValidator) ? 'block' : 'none'; |
| } |
| } |
| |
| function toggleTimeList (show) { |
| var display = typeof show === 'boolean' ? show : timelist.style.display === 'none'; |
| if (display) { |
| showTimeList(); |
| } else { |
| hideTimeList(); |
| } |
| } |
| |
| function showTimeList () { if (timelist) { timelist.style.display = 'block'; } } |
| function hideTimeList () { if (timelist) { timelist.style.display = 'none'; } } |
| function showCalendar () { container.style.display = 'inline-block'; api.emit('show'); } |
| function hideCalendar () { container.style.display = 'none'; api.emit('hide'); } |
| |
| function show () { |
| render(); |
| refresh(); |
| toggleTimeList(!o.date); |
| showCalendar(); |
| return api; |
| } |
| |
| function hide () { |
| hideTimeList(); |
| raf(hideCalendar); |
| return api; |
| } |
| |
| function hideConditionally () { |
| hideTimeList(); |
| |
| var pos = classes.contains(container, o.styles.positioned); |
| if (pos) { |
| raf(hideCalendar); |
| } |
| return api; |
| } |
| |
| function calendarEventTarget (e) { |
| var target = e.target; |
| if (target === api.associated) { |
| return true; |
| } |
| while (target) { |
| if (target === container) { |
| return true; |
| } |
| target = target.parentNode; |
| } |
| } |
| |
| function hideOnBlur (e) { |
| if (calendarEventTarget(e)) { |
| return; |
| } |
| hideConditionally(); |
| } |
| |
| function hideOnClick (e) { |
| if (calendarEventTarget(e)) { |
| return; |
| } |
| hideConditionally(); |
| } |
| |
| function subtractMonth () { changeMonth('subtract'); } |
| function addMonth () { changeMonth('add'); } |
| function changeMonth (op) { |
| var bound; |
| var direction = op === 'add' ? -1 : 1; |
| var offset = o.monthsInCalendar + direction * getMonthOffset(lastDayElement); |
| refCal[op](offset, 'months'); |
| bound = inRange(refCal.clone()); |
| ref = bound || ref; |
| if (bound) { refCal = bound.clone(); } |
| update(); |
| } |
| |
| function update (silent) { |
| updateCalendar(); |
| updateTime(); |
| if (silent !== true) { emitValues(); } |
| displayValidTimesOnly(); |
| } |
| |
| function updateCalendar () { |
| if (!o.date || !rendered) { |
| return; |
| } |
| var y = refCal.year(); |
| var m = refCal.month(); |
| var d = refCal.date(); |
| if (d === lastDay && m === lastMonth && y === lastYear) { |
| return; |
| } |
| var canStay = isDisplayed(); |
| lastDay = refCal.date(); |
| lastMonth = refCal.month(); |
| lastYear = refCal.year(); |
| if (canStay) { updateCalendarSelection(); return; } |
| calendarMonths.forEach(updateMonth); |
| renderAllDays(); |
| |
| function updateMonth (month, i) { |
| var offsetCal = refCal.clone().add(i, 'months'); |
| text(month.label, offsetCal.format(o.monthFormat)); |
| removeChildren(month.body); |
| } |
| } |
| |
| function updateCalendarSelection () { |
| var day = refCal.date() - 1; |
| selectDayElement(false); |
| calendarMonths.forEach(function (cal) { |
| var days; |
| if (sameCalendarMonth(cal.date, refCal)) { |
| days = cast(cal.body.children).map(aggregate); |
| days = Array.prototype.concat.apply([], days).filter(inside); |
| selectDayElement(days[day]); |
| } |
| }); |
| |
| function cast (like) { |
| var dest = []; |
| var i; |
| for (i = 0; i < like.length; i++) { |
| dest.push(like[i]); |
| } |
| return dest; |
| } |
| |
| function aggregate (child) { |
| return cast(child.children); |
| } |
| |
| function inside (child) { |
| return !classes.contains(child, o.styles.dayPrevMonth) && |
| !classes.contains(child, o.styles.dayNextMonth); |
| } |
| } |
| |
| function isDisplayed () { |
| return calendarMonths.some(matches); |
| |
| function matches (cal) { |
| if (!lastYear) { return false; } |
| return sameCalendarMonth(cal.date, refCal); |
| } |
| } |
| |
| function sameCalendarMonth (left, right) { |
| return left && right && left.year() === right.year() && left.month() === right.month(); |
| } |
| |
| function updateTime () { |
| if (!o.time || !rendered) { |
| return; |
| } |
| text(time, ref.format(o.timeFormat)); |
| } |
| |
| function emitValues () { |
| api.emit('data', getDateString()); |
| api.emit('year', ref.year()); |
| api.emit('month', ref.month()); |
| api.emit('day', ref.day()); |
| api.emit('time', ref.format(o.timeFormat)); |
| return api; |
| } |
| |
| function refresh () { |
| lastYear = false; |
| lastMonth = false; |
| lastDay = false; |
| update(true); |
| return api; |
| } |
| |
| function setValue (value) { |
| var date = parse(value, o.inputFormat); |
| if (date === null) { |
| return; |
| } |
| ref = inRange(date) || ref; |
| refCal = ref.clone(); |
| update(true); |
| |
| return api; |
| } |
| |
| function removeChildren (elem, self) { |
| while (elem && elem.firstChild) { |
| elem.removeChild(elem.firstChild); |
| } |
| if (self === true) { |
| elem.parentNode.removeChild(elem); |
| } |
| } |
| |
| function renderAllDays () { |
| var i; |
| for (i = 0; i < o.monthsInCalendar; i++) { |
| renderDays(i); |
| } |
| } |
| |
| function renderDays (offset) { |
| var month = calendarMonths[offset]; |
| var offsetCal = refCal.clone().add(offset, 'months'); |
| var total = offsetCal.daysInMonth(); |
| var current = offsetCal.month() !== ref.month() ? -1 : ref.date(); // -1 : 1..31 |
| var first = offsetCal.clone().date(1); |
| var firstDay = weekday(first.day(), true); // 0..6 |
| var tr = dom({ type: 'tr', className: o.styles.dayRow, parent: month.body }); |
| var prevMonth = hiddenWhen(offset !== 0, [o.styles.dayBodyElem, o.styles.dayPrevMonth]); |
| var nextMonth = hiddenWhen(offset !== o.monthsInCalendar - 1, [o.styles.dayBodyElem, o.styles.dayNextMonth]); |
| var disabled = o.styles.dayDisabled; |
| var lastDay; |
| |
| part({ |
| base: first.clone().subtract(firstDay, 'days'), |
| length: firstDay, |
| cell: prevMonth |
| }); |
| |
| part({ |
| base: first.clone(), |
| length: total, |
| cell: [o.styles.dayBodyElem], |
| selectable: true |
| }); |
| |
| lastDay = first.clone().add(total, 'days'); |
| |
| part({ |
| base: lastDay, |
| length: weekdayCount - tr.children.length, |
| cell: nextMonth |
| }); |
| |
| back.disabled = !isInRangeLeft(first, true); |
| next.disabled = !isInRangeRight(lastDay, true); |
| month.date = offsetCal.clone(); |
| |
| function part (data) { |
| var i, day, node; |
| for (i = 0; i < data.length; i++) { |
| if (tr.children.length === weekdayCount) { |
| tr = dom({ type: 'tr', className: o.styles.dayRow, parent: month.body }); |
| } |
| day = data.base.clone().add(i, 'days'); |
| node = dom({ |
| type: 'td', |
| parent: tr, |
| text: day.format(o.dayFormat), |
| className: validationTest(day, data.cell.join(' ').split(' ')).join(' ') |
| }); |
| if (data.selectable && day.date() === current) { |
| selectDayElement(node); |
| } |
| } |
| } |
| |
| function validationTest (day, cell) { |
| if (!isInRange(day, true, o.dateValidator)) { cell.push(disabled); } |
| return cell; |
| } |
| |
| function hiddenWhen (value, cell) { |
| if (value) { cell.push(o.styles.dayConcealed); } |
| return cell; |
| } |
| } |
| |
| function isInRange (date, allday, validator) { |
| if (!isInRangeLeft(date, allday)) { |
| return false; |
| } |
| if (!isInRangeRight(date, allday)) { |
| return false; |
| } |
| var valid = (validator || Function.prototype).call(api, date.toDate()); |
| return valid !== false; |
| } |
| |
| function isInRangeLeft (date, allday) { |
| var min = !o.min ? false : (allday ? o.min.clone().startOf('day') : o.min); |
| return !min || !date.isBefore(min); |
| } |
| |
| function isInRangeRight (date, allday) { |
| var max = !o.max ? false : (allday ? o.max.clone().endOf('day') : o.max); |
| return !max || !date.isAfter(max); |
| } |
| |
| function inRange (date) { |
| if (o.min && date.isBefore(o.min)) { |
| return inRange(o.min.clone()); |
| } else if (o.max && date.isAfter(o.max)) { |
| return inRange(o.max.clone()); |
| } |
| var value = date.clone().subtract(1, 'days'); |
| if (validateTowards(value, date, 'add')) { |
| return inTimeRange(value); |
| } |
| value = date.clone(); |
| if (validateTowards(value, date, 'subtract')) { |
| return inTimeRange(value); |
| } |
| } |
| |
| function inTimeRange (value) { |
| var copy = value.clone().subtract(o.timeInterval, 'seconds'); |
| var times = Math.ceil(secondsInDay / o.timeInterval); |
| var i; |
| for (i = 0; i < times; i++) { |
| copy.add(o.timeInterval, 'seconds'); |
| if (copy.date() > value.date()) { |
| copy.subtract(1, 'days'); |
| } |
| if (o.timeValidator.call(api, copy.toDate()) !== false) { |
| return copy; |
| } |
| } |
| } |
| |
| function validateTowards (value, date, op) { |
| var valid = false; |
| while (valid === false) { |
| value[op](1, 'days'); |
| if (value.month() !== date.month()) { |
| break; |
| } |
| valid = o.dateValidator.call(api, value.toDate()); |
| } |
| return valid !== false; |
| } |
| |
| function pickDay (e) { |
| var target = e.target; |
| if (classes.contains(target, o.styles.dayDisabled) || !classes.contains(target, o.styles.dayBodyElem)) { |
| return; |
| } |
| var day = parseInt(text(target), 10); |
| var prev = classes.contains(target, o.styles.dayPrevMonth); |
| var next = classes.contains(target, o.styles.dayNextMonth); |
| var offset = getMonthOffset(target) - getMonthOffset(lastDayElement); |
| ref.add(offset, 'months'); |
| if (prev || next) { |
| ref.add(prev ? -1 : 1, 'months'); |
| } |
| selectDayElement(target); |
| ref.date(day); // must run after setting the month |
| setTime(ref, inRange(ref) || ref); |
| refCal = ref.clone(); |
| if (o.autoClose === true) { hideConditionally(); } |
| update(); |
| } |
| |
| function selectDayElement (node) { |
| if (lastDayElement) { |
| classes.remove(lastDayElement, o.styles.selectedDay); |
| } |
| if (node) { |
| classes.add(node, o.styles.selectedDay); |
| } |
| lastDayElement = node; |
| } |
| |
| function getMonthOffset (elem) { |
| var offset; |
| while (elem && elem.getAttribute) { |
| offset = elem.getAttribute(monthOffsetAttribute); |
| if (typeof offset === 'string') { |
| return parseInt(offset, 10); |
| } |
| elem = elem.parentNode; |
| } |
| return 0; |
| } |
| |
| function setTime (to, from) { |
| to.hour(from.hour()).minute(from.minute()).second(from.second()); |
| return to; |
| } |
| |
| function pickTime (e) { |
| var target = e.target; |
| if (!classes.contains(target, o.styles.timeOption)) { |
| return; |
| } |
| var value = momentum.moment(text(target), o.timeFormat); |
| setTime(ref, value); |
| refCal = ref.clone(); |
| emitValues(); |
| updateTime(); |
| if ((!o.date && o.autoClose === true) || o.autoClose === 'time') { |
| hideConditionally(); |
| } else { |
| hideTimeList(); |
| } |
| } |
| |
| function getDate () { |
| return ref.toDate(); |
| } |
| |
| function getDateString (format) { |
| return ref.format(format || o.inputFormat); |
| } |
| |
| function getMoment () { |
| return ref.clone(); |
| } |
| } |
| |
| module.exports = calendar; |
| |
| },{"./classes":8,"./clone":9,"./defaults":11,"./dom":12,"./events":13,"./momentum":18,"./noop":19,"./parse":20,"./text":32,"contra.emitter":2,"raf":4}],8:[function(_dereq_,module,exports){ |
| 'use strict'; |
| |
| var trim = /^\s+|\s+$/g; |
| var whitespace = /\s+/; |
| |
| function classes (node) { |
| return node.className.replace(trim, '').split(whitespace); |
| } |
| |
| function set (node, value) { |
| node.className = value.join(' '); |
| } |
| |
| function add (node, value) { |
| var values = remove(node, value); |
| values.push(value); |
| set(node, values); |
| } |
| |
| function remove (node, value) { |
| var values = classes(node); |
| var i = values.indexOf(value); |
| if (i !== -1) { |
| values.splice(i, 1); |
| set(node, values); |
| } |
| return values; |
| } |
| |
| function contains (node, value) { |
| return classes(node).indexOf(value) !== -1; |
| } |
| |
| module.exports = { |
| add: add, |
| remove: remove, |
| contains: contains |
| }; |
| |
| },{}],9:[function(_dereq_,module,exports){ |
| 'use strict'; |
| |
| var momentum = _dereq_('./momentum'); |
| |
| // naïve implementation, specifically meant to clone `options` objects |
| function clone (thing) { |
| var copy = {}; |
| var value; |
| |
| for (var key in thing) { |
| value = thing[key]; |
| |
| if (!value) { |
| copy[key] = value; |
| } else if (momentum.isMoment(value)) { |
| copy[key] = value.clone(); |
| } else if (value._isStylesConfiguration) { |
| copy[key] = clone(value); |
| } else { |
| copy[key] = value; |
| } |
| } |
| |
| return copy; |
| } |
| |
| module.exports = clone; |
| |
| },{"./momentum":18}],10:[function(_dereq_,module,exports){ |
| 'use strict'; |
| |
| var index = _dereq_('./index'); |
| var input = _dereq_('./input'); |
| var inline = _dereq_('./inline'); |
| var isInput = _dereq_('./isInput'); |
| |
| function core (elem, options) { |
| var cal; |
| var existing = index.find(elem); |
| if (existing) { |
| return existing; |
| } |
| |
| if (isInput(elem)) { |
| cal = input(elem, options); |
| } else { |
| cal = inline(elem, options); |
| } |
| cal.associated = elem; |
| index.assign(elem, cal); |
| |
| return cal; |
| } |
| |
| module.exports = core; |
| |
| },{"./index":14,"./inline":15,"./input":16,"./isInput":17}],11:[function(_dereq_,module,exports){ |
| 'use strict'; |
| |
| var parse = _dereq_('./parse'); |
| var isInput = _dereq_('./isInput'); |
| var momentum = _dereq_('./momentum'); |
| |
| function defaults (options, cal) { |
| var temp; |
| var no; |
| var o = options || {}; |
| if (o.autoHideOnClick === no) { o.autoHideOnClick = true; } |
| if (o.autoHideOnBlur === no) { o.autoHideOnBlur = true; } |
| if (o.autoClose === no) { o.autoClose = true; } |
| if (o.appendTo === no) { o.appendTo = document.body; } |
| if (o.appendTo === 'parent') { |
| if (isInput(cal.associated)) { |
| o.appendTo = cal.associated.parentNode; |
| } else { |
| throw new Error('Inline calendars must be appended to a parent node explicitly.'); |
| } |
| } |
| if (o.invalidate === no) { o.invalidate = true; } |
| if (o.required === no) { o.required = false; } |
| if (o.date === no) { o.date = true; } |
| if (o.time === no) { o.time = true; } |
| if (o.date === false && o.time === false) { throw new Error('At least one of `date` or `time` must be `true`.'); } |
| if (o.inputFormat === no) { |
| if (o.date && o.time) { |
| o.inputFormat = 'YYYY-MM-DD HH:mm'; |
| } else if (o.date) { |
| o.inputFormat = 'YYYY-MM-DD'; |
| } else { |
| o.inputFormat = 'HH:mm'; |
| } |
| } |
| if (o.initialValue === no) { |
| o.initialValue = null; |
| } else { |
| o.initialValue = parse(o.initialValue, o.inputFormat); |
| } |
| if (o.min === no) { o.min = null; } else { o.min = parse(o.min, o.inputFormat); } |
| if (o.max === no) { o.max = null; } else { o.max = parse(o.max, o.inputFormat); } |
| if (o.timeInterval === no) { o.timeInterval = 60 * 30; } // 30 minutes by default |
| if (o.min && o.max) { |
| if (o.max.isBefore(o.min)) { |
| temp = o.max; |
| o.max = o.min; |
| o.min = temp; |
| } |
| if (o.date === true) { |
| if (o.max.clone().subtract(1, 'days').isBefore(o.min)) { |
| throw new Error('`max` must be at least one day after `min`'); |
| } |
| } else if (o.timeInterval * 1000 - o.min % (o.timeInterval * 1000) > o.max - o.min) { |
| throw new Error('`min` to `max` range must allow for at least one time option that matches `timeInterval`'); |
| } |
| } |
| if (o.dateValidator === no) { o.dateValidator = Function.prototype; } |
| if (o.timeValidator === no) { o.timeValidator = Function.prototype; } |
| if (o.timeFormat === no) { o.timeFormat = 'HH:mm'; } |
| if (o.weekStart === no) { o.weekStart = momentum.moment().weekday(0).day(); } |
| if (o.weekdayFormat === no) { o.weekdayFormat = 'min'; } |
| if (o.weekdayFormat === 'long') { |
| o.weekdayFormat = momentum.moment.weekdays(); |
| } else if (o.weekdayFormat === 'short') { |
| o.weekdayFormat = momentum.moment.weekdaysShort(); |
| } else if (o.weekdayFormat === 'min') { |
| o.weekdayFormat = momentum.moment.weekdaysMin(); |
| } else if (!Array.isArray(o.weekdayFormat) || o.weekdayFormat.length < 7) { |
| throw new Error('`weekdays` must be `min`, `short`, or `long`'); |
| } |
| if (o.monthsInCalendar === no) { o.monthsInCalendar = 1; } |
| if (o.monthFormat === no) { o.monthFormat = 'MMMM YYYY'; } |
| if (o.dayFormat === no) { o.dayFormat = 'DD'; } |
| if (o.styles === no) { o.styles = {}; } |
| |
| o.styles._isStylesConfiguration = true; |
| |
| var styl = o.styles; |
| if (styl.back === no) { styl.back = 'rd-back'; } |
| if (styl.container === no) { styl.container = 'rd-container'; } |
| if (styl.positioned === no) { styl.positioned = 'rd-container-attachment'; } |
| if (styl.date === no) { styl.date = 'rd-date'; } |
| if (styl.dayBody === no) { styl.dayBody = 'rd-days-body'; } |
| if (styl.dayBodyElem === no) { styl.dayBodyElem = 'rd-day-body'; } |
| if (styl.dayPrevMonth === no) { styl.dayPrevMonth = 'rd-day-prev-month'; } |
| if (styl.dayNextMonth === no) { styl.dayNextMonth = 'rd-day-next-month'; } |
| if (styl.dayDisabled === no) { styl.dayDisabled = 'rd-day-disabled'; } |
| if (styl.dayConcealed === no) { styl.dayConcealed = 'rd-day-concealed'; } |
| if (styl.dayHead === no) { styl.dayHead = 'rd-days-head'; } |
| if (styl.dayHeadElem === no) { styl.dayHeadElem = 'rd-day-head'; } |
| if (styl.dayRow === no) { styl.dayRow = 'rd-days-row'; } |
| if (styl.dayTable === no) { styl.dayTable = 'rd-days'; } |
| if (styl.month === no) { styl.month = 'rd-month'; } |
| if (styl.monthLabel === no) { styl.monthLabel = 'rd-month-label'; } |
| if (styl.next === no) { styl.next = 'rd-next'; } |
| if (styl.selectedDay === no) { styl.selectedDay = 'rd-day-selected'; } |
| if (styl.selectedTime === no) { styl.selectedTime = 'rd-time-selected'; } |
| if (styl.time === no) { styl.time = 'rd-time'; } |
| if (styl.timeList === no) { styl.timeList = 'rd-time-list'; } |
| if (styl.timeOption === no) { styl.timeOption = 'rd-time-option'; } |
| |
| return o; |
| } |
| |
| module.exports = defaults; |
| |
| },{"./isInput":17,"./momentum":18,"./parse":20}],12:[function(_dereq_,module,exports){ |
| 'use strict'; |
| |
| function dom (options) { |
| var o = options || {}; |
| if (!o.type) { o.type = 'div'; } |
| var elem = document.createElement(o.type); |
| if (o.className) { elem.className = o.className; } |
| if (o.text) { elem.innerText = elem.textContent = o.text; } |
| if (o.attributes) { |
| Object.keys(o.attributes).forEach(function(key) { |
| elem.setAttribute(key, o.attributes[key]); |
| }); |
| } |
| if (o.parent) { o.parent.appendChild(elem); } |
| return elem; |
| } |
| |
| module.exports = dom; |
| |
| },{}],13:[function(_dereq_,module,exports){ |
| 'use strict'; |
| |
| var addEvent = addEventEasy; |
| var removeEvent = removeEventEasy; |
| |
| if (!window.addEventListener) { |
| addEvent = addEventHard; |
| } |
| |
| if (!window.removeEventListener) { |
| removeEvent = removeEventHard; |
| } |
| |
| function addEventEasy (element, evt, fn, capture) { |
| return element.addEventListener(evt, fn, capture); |
| } |
| |
| function addEventHard (element, evt, fn, capture) { |
| return element.attachEvent('on' + evt, function (ae) { |
| var e = ae || window.event; |
| e.target = e.target || e.srcElement; |
| e.preventDefault = e.preventDefault || function preventDefault () { e.returnValue = false; }; |
| e.stopPropagation = e.stopPropagation || function stopPropagation () { e.cancelBubble = true; }; |
| fn.call(element, e); |
| }, capture); |
| } |
| |
| function removeEventEasy (element, evt, fn) { |
| return element.removeEventListener(evt, fn); |
| } |
| |
| function removeEventHard (element, evt, fn) { |
| return element.detachEvent('on' + evt, fn); |
| } |
| |
| module.exports = { |
| add: addEvent, |
| remove: removeEvent |
| }; |
| |
| },{}],14:[function(_dereq_,module,exports){ |
| 'use strict'; |
| var no; |
| var ikey = 'data-rome-id'; |
| var index = []; |
| |
| function find (thing) { // can be a DOM element or a number |
| if (typeof thing !== 'number' && thing && thing.getAttribute) { |
| return find(thing.getAttribute(ikey)); |
| } |
| var existing = index[thing]; |
| if (existing !== no) { |
| return existing; |
| } |
| return null; |
| } |
| |
| function assign (elem, instance) { |
| elem.setAttribute(ikey, instance.id = index.push(instance) - 1); |
| } |
| |
| module.exports = { |
| find: find, |
| assign: assign |
| }; |
| |
| },{}],15:[function(_dereq_,module,exports){ |
| 'use strict'; |
| |
| var raf = _dereq_('raf'); |
| var calendar = _dereq_('./calendar'); |
| |
| function inline (elem, calendarOptions) { |
| var o = calendarOptions || {}; |
| |
| o.appendTo = elem; |
| |
| return calendar(o); |
| } |
| |
| module.exports = inline; |
| |
| },{"./calendar":7,"raf":4}],16:[function(_dereq_,module,exports){ |
| 'use strict'; |
| |
| var throttle = _dereq_('./throttle'); |
| var raf = _dereq_('raf'); |
| var clone = _dereq_('./clone'); |
| var defaults = _dereq_('./defaults'); |
| var calendar = _dereq_('./calendar'); |
| var momentum = _dereq_('./momentum'); |
| var classes = _dereq_('./classes'); |
| var events = _dereq_('./events'); |
| |
| function inputCalendar (input, calendarOptions) { |
| var o; |
| var api = calendar(calendarOptions); |
| var throttledTakeInput = throttle(takeInput, 30); |
| var throttledPosition = throttle(position, 30); |
| var ignoreInvalidation; |
| var ignoreShow; |
| |
| init(calendarOptions); |
| |
| return api; |
| |
| function init (initOptions) { |
| o = defaults(initOptions || calendarOptions, api); |
| |
| classes.add(api.container, o.styles.positioned); |
| events.add(api.container, 'mousedown', containerMouseDown); |
| events.add(api.container, 'click', containerClick); |
| |
| api.getDate = unrequire(api.getDate); |
| api.getDateString = unrequire(api.getDateString); |
| api.getMoment = unrequire(api.getMoment); |
| |
| if (o.initialValue) { |
| input.value = o.initialValue.format(o.inputFormat); |
| } |
| |
| api.on('data', updateInput); |
| api.on('show', throttledPosition); |
| |
| eventListening(); |
| throttledTakeInput(); |
| |
| api.hide(); |
| } |
| |
| function destroy () { |
| eventListening(true); |
| } |
| |
| function eventListening (remove) { |
| var op = remove ? 'remove' : 'add'; |
| events[op](input, 'click', show); |
| events[op](input, 'touchend', show); |
| events[op](input, 'focusin', show); |
| events[op](input, 'change', throttledTakeInput); |
| events[op](input, 'keypress', throttledTakeInput); |
| events[op](input, 'keydown', throttledTakeInput); |
| events[op](input, 'input', throttledTakeInput); |
| if (o.invalidate) { events[op](input, 'blur', invalidateInput); } |
| events[op](window, 'resize', throttledPosition); |
| |
| if (remove) { |
| api.once('ready', init); |
| api.off('destroyed', destroy); |
| } else { |
| api.off('ready', init); |
| api.once('destroyed', destroy); |
| } |
| } |
| |
| function containerClick () { |
| ignoreShow = true; |
| input.focus(); |
| ignoreShow = false; |
| } |
| |
| function containerMouseDown () { |
| ignoreInvalidation = true; |
| raf(unignore); |
| |
| function unignore () { |
| ignoreInvalidation = false; |
| } |
| } |
| |
| function invalidateInput () { |
| if (!ignoreInvalidation && !isEmpty()) { |
| api.emitValues(); |
| } |
| } |
| |
| function show () { |
| if (ignoreShow) { |
| return; |
| } |
| api.show(); |
| } |
| |
| function position () { |
| var bounds = input.getBoundingClientRect(); |
| var scrollTop = document.body.scrollTop || document.documentElement.scrollTop; |
| api.container.style.top = bounds.top + scrollTop + input.offsetHeight + 'px'; |
| api.container.style.left = bounds.left + 'px'; |
| } |
| |
| function takeInput () { |
| var value = input.value.trim(); |
| if (isEmpty()) { |
| return; |
| } |
| var date = momentum.moment(value, o.inputFormat, o.strictParse); |
| api.setValue(date); |
| } |
| |
| function updateInput (data) { |
| input.value = data; |
| } |
| |
| function isEmpty () { |
| return o.required === false && input.value.trim() === ''; |
| } |
| |
| function unrequire (fn) { |
| return function maybe () { |
| return isEmpty() ? null : fn.apply(this, arguments); |
| }; |
| } |
| } |
| |
| module.exports = inputCalendar; |
| |
| },{"./calendar":7,"./classes":8,"./clone":9,"./defaults":11,"./events":13,"./momentum":18,"./throttle":33,"raf":4}],17:[function(_dereq_,module,exports){ |
| 'use strict'; |
| |
| function isInput (elem) { |
| return elem && elem.nodeName && elem.nodeName.toLowerCase() === 'input'; |
| } |
| |
| module.exports = isInput; |
| |
| },{}],18:[function(_dereq_,module,exports){ |
| 'use strict'; |
| |
| function isMoment (value) { |
| return value && Object.prototype.hasOwnProperty.call(value, '_isAMomentObject'); |
| } |
| |
| var api = { |
| moment: null, |
| isMoment: isMoment |
| }; |
| |
| module.exports = api; |
| |
| },{}],19:[function(_dereq_,module,exports){ |
| 'use strict'; |
| |
| function noop () {} |
| |
| module.exports = noop; |
| |
| },{}],20:[function(_dereq_,module,exports){ |
| 'use strict'; |
| |
| var momentum = _dereq_('./momentum'); |
| |
| function raw (date, format) { |
| if (typeof date === 'string') { |
| return momentum.moment(date, format); |
| } |
| if (Object.prototype.toString.call(date) === '[object Date]') { |
| return momentum.moment(date); |
| } |
| if (momentum.isMoment(date)) { |
| return date.clone(); |
| } |
| } |
| |
| function parse (date, format) { |
| var m = raw(date, typeof format === 'string' ? format : null); |
| return m && m.isValid() ? m : null; |
| } |
| |
| module.exports = parse; |
| |
| },{"./momentum":18}],21:[function(_dereq_,module,exports){ |
| 'use strict'; |
| |
| if (!Array.prototype.filter) { |
| Array.prototype.filter = function (fn, ctx) { |
| var f = []; |
| this.forEach(function (v, i, t) { |
| if (fn.call(ctx, v, i, t)) { f.push(v); } |
| }, ctx); |
| return f; |
| }; |
| } |
| |
| },{}],22:[function(_dereq_,module,exports){ |
| 'use strict'; |
| |
| if (!Array.prototype.forEach) { |
| Array.prototype.forEach = function (fn, ctx) { |
| if (this === void 0 || this === null || typeof fn !== 'function') { |
| throw new TypeError(); |
| } |
| var t = this; |
| var len = t.length; |
| for (var i = 0; i < len; i++) { |
| if (i in t) { fn.call(ctx, t[i], i, t); } |
| } |
| }; |
| } |
| |
| },{}],23:[function(_dereq_,module,exports){ |
| 'use strict'; |
| |
| if (!Array.prototype.indexOf) { |
| Array.prototype.indexOf = function (what, start) { |
| if (this === undefined || this === null) { |
| throw new TypeError(); |
| } |
| var length = this.length; |
| start = +start || 0; |
| if (Math.abs(start) === Infinity) { |
| start = 0; |
| } else if (start < 0) { |
| start += length; |
| if (start < 0) { start = 0; } |
| } |
| for (; start < length; start++) { |
| if (this[start] === what) { |
| return start; |
| } |
| } |
| return -1; |
| }; |
| } |
| |
| },{}],24:[function(_dereq_,module,exports){ |
| 'use strict'; |
| |
| Array.isArray || (Array.isArray = function (a) { |
| return '' + a !== a && Object.prototype.toString.call(a) === '[object Array]'; |
| }); |
| |
| },{}],25:[function(_dereq_,module,exports){ |
| 'use strict'; |
| |
| if (!Array.prototype.map) { |
| Array.prototype.map = function (fn, ctx) { |
| var context, result, i; |
| |
| if (this == null) { |
| throw new TypeError('this is null or not defined'); |
| } |
| |
| var source = Object(this); |
| var len = source.length >>> 0; |
| |
| if (typeof fn !== 'function') { |
| throw new TypeError(fn + ' is not a function'); |
| } |
| |
| if (arguments.length > 1) { |
| context = ctx; |
| } |
| |
| result = new Array(len); |
| i = 0; |
| |
| while (i < len) { |
| if (i in source) { |
| result[i] = fn.call(context, source[i], i, source); |
| } |
| i++; |
| } |
| return result; |
| }; |
| } |
| |
| },{}],26:[function(_dereq_,module,exports){ |
| 'use strict'; |
| |
| if (!Array.prototype.some) { |
| Array.prototype.some = function (fn, ctx) { |
| var context, i; |
| |
| if (this == null) { |
| throw new TypeError('this is null or not defined'); |
| } |
| |
| var source = Object(this); |
| var len = source.length >>> 0; |
| |
| if (typeof fn !== 'function') { |
| throw new TypeError(fn + ' is not a function'); |
| } |
| |
| if (arguments.length > 1) { |
| context = ctx; |
| } |
| |
| i = 0; |
| |
| while (i < len) { |
| if (i in source) { |
| var test = fn.call(context, source[i], i, source); |
| if (test) { |
| return true; |
| } |
| } |
| i++; |
| } |
| return false; |
| }; |
| } |
| |
| },{}],27:[function(_dereq_,module,exports){ |
| 'use strict'; |
| |
| if (!Function.prototype.bind) { |
| Function.prototype.bind = function (context) { |
| if (typeof this !== 'function') { |
| throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable'); |
| } |
| var curried = Array.prototype.slice.call(arguments, 1); |
| var original = this; |
| var NoOp = function () {}; |
| var bound = function () { |
| var ctx = this instanceof NoOp && context ? this : context; |
| var args = curried.concat(Array.prototype.slice.call(arguments)); |
| return original.apply(ctx, args); |
| }; |
| NoOp.prototype = this.prototype; |
| bound.prototype = new NoOp(); |
| return bound; |
| }; |
| } |
| |
| },{}],28:[function(_dereq_,module,exports){ |
| 'use strict'; |
| |
| var hasOwn = Object.prototype.hasOwnProperty; |
| var hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString'); |
| var dontEnums = [ |
| 'toString', |
| 'toLocaleString', |
| 'valueOf', |
| 'hasOwnProperty', |
| 'isPrototypeOf', |
| 'propertyIsEnumerable', |
| 'constructor' |
| ]; |
| var dontEnumsLength = dontEnums.length; |
| |
| if (!Object.keys) { |
| Object.keys = function(obj) { |
| if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) { |
| throw new TypeError('Object.keys called on non-object'); |
| } |
| |
| var result = [], prop, i; |
| |
| for (prop in obj) { |
| if (hasOwn.call(obj, prop)) { |
| result.push(prop); |
| } |
| } |
| |
| if (hasDontEnumBug) { |
| for (i = 0; i < dontEnumsLength; i++) { |
| if (hasOwn.call(obj, dontEnums[i])) { |
| result.push(dontEnums[i]); |
| } |
| } |
| } |
| return result; |
| }; |
| } |
| |
| },{}],29:[function(_dereq_,module,exports){ |
| 'use strict'; |
| |
| if (!String.prototype.trim) { |
| String.prototype.trim = function () { |
| return this.replace(/^\s+|\s+$/g, ''); |
| }; |
| } |
| |
| },{}],30:[function(_dereq_,module,exports){ |
| 'use strict'; |
| |
| // these are only required for IE < 9 |
| // maybe move to IE-specific distro? |
| _dereq_('./polyfills/function.bind'); |
| _dereq_('./polyfills/array.foreach'); |
| _dereq_('./polyfills/array.map'); |
| _dereq_('./polyfills/array.filter'); |
| _dereq_('./polyfills/array.isarray'); |
| _dereq_('./polyfills/array.indexof'); |
| _dereq_('./polyfills/array.some'); |
| _dereq_('./polyfills/string.trim'); |
| _dereq_('./polyfills/object.keys'); |
| |
| var core = _dereq_('./core'); |
| var index = _dereq_('./index'); |
| var use = _dereq_('./use'); |
| |
| core.use = use.bind(core); |
| core.find = index.find; |
| core.val = _dereq_('./validators'); |
| |
| module.exports = core; |
| |
| },{"./core":10,"./index":14,"./polyfills/array.filter":21,"./polyfills/array.foreach":22,"./polyfills/array.indexof":23,"./polyfills/array.isarray":24,"./polyfills/array.map":25,"./polyfills/array.some":26,"./polyfills/function.bind":27,"./polyfills/object.keys":28,"./polyfills/string.trim":29,"./use":34,"./validators":35}],31:[function(_dereq_,module,exports){ |
| (function (global){ |
| var rome = _dereq_('./rome'); |
| var momentum = _dereq_('./momentum'); |
| |
| rome.use(global.moment); |
| |
| if (momentum.moment === void 0) { |
| throw new Error('rome depends on moment.js, you can get it at http://momentjs.com, or you could use the bundled distribution file instead.'); |
| } |
| |
| module.exports = rome; |
| |
| }).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) |
| },{"./momentum":18,"./rome":30}],32:[function(_dereq_,module,exports){ |
| 'use strict'; |
| |
| function text (elem, value) { |
| if (arguments.length === 2) { |
| elem.innerText = elem.textContent = value; |
| } |
| return elem.innerText || elem.textContent; |
| } |
| |
| module.exports = text; |
| |
| },{}],33:[function(_dereq_,module,exports){ |
| 'use strict'; |
| |
| module.exports = function throttle (fn, boundary) { |
| var last = -Infinity; |
| var timer; |
| return function bounced () { |
| if (timer) { |
| return; |
| } |
| unbound(); |
| |
| function unbound () { |
| clearTimeout(timer); |
| timer = null; |
| var next = last + boundary; |
| var now = Date.now(); |
| if (now > next) { |
| last = now; |
| fn.apply(this, arguments); |
| } else { |
| timer = setTimeout(unbound, next - now); |
| } |
| } |
| }; |
| }; |
| |
| },{}],34:[function(_dereq_,module,exports){ |
| 'use strict'; |
| |
| var momentum = _dereq_('./momentum'); |
| |
| function use (moment) { |
| this.moment = momentum.moment = moment; |
| } |
| |
| module.exports = use; |
| |
| },{"./momentum":18}],35:[function(_dereq_,module,exports){ |
| 'use strict'; |
| |
| var index = _dereq_('./index'); |
| var parse = _dereq_('./parse'); |
| var association = _dereq_('./association'); |
| |
| function compareBuilder (compare) { |
| return function factory (value) { |
| var fixed = parse(value); |
| |
| return function validate (date) { |
| var cal = index.find(value); |
| var left = parse(date); |
| var right = fixed || cal && cal.getMoment(); |
| if (!right) { |
| return true; |
| } |
| if (cal) { |
| association.add(this, cal); |
| } |
| return compare(left, right); |
| }; |
| }; |
| } |
| |
| function rangeBuilder (how, compare) { |
| return function factory (start, end) { |
| var dates; |
| var len = arguments.length; |
| |
| if (Array.isArray(start)) { |
| dates = start; |
| } else { |
| if (len === 1) { |
| dates = [start]; |
| } else if (len === 2) { |
| dates = [[start, end]]; |
| } |
| } |
| |
| return function validate (date) { |
| return dates.map(expand.bind(this))[how](compare.bind(this, date)); |
| }; |
| |
| function expand (value) { |
| var start, end; |
| var cal = index.find(value); |
| if (cal) { |
| start = end = cal.getMoment(); |
| } else if (Array.isArray(value)) { |
| start = value[0]; end = value[1]; |
| } else { |
| start = end = value; |
| } |
| if (cal) { |
| association.add(cal, this); |
| } |
| return { |
| start: parse(start).startOf('day').toDate(), |
| end: parse(end).endOf('day').toDate() |
| }; |
| } |
| }; |
| } |
| |
| var afterEq = compareBuilder(function (left, right) { return left >= right; }); |
| var after = compareBuilder(function (left, right) { return left > right; }); |
| var beforeEq = compareBuilder(function (left, right) { return left <= right; }); |
| var before = compareBuilder(function (left, right) { return left < right; }); |
| |
| var except = rangeBuilder('every', function (left, right) { return right.start > left || right.end < left; }); |
| var only = rangeBuilder('some', function (left, right) { return right.start <= left && right.end >= left; }); |
| |
| module.exports = { |
| afterEq: afterEq, |
| after: after, |
| beforeEq: beforeEq, |
| before: before, |
| except: except, |
| only: only |
| }; |
| |
| },{"./association":6,"./index":14,"./parse":20}]},{},[31]) |
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9Vc2Vycy9uaWNvL2Rldi9yb21lL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCIvVXNlcnMvbmljby9kZXYvcm9tZS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcHJvY2Vzcy9icm93c2VyLmpzIiwiL1VzZXJzL25pY28vZGV2L3JvbWUvbm9kZV9tb2R1bGVzL2NvbnRyYS5lbWl0dGVyL2luZGV4LmpzIiwiL1VzZXJzL25pY28vZGV2L3JvbWUvbm9kZV9tb2R1bGVzL2NvbnRyYS5lbWl0dGVyL3NyYy9jb250cmEuZW1pdHRlci5qcyIsIi9Vc2Vycy9uaWNvL2Rldi9yb21lL25vZGVfbW9kdWxlcy9yYWYvaW5kZXguanMiLCIvVXNlcnMvbmljby9kZXYvcm9tZS9ub2RlX21vZHVsZXMvcmFmL25vZGVfbW9kdWxlcy9wZXJmb3JtYW5jZS1ub3cvbGliL3BlcmZvcm1hbmNlLW5vdy5qcyIsIi9Vc2Vycy9uaWNvL2Rldi9yb21lL3NyYy9hc3NvY2lhdGlvbi5qcyIsIi9Vc2Vycy9uaWNvL2Rldi9yb21lL3NyYy9jYWxlbmRhci5qcyIsIi9Vc2Vycy9uaWNvL2Rldi9yb21lL3NyYy9jbGFzc2VzLmpzIiwiL1VzZXJzL25pY28vZGV2L3JvbWUvc3JjL2Nsb25lLmpzIiwiL1VzZXJzL25pY28vZGV2L3JvbWUvc3JjL2NvcmUuanMiLCIvVXNlcnMvbmljby9kZXYvcm9tZS9zcmMvZGVmYXVsdHMuanMiLCIvVXNlcnMvbmljby9kZXYvcm9tZS9zcmMvZG9tLmpzIiwiL1VzZXJzL25pY28vZGV2L3JvbWUvc3JjL2V2ZW50cy5qcyIsIi9Vc2Vycy9uaWNvL2Rldi9yb21lL3NyYy9pbmRleC5qcyIsIi9Vc2Vycy9uaWNvL2Rldi9yb21lL3NyYy9pbmxpbmUuanMiLCIvVXNlcnMvbmljby9kZXYvcm9tZS9zcmMvaW5wdXQuanMiLCIvVXNlcnMvbmljby9kZXYvcm9tZS9zcmMvaXNJbnB1dC5qcyIsIi9Vc2Vycy9uaWNvL2Rldi9yb21lL3NyYy9tb21lbnR1bS5qcyIsIi9Vc2Vycy9uaWNvL2Rldi9yb21lL3NyYy9ub29wLmpzIiwiL1VzZXJzL25pY28vZGV2L3JvbWUvc3JjL3BhcnNlLmpzIiwiL1VzZXJzL25pY28vZGV2L3JvbWUvc3JjL3BvbHlmaWxscy9hcnJheS5maWx0ZXIuanMiLCIvVXNlcnMvbmljby9kZXYvcm9tZS9zcmMvcG9seWZpbGxzL2FycmF5LmZvcmVhY2guanMiLCIvVXNlcnMvbmljby9kZXYvcm9tZS9zcmMvcG9seWZpbGxzL2FycmF5LmluZGV4b2YuanMiLCIvVXNlcnMvbmljby9kZXYvcm9tZS9zcmMvcG9seWZpbGxzL2FycmF5LmlzYXJyYXkuanMiLCIvVXNlcnMvbmljby9kZXYvcm9tZS9zcmMvcG9seWZpbGxzL2FycmF5Lm1hcC5qcyIsIi9Vc2Vycy9uaWNvL2Rldi9yb21lL3NyYy9wb2x5ZmlsbHMvYXJyYXkuc29tZS5qcyIsIi9Vc2Vycy9uaWNvL2Rldi9yb21lL3NyYy9wb2x5ZmlsbHMvZnVuY3Rpb24uYmluZC5qcyIsIi9Vc2Vycy9uaWNvL2Rldi9yb21lL3NyYy9wb2x5ZmlsbHMvb2JqZWN0LmtleXMuanMiLCIvVXNlcnMvbmljby9kZXYvcm9tZS9zcmMvcG9seWZpbGxzL3N0cmluZy50cmltLmpzIiwiL1VzZXJzL25pY28vZGV2L3JvbWUvc3JjL3JvbWUuanMiLCIvVXNlcnMvbmljby9kZXYvcm9tZS9zcmMvcm9tZS5zdGFuZGFsb25lLmpzIiwiL1VzZXJzL25pY28vZGV2L3JvbWUvc3JjL3RleHQuanMiLCIvVXNlcnMvbmljby9kZXYvcm9tZS9zcmMvdGhyb3R0bGUuanMiLCIvVXNlcnMvbmljby9kZXYvcm9tZS9zcmMvdXNlLmpzIiwiL1VzZXJzL25pY28vZGV2L3JvbWUvc3JjL3ZhbGlkYXRvcnMuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvREE7QUFDQTs7QUNEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0VBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcElBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNYQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dGhyb3cgbmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKX12YXIgZj1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwoZi5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxmLGYuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc30pIiwiLy8gc2hpbSBmb3IgdXNpbmcgcHJvY2VzcyBpbiBicm93c2VyXG5cbnZhciBwcm9jZXNzID0gbW9kdWxlLmV4cG9ydHMgPSB7fTtcblxucHJvY2Vzcy5uZXh0VGljayA9IChmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGNhblNldEltbWVkaWF0ZSA9IHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnXG4gICAgJiYgd2luZG93LnNldEltbWVkaWF0ZTtcbiAgICB2YXIgY2FuUG9zdCA9IHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnXG4gICAgJiYgd2luZG93LnBvc3RNZXNzYWdlICYmIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyXG4gICAgO1xuXG4gICAgaWYgKGNhblNldEltbWVkaWF0ZSkge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKGYpIHsgcmV0dXJuIHdpbmRvdy5zZXRJbW1lZGlhdGUoZikgfTtcbiAgICB9XG5cbiAgICBpZiAoY2FuUG9zdCkge1xuICAgICAgICB2YXIgcXVldWUgPSBbXTtcbiAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBmdW5jdGlvbiAoZXYpIHtcbiAgICAgICAgICAgIHZhciBzb3VyY2UgPSBldi5zb3VyY2U7XG4gICAgICAgICAgICBpZiAoKHNvdXJjZSA9PT0gd2luZG93IHx8IHNvdXJjZSA9PT0gbnVsbCkgJiYgZXYuZGF0YSA9PT0gJ3Byb2Nlc3MtdGljaycpIHtcbiAgICAgICAgICAgICAgICBldi5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICAgICAgICBpZiAocXVldWUubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgZm4gPSBxdWV1ZS5zaGlmdCgpO1xuICAgICAgICAgICAgICAgICAgICBmbigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSwgdHJ1ZSk7XG5cbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIG5leHRUaWNrKGZuKSB7XG4gICAgICAgICAgICBxdWV1ZS5wdXNoKGZuKTtcbiAgICAgICAgICAgIHdpbmRvdy5wb3N0TWVzc2FnZSgncHJvY2Vzcy10aWNrJywgJyonKTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICByZXR1cm4gZnVuY3Rpb24gbmV4dFRpY2soZm4pIHtcbiAgICAgICAgc2V0VGltZW91dChmbiwgMCk7XG4gICAgfTtcbn0pKCk7XG5cbnByb2Nlc3MudGl0bGUgPSAnYnJvd3Nlcic7XG5wcm9jZXNzLmJyb3dzZXIgPSB0cnVlO1xucHJvY2Vzcy5lbnYgPSB7fTtcbnByb2Nlc3MuYXJndiA9IFtdO1xuXG5mdW5jdGlvbiBub29wKCkge31cblxucHJvY2Vzcy5vbiA9IG5vb3A7XG5wcm9jZXNzLmFkZExpc3RlbmVyID0gbm9vcDtcbnByb2Nlc3Mub25jZSA9IG5vb3A7XG5wcm9jZXNzLm9mZiA9IG5vb3A7XG5wcm9jZXNzLnJlbW92ZUxpc3RlbmVyID0gbm9vcDtcbnByb2Nlc3MucmVtb3ZlQWxsTGlzdGVuZXJzID0gbm9vcDtcbnByb2Nlc3MuZW1pdCA9IG5vb3A7XG5cbnByb2Nlc3MuYmluZGluZyA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwcm9jZXNzLmJpbmRpbmcgaXMgbm90IHN1cHBvcnRlZCcpO1xufVxuXG4vLyBUT0RPKHNodHlsbWFuKVxucHJvY2Vzcy5jd2QgPSBmdW5jdGlvbiAoKSB7IHJldHVybiAnLycgfTtcbnByb2Nlc3MuY2hkaXIgPSBmdW5jdGlvbiAoZGlyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwcm9jZXNzLmNoZGlyIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn07XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vc3JjL2NvbnRyYS5lbWl0dGVyLmpzJyk7XG4iLCIoZnVuY3Rpb24gKHByb2Nlc3Mpe1xuKGZ1bmN0aW9uIChyb290LCB1bmRlZmluZWQpIHtcbiAgJ3VzZSBzdHJpY3QnO1xuXG4gIHZhciB1bmRlZiA9ICcnICsgdW5kZWZpbmVkO1xuICBmdW5jdGlvbiBhdG9hIChhLCBuKSB7IHJldHVybiBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhLCBuKTsgfVxuICBmdW5jdGlvbiBkZWJvdW5jZSAoZm4sIGFyZ3MsIGN0eCkgeyBpZiAoIWZuKSB7IHJldHVybjsgfSB0aWNrKGZ1bmN0aW9uIHJ1biAoKSB7IGZuLmFwcGx5KGN0eCB8fCBudWxsLCBhcmdzIHx8IFtdKTsgfSk7IH1cblxuICAvLyBjcm9zcy1wbGF0Zm9ybSB0aWNrZXJcbiAgdmFyIHNpID0gdHlwZW9mIHNldEltbWVkaWF0ZSA9PT0gJ2Z1bmN0aW9uJywgdGljaztcbiAgaWYgKHNpKSB7XG4gICAgdGljayA9IGZ1bmN0aW9uIChmbikgeyBzZXRJbW1lZGlhdGUoZm4pOyB9O1xuICB9IGVsc2UgaWYgKHR5cGVvZiBwcm9jZXNzICE9PSB1bmRlZiAmJiBwcm9jZXNzLm5leHRUaWNrKSB7XG4gICAgdGljayA9IHByb2Nlc3MubmV4dFRpY2s7XG4gIH0gZWxzZSB7XG4gICAgdGljayA9IGZ1bmN0aW9uIChmbikgeyBzZXRUaW1lb3V0KGZuLCAwKTsgfTtcbiAgfVxuXG4gIGZ1bmN0aW9uIF9lbWl0dGVyICh0aGluZywgb3B0aW9ucykge1xuICAgIHZhciBvcHRzID0gb3B0aW9ucyB8fCB7fTtcbiAgICB2YXIgZXZ0ID0ge307XG4gICAgaWYgKHRoaW5nID09PSB1bmRlZmluZWQpIHsgdGhpbmcgPSB7fTsgfVxuICAgIHRoaW5nLm9uID0gZnVuY3Rpb24gKHR5cGUsIGZuKSB7XG4gICAgICBpZiAoIWV2dFt0eXBlXSkge1xuICAgICAgICBldnRbdHlwZV0gPSBbZm5dO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZXZ0W3R5cGVdLnB1c2goZm4pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaW5nO1xuICAgIH07XG4gICAgdGhpbmcub25jZSA9IGZ1bmN0aW9uICh0eXBlLCBmbikge1xuICAgICAgZm4uX29uY2UgPSB0cnVlOyAvLyB0aGluZy5vZmYoZm4pIHN0aWxsIHdvcmtzIVxuICAgICAgdGhpbmcub24odHlwZSwgZm4pO1xuICAgICAgcmV0dXJuIHRoaW5nO1xuICAgIH07XG4gICAgdGhpbmcub2ZmID0gZnVuY3Rpb24gKHR5cGUsIGZuKSB7XG4gICAgICB2YXIgYyA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gICAgICBpZiAoYyA9PT0gMSkge1xuICAgICAgICBkZWxldGUgZXZ0W3R5cGVdO1xuICAgICAgfSBlbHNlIGlmIChjID09PSAwKSB7XG4gICAgICAgIGV2dCA9IHt9O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIGV0ID0gZXZ0W3R5cGVdO1xuICAgICAgICBpZiAoIWV0KSB7IHJldHVybiB0aGluZzsgfVxuICAgICAgICBldC5zcGxpY2UoZXQuaW5kZXhPZihmbiksIDEpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaW5nO1xuICAgIH07XG4gICAgdGhpbmcuZW1pdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBhcmdzID0gYXRvYShhcmd1bWVudHMpO1xuICAgICAgcmV0dXJuIHRoaW5nLmVtaXR0ZXJTbmFwc2hvdChhcmdzLnNoaWZ0KCkpLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgIH07XG4gICAgdGhpbmcuZW1pdHRlclNuYXBzaG90ID0gZnVuY3Rpb24gKHR5cGUpIHtcbiAgICAgIHZhciBldCA9IChldnRbdHlwZV0gfHwgW10pLnNsaWNlKDApO1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGFyZ3MgPSBhdG9hKGFyZ3VtZW50cyk7XG4gICAgICAgIHZhciBjdHggPSB0aGlzIHx8IHRoaW5nO1xuICAgICAgICBpZiAodHlwZSA9PT0gJ2Vycm9yJyAmJiBvcHRzLnRocm93cyAhPT0gZmFsc2UgJiYgIWV0Lmxlbmd0aCkgeyB0aHJvdyBhcmdzLmxlbmd0aCA9PT0gMSA/IGFyZ3NbMF0gOiBhcmdzOyB9XG4gICAgICAgIGV2dFt0eXBlXSA9IGV0LmZpbHRlcihmdW5jdGlvbiBlbWl0dGVyIChsaXN0ZW4pIHtcbiAgICAgICAgICBpZiAob3B0cy5hc3luYykgeyBkZWJvdW5jZShsaXN0ZW4sIGFyZ3MsIGN0eCk7IH0gZWxzZSB7IGxpc3Rlbi5hcHBseShjdHgsIGFyZ3MpOyB9XG4gICAgICAgICAgcmV0dXJuICFsaXN0ZW4uX29uY2U7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdGhpbmc7XG4gICAgICB9O1xuICAgIH1cbiAgICByZXR1cm4gdGhpbmc7XG4gIH1cblxuICAvLyBjcm9zcy1wbGF0Zm9ybSBleHBvcnRcbiAgaWYgKHR5cGVvZiBtb2R1bGUgIT09IHVuZGVmICYmIG1vZHVsZS5leHBvcnRzKSB7XG4gICAgbW9kdWxlLmV4cG9ydHMgPSBfZW1pdHRlcjtcbiAgfSBlbHNlIHtcbiAgICByb290LmNvbnRyYSA9IHJvb3QuY29udHJhIHx8IHt9O1xuICAgIHJvb3QuY29udHJhLmVtaXR0ZXIgPSBfZW1pdHRlcjtcbiAgfVxufSkodGhpcyk7XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwiRldhQVNIXCIpKSIsInZhciBub3cgPSByZXF1aXJlKCdwZXJmb3JtYW5jZS1ub3cnKVxuICAsIGdsb2JhbCA9IHR5cGVvZiB3aW5kb3cgPT09ICd1bmRlZmluZWQnID8ge30gOiB3aW5kb3dcbiAgLCB2ZW5kb3JzID0gWydtb3onLCAnd2Via2l0J11cbiAgLCBzdWZmaXggPSAnQW5pbWF0aW9uRnJhbWUnXG4gICwgcmFmID0gZ2xvYmFsWydyZXF1ZXN0JyArIHN1ZmZpeF1cbiAgLCBjYWYgPSBnbG9iYWxbJ2NhbmNlbCcgKyBzdWZmaXhdIHx8IGdsb2JhbFsnY2FuY2VsUmVxdWVzdCcgKyBzdWZmaXhdXG4gICwgaXNOYXRpdmUgPSB0cnVlXG5cbmZvcih2YXIgaSA9IDA7IGkgPCB2ZW5kb3JzLmxlbmd0aCAmJiAhcmFmOyBpKyspIHtcbiAgcmFmID0gZ2xvYmFsW3ZlbmRvcnNbaV0gKyAnUmVxdWVzdCcgKyBzdWZmaXhdXG4gIGNhZiA9IGdsb2JhbFt2ZW5kb3JzW2ldICsgJ0NhbmNlbCcgKyBzdWZmaXhdXG4gICAgICB8fCBnbG9iYWxbdmVuZG9yc1tpXSArICdDYW5jZWxSZXF1ZXN0JyArIHN1ZmZpeF1cbn1cblxuLy8gU29tZSB2ZXJzaW9ucyBvZiBGRiBoYXZlIHJBRiBidXQgbm90IGNBRlxuaWYoIXJhZiB8fCAhY2FmKSB7XG4gIGlzTmF0aXZlID0gZmFsc2VcblxuICB2YXIgbGFzdCA9IDBcbiAgICAsIGlkID0gMFxuICAgICwgcXVldWUgPSBbXVxuICAgICwgZnJhbWVEdXJhdGlvbiA9IDEwMDAgLyA2MFxuXG4gIHJhZiA9IGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG4gICAgaWYocXVldWUubGVuZ3RoID09PSAwKSB7XG4gICAgICB2YXIgX25vdyA9IG5vdygpXG4gICAgICAgICwgbmV4dCA9IE1hdGgubWF4KDAsIGZyYW1lRHVyYXRpb24gLSAoX25vdyAtIGxhc3QpKVxuICAgICAgbGFzdCA9IG5leHQgKyBfbm93XG4gICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgY3AgPSBxdWV1ZS5zbGljZSgwKVxuICAgICAgICAvLyBDbGVhciBxdWV1ZSBoZXJlIHRvIHByZXZlbnRcbiAgICAgICAgLy8gY2FsbGJhY2tzIGZyb20gYXBwZW5kaW5nIGxpc3RlbmVyc1xuICAgICAgICAvLyB0byB0aGUgY3VycmVudCBmcmFtZSdzIHF1ZXVlXG4gICAgICAgIHF1ZXVlLmxlbmd0aCA9IDBcbiAgICAgICAgZm9yKHZhciBpID0gMDsgaSA8IGNwLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgaWYoIWNwW2ldLmNhbmNlbGxlZCkge1xuICAgICAgICAgICAgdHJ5e1xuICAgICAgICAgICAgICBjcFtpXS5jYWxsYmFjayhsYXN0KVxuICAgICAgICAgICAgfSBjYXRjaChlKSB7XG4gICAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7IHRocm93IGUgfSwgMClcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0sIE1hdGgucm91bmQobmV4dCkpXG4gICAgfVxuICAgIHF1ZXVlLnB1c2goe1xuICAgICAgaGFuZGxlOiArK2lkLFxuICAgICAgY2FsbGJhY2s6IGNhbGxiYWNrLFxuICAgICAgY2FuY2VsbGVkOiBmYWxzZVxuICAgIH0pXG4gICAgcmV0dXJuIGlkXG4gIH1cblxuICBjYWYgPSBmdW5jdGlvbihoYW5kbGUpIHtcbiAgICBmb3IodmFyIGkgPSAwOyBpIDwgcXVldWUubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmKHF1ZXVlW2ldLmhhbmRsZSA9PT0gaGFuZGxlKSB7XG4gICAgICAgIHF1ZXVlW2ldLmNhbmNlbGxlZCA9IHRydWVcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihmbikge1xuICAvLyBXcmFwIGluIGEgbmV3IGZ1bmN0aW9uIHRvIHByZXZlbnRcbiAgLy8gYGNhbmNlbGAgcG90ZW50aWFsbHkgYmVpbmcgYXNzaWduZWRcbiAgLy8gdG8gdGhlIG5hdGl2ZSByQUYgZnVuY3Rpb25cbiAgaWYoIWlzTmF0aXZlKSB7XG4gICAgcmV0dXJuIHJhZi5jYWxsKGdsb2JhbCwgZm4pXG4gIH1cbiAgcmV0dXJuIHJhZi5jYWxsKGdsb2JhbCwgZnVuY3Rpb24oKSB7XG4gICAgdHJ5e1xuICAgICAgZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKVxuICAgIH0gY2F0Y2goZSkge1xuICAgICAgc2V0VGltZW91dChmdW5jdGlvbigpIHsgdGhyb3cgZSB9LCAwKVxuICAgIH1cbiAgfSlcbn1cbm1vZHVsZS5leHBvcnRzLmNhbmNlbCA9IGZ1bmN0aW9uKCkge1xuICBjYWYuYXBwbHkoZ2xvYmFsLCBhcmd1bWVudHMpXG59XG4iLCIoZnVuY3Rpb24gKHByb2Nlc3Mpe1xuLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjYuM1xuKGZ1bmN0aW9uKCkge1xuICB2YXIgZ2V0TmFub1NlY29uZHMsIGhydGltZSwgbG9hZFRpbWU7XG5cbiAgaWYgKCh0eXBlb2YgcGVyZm9ybWFuY2UgIT09IFwidW5kZWZpbmVkXCIgJiYgcGVyZm9ybWFuY2UgIT09IG51bGwpICYmIHBlcmZvcm1hbmNlLm5vdykge1xuICAgIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gcGVyZm9ybWFuY2Uubm93KCk7XG4gICAgfTtcbiAgfSBlbHNlIGlmICgodHlwZW9mIHByb2Nlc3MgIT09IFwidW5kZWZpbmVkXCIgJiYgcHJvY2VzcyAhPT0gbnVsbCkgJiYgcHJvY2Vzcy5ocnRpbWUpIHtcbiAgICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIChnZXROYW5vU2Vjb25kcygpIC0gbG9hZFRpbWUpIC8gMWU2O1xuICAgIH07XG4gICAgaHJ0aW1lID0gcHJvY2Vzcy5ocnRpbWU7XG4gICAgZ2V0TmFub1NlY29uZHMgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBocjtcbiAgICAgIGhyID0gaHJ0aW1lKCk7XG4gICAgICByZXR1cm4gaHJbMF0gKiAxZTkgKyBoclsxXTtcbiAgICB9O1xuICAgIGxvYWRUaW1lID0gZ2V0TmFub1NlY29uZHMoKTtcbiAgfSBlbHNlIGlmIChEYXRlLm5vdykge1xuICAgIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gRGF0ZS5ub3coKSAtIGxvYWRUaW1lO1xuICAgIH07XG4gICAgbG9hZFRpbWUgPSBEYXRlLm5vdygpO1xuICB9IGVsc2Uge1xuICAgIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gbmV3IERhdGUoKS5nZXRUaW1lKCkgLSBsb2FkVGltZTtcbiAgICB9O1xuICAgIGxvYWRUaW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gIH1cblxufSkuY2FsbCh0aGlzKTtcblxuLypcbi8vQCBzb3VyY2VNYXBwaW5nVVJMPXBlcmZvcm1hbmNlLW5vdy5tYXBcbiovXG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwiRldhQVNIXCIpKSIsIid1c2Ugc3RyaWN0JztcblxudmFyIGlzSW5wdXQgPSByZXF1aXJlKCcuL2lzSW5wdXQnKTtcbnZhciBiaW5kaW5ncyA9IHt9O1xuXG5mdW5jdGlvbiBoYXMgKHNvdXJjZSwgdGFyZ2V0KSB7XG4gIHZhciBiaW5kaW5nID0gYmluZGluZ3Nbc291cmNlLmlkXTtcbiAgcmV0dXJuIGJpbmRpbmcgJiYgYmluZGluZ1t0YXJnZXQuaWRdO1xufVxuXG5mdW5jdGlvbiBpbnNlcnQgKHNvdXJjZSwgdGFyZ2V0KSB7XG4gIHZhciBiaW5kaW5nID0gYmluZGluZ3Nbc291cmNlLmlkXTtcbiAgaWYgKCFiaW5kaW5nKSB7XG4gICAgYmluZGluZyA9IGJpbmRpbmdzW3NvdXJjZS5pZF0gPSB7fTtcbiAgfVxuICB2YXIgaW52YWxpZGF0ZSA9IGludmFsaWRhdG9yKHRhcmdldCk7XG4gIGJpbmRpbmdbdGFyZ2V0LmlkXSA9IGludmFsaWRhdGU7XG4gIHNvdXJjZS5vbignZGF0YScsIGludmFsaWRhdGUpO1xuICBzb3VyY2Uub24oJ2Rlc3Ryb3llZCcsIHJlbW92ZS5iaW5kKG51bGwsIHNvdXJjZSwgdGFyZ2V0KSk7XG59XG5cbmZ1bmN0aW9uIHJlbW92ZSAoc291cmNlLCB0YXJnZXQpIHtcbiAgdmFyIGJpbmRpbmcgPSBiaW5kaW5nc1tzb3VyY2UuaWRdO1xuICBpZiAoIWJpbmRpbmcpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgdmFyIGludmFsaWRhdGUgPSBiaW5kaW5nW3RhcmdldC5pZF07XG4gIHNvdXJjZS5vZmYoJ2RhdGEnLCBpbnZhbGlkYXRlKTtcbiAgZGVsZXRlIGJpbmRpbmdbdGFyZ2V0LmlkXTtcbn1cblxuZnVuY3Rpb24gaW52YWxpZGF0b3IgKHRhcmdldCkge1xuICByZXR1cm4gZnVuY3Rpb24gaW52YWxpZGF0ZSAoKSB7XG4gICAgdGFyZ2V0LnJlZnJlc2goKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gYWRkIChzb3VyY2UsIHRhcmdldCkge1xuICBpZiAoaXNJbnB1dCh0YXJnZXQuYXNzb2NpYXRlZCkgfHwgaGFzKHNvdXJjZSwgdGFyZ2V0KSkge1xuICAgIHJldHVybjtcbiAgfVxuICBpbnNlcnQoc291cmNlLCB0YXJnZXQpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgYWRkOiBhZGQsXG4gIHJlbW92ZTogcmVtb3ZlXG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgZW1pdHRlciA9IHJlcXVpcmUoJ2NvbnRyYS5lbWl0dGVyJyk7XG52YXIgcmFmID0gcmVxdWlyZSgncmFmJyk7XG52YXIgZG9tID0gcmVxdWlyZSgnLi9kb20nKTtcbnZhciB0ZXh0ID0gcmVxdWlyZSgnLi90ZXh0Jyk7XG52YXIgcGFyc2UgPSByZXF1aXJlKCcuL3BhcnNlJyk7XG52YXIgY2xvbmUgPSByZXF1aXJlKCcuL2Nsb25lJyk7XG52YXIgZGVmYXVsdHMgPSByZXF1aXJlKCcuL2RlZmF1bHRzJyk7XG52YXIgbW9tZW50dW0gPSByZXF1aXJlKCcuL21vbWVudHVtJyk7XG52YXIgY2xhc3NlcyA9IHJlcXVpcmUoJy4vY2xhc3NlcycpO1xudmFyIGV2ZW50cyA9IHJlcXVpcmUoJy4vZXZlbnRzJyk7XG52YXIgbm9vcCA9IHJlcXVpcmUoJy4vbm9vcCcpO1xudmFyIG5vO1xuXG5mdW5jdGlvbiBjYWxlbmRhciAoY2FsZW5kYXJPcHRpb25zKSB7XG4gIHZhciBvO1xuICB2YXIgYXBpID0gZW1pdHRlcih7fSk7XG4gIHZhciByZWY7XG4gIHZhciByZWZDYWw7XG4gIHZhciBjb250YWluZXI7XG4gIHZhciByZW5kZXJlZCA9IGZhbHNlO1xuXG4gIC8vIGRhdGUgdmFyaWFibGVzXG4gIHZhciBtb250aE9mZnNldEF0dHJpYnV0ZSA9ICdkYXRhLXJvbWUtb2Zmc2V0JztcbiAgdmFyIHdlZWtkYXlzO1xuICB2YXIgd2Vla2RheUNvdW50O1xuICB2YXIgY2FsZW5kYXJNb250aHMgPSBbXTtcbiAgdmFyIGxhc3RZZWFyO1xuICB2YXIgbGFzdE1vbnRoO1xuICB2YXIgbGFzdERheTtcbiAgdmFyIGxhc3REYXlFbGVtZW50O1xuICB2YXIgZGF0ZXdyYXBwZXI7XG4gIHZhciBiYWNrO1xuICB2YXIgbmV4dDtcblxuICAvLyB0aW1lIHZhcmlhYmxlc1xuICB2YXIgc2Vjb25kc0luRGF5ID0gNjAgKiA2MCAqIDI0O1xuICB2YXIgdGltZTtcbiAgdmFyIHRpbWVsaXN0O1xuXG4gIGluaXQoKTtcbiAgcmFmKHJlYWR5KTtcblxuICByZXR1cm4gYXBpO1xuXG4gIGZ1bmN0aW9uIG5hcGkgKCkgeyByZXR1cm4gYXBpOyB9XG5cbiAgZnVuY3Rpb24gaW5pdCAoaW5pdE9wdGlvbnMpIHtcbiAgICBvID0gZGVmYXVsdHMoaW5pdE9wdGlvbnMgfHwgY2FsZW5kYXJPcHRpb25zLCBhcGkpO1xuICAgIGlmICghY29udGFpbmVyKSB7IGNvbnRhaW5lciA9IGRvbSh7IGNsYXNzTmFtZTogby5zdHlsZXMuY29udGFpbmVyIH0pOyB9XG4gICAgd2Vla2RheXMgPSBvLndlZWtkYXlGb3JtYXQ7XG4gICAgd2Vla2RheUNvdW50ID0gd2Vla2RheXMubGVuZ3RoO1xuICAgIGxhc3RNb250aCA9IG5vO1xuICAgIGxhc3RZZWFyID0gbm87XG4gICAgbGFzdERheSA9IG5vO1xuICAgIGxhc3REYXlFbGVtZW50ID0gbm87XG4gICAgby5hcHBlbmRUby5hcHBlbmRDaGlsZChjb250YWluZXIpO1xuXG4gICAgcmVtb3ZlQ2hpbGRyZW4oY29udGFpbmVyKTtcbiAgICByZW5kZXJlZCA9IGZhbHNlO1xuICAgIHJlZiA9IG8uaW5pdGlhbFZhbHVlID8gby5pbml0aWFsVmFsdWUgOiBtb21lbnR1bS5tb21lbnQoKTtcbiAgICByZWZDYWwgPSByZWYuY2xvbmUoKTtcblxuICAgIGFwaS5jb250YWluZXIgPSBjb250YWluZXI7XG4gICAgYXBpLmRlc3Ryb3llZCA9IGZhbHNlO1xuICAgIGFwaS5kZXN0cm95ID0gZGVzdHJveS5iaW5kKGFwaSwgZmFsc2UpO1xuICAgIGFwaS5lbWl0VmFsdWVzID0gZW1pdFZhbHVlcztcbiAgICBhcGkuZ2V0RGF0ZSA9IGdldERhdGU7XG4gICAgYXBpLmdldERhdGVTdHJpbmcgPSBnZXREYXRlU3RyaW5nO1xuICAgIGFwaS5nZXRNb21lbnQgPSBnZXRNb21lbnQ7XG4gICAgYXBpLmhpZGUgPSBoaWRlO1xuICAgIGFwaS5vcHRpb25zID0gY2hhbmdlT3B0aW9ucztcbiAgICBhcGkub3B0aW9ucy5yZXNldCA9IHJlc2V0T3B0aW9ucztcbiAgICBhcGkucmVmcmVzaCA9IHJlZnJlc2g7XG4gICAgYXBpLnJlc3RvcmUgPSBuYXBpO1xuICAgIGFwaS5zZXRWYWx1ZSA9IHNldFZhbHVlO1xuICAgIGFwaS5zaG93ID0gc2hvdztcblxuICAgIHNob3coKTtcbiAgICBldmVudExpc3RlbmluZygpO1xuICAgIHJlYWR5KCk7XG5cbiAgICByZXR1cm4gYXBpO1xuICB9XG5cbiAgZnVuY3Rpb24gcmVhZHkgKCkge1xuICAgIGFwaS5lbWl0KCdyZWFkeScsIGNsb25lKG8pKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGRlc3Ryb3kgKHNpbGVudCkge1xuICAgIGlmIChjb250YWluZXIpIHtcbiAgICAgIGNvbnRhaW5lci5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKGNvbnRhaW5lcik7XG4gICAgfVxuXG4gICAgaWYgKG8pIHtcbiAgICAgIGV2ZW50TGlzdGVuaW5nKHRydWUpO1xuICAgIH1cblxuICAgIHZhciBkZXN0cm95ZWQgPSBhcGkuZW1pdHRlclNuYXBzaG90KCdkZXN0cm95ZWQnKTtcbiAgICBhcGkuZGVzdHJveWVkID0gdHJ1ZTtcbiAgICBhcGkuZGVzdHJveSA9IG5hcGk7XG4gICAgYXBpLmVtaXRWYWx1ZXMgPSBuYXBpO1xuICAgIGFwaS5nZXREYXRlID0gbm9vcDtcbiAgICBhcGkuZ2V0RGF0ZVN0cmluZyA9IG5vb3A7XG4gICAgYXBpLmdldE1vbWVudCA9IG5vb3A7XG4gICAgYXBpLmhpZGUgPSBuYXBpO1xuICAgIGFwaS5vcHRpb25zID0gbmFwaTtcbiAgICBhcGkub3B0aW9ucy5yZXNldCA9IG5hcGk7XG4gICAgYXBpLnJlZnJlc2ggPSBuYXBpO1xuICAgIGFwaS5yZXN0b3JlID0gaW5pdDtcbiAgICBhcGkuc2V0VmFsdWUgPSBuYXBpO1xuICAgIGFwaS5zaG93ID0gbmFwaTtcbiAgICBhcGkub2ZmKCk7XG5cbiAgICBpZiAoc2lsZW50ICE9PSB0cnVlKSB7XG4gICAgICBkZXN0cm95ZWQoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXBpO1xuICB9XG5cbiAgZnVuY3Rpb24gZXZlbnRMaXN0ZW5pbmcgKHJlbW92ZSkge1xuICAgIHZhciBvcCA9IHJlbW92ZSA/ICdyZW1vdmUnIDogJ2FkZCc7XG4gICAgaWYgKG8uYXV0b0hpZGVPbkJsdXIpIHsgZXZlbnRzW29wXShkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQsICdmb2N1cycsIGhpZGVPbkJsdXIsIHRydWUpOyB9XG4gICAgaWYgKG8uYXV0b0hpZGVPbkNsaWNrKSB7IGV2ZW50c1tvcF0oZG9jdW1lbnQsICdjbGljaycsIGhpZGVPbkNsaWNrKTsgfVxuICB9XG5cbiAgZnVuY3Rpb24gY2hhbmdlT3B0aW9ucyAob3B0aW9ucykge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gY2xvbmUobyk7XG4gICAgfVxuICAgIGRlc3Ryb3koKTtcbiAgICBpbml0KG9wdGlvbnMpO1xuICAgIHJldHVybiBhcGk7XG4gIH1cblxuICBmdW5jdGlvbiByZXNldE9wdGlvbnMgKCkge1xuICAgIHJldHVybiBjaGFuZ2VPcHRpb25zKHsgYXBwZW5kVG86IG8uYXBwZW5kVG8gfSk7XG4gIH1cblxuICBmdW5jdGlvbiByZW5kZXIgKCkge1xuICAgIGlmIChyZW5kZXJlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICByZW5kZXJlZCA9IHRydWU7XG4gICAgcmVuZGVyRGF0ZXMoKTtcbiAgICByZW5kZXJUaW1lKCk7XG4gICAgYXBpLmVtaXQoJ3JlbmRlcicpO1xuICB9XG5cbiAgZnVuY3Rpb24gcmVuZGVyRGF0ZXMgKCkge1xuICAgIGlmICghby5kYXRlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHZhciBpO1xuICAgIGNhbGVuZGFyTW9udGhzID0gW107XG5cbiAgICBkYXRld3JhcHBlciA9IGRvbSh7IGNsYXNzTmFtZTogby5zdHlsZXMuZGF0ZSwgcGFyZW50OiBjb250YWluZXIgfSk7XG5cbiAgICBmb3IgKGkgPSAwOyBpIDwgby5tb250aHNJbkNhbGVuZGFyOyBpKyspIHtcbiAgICAgIHJlbmRlck1vbnRoKGkpO1xuICAgIH1cblxuICAgIGV2ZW50cy5hZGQoYmFjaywgJ2NsaWNrJywgc3VidHJhY3RNb250aCk7XG4gICAgZXZlbnRzLmFkZChuZXh0LCAnY2xpY2snLCBhZGRNb250aCk7XG4gICAgZXZlbnRzLmFkZChkYXRld3JhcHBlciwgJ2NsaWNrJywgcGlja0RheSk7XG5cbiAgICBmdW5jdGlvbiByZW5kZXJNb250aCAoaSkge1xuICAgICAgdmFyIG1vbnRoID0gZG9tKHsgY2xhc3NOYW1lOiBvLnN0eWxlcy5tb250aCwgcGFyZW50OiBkYXRld3JhcHBlciB9KTtcbiAgICAgIGlmIChpID09PSAwKSB7XG4gICAgICAgIGJhY2sgPSBkb20oeyB0eXBlOiAnYnV0dG9uJywgY2xhc3NOYW1lOiBvLnN0eWxlcy5iYWNrLCBhdHRyaWJ1dGVzOiB7IHR5cGU6ICdidXR0b24nIH0sIHBhcmVudDogbW9udGggfSk7XG4gICAgICB9XG4gICAgICBpZiAoaSA9PT0gby5tb250aHNJbkNhbGVuZGFyIC0xKSB7XG4gICAgICAgIG5leHQgPSBkb20oeyB0eXBlOiAnYnV0dG9uJywgY2xhc3NOYW1lOiBvLnN0eWxlcy5uZXh0LCBhdHRyaWJ1dGVzOiB7IHR5cGU6ICdidXR0b24nIH0sIHBhcmVudDogbW9udGggfSk7XG4gICAgICB9XG4gICAgICB2YXIgbGFiZWwgPSBkb20oeyBjbGFzc05hbWU6IG8uc3R5bGVzLm1vbnRoTGFiZWwsIHBhcmVudDogbW9udGggfSk7XG4gICAgICB2YXIgZGF0ZSA9IGRvbSh7IHR5cGU6ICd0YWJsZScsIGNsYXNzTmFtZTogby5zdHlsZXMuZGF5VGFibGUsIHBhcmVudDogbW9udGggfSk7XG4gICAgICB2YXIgZGF0ZWhlYWQgPSBkb20oeyB0eXBlOiAndGhlYWQnLCBjbGFzc05hbWU6IG8uc3R5bGVzLmRheUhlYWQsIHBhcmVudDogZGF0ZSB9KTtcbiAgICAgIHZhciBkYXRlaGVhZHJvdyA9IGRvbSh7IHR5cGU6ICd0cicsIGNsYXNzTmFtZTogby5zdHlsZXMuZGF5Um93LCBwYXJlbnQ6IGRhdGVoZWFkIH0pO1xuICAgICAgdmFyIGRhdGVib2R5ID0gZG9tKHsgdHlwZTogJ3Rib2R5JywgY2xhc3NOYW1lOiBvLnN0eWxlcy5kYXlCb2R5LCBwYXJlbnQ6IGRhdGUgfSk7XG4gICAgICB2YXIgajtcblxuICAgICAgZm9yIChqID0gMDsgaiA8IHdlZWtkYXlDb3VudDsgaisrKSB7XG4gICAgICAgIGRvbSh7IHR5cGU6ICd0aCcsIGNsYXNzTmFtZTogby5zdHlsZXMuZGF5SGVhZEVsZW0sIHBhcmVudDogZGF0ZWhlYWRyb3csIHRleHQ6IHdlZWtkYXlzW3dlZWtkYXkoaildIH0pO1xuICAgICAgfVxuXG4gICAgICBkYXRlYm9keS5zZXRBdHRyaWJ1dGUobW9udGhPZmZzZXRBdHRyaWJ1dGUsIGkpO1xuICAgICAgY2FsZW5kYXJNb250aHMucHVzaCh7XG4gICAgICAgIGxhYmVsOiBsYWJlbCxcbiAgICAgICAgYm9keTogZGF0ZWJvZHlcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHJlbmRlclRpbWUgKCkge1xuICAgIGlmICghby50aW1lIHx8ICFvLnRpbWVJbnRlcnZhbCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB2YXIgdGltZXdyYXBwZXIgPSBkb20oeyBjbGFzc05hbWU6IG8uc3R5bGVzLnRpbWUsIHBhcmVudDogY29udGFpbmVyIH0pO1xuICAgIHRpbWUgPSBkb20oeyBjbGFzc05hbWU6IG8uc3R5bGVzLnNlbGVjdGVkVGltZSwgcGFyZW50OiB0aW1ld3JhcHBlciwgdGV4dDogcmVmLmZvcm1hdChvLnRpbWVGb3JtYXQpIH0pO1xuICAgIGV2ZW50cy5hZGQodGltZSwgJ2NsaWNrJywgdG9nZ2xlVGltZUxpc3QpO1xuICAgIHRpbWVsaXN0ID0gZG9tKHsgY2xhc3NOYW1lOiBvLnN0eWxlcy50aW1lTGlzdCwgcGFyZW50OiB0aW1ld3JhcHBlciB9KTtcbiAgICBldmVudHMuYWRkKHRpbWVsaXN0LCAnY2xpY2snLCBwaWNrVGltZSk7XG4gICAgdmFyIG5leHQgPSBtb21lbnR1bS5tb21lbnQoJzAwOjAwOjAwJywgJ0hIOm1tOnNzJyk7XG4gICAgdmFyIGxhdGVzdCA9IG5leHQuY2xvbmUoKS5hZGQoMSwgJ2RheXMnKTtcbiAgICB3aGlsZSAobmV4dC5pc0JlZm9yZShsYXRlc3QpKSB7XG4gICAgICBkb20oeyBjbGFzc05hbWU6IG8uc3R5bGVzLnRpbWVPcHRpb24sIHBhcmVudDogdGltZWxpc3QsIHRleHQ6IG5leHQuZm9ybWF0KG8udGltZUZvcm1hdCkgfSk7XG4gICAgICBuZXh0LmFkZChvLnRpbWVJbnRlcnZhbCwgJ3NlY29uZHMnKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiB3ZWVrZGF5IChpbmRleCwgYmFja3dhcmRzKSB7XG4gICAgdmFyIGZhY3RvciA9IGJhY2t3YXJkcyA/IC0xIDogMTtcbiAgICB2YXIgb2Zmc2V0ID0gaW5kZXggKyBvLndlZWtTdGFydCAqIGZhY3RvcjtcbiAgICBpZiAob2Zmc2V0ID49IHdlZWtkYXlDb3VudCB8fCBvZmZzZXQgPCAwKSB7XG4gICAgICBvZmZzZXQgKz0gd2Vla2RheUNvdW50ICogLWZhY3RvcjtcbiAgICB9XG4gICAgcmV0dXJuIG9mZnNldDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGRpc3BsYXlWYWxpZFRpbWVzT25seSAoKSB7XG4gICAgaWYgKCFvLnRpbWUgfHwgIXJlbmRlcmVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHZhciB0aW1lcyA9IHRpbWVsaXN0LmNoaWxkcmVuO1xuICAgIHZhciBsZW5ndGggPSB0aW1lcy5sZW5ndGg7XG4gICAgdmFyIGRhdGU7XG4gICAgdmFyIHRpbWU7XG4gICAgdmFyIGl0ZW07XG4gICAgdmFyIGk7XG4gICAgZm9yIChpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICBpdGVtID0gdGltZXNbaV07XG4gICAgICB0aW1lID0gbW9tZW50dW0ubW9tZW50KHRleHQoaXRlbSksIG8udGltZUZvcm1hdCk7XG4gICAgICBkYXRlID0gc2V0VGltZShyZWYuY2xvbmUoKSwgdGltZSk7XG4gICAgICBpdGVtLnN0eWxlLmRpc3BsYXkgPSBpc0luUmFuZ2UoZGF0ZSwgZmFsc2UsIG8udGltZVZhbGlkYXRvcikgPyAnYmxvY2snIDogJ25vbmUnO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHRvZ2dsZVRpbWVMaXN0IChzaG93KSB7XG4gICAgdmFyIGRpc3BsYXkgPSB0eXBlb2Ygc2hvdyA9PT0gJ2Jvb2xlYW4nID8gc2hvdyA6IHRpbWVsaXN0LnN0eWxlLmRpc3BsYXkgPT09ICdub25lJztcbiAgICBpZiAoZGlzcGxheSkge1xuICAgICAgc2hvd1RpbWVMaXN0KCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGhpZGVUaW1lTGlzdCgpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHNob3dUaW1lTGlzdCAoKSB7IGlmICh0aW1lbGlzdCkgeyB0aW1lbGlzdC5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJzsgfSB9XG4gIGZ1bmN0aW9uIGhpZGVUaW1lTGlzdCAoKSB7IGlmICh0aW1lbGlzdCkgeyB0aW1lbGlzdC5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnOyB9IH1cbiAgZnVuY3Rpb24gc2hvd0NhbGVuZGFyICgpIHsgY29udGFpbmVyLnN0eWxlLmRpc3BsYXkgPSAnaW5saW5lLWJsb2NrJzsgYXBpLmVtaXQoJ3Nob3cnKTsgfVxuICBmdW5jdGlvbiBoaWRlQ2FsZW5kYXIgKCkgeyBjb250YWluZXIuc3R5bGUuZGlzcGxheSA9ICdub25lJzsgYXBpLmVtaXQoJ2hpZGUnKTsgfVxuXG4gIGZ1bmN0aW9uIHNob3cgKCkge1xuICAgIHJlbmRlcigpO1xuICAgIHJlZnJlc2goKTtcbiAgICB0b2dnbGVUaW1lTGlzdCghby5kYXRlKTtcbiAgICBzaG93Q2FsZW5kYXIoKTtcbiAgICByZXR1cm4gYXBpO1xuICB9XG5cbiAgZnVuY3Rpb24gaGlkZSAoKSB7XG4gICAgaGlkZVRpbWVMaXN0KCk7XG4gICAgcmFmKGhpZGVDYWxlbmRhcik7XG4gICAgcmV0dXJuIGFwaTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGhpZGVDb25kaXRpb25hbGx5ICgpIHtcbiAgICBoaWRlVGltZUxpc3QoKTtcblxuICAgIHZhciBwb3MgPSBjbGFzc2VzLmNvbnRhaW5zKGNvbnRhaW5lciwgby5zdHlsZXMucG9zaXRpb25lZCk7XG4gICAgaWYgKHBvcykge1xuICAgICAgcmFmKGhpZGVDYWxlbmRhcik7XG4gICAgfVxuICAgIHJldHVybiBhcGk7XG4gIH1cblxuICBmdW5jdGlvbiBjYWxlbmRhckV2ZW50VGFyZ2V0IChlKSB7XG4gICAgdmFyIHRhcmdldCA9IGUudGFyZ2V0O1xuICAgIGlmICh0YXJnZXQgPT09IGFwaS5hc3NvY2lhdGVkKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgd2hpbGUgKHRhcmdldCkge1xuICAgICAgaWYgKHRhcmdldCA9PT0gY29udGFpbmVyKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgICAgdGFyZ2V0ID0gdGFyZ2V0LnBhcmVudE5vZGU7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gaGlkZU9uQmx1ciAoZSkge1xuICAgIGlmIChjYWxlbmRhckV2ZW50VGFyZ2V0KGUpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGhpZGVDb25kaXRpb25hbGx5KCk7XG4gIH1cblxuICBmdW5jdGlvbiBoaWRlT25DbGljayAoZSkge1xuICAgIGlmIChjYWxlbmRhckV2ZW50VGFyZ2V0KGUpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGhpZGVDb25kaXRpb25hbGx5KCk7XG4gIH1cblxuICBmdW5jdGlvbiBzdWJ0cmFjdE1vbnRoICgpIHsgY2hhbmdlTW9udGgoJ3N1YnRyYWN0Jyk7IH1cbiAgZnVuY3Rpb24gYWRkTW9udGggKCkgeyBjaGFuZ2VNb250aCgnYWRkJyk7IH1cbiAgZnVuY3Rpb24gY2hhbmdlTW9udGggKG9wKSB7XG4gICAgdmFyIGJvdW5kO1xuICAgIHZhciBkaXJlY3Rpb24gPSBvcCA9PT0gJ2FkZCcgPyAtMSA6IDE7XG4gICAgdmFyIG9mZnNldCA9IG8ubW9udGhzSW5DYWxlbmRhciArIGRpcmVjdGlvbiAqIGdldE1vbnRoT2Zmc2V0KGxhc3REYXlFbGVtZW50KTtcbiAgICByZWZDYWxbb3BdKG9mZnNldCwgJ21vbnRocycpO1xuICAgIGJvdW5kID0gaW5SYW5nZShyZWZDYWwuY2xvbmUoKSk7XG4gICAgcmVmID0gYm91bmQgfHwgcmVmO1xuICAgIGlmIChib3VuZCkgeyByZWZDYWwgPSBib3VuZC5jbG9uZSgpOyB9XG4gICAgdXBkYXRlKCk7XG4gIH1cblxuICBmdW5jdGlvbiB1cGRhdGUgKHNpbGVudCkge1xuICAgIHVwZGF0ZUNhbGVuZGFyKCk7XG4gICAgdXBkYXRlVGltZSgpO1xuICAgIGlmIChzaWxlbnQgIT09IHRydWUpIHsgZW1pdFZhbHVlcygpOyB9XG4gICAgZGlzcGxheVZhbGlkVGltZXNPbmx5KCk7XG4gIH1cblxuICBmdW5jdGlvbiB1cGRhdGVDYWxlbmRhciAoKSB7XG4gICAgaWYgKCFvLmRhdGUgfHwgIXJlbmRlcmVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHZhciB5ID0gcmVmQ2FsLnllYXIoKTtcbiAgICB2YXIgbSA9IHJlZkNhbC5tb250aCgpO1xuICAgIHZhciBkID0gcmVmQ2FsLmRhdGUoKTtcbiAgICBpZiAoZCA9PT0gbGFzdERheSAmJiBtID09PSBsYXN0TW9udGggJiYgeSA9PT0gbGFzdFllYXIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdmFyIGNhblN0YXkgPSBpc0Rpc3BsYXllZCgpO1xuICAgIGxhc3REYXkgPSByZWZDYWwuZGF0ZSgpO1xuICAgIGxhc3RNb250aCA9IHJlZkNhbC5tb250aCgpO1xuICAgIGxhc3RZZWFyID0gcmVmQ2FsLnllYXIoKTtcbiAgICBpZiAoY2FuU3RheSkgeyB1cGRhdGVDYWxlbmRhclNlbGVjdGlvbigpOyByZXR1cm47IH1cbiAgICBjYWxlbmRhck1vbnRocy5mb3JFYWNoKHVwZGF0ZU1vbnRoKTtcbiAgICByZW5kZXJBbGxEYXlzKCk7XG5cbiAgICBmdW5jdGlvbiB1cGRhdGVNb250aCAobW9udGgsIGkpIHtcbiAgICAgIHZhciBvZmZzZXRDYWwgPSByZWZDYWwuY2xvbmUoKS5hZGQoaSwgJ21vbnRocycpO1xuICAgICAgdGV4dChtb250aC5sYWJlbCwgb2Zmc2V0Q2FsLmZvcm1hdChvLm1vbnRoRm9ybWF0KSk7XG4gICAgICByZW1vdmVDaGlsZHJlbihtb250aC5ib2R5KTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiB1cGRhdGVDYWxlbmRhclNlbGVjdGlvbiAoKSB7XG4gICAgdmFyIGRheSA9IHJlZkNhbC5kYXRlKCkgLSAxO1xuICAgIHNlbGVjdERheUVsZW1lbnQoZmFsc2UpO1xuICAgIGNhbGVuZGFyTW9udGhzLmZvckVhY2goZnVuY3Rpb24gKGNhbCkge1xuICAgICAgdmFyIGRheXM7XG4gICAgICBpZiAoc2FtZUNhbGVuZGFyTW9udGgoY2FsLmRhdGUsIHJlZkNhbCkpIHtcbiAgICAgICAgZGF5cyA9IGNhc3QoY2FsLmJvZHkuY2hpbGRyZW4pLm1hcChhZ2dyZWdhdGUpO1xuICAgICAgICBkYXlzID0gQXJyYXkucHJvdG90eXBlLmNvbmNhdC5hcHBseShbXSwgZGF5cykuZmlsdGVyKGluc2lkZSk7XG4gICAgICAgIHNlbGVjdERheUVsZW1lbnQoZGF5c1tkYXldKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGZ1bmN0aW9uIGNhc3QgKGxpa2UpIHtcbiAgICAgIHZhciBkZXN0ID0gW107XG4gICAgICB2YXIgaTtcbiAgICAgIGZvciAoaSA9IDA7IGkgPCBsaWtlLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGRlc3QucHVzaChsaWtlW2ldKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBkZXN0O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGFnZ3JlZ2F0ZSAoY2hpbGQpIHtcbiAgICAgIHJldHVybiBjYXN0KGNoaWxkLmNoaWxkcmVuKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpbnNpZGUgKGNoaWxkKSB7XG4gICAgICByZXR1cm4gIWNsYXNzZXMuY29udGFpbnMoY2hpbGQsIG8uc3R5bGVzLmRheVByZXZNb250aCkgJiZcbiAgICAgICAgICAgICAhY2xhc3Nlcy5jb250YWlucyhjaGlsZCwgby5zdHlsZXMuZGF5TmV4dE1vbnRoKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBpc0Rpc3BsYXllZCAoKSB7XG4gICAgcmV0dXJuIGNhbGVuZGFyTW9udGhzLnNvbWUobWF0Y2hlcyk7XG5cbiAgICBmdW5jdGlvbiBtYXRjaGVzIChjYWwpIHtcbiAgICAgIGlmICghbGFzdFllYXIpIHsgcmV0dXJuIGZhbHNlOyB9XG4gICAgICByZXR1cm4gc2FtZUNhbGVuZGFyTW9udGgoY2FsLmRhdGUsIHJlZkNhbCk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gc2FtZUNhbGVuZGFyTW9udGggKGxlZnQsIHJpZ2h0KSB7XG4gICAgcmV0dXJuIGxlZnQgJiYgcmlnaHQgJiYgbGVmdC55ZWFyKCkgPT09IHJpZ2h0LnllYXIoKSAmJiBsZWZ0Lm1vbnRoKCkgPT09IHJpZ2h0Lm1vbnRoKCk7XG4gIH1cblxuICBmdW5jdGlvbiB1cGRhdGVUaW1lICgpIHtcbiAgICBpZiAoIW8udGltZSB8fCAhcmVuZGVyZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGV4dCh0aW1lLCByZWYuZm9ybWF0KG8udGltZUZvcm1hdCkpO1xuICB9XG5cbiAgZnVuY3Rpb24gZW1pdFZhbHVlcyAoKSB7XG4gICAgYXBpLmVtaXQoJ2RhdGEnLCBnZXREYXRlU3RyaW5nKCkpO1xuICAgIGFwaS5lbWl0KCd5ZWFyJywgcmVmLnllYXIoKSk7XG4gICAgYXBpLmVtaXQoJ21vbnRoJywgcmVmLm1vbnRoKCkpO1xuICAgIGFwaS5lbWl0KCdkYXknLCByZWYuZGF5KCkpO1xuICAgIGFwaS5lbWl0KCd0aW1lJywgcmVmLmZvcm1hdChvLnRpbWVGb3JtYXQpKTtcbiAgICByZXR1cm4gYXBpO1xuICB9XG5cbiAgZnVuY3Rpb24gcmVmcmVzaCAoKSB7XG4gICAgbGFzdFllYXIgPSBmYWxzZTtcbiAgICBsYXN0TW9udGggPSBmYWxzZTtcbiAgICBsYXN0RGF5ID0gZmFsc2U7XG4gICAgdXBkYXRlKHRydWUpO1xuICAgIHJldHVybiBhcGk7XG4gIH1cblxuICBmdW5jdGlvbiBzZXRWYWx1ZSAodmFsdWUpIHtcbiAgICB2YXIgZGF0ZSA9IHBhcnNlKHZhbHVlLCBvLmlucHV0Rm9ybWF0KTtcbiAgICBpZiAoZGF0ZSA9PT0gbnVsbCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICByZWYgPSBpblJhbmdlKGRhdGUpIHx8IHJlZjtcbiAgICByZWZDYWwgPSByZWYuY2xvbmUoKTtcbiAgICB1cGRhdGUodHJ1ZSk7XG5cbiAgICByZXR1cm4gYXBpO1xuICB9XG5cbiAgZnVuY3Rpb24gcmVtb3ZlQ2hpbGRyZW4gKGVsZW0sIHNlbGYpIHtcbiAgICB3aGlsZSAoZWxlbSAmJiBlbGVtLmZpcnN0Q2hpbGQpIHtcbiAgICAgIGVsZW0ucmVtb3ZlQ2hpbGQoZWxlbS5maXJzdENoaWxkKTtcbiAgICB9XG4gICAgaWYgKHNlbGYgPT09IHRydWUpIHtcbiAgICAgIGVsZW0ucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChlbGVtKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiByZW5kZXJBbGxEYXlzICgpIHtcbiAgICB2YXIgaTtcbiAgICBmb3IgKGkgPSAwOyBpIDwgby5tb250aHNJbkNhbGVuZGFyOyBpKyspIHtcbiAgICAgIHJlbmRlckRheXMoaSk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gcmVuZGVyRGF5cyAob2Zmc2V0KSB7XG4gICAgdmFyIG1vbnRoID0gY2FsZW5kYXJNb250aHNbb2Zmc2V0XTtcbiAgICB2YXIgb2Zmc2V0Q2FsID0gcmVmQ2FsLmNsb25lKCkuYWRkKG9mZnNldCwgJ21vbnRocycpO1xuICAgIHZhciB0b3RhbCA9IG9mZnNldENhbC5kYXlzSW5Nb250aCgpO1xuICAgIHZhciBjdXJyZW50ID0gb2Zmc2V0Q2FsLm1vbnRoKCkgIT09IHJlZi5tb250aCgpID8gLTEgOiByZWYuZGF0ZSgpOyAvLyAtMSA6IDEuLjMxXG4gICAgdmFyIGZpcnN0ID0gb2Zmc2V0Q2FsLmNsb25lKCkuZGF0ZSgxKTtcbiAgICB2YXIgZmlyc3REYXkgPSB3ZWVrZGF5KGZpcnN0LmRheSgpLCB0cnVlKTsgLy8gMC4uNlxuICAgIHZhciB0ciA9IGRvbSh7IHR5cGU6ICd0cicsIGNsYXNzTmFtZTogby5zdHlsZXMuZGF5Um93LCBwYXJlbnQ6IG1vbnRoLmJvZHkgfSk7XG4gICAgdmFyIHByZXZNb250aCA9IGhpZGRlbldoZW4ob2Zmc2V0ICE9PSAwLCBbby5zdHlsZXMuZGF5Qm9keUVsZW0sIG8uc3R5bGVzLmRheVByZXZNb250aF0pO1xuICAgIHZhciBuZXh0TW9udGggPSBoaWRkZW5XaGVuKG9mZnNldCAhPT0gby5tb250aHNJbkNhbGVuZGFyIC0gMSwgW28uc3R5bGVzLmRheUJvZHlFbGVtLCBvLnN0eWxlcy5kYXlOZXh0TW9udGhdKTtcbiAgICB2YXIgZGlzYWJsZWQgPSBvLnN0eWxlcy5kYXlEaXNhYmxlZDtcbiAgICB2YXIgbGFzdERheTtcblxuICAgIHBhcnQoe1xuICAgICAgYmFzZTogZmlyc3QuY2xvbmUoKS5zdWJ0cmFjdChmaXJzdERheSwgJ2RheXMnKSxcbiAgICAgIGxlbmd0aDogZmlyc3REYXksXG4gICAgICBjZWxsOiBwcmV2TW9udGhcbiAgICB9KTtcblxuICAgIHBhcnQoe1xuICAgICAgYmFzZTogZmlyc3QuY2xvbmUoKSxcbiAgICAgIGxlbmd0aDogdG90YWwsXG4gICAgICBjZWxsOiBbby5zdHlsZXMuZGF5Qm9keUVsZW1dLFxuICAgICAgc2VsZWN0YWJsZTogdHJ1ZVxuICAgIH0pO1xuXG4gICAgbGFzdERheSA9IGZpcnN0LmNsb25lKCkuYWRkKHRvdGFsLCAnZGF5cycpO1xuXG4gICAgcGFydCh7XG4gICAgICBiYXNlOiBsYXN0RGF5LFxuICAgICAgbGVuZ3RoOiB3ZWVrZGF5Q291bnQgLSB0ci5jaGlsZHJlbi5sZW5ndGgsXG4gICAgICBjZWxsOiBuZXh0TW9udGhcbiAgICB9KTtcblxuICAgIGJhY2suZGlzYWJsZWQgPSAhaXNJblJhbmdlTGVmdChmaXJzdCwgdHJ1ZSk7XG4gICAgbmV4dC5kaXNhYmxlZCA9ICFpc0luUmFuZ2VSaWdodChsYXN0RGF5LCB0cnVlKTtcbiAgICBtb250aC5kYXRlID0gb2Zmc2V0Q2FsLmNsb25lKCk7XG5cbiAgICBmdW5jdGlvbiBwYXJ0IChkYXRhKSB7XG4gICAgICB2YXIgaSwgZGF5LCBub2RlO1xuICAgICAgZm9yIChpID0gMDsgaSA8IGRhdGEubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKHRyLmNoaWxkcmVuLmxlbmd0aCA9PT0gd2Vla2RheUNvdW50KSB7XG4gICAgICAgICAgdHIgPSBkb20oeyB0eXBlOiAndHInLCBjbGFzc05hbWU6IG8uc3R5bGVzLmRheVJvdywgcGFyZW50OiBtb250aC5ib2R5IH0pO1xuICAgICAgICB9XG4gICAgICAgIGRheSA9IGRhdGEuYmFzZS5jbG9uZSgpLmFkZChpLCAnZGF5cycpO1xuICAgICAgICBub2RlID0gZG9tKHtcbiAgICAgICAgICB0eXBlOiAndGQnLFxuICAgICAgICAgIHBhcmVudDogdHIsXG4gICAgICAgICAgdGV4dDogZGF5LmZvcm1hdChvLmRheUZvcm1hdCksXG4gICAgICAgICAgY2xhc3NOYW1lOiB2YWxpZGF0aW9uVGVzdChkYXksIGRhdGEuY2VsbC5qb2luKCcgJykuc3BsaXQoJyAnKSkuam9pbignICcpXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoZGF0YS5zZWxlY3RhYmxlICYmIGRheS5kYXRlKCkgPT09IGN1cnJlbnQpIHtcbiAgICAgICAgICBzZWxlY3REYXlFbGVtZW50KG5vZGUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gdmFsaWRhdGlvblRlc3QgKGRheSwgY2VsbCkge1xuICAgICAgaWYgKCFpc0luUmFuZ2UoZGF5LCB0cnVlLCBvLmRhdGVWYWxpZGF0b3IpKSB7IGNlbGwucHVzaChkaXNhYmxlZCk7IH1cbiAgICAgIHJldHVybiBjZWxsO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGhpZGRlbldoZW4gKHZhbHVlLCBjZWxsKSB7XG4gICAgICBpZiAodmFsdWUpIHsgY2VsbC5wdXNoKG8uc3R5bGVzLmRheUNvbmNlYWxlZCk7IH1cbiAgICAgIHJldHVybiBjZWxsO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGlzSW5SYW5nZSAoZGF0ZSwgYWxsZGF5LCB2YWxpZGF0b3IpIHtcbiAgICBpZiAoIWlzSW5SYW5nZUxlZnQoZGF0ZSwgYWxsZGF5KSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoIWlzSW5SYW5nZVJpZ2h0KGRhdGUsIGFsbGRheSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgdmFyIHZhbGlkID0gKHZhbGlkYXRvciB8fCBGdW5jdGlvbi5wcm90b3R5cGUpLmNhbGwoYXBpLCBkYXRlLnRvRGF0ZSgpKTtcbiAgICByZXR1cm4gdmFsaWQgIT09IGZhbHNlO1xuICB9XG5cbiAgZnVuY3Rpb24gaXNJblJhbmdlTGVmdCAoZGF0ZSwgYWxsZGF5KSB7XG4gICAgdmFyIG1pbiA9ICFvLm1pbiA/IGZhbHNlIDogKGFsbGRheSA/IG8ubWluLmNsb25lKCkuc3RhcnRPZignZGF5JykgOiBvLm1pbik7XG4gICAgcmV0dXJuICFtaW4gfHwgIWRhdGUuaXNCZWZvcmUobWluKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGlzSW5SYW5nZVJpZ2h0IChkYXRlLCBhbGxkYXkpIHtcbiAgICB2YXIgbWF4ID0gIW8ubWF4ID8gZmFsc2UgOiAoYWxsZGF5ID8gby5tYXguY2xvbmUoKS5lbmRPZignZGF5JykgOiBvLm1heCk7XG4gICAgcmV0dXJuICFtYXggfHwgIWRhdGUuaXNBZnRlcihtYXgpO1xuICB9XG5cbiAgZnVuY3Rpb24gaW5SYW5nZSAoZGF0ZSkge1xuICAgIGlmIChvLm1pbiAmJiBkYXRlLmlzQmVmb3JlKG8ubWluKSkge1xuICAgICAgcmV0dXJuIGluUmFuZ2Uoby5taW4uY2xvbmUoKSk7XG4gICAgfSBlbHNlIGlmIChvLm1heCAmJiBkYXRlLmlzQWZ0ZXIoby5tYXgpKSB7XG4gICAgICByZXR1cm4gaW5SYW5nZShvLm1heC5jbG9uZSgpKTtcbiAgICB9XG4gICAgdmFyIHZhbHVlID0gZGF0ZS5jbG9uZSgpLnN1YnRyYWN0KDEsICdkYXlzJyk7XG4gICAgaWYgKHZhbGlkYXRlVG93YXJkcyh2YWx1ZSwgZGF0ZSwgJ2FkZCcpKSB7XG4gICAgICByZXR1cm4gaW5UaW1lUmFuZ2UodmFsdWUpO1xuICAgIH1cbiAgICB2YWx1ZSA9IGRhdGUuY2xvbmUoKTtcbiAgICBpZiAodmFsaWRhdGVUb3dhcmRzKHZhbHVlLCBkYXRlLCAnc3VidHJhY3QnKSkge1xuICAgICAgcmV0dXJuIGluVGltZVJhbmdlKHZhbHVlKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBpblRpbWVSYW5nZSAodmFsdWUpIHtcbiAgICB2YXIgY29weSA9IHZhbHVlLmNsb25lKCkuc3VidHJhY3Qoby50aW1lSW50ZXJ2YWwsICdzZWNvbmRzJyk7XG4gICAgdmFyIHRpbWVzID0gTWF0aC5jZWlsKHNlY29uZHNJbkRheSAvIG8udGltZUludGVydmFsKTtcbiAgICB2YXIgaTtcbiAgICBmb3IgKGkgPSAwOyBpIDwgdGltZXM7IGkrKykge1xuICAgICAgY29weS5hZGQoby50aW1lSW50ZXJ2YWwsICdzZWNvbmRzJyk7XG4gICAgICBpZiAoY29weS5kYXRlKCkgPiB2YWx1ZS5kYXRlKCkpIHtcbiAgICAgICAgY29weS5zdWJ0cmFjdCgxLCAnZGF5cycpO1xuICAgICAgfVxuICAgICAgaWYgKG8udGltZVZhbGlkYXRvci5jYWxsKGFwaSwgY29weS50b0RhdGUoKSkgIT09IGZhbHNlKSB7XG4gICAgICAgIHJldHVybiBjb3B5O1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHZhbGlkYXRlVG93YXJkcyAodmFsdWUsIGRhdGUsIG9wKSB7XG4gICAgdmFyIHZhbGlkID0gZmFsc2U7XG4gICAgd2hpbGUgKHZhbGlkID09PSBmYWxzZSkge1xuICAgICAgdmFsdWVbb3BdKDEsICdkYXlzJyk7XG4gICAgICBpZiAodmFsdWUubW9udGgoKSAhPT0gZGF0ZS5tb250aCgpKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgdmFsaWQgPSBvLmRhdGVWYWxpZGF0b3IuY2FsbChhcGksIHZhbHVlLnRvRGF0ZSgpKTtcbiAgICB9XG4gICAgcmV0dXJuIHZhbGlkICE9PSBmYWxzZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHBpY2tEYXkgKGUpIHtcbiAgICB2YXIgdGFyZ2V0ID0gZS50YXJnZXQ7XG4gICAgaWYgKGNsYXNzZXMuY29udGFpbnModGFyZ2V0LCBvLnN0eWxlcy5kYXlEaXNhYmxlZCkgfHwgIWNsYXNzZXMuY29udGFpbnModGFyZ2V0LCBvLnN0eWxlcy5kYXlCb2R5RWxlbSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdmFyIGRheSA9IHBhcnNlSW50KHRleHQodGFyZ2V0KSwgMTApO1xuICAgIHZhciBwcmV2ID0gY2xhc3Nlcy5jb250YWlucyh0YXJnZXQsIG8uc3R5bGVzLmRheVByZXZNb250aCk7XG4gICAgdmFyIG5leHQgPSBjbGFzc2VzLmNvbnRhaW5zKHRhcmdldCwgby5zdHlsZXMuZGF5TmV4dE1vbnRoKTtcbiAgICB2YXIgb2Zmc2V0ID0gZ2V0TW9udGhPZmZzZXQodGFyZ2V0KSAtIGdldE1vbnRoT2Zmc2V0KGxhc3REYXlFbGVtZW50KTtcbiAgICByZWYuYWRkKG9mZnNldCwgJ21vbnRocycpO1xuICAgIGlmIChwcmV2IHx8IG5leHQpIHtcbiAgICAgIHJlZi5hZGQocHJldiA/IC0xIDogMSwgJ21vbnRocycpO1xuICAgIH1cbiAgICBzZWxlY3REYXlFbGVtZW50KHRhcmdldCk7XG4gICAgcmVmLmRhdGUoZGF5KTsgLy8gbXVzdCBydW4gYWZ0ZXIgc2V0dGluZyB0aGUgbW9udGhcbiAgICBzZXRUaW1lKHJlZiwgaW5SYW5nZShyZWYpIHx8IHJlZik7XG4gICAgcmVmQ2FsID0gcmVmLmNsb25lKCk7XG4gICAgaWYgKG8uYXV0b0Nsb3NlID09PSB0cnVlKSB7IGhpZGVDb25kaXRpb25hbGx5KCk7IH1cbiAgICB1cGRhdGUoKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHNlbGVjdERheUVsZW1lbnQgKG5vZGUpIHtcbiAgICBpZiAobGFzdERheUVsZW1lbnQpIHtcbiAgICAgIGNsYXNzZXMucmVtb3ZlKGxhc3REYXlFbGVtZW50LCBvLnN0eWxlcy5zZWxlY3RlZERheSk7XG4gICAgfVxuICAgIGlmIChub2RlKSB7XG4gICAgICBjbGFzc2VzLmFkZChub2RlLCBvLnN0eWxlcy5zZWxlY3RlZERheSk7XG4gICAgfVxuICAgIGxhc3REYXlFbGVtZW50ID0gbm9kZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldE1vbnRoT2Zmc2V0IChlbGVtKSB7XG4gICAgdmFyIG9mZnNldDtcbiAgICB3aGlsZSAoZWxlbSAmJiBlbGVtLmdldEF0dHJpYnV0ZSkge1xuICAgICAgb2Zmc2V0ID0gZWxlbS5nZXRBdHRyaWJ1dGUobW9udGhPZmZzZXRBdHRyaWJ1dGUpO1xuICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHJldHVybiBwYXJzZUludChvZmZzZXQsIDEwKTtcbiAgICAgIH1cbiAgICAgIGVsZW0gPSBlbGVtLnBhcmVudE5vZGU7XG4gICAgfVxuICAgIHJldHVybiAwO1xuICB9XG5cbiAgZnVuY3Rpb24gc2V0VGltZSAodG8sIGZyb20pIHtcbiAgICB0by5ob3VyKGZyb20uaG91cigpKS5taW51dGUoZnJvbS5taW51dGUoKSkuc2Vjb25kKGZyb20uc2Vjb25kKCkpO1xuICAgIHJldHVybiB0bztcbiAgfVxuXG4gIGZ1bmN0aW9uIHBpY2tUaW1lIChlKSB7XG4gICAgdmFyIHRhcmdldCA9IGUudGFyZ2V0O1xuICAgIGlmICghY2xhc3Nlcy5jb250YWlucyh0YXJnZXQsIG8uc3R5bGVzLnRpbWVPcHRpb24pKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHZhciB2YWx1ZSA9IG1vbWVudHVtLm1vbWVudCh0ZXh0KHRhcmdldCksIG8udGltZUZvcm1hdCk7XG4gICAgc2V0VGltZShyZWYsIHZhbHVlKTtcbiAgICByZWZDYWwgPSByZWYuY2xvbmUoKTtcbiAgICBlbWl0VmFsdWVzKCk7XG4gICAgdXBkYXRlVGltZSgpO1xuICAgIGlmICgoIW8uZGF0ZSAmJiBvLmF1dG9DbG9zZSA9PT0gdHJ1ZSkgfHwgby5hdXRvQ2xvc2UgPT09ICd0aW1lJykge1xuICAgICAgaGlkZUNvbmRpdGlvbmFsbHkoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaGlkZVRpbWVMaXN0KCk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gZ2V0RGF0ZSAoKSB7XG4gICAgcmV0dXJuIHJlZi50b0RhdGUoKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldERhdGVTdHJpbmcgKGZvcm1hdCkge1xuICAgIHJldHVybiByZWYuZm9ybWF0KGZvcm1hdCB8fCBvLmlucHV0Rm9ybWF0KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldE1vbWVudCAoKSB7XG4gICAgcmV0dXJuIHJlZi5jbG9uZSgpO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY2FsZW5kYXI7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciB0cmltID0gL15cXHMrfFxccyskL2c7XG52YXIgd2hpdGVzcGFjZSA9IC9cXHMrLztcblxuZnVuY3Rpb24gY2xhc3NlcyAobm9kZSkge1xuICByZXR1cm4gbm9kZS5jbGFzc05hbWUucmVwbGFjZSh0cmltLCAnJykuc3BsaXQod2hpdGVzcGFjZSk7XG59XG5cbmZ1bmN0aW9uIHNldCAobm9kZSwgdmFsdWUpIHtcbiAgbm9kZS5jbGFzc05hbWUgPSB2YWx1ZS5qb2luKCcgJyk7XG59XG5cbmZ1bmN0aW9uIGFkZCAobm9kZSwgdmFsdWUpIHtcbiAgdmFyIHZhbHVlcyA9IHJlbW92ZShub2RlLCB2YWx1ZSk7XG4gIHZhbHVlcy5wdXNoKHZhbHVlKTtcbiAgc2V0KG5vZGUsIHZhbHVlcyk7XG59XG5cbmZ1bmN0aW9uIHJlbW92ZSAobm9kZSwgdmFsdWUpIHtcbiAgdmFyIHZhbHVlcyA9IGNsYXNzZXMobm9kZSk7XG4gIHZhciBpID0gdmFsdWVzLmluZGV4T2YodmFsdWUpO1xuICBpZiAoaSAhPT0gLTEpIHtcbiAgICB2YWx1ZXMuc3BsaWNlKGksIDEpO1xuICAgIHNldChub2RlLCB2YWx1ZXMpO1xuICB9XG4gIHJldHVybiB2YWx1ZXM7XG59XG5cbmZ1bmN0aW9uIGNvbnRhaW5zIChub2RlLCB2YWx1ZSkge1xuICByZXR1cm4gY2xhc3Nlcyhub2RlKS5pbmRleE9mKHZhbHVlKSAhPT0gLTE7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBhZGQ6IGFkZCxcbiAgcmVtb3ZlOiByZW1vdmUsXG4gIGNvbnRhaW5zOiBjb250YWluc1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIG1vbWVudHVtID0gcmVxdWlyZSgnLi9tb21lbnR1bScpO1xuXG4vLyBuYcOvdmUgaW1wbGVtZW50YXRpb24sIHNwZWNpZmljYWxseSBtZWFudCB0byBjbG9uZSBgb3B0aW9uc2Agb2JqZWN0c1xuZnVuY3Rpb24gY2xvbmUgKHRoaW5nKSB7XG4gIHZhciBjb3B5ID0ge307XG4gIHZhciB2YWx1ZTtcblxuICBmb3IgKHZhciBrZXkgaW4gdGhpbmcpIHtcbiAgICB2YWx1ZSA9IHRoaW5nW2tleV07XG5cbiAgICBpZiAoIXZhbHVlKSB7XG4gICAgICBjb3B5W2tleV0gPSB2YWx1ZTtcbiAgICB9IGVsc2UgaWYgKG1vbWVudHVtLmlzTW9tZW50KHZhbHVlKSkge1xuICAgICAgY29weVtrZXldID0gdmFsdWUuY2xvbmUoKTtcbiAgICB9IGVsc2UgaWYgKHZhbHVlLl9pc1N0eWxlc0NvbmZpZ3VyYXRpb24pIHtcbiAgICAgIGNvcHlba2V5XSA9IGNsb25lKHZhbHVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29weVtrZXldID0gdmFsdWU7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGNvcHk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY2xvbmU7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBpbmRleCA9IHJlcXVpcmUoJy4vaW5kZXgnKTtcbnZhciBpbnB1dCA9IHJlcXVpcmUoJy4vaW5wdXQnKTtcbnZhciBpbmxpbmUgPSByZXF1aXJlKCcuL2lubGluZScpO1xudmFyIGlzSW5wdXQgPSByZXF1aXJlKCcuL2lzSW5wdXQnKTtcblxuZnVuY3Rpb24gY29yZSAoZWxlbSwgb3B0aW9ucykge1xuICB2YXIgY2FsO1xuICB2YXIgZXhpc3RpbmcgPSBpbmRleC5maW5kKGVsZW0pO1xuICBpZiAoZXhpc3RpbmcpIHtcbiAgICByZXR1cm4gZXhpc3Rpbmc7XG4gIH1cblxuICBpZiAoaXNJbnB1dChlbGVtKSkge1xuICAgIGNhbCA9IGlucHV0KGVsZW0sIG9wdGlvbnMpO1xuICB9IGVsc2Uge1xuICAgIGNhbCA9IGlubGluZShlbGVtLCBvcHRpb25zKTtcbiAgfVxuICBjYWwuYXNzb2NpYXRlZCA9IGVsZW07XG4gIGluZGV4LmFzc2lnbihlbGVtLCBjYWwpO1xuXG4gIHJldHVybiBjYWw7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY29yZTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIHBhcnNlID0gcmVxdWlyZSgnLi9wYXJzZScpO1xudmFyIGlzSW5wdXQgPSByZXF1aXJlKCcuL2lzSW5wdXQnKTtcbnZhciBtb21lbnR1bSA9IHJlcXVpcmUoJy4vbW9tZW50dW0nKTtcblxuZnVuY3Rpb24gZGVmYXVsdHMgKG9wdGlvbnMsIGNhbCkge1xuICB2YXIgdGVtcDtcbiAgdmFyIG5vO1xuICB2YXIgbyA9IG9wdGlvbnMgfHwge307XG4gIGlmIChvLmF1dG9IaWRlT25DbGljayA9PT0gbm8pIHsgby5hdXRvSGlkZU9uQ2xpY2sgPSB0cnVlOyB9XG4gIGlmIChvLmF1dG9IaWRlT25CbHVyID09PSBubykgeyBvLmF1dG9IaWRlT25CbHVyID0gdHJ1ZTsgfVxuICBpZiAoby5hdXRvQ2xvc2UgPT09IG5vKSB7IG8uYXV0b0Nsb3NlID0gdHJ1ZTsgfVxuICBpZiAoby5hcHBlbmRUbyA9PT0gbm8pIHsgby5hcHBlbmRUbyA9IGRvY3VtZW50LmJvZHk7IH1cbiAgaWYgKG8uYXBwZW5kVG8gPT09ICdwYXJlbnQnKSB7XG4gICAgaWYgKGlzSW5wdXQoY2FsLmFzc29jaWF0ZWQpKSB7XG4gICAgICBvLmFwcGVuZFRvID0gY2FsLmFzc29jaWF0ZWQucGFyZW50Tm9kZTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbmxpbmUgY2FsZW5kYXJzIG11c3QgYmUgYXBwZW5kZWQgdG8gYSBwYXJlbnQgbm9kZSBleHBsaWNpdGx5LicpO1xuICAgIH1cbiAgfVxuICBpZiAoby5pbnZhbGlkYXRlID09PSBubykgeyBvLmludmFsaWRhdGUgPSB0cnVlOyB9XG4gIGlmIChvLnJlcXVpcmVkID09PSBubykgeyBvLnJlcXVpcmVkID0gZmFsc2U7IH1cbiAgaWYgKG8uZGF0ZSA9PT0gbm8pIHsgby5kYXRlID0gdHJ1ZTsgfVxuICBpZiAoby50aW1lID09PSBubykgeyBvLnRpbWUgPSB0cnVlOyB9XG4gIGlmIChvLmRhdGUgPT09IGZhbHNlICYmIG8udGltZSA9PT0gZmFsc2UpIHsgdGhyb3cgbmV3IEVycm9yKCdBdCBsZWFzdCBvbmUgb2YgYGRhdGVgIG9yIGB0aW1lYCBtdXN0IGJlIGB0cnVlYC4nKTsgfVxuICBpZiAoby5pbnB1dEZvcm1hdCA9PT0gbm8pIHtcbiAgICBpZiAoby5kYXRlICYmIG8udGltZSkge1xuICAgICAgby5pbnB1dEZvcm1hdCA9ICdZWVlZLU1NLUREIEhIOm1tJztcbiAgICB9IGVsc2UgaWYgKG8uZGF0ZSkge1xuICAgICAgby5pbnB1dEZvcm1hdCA9ICdZWVlZLU1NLUREJztcbiAgICB9IGVsc2Uge1xuICAgICAgby5pbnB1dEZvcm1hdCA9ICdISDptbSc7XG4gICAgfVxuICB9XG4gIGlmIChvLmluaXRpYWxWYWx1ZSA9PT0gbm8pIHtcbiAgICBvLmluaXRpYWxWYWx1ZSA9IG51bGw7XG4gIH0gZWxzZSB7XG4gICAgby5pbml0aWFsVmFsdWUgPSBwYXJzZShvLmluaXRpYWxWYWx1ZSwgby5pbnB1dEZvcm1hdCk7XG4gIH1cbiAgaWYgKG8ubWluID09PSBubykgeyBvLm1pbiA9IG51bGw7IH0gZWxzZSB7IG8ubWluID0gcGFyc2Uoby5taW4sIG8uaW5wdXRGb3JtYXQpOyB9XG4gIGlmIChvLm1heCA9PT0gbm8pIHsgby5tYXggPSBudWxsOyB9IGVsc2UgeyBvLm1heCA9IHBhcnNlKG8ubWF4LCBvLmlucHV0Rm9ybWF0KTsgfVxuICBpZiAoby50aW1lSW50ZXJ2YWwgPT09IG5vKSB7IG8udGltZUludGVydmFsID0gNjAgKiAzMDsgfSAvLyAzMCBtaW51dGVzIGJ5IGRlZmF1bHRcbiAgaWYgKG8ubWluICYmIG8ubWF4KSB7XG4gICAgaWYgKG8ubWF4LmlzQmVmb3JlKG8ubWluKSkge1xuICAgICAgdGVtcCA9IG8ubWF4O1xuICAgICAgby5tYXggPSBvLm1pbjtcbiAgICAgIG8ubWluID0gdGVtcDtcbiAgICB9XG4gICAgaWYgKG8uZGF0ZSA9PT0gdHJ1ZSkge1xuICAgICAgaWYgKG8ubWF4LmNsb25lKCkuc3VidHJhY3QoMSwgJ2RheXMnKS5pc0JlZm9yZShvLm1pbikpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdgbWF4YCBtdXN0IGJlIGF0IGxlYXN0IG9uZSBkYXkgYWZ0ZXIgYG1pbmAnKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKG8udGltZUludGVydmFsICogMTAwMCAtIG8ubWluICUgKG8udGltZUludGVydmFsICogMTAwMCkgPiBvLm1heCAtIG8ubWluKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2BtaW5gIHRvIGBtYXhgIHJhbmdlIG11c3QgYWxsb3cgZm9yIGF0IGxlYXN0IG9uZSB0aW1lIG9wdGlvbiB0aGF0IG1hdGNoZXMgYHRpbWVJbnRlcnZhbGAnKTtcbiAgICB9XG4gIH1cbiAgaWYgKG8uZGF0ZVZhbGlkYXRvciA9PT0gbm8pIHsgby5kYXRlVmFsaWRhdG9yID0gRnVuY3Rpb24ucHJvdG90eXBlOyB9XG4gIGlmIChvLnRpbWVWYWxpZGF0b3IgPT09IG5vKSB7IG8udGltZVZhbGlkYXRvciA9IEZ1bmN0aW9uLnByb3RvdHlwZTsgfVxuICBpZiAoby50aW1lRm9ybWF0ID09PSBubykgeyBvLnRpbWVGb3JtYXQgPSAnSEg6bW0nOyB9XG4gIGlmIChvLndlZWtTdGFydCA9PT0gbm8pIHsgby53ZWVrU3RhcnQgPSBtb21lbnR1bS5tb21lbnQoKS53ZWVrZGF5KDApLmRheSgpOyB9XG4gIGlmIChvLndlZWtkYXlGb3JtYXQgPT09IG5vKSB7IG8ud2Vla2RheUZvcm1hdCA9ICdtaW4nOyB9XG4gIGlmIChvLndlZWtkYXlGb3JtYXQgPT09ICdsb25nJykge1xuICAgIG8ud2Vla2RheUZvcm1hdCA9IG1vbWVudHVtLm1vbWVudC53ZWVrZGF5cygpO1xuICB9IGVsc2UgaWYgKG8ud2Vla2RheUZvcm1hdCA9PT0gJ3Nob3J0Jykge1xuICAgIG8ud2Vla2RheUZvcm1hdCA9IG1vbWVudHVtLm1vbWVudC53ZWVrZGF5c1Nob3J0KCk7XG4gIH0gZWxzZSBpZiAoby53ZWVrZGF5Rm9ybWF0ID09PSAnbWluJykge1xuICAgIG8ud2Vla2RheUZvcm1hdCA9IG1vbWVudHVtLm1vbWVudC53ZWVrZGF5c01pbigpO1xuICB9IGVsc2UgaWYgKCFBcnJheS5pc0FycmF5KG8ud2Vla2RheUZvcm1hdCkgfHwgby53ZWVrZGF5Rm9ybWF0Lmxlbmd0aCA8IDcpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2B3ZWVrZGF5c2AgbXVzdCBiZSBgbWluYCwgYHNob3J0YCwgb3IgYGxvbmdgJyk7XG4gIH1cbiAgaWYgKG8ubW9udGhzSW5DYWxlbmRhciA9PT0gbm8pIHsgby5tb250aHNJbkNhbGVuZGFyID0gMTsgfVxuICBpZiAoby5tb250aEZvcm1hdCA9PT0gbm8pIHsgby5tb250aEZvcm1hdCA9ICdNTU1NIFlZWVknOyB9XG4gIGlmIChvLmRheUZvcm1hdCA9PT0gbm8pIHsgby5kYXlGb3JtYXQgPSAnREQnOyB9XG4gIGlmIChvLnN0eWxlcyA9PT0gbm8pIHsgby5zdHlsZXMgPSB7fTsgfVxuXG4gIG8uc3R5bGVzLl9pc1N0eWxlc0NvbmZpZ3VyYXRpb24gPSB0cnVlO1xuXG4gIHZhciBzdHlsID0gby5zdHlsZXM7XG4gIGlmIChzdHlsLmJhY2sgPT09IG5vKSB7IHN0eWwuYmFjayA9ICdyZC1iYWNrJzsgfVxuICBpZiAoc3R5bC5jb250YWluZXIgPT09IG5vKSB7IHN0eWwuY29udGFpbmVyID0gJ3JkLWNvbnRhaW5lcic7IH1cbiAgaWYgKHN0eWwucG9zaXRpb25lZCA9PT0gbm8pIHsgc3R5bC5wb3NpdGlvbmVkID0gJ3JkLWNvbnRhaW5lci1hdHRhY2htZW50JzsgfVxuICBpZiAoc3R5bC5kYXRlID09PSBubykgeyBzdHlsLmRhdGUgPSAncmQtZGF0ZSc7IH1cbiAgaWYgKHN0eWwuZGF5Qm9keSA9PT0gbm8pIHsgc3R5bC5kYXlCb2R5ID0gJ3JkLWRheXMtYm9keSc7IH1cbiAgaWYgKHN0eWwuZGF5Qm9keUVsZW0gPT09IG5vKSB7IHN0eWwuZGF5Qm9keUVsZW0gPSAncmQtZGF5LWJvZHknOyB9XG4gIGlmIChzdHlsLmRheVByZXZNb250aCA9PT0gbm8pIHsgc3R5bC5kYXlQcmV2TW9udGggPSAncmQtZGF5LXByZXYtbW9udGgnOyB9XG4gIGlmIChzdHlsLmRheU5leHRNb250aCA9PT0gbm8pIHsgc3R5bC5kYXlOZXh0TW9udGggPSAncmQtZGF5LW5leHQtbW9udGgnOyB9XG4gIGlmIChzdHlsLmRheURpc2FibGVkID09PSBubykgeyBzdHlsLmRheURpc2FibGVkID0gJ3JkLWRheS1kaXNhYmxlZCc7IH1cbiAgaWYgKHN0eWwuZGF5Q29uY2VhbGVkID09PSBubykgeyBzdHlsLmRheUNvbmNlYWxlZCA9ICdyZC1kYXktY29uY2VhbGVkJzsgfVxuICBpZiAoc3R5bC5kYXlIZWFkID09PSBubykgeyBzdHlsLmRheUhlYWQgPSAncmQtZGF5cy1oZWFkJzsgfVxuICBpZiAoc3R5bC5kYXlIZWFkRWxlbSA9PT0gbm8pIHsgc3R5bC5kYXlIZWFkRWxlbSA9ICdyZC1kYXktaGVhZCc7IH1cbiAgaWYgKHN0eWwuZGF5Um93ID09PSBubykgeyBzdHlsLmRheVJvdyA9ICdyZC1kYXlzLXJvdyc7IH1cbiAgaWYgKHN0eWwuZGF5VGFibGUgPT09IG5vKSB7IHN0eWwuZGF5VGFibGUgPSAncmQtZGF5cyc7IH1cbiAgaWYgKHN0eWwubW9udGggPT09IG5vKSB7IHN0eWwubW9udGggPSAncmQtbW9udGgnOyB9XG4gIGlmIChzdHlsLm1vbnRoTGFiZWwgPT09IG5vKSB7IHN0eWwubW9udGhMYWJlbCA9ICdyZC1tb250aC1sYWJlbCc7IH1cbiAgaWYgKHN0eWwubmV4dCA9PT0gbm8pIHsgc3R5bC5uZXh0ID0gJ3JkLW5leHQnOyB9XG4gIGlmIChzdHlsLnNlbGVjdGVkRGF5ID09PSBubykgeyBzdHlsLnNlbGVjdGVkRGF5ID0gJ3JkLWRheS1zZWxlY3RlZCc7IH1cbiAgaWYgKHN0eWwuc2VsZWN0ZWRUaW1lID09PSBubykgeyBzdHlsLnNlbGVjdGVkVGltZSA9ICdyZC10aW1lLXNlbGVjdGVkJzsgfVxuICBpZiAoc3R5bC50aW1lID09PSBubykgeyBzdHlsLnRpbWUgPSAncmQtdGltZSc7IH1cbiAgaWYgKHN0eWwudGltZUxpc3QgPT09IG5vKSB7IHN0eWwudGltZUxpc3QgPSAncmQtdGltZS1saXN0JzsgfVxuICBpZiAoc3R5bC50aW1lT3B0aW9uID09PSBubykgeyBzdHlsLnRpbWVPcHRpb24gPSAncmQtdGltZS1vcHRpb24nOyB9XG5cbiAgcmV0dXJuIG87XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZGVmYXVsdHM7XG4iLCIndXNlIHN0cmljdCc7XG5cbmZ1bmN0aW9uIGRvbSAob3B0aW9ucykge1xuICB2YXIgbyA9IG9wdGlvbnMgfHwge307XG4gIGlmICghby50eXBlKSB7IG8udHlwZSA9ICdkaXYnOyB9XG4gIHZhciBlbGVtID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChvLnR5cGUpO1xuICBpZiAoby5jbGFzc05hbWUpIHsgZWxlbS5jbGFzc05hbWUgPSBvLmNsYXNzTmFtZTsgfVxuICBpZiAoby50ZXh0KSB7IGVsZW0uaW5uZXJUZXh0ID0gZWxlbS50ZXh0Q29udGVudCA9IG8udGV4dDsgfVxuICBpZiAoby5hdHRyaWJ1dGVzKSB7XG4gICAgT2JqZWN0LmtleXMoby5hdHRyaWJ1dGVzKS5mb3JFYWNoKGZ1bmN0aW9uKGtleSkge1xuICAgICAgZWxlbS5zZXRBdHRyaWJ1dGUoa2V5LCBvLmF0dHJpYnV0ZXNba2V5XSk7XG4gICAgfSk7XG4gIH1cbiAgaWYgKG8ucGFyZW50KSB7IG8ucGFyZW50LmFwcGVuZENoaWxkKGVsZW0pOyB9XG4gIHJldHVybiBlbGVtO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGRvbTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGFkZEV2ZW50ID0gYWRkRXZlbnRFYXN5O1xudmFyIHJlbW92ZUV2ZW50ID0gcmVtb3ZlRXZlbnRFYXN5O1xuXG5pZiAoIXdpbmRvdy5hZGRFdmVudExpc3RlbmVyKSB7XG4gIGFkZEV2ZW50ID0gYWRkRXZlbnRIYXJkO1xufVxuXG5pZiAoIXdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKSB7XG4gIHJlbW92ZUV2ZW50ID0gcmVtb3ZlRXZlbnRIYXJkO1xufVxuXG5mdW5jdGlvbiBhZGRFdmVudEVhc3kgKGVsZW1lbnQsIGV2dCwgZm4sIGNhcHR1cmUpIHtcbiAgcmV0dXJuIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihldnQsIGZuLCBjYXB0dXJlKTtcbn1cblxuZnVuY3Rpb24gYWRkRXZlbnRIYXJkIChlbGVtZW50LCBldnQsIGZuLCBjYXB0dXJlKSB7XG4gIHJldHVybiBlbGVtZW50LmF0dGFjaEV2ZW50KCdvbicgKyBldnQsIGZ1bmN0aW9uIChhZSkge1xuICAgIHZhciBlID0gYWUgfHwgd2luZG93LmV2ZW50O1xuICAgIGUudGFyZ2V0ID0gZS50YXJnZXQgfHwgZS5zcmNFbGVtZW50O1xuICAgIGUucHJldmVudERlZmF1bHQgID0gZS5wcmV2ZW50RGVmYXVsdCB8fCBmdW5jdGlvbiBwcmV2ZW50RGVmYXVsdCAoKSB7IGUucmV0dXJuVmFsdWUgPSBmYWxzZTsgfTtcbiAgICBlLnN0b3BQcm9wYWdhdGlvbiA9IGUuc3RvcFByb3BhZ2F0aW9uIHx8IGZ1bmN0aW9uIHN0b3BQcm9wYWdhdGlvbiAoKSB7IGUuY2FuY2VsQnViYmxlID0gdHJ1ZTsgfTtcbiAgICBmbi5jYWxsKGVsZW1lbnQsIGUpO1xuICB9LCBjYXB0dXJlKTtcbn1cblxuZnVuY3Rpb24gcmVtb3ZlRXZlbnRFYXN5IChlbGVtZW50LCBldnQsIGZuKSB7XG4gIHJldHVybiBlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoZXZ0LCBmbik7XG59XG5cbmZ1bmN0aW9uIHJlbW92ZUV2ZW50SGFyZCAoZWxlbWVudCwgZXZ0LCBmbikge1xuICByZXR1cm4gZWxlbWVudC5kZXRhY2hFdmVudCgnb24nICsgZXZ0LCBmbik7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBhZGQ6IGFkZEV2ZW50LFxuICByZW1vdmU6IHJlbW92ZUV2ZW50XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIG5vO1xudmFyIGlrZXkgPSAnZGF0YS1yb21lLWlkJztcbnZhciBpbmRleCA9IFtdO1xuXG5mdW5jdGlvbiBmaW5kICh0aGluZykgeyAvLyBjYW4gYmUgYSBET00gZWxlbWVudCBvciBhIG51bWJlclxuICBpZiAodHlwZW9mIHRoaW5nICE9PSAnbnVtYmVyJyAmJiB0aGluZyAmJiB0aGluZy5nZXRBdHRyaWJ1dGUpIHtcbiAgICByZXR1cm4gZmluZCh0aGluZy5nZXRBdHRyaWJ1dGUoaWtleSkpO1xuICB9XG4gIHZhciBleGlzdGluZyA9IGluZGV4W3RoaW5nXTtcbiAgaWYgKGV4aXN0aW5nICE9PSBubykge1xuICAgIHJldHVybiBleGlzdGluZztcbiAgfVxuICByZXR1cm4gbnVsbDtcbn1cblxuZnVuY3Rpb24gYXNzaWduIChlbGVtLCBpbnN0YW5jZSkge1xuICBlbGVtLnNldEF0dHJpYnV0ZShpa2V5LCBpbnN0YW5jZS5pZCA9IGluZGV4LnB1c2goaW5zdGFuY2UpIC0gMSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBmaW5kOiBmaW5kLFxuICBhc3NpZ246IGFzc2lnblxufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIHJhZiA9IHJlcXVpcmUoJ3JhZicpO1xudmFyIGNhbGVuZGFyID0gcmVxdWlyZSgnLi9jYWxlbmRhcicpO1xuXG5mdW5jdGlvbiBpbmxpbmUgKGVsZW0sIGNhbGVuZGFyT3B0aW9ucykge1xuICB2YXIgbyA9IGNhbGVuZGFyT3B0aW9ucyB8fCB7fTtcblxuICBvLmFwcGVuZFRvID0gZWxlbTtcblxuICByZXR1cm4gY2FsZW5kYXIobyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaW5saW5lO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdGhyb3R0bGUgPSByZXF1aXJlKCcuL3Rocm90dGxlJyk7XG52YXIgcmFmID0gcmVxdWlyZSgncmFmJyk7XG52YXIgY2xvbmUgPSByZXF1aXJlKCcuL2Nsb25lJyk7XG52YXIgZGVmYXVsdHMgPSByZXF1aXJlKCcuL2RlZmF1bHRzJyk7XG52YXIgY2FsZW5kYXIgPSByZXF1aXJlKCcuL2NhbGVuZGFyJyk7XG52YXIgbW9tZW50dW0gPSByZXF1aXJlKCcuL21vbWVudHVtJyk7XG52YXIgY2xhc3NlcyA9IHJlcXVpcmUoJy4vY2xhc3NlcycpO1xudmFyIGV2ZW50cyA9IHJlcXVpcmUoJy4vZXZlbnRzJyk7XG5cbmZ1bmN0aW9uIGlucHV0Q2FsZW5kYXIgKGlucHV0LCBjYWxlbmRhck9wdGlvbnMpIHtcbiAgdmFyIG87XG4gIHZhciBhcGkgPSBjYWxlbmRhcihjYWxlbmRhck9wdGlvbnMpO1xuICB2YXIgdGhyb3R0bGVkVGFrZUlucHV0ID0gdGhyb3R0bGUodGFrZUlucHV0LCAzMCk7XG4gIHZhciB0aHJvdHRsZWRQb3NpdGlvbiA9IHRocm90dGxlKHBvc2l0aW9uLCAzMCk7XG4gIHZhciBpZ25vcmVJbnZhbGlkYXRpb247XG4gIHZhciBpZ25vcmVTaG93O1xuXG4gIGluaXQoY2FsZW5kYXJPcHRpb25zKTtcblxuICByZXR1cm4gYXBpO1xuXG4gIGZ1bmN0aW9uIGluaXQgKGluaXRPcHRpb25zKSB7XG4gICAgbyA9IGRlZmF1bHRzKGluaXRPcHRpb25zIHx8IGNhbGVuZGFyT3B0aW9ucywgYXBpKTtcblxuICAgIGNsYXNzZXMuYWRkKGFwaS5jb250YWluZXIsIG8uc3R5bGVzLnBvc2l0aW9uZWQpO1xuICAgIGV2ZW50cy5hZGQoYXBpLmNvbnRhaW5lciwgJ21vdXNlZG93bicsIGNvbnRhaW5lck1vdXNlRG93bik7XG4gICAgZXZlbnRzLmFkZChhcGkuY29udGFpbmVyLCAnY2xpY2snLCBjb250YWluZXJDbGljayk7XG5cbiAgICBhcGkuZ2V0RGF0ZSA9IHVucmVxdWlyZShhcGkuZ2V0RGF0ZSk7XG4gICAgYXBpLmdldERhdGVTdHJpbmcgPSB1bnJlcXVpcmUoYXBpLmdldERhdGVTdHJpbmcpO1xuICAgIGFwaS5nZXRNb21lbnQgPSB1bnJlcXVpcmUoYXBpLmdldE1vbWVudCk7XG5cbiAgICBpZiAoby5pbml0aWFsVmFsdWUpIHtcbiAgICAgIGlucHV0LnZhbHVlID0gby5pbml0aWFsVmFsdWUuZm9ybWF0KG8uaW5wdXRGb3JtYXQpO1xuICAgIH1cblxuICAgIGFwaS5vbignZGF0YScsIHVwZGF0ZUlucHV0KTtcbiAgICBhcGkub24oJ3Nob3cnLCB0aHJvdHRsZWRQb3NpdGlvbik7XG5cbiAgICBldmVudExpc3RlbmluZygpO1xuICAgIHRocm90dGxlZFRha2VJbnB1dCgpO1xuXG4gICAgYXBpLmhpZGUoKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGRlc3Ryb3kgKCkge1xuICAgIGV2ZW50TGlzdGVuaW5nKHRydWUpO1xuICB9XG5cbiAgZnVuY3Rpb24gZXZlbnRMaXN0ZW5pbmcgKHJlbW92ZSkge1xuICAgIHZhciBvcCA9IHJlbW92ZSA/ICdyZW1vdmUnIDogJ2FkZCc7XG4gICAgZXZlbnRzW29wXShpbnB1dCwgJ2NsaWNrJywgc2hvdyk7XG4gICAgZXZlbnRzW29wXShpbnB1dCwgJ3RvdWNoZW5kJywgc2hvdyk7XG4gICAgZXZlbnRzW29wXShpbnB1dCwgJ2ZvY3VzaW4nLCBzaG93KTtcbiAgICBldmVudHNbb3BdKGlucHV0LCAnY2hhbmdlJywgdGhyb3R0bGVkVGFrZUlucHV0KTtcbiAgICBldmVudHNbb3BdKGlucHV0LCAna2V5cHJlc3MnLCB0aHJvdHRsZWRUYWtlSW5wdXQpO1xuICAgIGV2ZW50c1tvcF0oaW5wdXQsICdrZXlkb3duJywgdGhyb3R0bGVkVGFrZUlucHV0KTtcbiAgICBldmVudHNbb3BdKGlucHV0LCAnaW5wdXQnLCB0aHJvdHRsZWRUYWtlSW5wdXQpO1xuICAgIGlmIChvLmludmFsaWRhdGUpIHsgZXZlbnRzW29wXShpbnB1dCwgJ2JsdXInLCBpbnZhbGlkYXRlSW5wdXQpOyB9XG4gICAgZXZlbnRzW29wXSh3aW5kb3csICdyZXNpemUnLCB0aHJvdHRsZWRQb3NpdGlvbik7XG5cbiAgICBpZiAocmVtb3ZlKSB7XG4gICAgICBhcGkub25jZSgncmVhZHknLCBpbml0KTtcbiAgICAgIGFwaS5vZmYoJ2Rlc3Ryb3llZCcsIGRlc3Ryb3kpO1xuICAgIH0gZWxzZSB7XG4gICAgICBhcGkub2ZmKCdyZWFkeScsIGluaXQpO1xuICAgICAgYXBpLm9uY2UoJ2Rlc3Ryb3llZCcsIGRlc3Ryb3kpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGNvbnRhaW5lckNsaWNrICgpIHtcbiAgICBpZ25vcmVTaG93ID0gdHJ1ZTtcbiAgICBpbnB1dC5mb2N1cygpO1xuICAgIGlnbm9yZVNob3cgPSBmYWxzZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNvbnRhaW5lck1vdXNlRG93biAoKSB7XG4gICAgaWdub3JlSW52YWxpZGF0aW9uID0gdHJ1ZTtcbiAgICByYWYodW5pZ25vcmUpO1xuXG4gICAgZnVuY3Rpb24gdW5pZ25vcmUgKCkge1xuICAgICAgaWdub3JlSW52YWxpZGF0aW9uID0gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gaW52YWxpZGF0ZUlucHV0ICgpIHtcbiAgICBpZiAoIWlnbm9yZUludmFsaWRhdGlvbiAmJiAhaXNFbXB0eSgpKSB7XG4gICAgICBhcGkuZW1pdFZhbHVlcygpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHNob3cgKCkge1xuICAgIGlmIChpZ25vcmVTaG93KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGFwaS5zaG93KCk7XG4gIH1cblxuICBmdW5jdGlvbiBwb3NpdGlvbiAoKSB7XG4gICAgdmFyIGJvdW5kcyA9IGlucHV0LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIHZhciBzY3JvbGxUb3AgPSBkb2N1bWVudC5ib2R5LnNjcm9sbFRvcCB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc2Nyb2xsVG9wO1xuICAgIGFwaS5jb250YWluZXIuc3R5bGUudG9wICA9IGJvdW5kcy50b3AgKyBzY3JvbGxUb3AgKyBpbnB1dC5vZmZzZXRIZWlnaHQgKyAncHgnO1xuICAgIGFwaS5jb250YWluZXIuc3R5bGUubGVmdCA9IGJvdW5kcy5sZWZ0ICsgJ3B4JztcbiAgfVxuXG4gIGZ1bmN0aW9uIHRha2VJbnB1dCAoKSB7XG4gICAgdmFyIHZhbHVlID0gaW5wdXQudmFsdWUudHJpbSgpO1xuICAgIGlmIChpc0VtcHR5KCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdmFyIGRhdGUgPSBtb21lbnR1bS5tb21lbnQodmFsdWUsIG8uaW5wdXRGb3JtYXQsIG8uc3RyaWN0UGFyc2UpO1xuICAgIGFwaS5zZXRWYWx1ZShkYXRlKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHVwZGF0ZUlucHV0IChkYXRhKSB7XG4gICAgaW5wdXQudmFsdWUgPSBkYXRhO1xuICB9XG5cbiAgZnVuY3Rpb24gaXNFbXB0eSAoKSB7XG4gICAgcmV0dXJuIG8ucmVxdWlyZWQgPT09IGZhbHNlICYmIGlucHV0LnZhbHVlLnRyaW0oKSA9PT0gJyc7XG4gIH1cblxuICBmdW5jdGlvbiB1bnJlcXVpcmUgKGZuKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIG1heWJlICgpIHtcbiAgICAgIHJldHVybiBpc0VtcHR5KCkgPyBudWxsIDogZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9O1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaW5wdXRDYWxlbmRhcjtcbiIsIid1c2Ugc3RyaWN0JztcblxuZnVuY3Rpb24gaXNJbnB1dCAoZWxlbSkge1xuICByZXR1cm4gZWxlbSAmJiBlbGVtLm5vZGVOYW1lICYmIGVsZW0ubm9kZU5hbWUudG9Mb3dlckNhc2UoKSA9PT0gJ2lucHV0Jztcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc0lucHV0O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5mdW5jdGlvbiBpc01vbWVudCAodmFsdWUpIHtcbiAgcmV0dXJuIHZhbHVlICYmIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh2YWx1ZSwgJ19pc0FNb21lbnRPYmplY3QnKTtcbn1cblxudmFyIGFwaSA9IHtcbiAgbW9tZW50OiBudWxsLFxuICBpc01vbWVudDogaXNNb21lbnRcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gYXBpO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5mdW5jdGlvbiBub29wICgpIHt9XG5cbm1vZHVsZS5leHBvcnRzID0gbm9vcDtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIG1vbWVudHVtID0gcmVxdWlyZSgnLi9tb21lbnR1bScpO1xuXG5mdW5jdGlvbiByYXcgKGRhdGUsIGZvcm1hdCkge1xuICBpZiAodHlwZW9mIGRhdGUgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIG1vbWVudHVtLm1vbWVudChkYXRlLCBmb3JtYXQpO1xuICB9XG4gIGlmIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoZGF0ZSkgPT09ICdbb2JqZWN0IERhdGVdJykge1xuICAgIHJldHVybiBtb21lbnR1bS5tb21lbnQoZGF0ZSk7XG4gIH1cbiAgaWYgKG1vbWVudHVtLmlzTW9tZW50KGRhdGUpKSB7XG4gICAgcmV0dXJuIGRhdGUuY2xvbmUoKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBwYXJzZSAoZGF0ZSwgZm9ybWF0KSB7XG4gIHZhciBtID0gcmF3KGRhdGUsIHR5cGVvZiBmb3JtYXQgPT09ICdzdHJpbmcnID8gZm9ybWF0IDogbnVsbCk7XG4gIHJldHVybiBtICYmIG0uaXNWYWxpZCgpID8gbSA6IG51bGw7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gcGFyc2U7XG4iLCIndXNlIHN0cmljdCc7XG5cbmlmICghQXJyYXkucHJvdG90eXBlLmZpbHRlcikge1xuICBBcnJheS5wcm90b3R5cGUuZmlsdGVyID0gZnVuY3Rpb24gKGZuLCBjdHgpIHtcbiAgICB2YXIgZiA9IFtdO1xuICAgIHRoaXMuZm9yRWFjaChmdW5jdGlvbiAodiwgaSwgdCkge1xuICAgICAgaWYgKGZuLmNhbGwoY3R4LCB2LCBpLCB0KSkgeyBmLnB1c2godik7IH1cbiAgICB9LCBjdHgpO1xuICAgIHJldHVybiBmO1xuICB9O1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG5pZiAoIUFycmF5LnByb3RvdHlwZS5mb3JFYWNoKSB7XG4gIEFycmF5LnByb3RvdHlwZS5mb3JFYWNoID0gZnVuY3Rpb24gKGZuLCBjdHgpIHtcbiAgICBpZiAodGhpcyA9PT0gdm9pZCAwIHx8IHRoaXMgPT09IG51bGwgfHwgdHlwZW9mIGZuICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7XG4gICAgfVxuICAgIHZhciB0ID0gdGhpcztcbiAgICB2YXIgbGVuID0gdC5sZW5ndGg7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgaWYgKGkgaW4gdCkgeyBmbi5jYWxsKGN0eCwgdFtpXSwgaSwgdCk7IH1cbiAgICB9XG4gIH07XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbmlmICghQXJyYXkucHJvdG90eXBlLmluZGV4T2YpIHtcbiAgQXJyYXkucHJvdG90eXBlLmluZGV4T2YgPSBmdW5jdGlvbiAod2hhdCwgc3RhcnQpIHtcbiAgICBpZiAodGhpcyA9PT0gdW5kZWZpbmVkIHx8IHRoaXMgPT09IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoKTtcbiAgICB9XG4gICAgdmFyIGxlbmd0aCA9IHRoaXMubGVuZ3RoO1xuICAgIHN0YXJ0ID0gK3N0YXJ0IHx8IDA7XG4gICAgaWYgKE1hdGguYWJzKHN0YXJ0KSA9PT0gSW5maW5pdHkpIHtcbiAgICAgIHN0YXJ0ID0gMDtcbiAgICB9IGVsc2UgaWYgKHN0YXJ0IDwgMCkge1xuICAgICAgc3RhcnQgKz0gbGVuZ3RoO1xuICAgICAgaWYgKHN0YXJ0IDwgMCkgeyBzdGFydCA9IDA7IH1cbiAgICB9XG4gICAgZm9yICg7IHN0YXJ0IDwgbGVuZ3RoOyBzdGFydCsrKSB7XG4gICAgICBpZiAodGhpc1tzdGFydF0gPT09IHdoYXQpIHtcbiAgICAgICAgcmV0dXJuIHN0YXJ0O1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gLTE7XG4gIH07XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbkFycmF5LmlzQXJyYXkgfHwgKEFycmF5LmlzQXJyYXkgPSBmdW5jdGlvbiAoYSkge1xuICByZXR1cm4gJycgKyBhICE9PSBhICYmIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChhKSA9PT0gJ1tvYmplY3QgQXJyYXldJztcbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5pZiAoIUFycmF5LnByb3RvdHlwZS5tYXApIHtcbiAgQXJyYXkucHJvdG90eXBlLm1hcCA9IGZ1bmN0aW9uIChmbiwgY3R4KSB7XG4gICAgdmFyIGNvbnRleHQsIHJlc3VsdCwgaTtcblxuICAgIGlmICh0aGlzID09IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ3RoaXMgaXMgbnVsbCBvciBub3QgZGVmaW5lZCcpO1xuICAgIH1cblxuICAgIHZhciBzb3VyY2UgPSBPYmplY3QodGhpcyk7XG4gICAgdmFyIGxlbiA9IHNvdXJjZS5sZW5ndGggPj4+IDA7XG5cbiAgICBpZiAodHlwZW9mIGZuICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGZuICsgJyBpcyBub3QgYSBmdW5jdGlvbicpO1xuICAgIH1cblxuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgY29udGV4dCA9IGN0eDtcbiAgICB9XG5cbiAgICByZXN1bHQgPSBuZXcgQXJyYXkobGVuKTtcbiAgICBpID0gMDtcblxuICAgIHdoaWxlIChpIDwgbGVuKSB7XG4gICAgICBpZiAoaSBpbiBzb3VyY2UpIHtcbiAgICAgICAgcmVzdWx0W2ldID0gZm4uY2FsbChjb250ZXh0LCBzb3VyY2VbaV0sIGksIHNvdXJjZSk7XG4gICAgICB9XG4gICAgICBpKys7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH07XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbmlmICghQXJyYXkucHJvdG90eXBlLnNvbWUpIHtcbiAgQXJyYXkucHJvdG90eXBlLnNvbWUgPSBmdW5jdGlvbiAoZm4sIGN0eCkge1xuICAgIHZhciBjb250ZXh0LCBpO1xuXG4gICAgaWYgKHRoaXMgPT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigndGhpcyBpcyBudWxsIG9yIG5vdCBkZWZpbmVkJyk7XG4gICAgfVxuXG4gICAgdmFyIHNvdXJjZSA9IE9iamVjdCh0aGlzKTtcbiAgICB2YXIgbGVuID0gc291cmNlLmxlbmd0aCA+Pj4gMDtcblxuICAgIGlmICh0eXBlb2YgZm4gIT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoZm4gKyAnIGlzIG5vdCBhIGZ1bmN0aW9uJyk7XG4gICAgfVxuXG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG4gICAgICBjb250ZXh0ID0gY3R4O1xuICAgIH1cblxuICAgIGkgPSAwO1xuXG4gICAgd2hpbGUgKGkgPCBsZW4pIHtcbiAgICAgIGlmIChpIGluIHNvdXJjZSkge1xuICAgICAgICB2YXIgdGVzdCA9IGZuLmNhbGwoY29udGV4dCwgc291cmNlW2ldLCBpLCBzb3VyY2UpO1xuICAgICAgICBpZiAodGVzdCkge1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpKys7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfTtcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxuaWYgKCFGdW5jdGlvbi5wcm90b3R5cGUuYmluZCkge1xuICBGdW5jdGlvbi5wcm90b3R5cGUuYmluZCA9IGZ1bmN0aW9uIChjb250ZXh0KSB7XG4gICAgaWYgKHR5cGVvZiB0aGlzICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdGdW5jdGlvbi5wcm90b3R5cGUuYmluZCAtIHdoYXQgaXMgdHJ5aW5nIHRvIGJlIGJvdW5kIGlzIG5vdCBjYWxsYWJsZScpO1xuICAgIH1cbiAgICB2YXIgY3VycmllZCA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG4gICAgdmFyIG9yaWdpbmFsID0gdGhpcztcbiAgICB2YXIgTm9PcCA9IGZ1bmN0aW9uICgpIHt9O1xuICAgIHZhciBib3VuZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBjdHggPSB0aGlzIGluc3RhbmNlb2YgTm9PcCAmJiBjb250ZXh0ID8gdGhpcyA6IGNvbnRleHQ7XG4gICAgICB2YXIgYXJncyA9IGN1cnJpZWQuY29uY2F0KEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cykpO1xuICAgICAgcmV0dXJuIG9yaWdpbmFsLmFwcGx5KGN0eCwgYXJncyk7XG4gICAgfTtcbiAgICBOb09wLnByb3RvdHlwZSA9IHRoaXMucHJvdG90eXBlO1xuICAgIGJvdW5kLnByb3RvdHlwZSA9IG5ldyBOb09wKCk7XG4gICAgcmV0dXJuIGJvdW5kO1xuICB9O1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgaGFzT3duID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcbnZhciBoYXNEb250RW51bUJ1ZyA9ICEoeyB0b1N0cmluZzogbnVsbCB9KS5wcm9wZXJ0eUlzRW51bWVyYWJsZSgndG9TdHJpbmcnKTtcbnZhciBkb250RW51bXMgPSBbXG4gICd0b1N0cmluZycsXG4gICd0b0xvY2FsZVN0cmluZycsXG4gICd2YWx1ZU9mJyxcbiAgJ2hhc093blByb3BlcnR5JyxcbiAgJ2lzUHJvdG90eXBlT2YnLFxuICAncHJvcGVydHlJc0VudW1lcmFibGUnLFxuICAnY29uc3RydWN0b3InXG5dO1xudmFyIGRvbnRFbnVtc0xlbmd0aCA9IGRvbnRFbnVtcy5sZW5ndGg7XG5cbmlmICghT2JqZWN0LmtleXMpIHtcbiAgT2JqZWN0LmtleXMgPSBmdW5jdGlvbihvYmopIHtcbiAgICBpZiAodHlwZW9mIG9iaiAhPT0gJ29iamVjdCcgJiYgKHR5cGVvZiBvYmogIT09ICdmdW5jdGlvbicgfHwgb2JqID09PSBudWxsKSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignT2JqZWN0LmtleXMgY2FsbGVkIG9uIG5vbi1vYmplY3QnKTtcbiAgICB9XG5cbiAgICB2YXIgcmVzdWx0ID0gW10sIHByb3AsIGk7XG5cbiAgICBmb3IgKHByb3AgaW4gb2JqKSB7XG4gICAgICBpZiAoaGFzT3duLmNhbGwob2JqLCBwcm9wKSkge1xuICAgICAgICByZXN1bHQucHVzaChwcm9wKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoaGFzRG9udEVudW1CdWcpIHtcbiAgICAgIGZvciAoaSA9IDA7IGkgPCBkb250RW51bXNMZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoaGFzT3duLmNhbGwob2JqLCBkb250RW51bXNbaV0pKSB7XG4gICAgICAgICAgcmVzdWx0LnB1c2goZG9udEVudW1zW2ldKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9O1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG5pZiAoIVN0cmluZy5wcm90b3R5cGUudHJpbSkge1xuICBTdHJpbmcucHJvdG90eXBlLnRyaW0gPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMucmVwbGFjZSgvXlxccyt8XFxzKyQvZywgJycpO1xuICB9O1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vLyB0aGVzZSBhcmUgb25seSByZXF1aXJlZCBmb3IgSUUgPCA5XG4vLyBtYXliZSBtb3ZlIHRvIElFLXNwZWNpZmljIGRpc3Rybz9cbnJlcXVpcmUoJy4vcG9seWZpbGxzL2Z1bmN0aW9uLmJpbmQnKTtcbnJlcXVpcmUoJy4vcG9seWZpbGxzL2FycmF5LmZvcmVhY2gnKTtcbnJlcXVpcmUoJy4vcG9seWZpbGxzL2FycmF5Lm1hcCcpO1xucmVxdWlyZSgnLi9wb2x5ZmlsbHMvYXJyYXkuZmlsdGVyJyk7XG5yZXF1aXJlKCcuL3BvbHlmaWxscy9hcnJheS5pc2FycmF5Jyk7XG5yZXF1aXJlKCcuL3BvbHlmaWxscy9hcnJheS5pbmRleG9mJyk7XG5yZXF1aXJlKCcuL3BvbHlmaWxscy9hcnJheS5zb21lJyk7XG5yZXF1aXJlKCcuL3BvbHlmaWxscy9zdHJpbmcudHJpbScpO1xucmVxdWlyZSgnLi9wb2x5ZmlsbHMvb2JqZWN0LmtleXMnKTtcblxudmFyIGNvcmUgPSByZXF1aXJlKCcuL2NvcmUnKTtcbnZhciBpbmRleCA9IHJlcXVpcmUoJy4vaW5kZXgnKTtcbnZhciB1c2UgPSByZXF1aXJlKCcuL3VzZScpO1xuXG5jb3JlLnVzZSA9IHVzZS5iaW5kKGNvcmUpO1xuY29yZS5maW5kID0gaW5kZXguZmluZDtcbmNvcmUudmFsID0gcmVxdWlyZSgnLi92YWxpZGF0b3JzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gY29yZTtcbiIsIihmdW5jdGlvbiAoZ2xvYmFsKXtcbnZhciByb21lID0gcmVxdWlyZSgnLi9yb21lJyk7XG52YXIgbW9tZW50dW0gPSByZXF1aXJlKCcuL21vbWVudHVtJyk7XG5cbnJvbWUudXNlKGdsb2JhbC5tb21lbnQpO1xuXG5pZiAobW9tZW50dW0ubW9tZW50ID09PSB2b2lkIDApIHtcbiAgdGhyb3cgbmV3IEVycm9yKCdyb21lIGRlcGVuZHMgb24gbW9tZW50LmpzLCB5b3UgY2FuIGdldCBpdCBhdCBodHRwOi8vbW9tZW50anMuY29tLCBvciB5b3UgY291bGQgdXNlIHRoZSBidW5kbGVkIGRpc3RyaWJ1dGlvbiBmaWxlIGluc3RlYWQuJyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gcm9tZTtcblxufSkuY2FsbCh0aGlzLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSkiLCIndXNlIHN0cmljdCc7XG5cbmZ1bmN0aW9uIHRleHQgKGVsZW0sIHZhbHVlKSB7XG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAyKSB7XG4gICAgZWxlbS5pbm5lclRleHQgPSBlbGVtLnRleHRDb250ZW50ID0gdmFsdWU7XG4gIH1cbiAgcmV0dXJuIGVsZW0uaW5uZXJUZXh0IHx8IGVsZW0udGV4dENvbnRlbnQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gdGV4dDtcbiIsIid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiB0aHJvdHRsZSAoZm4sIGJvdW5kYXJ5KSB7XG4gIHZhciBsYXN0ID0gLUluZmluaXR5O1xuICB2YXIgdGltZXI7XG4gIHJldHVybiBmdW5jdGlvbiBib3VuY2VkICgpIHtcbiAgICBpZiAodGltZXIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdW5ib3VuZCgpO1xuXG4gICAgZnVuY3Rpb24gdW5ib3VuZCAoKSB7XG4gICAgICBjbGVhclRpbWVvdXQodGltZXIpO1xuICAgICAgdGltZXIgPSBudWxsO1xuICAgICAgdmFyIG5leHQgPSBsYXN0ICsgYm91bmRhcnk7XG4gICAgICB2YXIgbm93ID0gRGF0ZS5ub3coKTtcbiAgICAgIGlmIChub3cgPiBuZXh0KSB7XG4gICAgICAgIGxhc3QgPSBub3c7XG4gICAgICAgIGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aW1lciA9IHNldFRpbWVvdXQodW5ib3VuZCwgbmV4dCAtIG5vdyk7XG4gICAgICB9XG4gICAgfVxuICB9O1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIG1vbWVudHVtID0gcmVxdWlyZSgnLi9tb21lbnR1bScpO1xuXG5mdW5jdGlvbiB1c2UgKG1vbWVudCkge1xuICB0aGlzLm1vbWVudCA9IG1vbWVudHVtLm1vbWVudCA9IG1vbWVudDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB1c2U7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBpbmRleCA9IHJlcXVpcmUoJy4vaW5kZXgnKTtcbnZhciBwYXJzZSA9IHJlcXVpcmUoJy4vcGFyc2UnKTtcbnZhciBhc3NvY2lhdGlvbiA9IHJlcXVpcmUoJy4vYXNzb2NpYXRpb24nKTtcblxuZnVuY3Rpb24gY29tcGFyZUJ1aWxkZXIgKGNvbXBhcmUpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIGZhY3RvcnkgKHZhbHVlKSB7XG4gICAgdmFyIGZpeGVkID0gcGFyc2UodmFsdWUpO1xuXG4gICAgcmV0dXJuIGZ1bmN0aW9uIHZhbGlkYXRlIChkYXRlKSB7XG4gICAgICB2YXIgY2FsID0gaW5kZXguZmluZCh2YWx1ZSk7XG4gICAgICB2YXIgbGVmdCA9IHBhcnNlKGRhdGUpO1xuICAgICAgdmFyIHJpZ2h0ID0gZml4ZWQgfHwgY2FsICYmIGNhbC5nZXRNb21lbnQoKTtcbiAgICAgIGlmICghcmlnaHQpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgICBpZiAoY2FsKSB7XG4gICAgICAgIGFzc29jaWF0aW9uLmFkZCh0aGlzLCBjYWwpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGNvbXBhcmUobGVmdCwgcmlnaHQpO1xuICAgIH07XG4gIH07XG59XG5cbmZ1bmN0aW9uIHJhbmdlQnVpbGRlciAoaG93LCBjb21wYXJlKSB7XG4gIHJldHVybiBmdW5jdGlvbiBmYWN0b3J5IChzdGFydCwgZW5kKSB7XG4gICAgdmFyIGRhdGVzO1xuICAgIHZhciBsZW4gPSBhcmd1bWVudHMubGVuZ3RoO1xuXG4gICAgaWYgKEFycmF5LmlzQXJyYXkoc3RhcnQpKSB7XG4gICAgICBkYXRlcyA9IHN0YXJ0O1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAobGVuID09PSAxKSB7XG4gICAgICAgIGRhdGVzID0gW3N0YXJ0XTtcbiAgICAgIH0gZWxzZSBpZiAobGVuID09PSAyKSB7XG4gICAgICAgIGRhdGVzID0gW1tzdGFydCwgZW5kXV07XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGZ1bmN0aW9uIHZhbGlkYXRlIChkYXRlKSB7XG4gICAgICByZXR1cm4gZGF0ZXMubWFwKGV4cGFuZC5iaW5kKHRoaXMpKVtob3ddKGNvbXBhcmUuYmluZCh0aGlzLCBkYXRlKSk7XG4gICAgfTtcblxuICAgIGZ1bmN0aW9uIGV4cGFuZCAodmFsdWUpIHtcbiAgICAgIHZhciBzdGFydCwgZW5kO1xuICAgICAgdmFyIGNhbCA9IGluZGV4LmZpbmQodmFsdWUpO1xuICAgICAgaWYgKGNhbCkge1xuICAgICAgICBzdGFydCA9IGVuZCA9IGNhbC5nZXRNb21lbnQoKTtcbiAgICAgIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgc3RhcnQgPSB2YWx1ZVswXTsgZW5kID0gdmFsdWVbMV07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzdGFydCA9IGVuZCA9IHZhbHVlO1xuICAgICAgfVxuICAgICAgaWYgKGNhbCkge1xuICAgICAgICBhc3NvY2lhdGlvbi5hZGQoY2FsLCB0aGlzKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB7XG4gICAgICAgIHN0YXJ0OiBwYXJzZShzdGFydCkuc3RhcnRPZignZGF5JykudG9EYXRlKCksXG4gICAgICAgIGVuZDogcGFyc2UoZW5kKS5lbmRPZignZGF5JykudG9EYXRlKClcbiAgICAgIH07XG4gICAgfVxuICB9O1xufVxuXG52YXIgYWZ0ZXJFcSAgPSBjb21wYXJlQnVpbGRlcihmdW5jdGlvbiAobGVmdCwgcmlnaHQpIHsgcmV0dXJuIGxlZnQgPj0gcmlnaHQ7IH0pO1xudmFyIGFmdGVyICAgID0gY29tcGFyZUJ1aWxkZXIoZnVuY3Rpb24gKGxlZnQsIHJpZ2h0KSB7IHJldHVybiBsZWZ0ICA+IHJpZ2h0OyB9KTtcbnZhciBiZWZvcmVFcSA9IGNvbXBhcmVCdWlsZGVyKGZ1bmN0aW9uIChsZWZ0LCByaWdodCkgeyByZXR1cm4gbGVmdCA8PSByaWdodDsgfSk7XG52YXIgYmVmb3JlICAgPSBjb21wYXJlQnVpbGRlcihmdW5jdGlvbiAobGVmdCwgcmlnaHQpIHsgcmV0dXJuIGxlZnQgIDwgcmlnaHQ7IH0pO1xuXG52YXIgZXhjZXB0ICAgPSByYW5nZUJ1aWxkZXIoJ2V2ZXJ5JywgZnVuY3Rpb24gKGxlZnQsIHJpZ2h0KSB7IHJldHVybiByaWdodC5zdGFydCAgPiBsZWZ0IHx8IHJpZ2h0LmVuZCAgPCBsZWZ0OyB9KTtcbnZhciBvbmx5ICAgICA9IHJhbmdlQnVpbGRlcignc29tZScsICBmdW5jdGlvbiAobGVmdCwgcmlnaHQpIHsgcmV0dXJuIHJpZ2h0LnN0YXJ0IDw9IGxlZnQgJiYgcmlnaHQuZW5kID49IGxlZnQ7IH0pO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgYWZ0ZXJFcTogYWZ0ZXJFcSxcbiAgYWZ0ZXI6IGFmdGVyLFxuICBiZWZvcmVFcTogYmVmb3JlRXEsXG4gIGJlZm9yZTogYmVmb3JlLFxuICBleGNlcHQ6IGV4Y2VwdCxcbiAgb25seTogb25seVxufTtcbiJdfQ== |
| (31) |
| }); |