You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@htrace.apache.org by cm...@apache.org on 2015/04/23 01:07:56 UTC

[02/41] incubator-htrace git commit: HTRACE-154. Move go and web to htrace-htraced (abe via cmccabe)

http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/39e89ea0/htrace-htraced/src/web/lib/rome-2.1.0/rome.standalone.js
----------------------------------------------------------------------
diff --git a/htrace-htraced/src/web/lib/rome-2.1.0/rome.standalone.js b/htrace-htraced/src/web/lib/rome-2.1.0/rome.standalone.js
new file mode 100644
index 0000000..a27667f
--- /dev/null
+++ b/htrace-htraced/src/web/lib/rome-2.1.0/rome.standalone.js
@@ -0,0 +1,1860 @@
+/**
+ * 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,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9Vc2Vycy9uaWNvL2Rldi9yb21lL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCIvVXNlcnMvbmljby9kZXYvcm9tZS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcHJvY2Vzcy9icm93c2VyLmpzIiwiL1VzZXJzL25pY28vZGV2L3JvbWUvbm9kZV9tb2R1bGVzL2NvbnRyYS5lbWl0dGVyL2luZGV4LmpzIiwiL1VzZXJzL25pY28vZGV2L3JvbWUvbm9kZV9tb2R1bGVzL2NvbnRyYS5lbWl0dGVyL3NyYy9jb250cmEuZW1pdHRlci5qcyIsIi9Vc2Vycy9uaWNvL2Rldi9yb21lL25vZGVfbW9kdWxlcy9yYWYvaW5kZXguanMiLCIvVXNlcnMvbmljby9kZXYvcm9tZS9ub2RlX21vZHVsZXMvcmFmL25vZGVfbW9kdWxlcy9wZXJmb3JtYW5jZS1ub3cvbGliL3BlcmZvcm1hbmNlLW5vdy5qcyIsIi9Vc2Vycy9uaWNvL2Rldi9yb21lL3NyYy9hc3NvY2lhdGlvbi5qcyIsIi9Vc2Vycy9uaWNvL2Rldi9yb21lL3NyYy9jYWxlbmRhci5qcyIsIi9Vc2Vycy9uaWNvL2Rldi9yb21lL3NyYy9jbGFzc2VzLmpzIiwiL1VzZXJzL25pY28vZGV2L3JvbWUvc3JjL2Nsb25lLmpzIiwiL1VzZXJzL25pY28vZGV2L3JvbWUvc3JjL2NvcmUuanMiLCIvVXNlcnMvbmljby9kZXYvcm9tZS9zcmMvZGVmYXVsdHMuanMiLCIvVXNlcnMvbmljby9kZXYvcm9
 tZS9zcmMvZG9tLmpzIiwiL1VzZXJzL25pY28vZGV2L3JvbWUvc3JjL2V2ZW50cy5qcyIsIi9Vc2Vycy9uaWNvL2Rldi9yb21lL3NyYy9pbmRleC5qcyIsIi9Vc2Vycy9uaWNvL2Rldi9yb21lL3NyYy9pbmxpbmUuanMiLCIvVXNlcnMvbmljby9kZXYvcm9tZS9zcmMvaW5wdXQuanMiLCIvVXNlcnMvbmljby9kZXYvcm9tZS9zcmMvaXNJbnB1dC5qcyIsIi9Vc2Vycy9uaWNvL2Rldi9yb21lL3NyYy9tb21lbnR1bS5qcyIsIi9Vc2Vycy9uaWNvL2Rldi9yb21lL3NyYy9ub29wLmpzIiwiL1VzZXJzL25pY28vZGV2L3JvbWUvc3JjL3BhcnNlLmpzIiwiL1VzZXJzL25pY28vZGV2L3JvbWUvc3JjL3BvbHlmaWxscy9hcnJheS5maWx0ZXIuanMiLCIvVXNlcnMvbmljby9kZXYvcm9tZS9zcmMvcG9seWZpbGxzL2FycmF5LmZvcmVhY2guanMiLCIvVXNlcnMvbmljby9kZXYvcm9tZS9zcmMvcG9seWZpbGxzL2FycmF5LmluZGV4b2YuanMiLCIvVXNlcnMvbmljby9kZXYvcm9tZS9zcmMvcG9seWZpbGxzL2FycmF5LmlzYXJyYXkuanMiLCIvVXNlcnMvbmljby9kZXYvcm9tZS9zcmMvcG9seWZpbGxzL2FycmF5Lm1hcC5qcyIsIi9Vc2Vycy9uaWNvL2Rldi9yb21lL3NyYy9wb2x5ZmlsbHMvYXJyYXkuc29tZS5qcyIsIi9Vc2Vycy9uaWNvL2Rldi9yb21lL3NyYy9wb2x5ZmlsbHMvZnVuY3Rpb24uYmluZC5qcyIsIi9Vc2Vycy9uaWNvL2Rldi9yb21lL3NyYy9wb2x5ZmlsbHMvb2JqZWN0LmtleXMuanMiLCIvVXNlcnMvbmljby9kZXYv
 cm9tZS9zcmMvcG9seWZpbGxzL3N0cmluZy50cmltLmpzIiwiL1VzZXJzL25pY28vZGV2L3JvbWUvc3JjL3JvbWUuanMiLCIvVXNlcnMvbmljby9kZXYvcm9tZS9zcmMvcm9tZS5zdGFuZGFsb25lLmpzIiwiL1VzZXJzL25pY28vZGV2L3JvbWUvc3JjL3RleHQuanMiLCIvVXNlcnMvbmljby9kZXYvcm9tZS9zcmMvdGhyb3R0bGUuanMiLCIvVXNlcnMvbmljby9kZXYvcm9tZS9zcmMvdXNlLmpzIiwiL1VzZXJzL25pY28vZGV2L3JvbWUvc3JjL3ZhbGlkYXRvcnMuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvREE7QUFDQTs7QUNEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Q
 UFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0VBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQT
 tBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUN
 BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtB
 QUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQ
 TtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QU
 FDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0F
 BQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFD
 QTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQ
 UNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcElBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOz
 tBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNYQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUN
 BO0FBQ0E7QUFDQTs7QUNuQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6QkE7QUFD
 QTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dGhyb3cgbmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKX12YXIgZj1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwoZi5leHBvc
 nRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxmLGYuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc30pIiwiLy8gc2hpbSBmb3IgdXNpbmcgcHJvY2VzcyBpbiBicm93c2VyXG5cbnZhciBwcm9jZXNzID0gbW9kdWxlLmV4cG9ydHMgPSB7fTtcblxucHJvY2Vzcy5uZXh0VGljayA9IChmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGNhblNldEltbWVkaWF0ZSA9IHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnXG4gICAgJiYgd2luZG93LnNldEltbWVkaWF0ZTtcbiAgICB2YXIgY2FuUG9zdCA9IHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnXG4gICAgJiYgd2luZG93LnBvc3RNZXNzYWdlICYmIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyXG4gICAgO1xuXG4gICAgaWYgKGNhblNldEltbWVkaWF0ZSkge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKGYpIHsgcmV0dXJuIHdpbmRvdy5zZXRJbW1lZGlhdGUoZikgfTtcbiAgICB9XG5cbiAgICBpZiAoY2FuUG9zdCkge1xuICAgICAgICB2YXIgcXVldWUgPSBbXTtcbiAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBmdW5jdGlvbiAoZXYpIHtcbiAgICAgICAgICAgIHZhciBzb3VyY2UgPSBldi5zb3VyY2U7XG4gICAgICAgICAgIC
 BpZiAoKHNvdXJjZSA9PT0gd2luZG93IHx8IHNvdXJjZSA9PT0gbnVsbCkgJiYgZXYuZGF0YSA9PT0gJ3Byb2Nlc3MtdGljaycpIHtcbiAgICAgICAgICAgICAgICBldi5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICAgICAgICBpZiAocXVldWUubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgZm4gPSBxdWV1ZS5zaGlmdCgpO1xuICAgICAgICAgICAgICAgICAgICBmbigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSwgdHJ1ZSk7XG5cbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIG5leHRUaWNrKGZuKSB7XG4gICAgICAgICAgICBxdWV1ZS5wdXNoKGZuKTtcbiAgICAgICAgICAgIHdpbmRvdy5wb3N0TWVzc2FnZSgncHJvY2Vzcy10aWNrJywgJyonKTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICByZXR1cm4gZnVuY3Rpb24gbmV4dFRpY2soZm4pIHtcbiAgICAgICAgc2V0VGltZW91dChmbiwgMCk7XG4gICAgfTtcbn0pKCk7XG5cbnByb2Nlc3MudGl0bGUgPSAnYnJvd3Nlcic7XG5wcm9jZXNzLmJyb3dzZXIgPSB0cnVlO1xucHJvY2Vzcy5lbnYgPSB7fTtcbnByb2Nlc3MuYXJndiA9IFtdO1xuXG5mdW5jdGlvbiBub29wKCkge31cblxucHJvY2Vzcy5vbiA9IG5vb3A7XG5wcm9jZXNzLmFkZExpc3RlbmVyID0gbm9vcDtcbnByb2Nlc3Mub25jZSA9IG5vb3A7XG5wcm9jZXNzLm9mZiA9IG5vb3A7XG5wcm9jZXNzLnJlbW92ZUxpc3RlbmVyID0gbm9vcDt
 cbnByb2Nlc3MucmVtb3ZlQWxsTGlzdGVuZXJzID0gbm9vcDtcbnByb2Nlc3MuZW1pdCA9IG5vb3A7XG5cbnByb2Nlc3MuYmluZGluZyA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwcm9jZXNzLmJpbmRpbmcgaXMgbm90IHN1cHBvcnRlZCcpO1xufVxuXG4vLyBUT0RPKHNodHlsbWFuKVxucHJvY2Vzcy5jd2QgPSBmdW5jdGlvbiAoKSB7IHJldHVybiAnLycgfTtcbnByb2Nlc3MuY2hkaXIgPSBmdW5jdGlvbiAoZGlyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwcm9jZXNzLmNoZGlyIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn07XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vc3JjL2NvbnRyYS5lbWl0dGVyLmpzJyk7XG4iLCIoZnVuY3Rpb24gKHByb2Nlc3Mpe1xuKGZ1bmN0aW9uIChyb290LCB1bmRlZmluZWQpIHtcbiAgJ3VzZSBzdHJpY3QnO1xuXG4gIHZhciB1bmRlZiA9ICcnICsgdW5kZWZpbmVkO1xuICBmdW5jdGlvbiBhdG9hIChhLCBuKSB7IHJldHVybiBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhLCBuKTsgfVxuICBmdW5jdGlvbiBkZWJvdW5jZSAoZm4sIGFyZ3MsIGN0eCkgeyBpZiAoIWZuKSB7IHJldHVybjsgfSB0aWNrKGZ1bmN0aW9uIHJ1biAoKSB7IGZuLmFwcGx5KGN0eCB8fCBudWxsLCBhcmdzIHx8IFtdKTsgfSk7IH1cblxuICAvLyBjcm9zcy1wbGF0Zm9ybSB0aWNrZXJcbiAgdmFyIHNpID0gdHlwZW9mIHNldEltbWVkaWF0ZSA9PT0gJ2Z1bmN0aW9u
 JywgdGljaztcbiAgaWYgKHNpKSB7XG4gICAgdGljayA9IGZ1bmN0aW9uIChmbikgeyBzZXRJbW1lZGlhdGUoZm4pOyB9O1xuICB9IGVsc2UgaWYgKHR5cGVvZiBwcm9jZXNzICE9PSB1bmRlZiAmJiBwcm9jZXNzLm5leHRUaWNrKSB7XG4gICAgdGljayA9IHByb2Nlc3MubmV4dFRpY2s7XG4gIH0gZWxzZSB7XG4gICAgdGljayA9IGZ1bmN0aW9uIChmbikgeyBzZXRUaW1lb3V0KGZuLCAwKTsgfTtcbiAgfVxuXG4gIGZ1bmN0aW9uIF9lbWl0dGVyICh0aGluZywgb3B0aW9ucykge1xuICAgIHZhciBvcHRzID0gb3B0aW9ucyB8fCB7fTtcbiAgICB2YXIgZXZ0ID0ge307XG4gICAgaWYgKHRoaW5nID09PSB1bmRlZmluZWQpIHsgdGhpbmcgPSB7fTsgfVxuICAgIHRoaW5nLm9uID0gZnVuY3Rpb24gKHR5cGUsIGZuKSB7XG4gICAgICBpZiAoIWV2dFt0eXBlXSkge1xuICAgICAgICBldnRbdHlwZV0gPSBbZm5dO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZXZ0W3R5cGVdLnB1c2goZm4pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaW5nO1xuICAgIH07XG4gICAgdGhpbmcub25jZSA9IGZ1bmN0aW9uICh0eXBlLCBmbikge1xuICAgICAgZm4uX29uY2UgPSB0cnVlOyAvLyB0aGluZy5vZmYoZm4pIHN0aWxsIHdvcmtzIVxuICAgICAgdGhpbmcub24odHlwZSwgZm4pO1xuICAgICAgcmV0dXJuIHRoaW5nO1xuICAgIH07XG4gICAgdGhpbmcub2ZmID0gZnVuY3Rpb24gKHR5cGUsIGZuKSB7XG4gICAgICB2YXIgYyA9IGFyZ
 3VtZW50cy5sZW5ndGg7XG4gICAgICBpZiAoYyA9PT0gMSkge1xuICAgICAgICBkZWxldGUgZXZ0W3R5cGVdO1xuICAgICAgfSBlbHNlIGlmIChjID09PSAwKSB7XG4gICAgICAgIGV2dCA9IHt9O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIGV0ID0gZXZ0W3R5cGVdO1xuICAgICAgICBpZiAoIWV0KSB7IHJldHVybiB0aGluZzsgfVxuICAgICAgICBldC5zcGxpY2UoZXQuaW5kZXhPZihmbiksIDEpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaW5nO1xuICAgIH07XG4gICAgdGhpbmcuZW1pdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBhcmdzID0gYXRvYShhcmd1bWVudHMpO1xuICAgICAgcmV0dXJuIHRoaW5nLmVtaXR0ZXJTbmFwc2hvdChhcmdzLnNoaWZ0KCkpLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgIH07XG4gICAgdGhpbmcuZW1pdHRlclNuYXBzaG90ID0gZnVuY3Rpb24gKHR5cGUpIHtcbiAgICAgIHZhciBldCA9IChldnRbdHlwZV0gfHwgW10pLnNsaWNlKDApO1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGFyZ3MgPSBhdG9hKGFyZ3VtZW50cyk7XG4gICAgICAgIHZhciBjdHggPSB0aGlzIHx8IHRoaW5nO1xuICAgICAgICBpZiAodHlwZSA9PT0gJ2Vycm9yJyAmJiBvcHRzLnRocm93cyAhPT0gZmFsc2UgJiYgIWV0Lmxlbmd0aCkgeyB0aHJvdyBhcmdzLmxlbmd0aCA9PT0gMSA/IGFyZ3NbMF0gOiBhcmdzOyB9XG4gICAgICAgIGV2dFt0eXBlXSA9IGV0LmZpbH
 RlcihmdW5jdGlvbiBlbWl0dGVyIChsaXN0ZW4pIHtcbiAgICAgICAgICBpZiAob3B0cy5hc3luYykgeyBkZWJvdW5jZShsaXN0ZW4sIGFyZ3MsIGN0eCk7IH0gZWxzZSB7IGxpc3Rlbi5hcHBseShjdHgsIGFyZ3MpOyB9XG4gICAgICAgICAgcmV0dXJuICFsaXN0ZW4uX29uY2U7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdGhpbmc7XG4gICAgICB9O1xuICAgIH1cbiAgICByZXR1cm4gdGhpbmc7XG4gIH1cblxuICAvLyBjcm9zcy1wbGF0Zm9ybSBleHBvcnRcbiAgaWYgKHR5cGVvZiBtb2R1bGUgIT09IHVuZGVmICYmIG1vZHVsZS5leHBvcnRzKSB7XG4gICAgbW9kdWxlLmV4cG9ydHMgPSBfZW1pdHRlcjtcbiAgfSBlbHNlIHtcbiAgICByb290LmNvbnRyYSA9IHJvb3QuY29udHJhIHx8IHt9O1xuICAgIHJvb3QuY29udHJhLmVtaXR0ZXIgPSBfZW1pdHRlcjtcbiAgfVxufSkodGhpcyk7XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwiRldhQVNIXCIpKSIsInZhciBub3cgPSByZXF1aXJlKCdwZXJmb3JtYW5jZS1ub3cnKVxuICAsIGdsb2JhbCA9IHR5cGVvZiB3aW5kb3cgPT09ICd1bmRlZmluZWQnID8ge30gOiB3aW5kb3dcbiAgLCB2ZW5kb3JzID0gWydtb3onLCAnd2Via2l0J11cbiAgLCBzdWZmaXggPSAnQW5pbWF0aW9uRnJhbWUnXG4gICwgcmFmID0gZ2xvYmFsWydyZXF1ZXN0JyArIHN1ZmZpeF1cbiAgLCBjYWYgPSBnbG9iYWxbJ2NhbmNlbCcgKyBzdWZmaXhdIHx8IGdsb2JhbFsnY2FuY2VsUmVxdWV
 zdCcgKyBzdWZmaXhdXG4gICwgaXNOYXRpdmUgPSB0cnVlXG5cbmZvcih2YXIgaSA9IDA7IGkgPCB2ZW5kb3JzLmxlbmd0aCAmJiAhcmFmOyBpKyspIHtcbiAgcmFmID0gZ2xvYmFsW3ZlbmRvcnNbaV0gKyAnUmVxdWVzdCcgKyBzdWZmaXhdXG4gIGNhZiA9IGdsb2JhbFt2ZW5kb3JzW2ldICsgJ0NhbmNlbCcgKyBzdWZmaXhdXG4gICAgICB8fCBnbG9iYWxbdmVuZG9yc1tpXSArICdDYW5jZWxSZXF1ZXN0JyArIHN1ZmZpeF1cbn1cblxuLy8gU29tZSB2ZXJzaW9ucyBvZiBGRiBoYXZlIHJBRiBidXQgbm90IGNBRlxuaWYoIXJhZiB8fCAhY2FmKSB7XG4gIGlzTmF0aXZlID0gZmFsc2VcblxuICB2YXIgbGFzdCA9IDBcbiAgICAsIGlkID0gMFxuICAgICwgcXVldWUgPSBbXVxuICAgICwgZnJhbWVEdXJhdGlvbiA9IDEwMDAgLyA2MFxuXG4gIHJhZiA9IGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG4gICAgaWYocXVldWUubGVuZ3RoID09PSAwKSB7XG4gICAgICB2YXIgX25vdyA9IG5vdygpXG4gICAgICAgICwgbmV4dCA9IE1hdGgubWF4KDAsIGZyYW1lRHVyYXRpb24gLSAoX25vdyAtIGxhc3QpKVxuICAgICAgbGFzdCA9IG5leHQgKyBfbm93XG4gICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgY3AgPSBxdWV1ZS5zbGljZSgwKVxuICAgICAgICAvLyBDbGVhciBxdWV1ZSBoZXJlIHRvIHByZXZlbnRcbiAgICAgICAgLy8gY2FsbGJhY2tzIGZyb20gYXBwZW5kaW5nIGxpc3RlbmVyc1xuICAgICAgICAv
 LyB0byB0aGUgY3VycmVudCBmcmFtZSdzIHF1ZXVlXG4gICAgICAgIHF1ZXVlLmxlbmd0aCA9IDBcbiAgICAgICAgZm9yKHZhciBpID0gMDsgaSA8IGNwLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgaWYoIWNwW2ldLmNhbmNlbGxlZCkge1xuICAgICAgICAgICAgdHJ5e1xuICAgICAgICAgICAgICBjcFtpXS5jYWxsYmFjayhsYXN0KVxuICAgICAgICAgICAgfSBjYXRjaChlKSB7XG4gICAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7IHRocm93IGUgfSwgMClcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0sIE1hdGgucm91bmQobmV4dCkpXG4gICAgfVxuICAgIHF1ZXVlLnB1c2goe1xuICAgICAgaGFuZGxlOiArK2lkLFxuICAgICAgY2FsbGJhY2s6IGNhbGxiYWNrLFxuICAgICAgY2FuY2VsbGVkOiBmYWxzZVxuICAgIH0pXG4gICAgcmV0dXJuIGlkXG4gIH1cblxuICBjYWYgPSBmdW5jdGlvbihoYW5kbGUpIHtcbiAgICBmb3IodmFyIGkgPSAwOyBpIDwgcXVldWUubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmKHF1ZXVlW2ldLmhhbmRsZSA9PT0gaGFuZGxlKSB7XG4gICAgICAgIHF1ZXVlW2ldLmNhbmNlbGxlZCA9IHRydWVcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihmbikge1xuICAvLyBXcmFwIGluIGEgbmV3IGZ1bmN0aW9uIHRvIHByZXZlbnRcbiAgLy8gYGNhbmNlbGAgcG90ZW50aWFsbHkgYmVpbmcgYXNza
 WduZWRcbiAgLy8gdG8gdGhlIG5hdGl2ZSByQUYgZnVuY3Rpb25cbiAgaWYoIWlzTmF0aXZlKSB7XG4gICAgcmV0dXJuIHJhZi5jYWxsKGdsb2JhbCwgZm4pXG4gIH1cbiAgcmV0dXJuIHJhZi5jYWxsKGdsb2JhbCwgZnVuY3Rpb24oKSB7XG4gICAgdHJ5e1xuICAgICAgZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKVxuICAgIH0gY2F0Y2goZSkge1xuICAgICAgc2V0VGltZW91dChmdW5jdGlvbigpIHsgdGhyb3cgZSB9LCAwKVxuICAgIH1cbiAgfSlcbn1cbm1vZHVsZS5leHBvcnRzLmNhbmNlbCA9IGZ1bmN0aW9uKCkge1xuICBjYWYuYXBwbHkoZ2xvYmFsLCBhcmd1bWVudHMpXG59XG4iLCIoZnVuY3Rpb24gKHByb2Nlc3Mpe1xuLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjYuM1xuKGZ1bmN0aW9uKCkge1xuICB2YXIgZ2V0TmFub1NlY29uZHMsIGhydGltZSwgbG9hZFRpbWU7XG5cbiAgaWYgKCh0eXBlb2YgcGVyZm9ybWFuY2UgIT09IFwidW5kZWZpbmVkXCIgJiYgcGVyZm9ybWFuY2UgIT09IG51bGwpICYmIHBlcmZvcm1hbmNlLm5vdykge1xuICAgIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gcGVyZm9ybWFuY2Uubm93KCk7XG4gICAgfTtcbiAgfSBlbHNlIGlmICgodHlwZW9mIHByb2Nlc3MgIT09IFwidW5kZWZpbmVkXCIgJiYgcHJvY2VzcyAhPT0gbnVsbCkgJiYgcHJvY2Vzcy5ocnRpbWUpIHtcbiAgICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKCkge1xuICAgIC
 AgcmV0dXJuIChnZXROYW5vU2Vjb25kcygpIC0gbG9hZFRpbWUpIC8gMWU2O1xuICAgIH07XG4gICAgaHJ0aW1lID0gcHJvY2Vzcy5ocnRpbWU7XG4gICAgZ2V0TmFub1NlY29uZHMgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBocjtcbiAgICAgIGhyID0gaHJ0aW1lKCk7XG4gICAgICByZXR1cm4gaHJbMF0gKiAxZTkgKyBoclsxXTtcbiAgICB9O1xuICAgIGxvYWRUaW1lID0gZ2V0TmFub1NlY29uZHMoKTtcbiAgfSBlbHNlIGlmIChEYXRlLm5vdykge1xuICAgIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gRGF0ZS5ub3coKSAtIGxvYWRUaW1lO1xuICAgIH07XG4gICAgbG9hZFRpbWUgPSBEYXRlLm5vdygpO1xuICB9IGVsc2Uge1xuICAgIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gbmV3IERhdGUoKS5nZXRUaW1lKCkgLSBsb2FkVGltZTtcbiAgICB9O1xuICAgIGxvYWRUaW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gIH1cblxufSkuY2FsbCh0aGlzKTtcblxuLypcbi8vQCBzb3VyY2VNYXBwaW5nVVJMPXBlcmZvcm1hbmNlLW5vdy5tYXBcbiovXG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwiRldhQVNIXCIpKSIsIid1c2Ugc3RyaWN0JztcblxudmFyIGlzSW5wdXQgPSByZXF1aXJlKCcuL2lzSW5wdXQnKTtcbnZhciBiaW5kaW5ncyA9IHt9O1xuXG5mdW5jdGlvbiBoYXMgKHNvdXJjZSwgdGFyZ2V0KSB7XG4gIHZhciBiaW5kaW5nID0gYml
 uZGluZ3Nbc291cmNlLmlkXTtcbiAgcmV0dXJuIGJpbmRpbmcgJiYgYmluZGluZ1t0YXJnZXQuaWRdO1xufVxuXG5mdW5jdGlvbiBpbnNlcnQgKHNvdXJjZSwgdGFyZ2V0KSB7XG4gIHZhciBiaW5kaW5nID0gYmluZGluZ3Nbc291cmNlLmlkXTtcbiAgaWYgKCFiaW5kaW5nKSB7XG4gICAgYmluZGluZyA9IGJpbmRpbmdzW3NvdXJjZS5pZF0gPSB7fTtcbiAgfVxuICB2YXIgaW52YWxpZGF0ZSA9IGludmFsaWRhdG9yKHRhcmdldCk7XG4gIGJpbmRpbmdbdGFyZ2V0LmlkXSA9IGludmFsaWRhdGU7XG4gIHNvdXJjZS5vbignZGF0YScsIGludmFsaWRhdGUpO1xuICBzb3VyY2Uub24oJ2Rlc3Ryb3llZCcsIHJlbW92ZS5iaW5kKG51bGwsIHNvdXJjZSwgdGFyZ2V0KSk7XG59XG5cbmZ1bmN0aW9uIHJlbW92ZSAoc291cmNlLCB0YXJnZXQpIHtcbiAgdmFyIGJpbmRpbmcgPSBiaW5kaW5nc1tzb3VyY2UuaWRdO1xuICBpZiAoIWJpbmRpbmcpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgdmFyIGludmFsaWRhdGUgPSBiaW5kaW5nW3RhcmdldC5pZF07XG4gIHNvdXJjZS5vZmYoJ2RhdGEnLCBpbnZhbGlkYXRlKTtcbiAgZGVsZXRlIGJpbmRpbmdbdGFyZ2V0LmlkXTtcbn1cblxuZnVuY3Rpb24gaW52YWxpZGF0b3IgKHRhcmdldCkge1xuICByZXR1cm4gZnVuY3Rpb24gaW52YWxpZGF0ZSAoKSB7XG4gICAgdGFyZ2V0LnJlZnJlc2goKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gYWRkIChzb3VyY2UsIHRhcmdldCkge1xuICBpZiAoaXNJ
 bnB1dCh0YXJnZXQuYXNzb2NpYXRlZCkgfHwgaGFzKHNvdXJjZSwgdGFyZ2V0KSkge1xuICAgIHJldHVybjtcbiAgfVxuICBpbnNlcnQoc291cmNlLCB0YXJnZXQpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgYWRkOiBhZGQsXG4gIHJlbW92ZTogcmVtb3ZlXG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgZW1pdHRlciA9IHJlcXVpcmUoJ2NvbnRyYS5lbWl0dGVyJyk7XG52YXIgcmFmID0gcmVxdWlyZSgncmFmJyk7XG52YXIgZG9tID0gcmVxdWlyZSgnLi9kb20nKTtcbnZhciB0ZXh0ID0gcmVxdWlyZSgnLi90ZXh0Jyk7XG52YXIgcGFyc2UgPSByZXF1aXJlKCcuL3BhcnNlJyk7XG52YXIgY2xvbmUgPSByZXF1aXJlKCcuL2Nsb25lJyk7XG52YXIgZGVmYXVsdHMgPSByZXF1aXJlKCcuL2RlZmF1bHRzJyk7XG52YXIgbW9tZW50dW0gPSByZXF1aXJlKCcuL21vbWVudHVtJyk7XG52YXIgY2xhc3NlcyA9IHJlcXVpcmUoJy4vY2xhc3NlcycpO1xudmFyIGV2ZW50cyA9IHJlcXVpcmUoJy4vZXZlbnRzJyk7XG52YXIgbm9vcCA9IHJlcXVpcmUoJy4vbm9vcCcpO1xudmFyIG5vO1xuXG5mdW5jdGlvbiBjYWxlbmRhciAoY2FsZW5kYXJPcHRpb25zKSB7XG4gIHZhciBvO1xuICB2YXIgYXBpID0gZW1pdHRlcih7fSk7XG4gIHZhciByZWY7XG4gIHZhciByZWZDYWw7XG4gIHZhciBjb250YWluZXI7XG4gIHZhciByZW5kZXJlZCA9IGZhbHNlO1xuXG4gIC8vIGRhdGUgdmFyaWFibGVzXG4gIHZhciBtb250aE9mZnNld
 EF0dHJpYnV0ZSA9ICdkYXRhLXJvbWUtb2Zmc2V0JztcbiAgdmFyIHdlZWtkYXlzO1xuICB2YXIgd2Vla2RheUNvdW50O1xuICB2YXIgY2FsZW5kYXJNb250aHMgPSBbXTtcbiAgdmFyIGxhc3RZZWFyO1xuICB2YXIgbGFzdE1vbnRoO1xuICB2YXIgbGFzdERheTtcbiAgdmFyIGxhc3REYXlFbGVtZW50O1xuICB2YXIgZGF0ZXdyYXBwZXI7XG4gIHZhciBiYWNrO1xuICB2YXIgbmV4dDtcblxuICAvLyB0aW1lIHZhcmlhYmxlc1xuICB2YXIgc2Vjb25kc0luRGF5ID0gNjAgKiA2MCAqIDI0O1xuICB2YXIgdGltZTtcbiAgdmFyIHRpbWVsaXN0O1xuXG4gIGluaXQoKTtcbiAgcmFmKHJlYWR5KTtcblxuICByZXR1cm4gYXBpO1xuXG4gIGZ1bmN0aW9uIG5hcGkgKCkgeyByZXR1cm4gYXBpOyB9XG5cbiAgZnVuY3Rpb24gaW5pdCAoaW5pdE9wdGlvbnMpIHtcbiAgICBvID0gZGVmYXVsdHMoaW5pdE9wdGlvbnMgfHwgY2FsZW5kYXJPcHRpb25zLCBhcGkpO1xuICAgIGlmICghY29udGFpbmVyKSB7IGNvbnRhaW5lciA9IGRvbSh7IGNsYXNzTmFtZTogby5zdHlsZXMuY29udGFpbmVyIH0pOyB9XG4gICAgd2Vla2RheXMgPSBvLndlZWtkYXlGb3JtYXQ7XG4gICAgd2Vla2RheUNvdW50ID0gd2Vla2RheXMubGVuZ3RoO1xuICAgIGxhc3RNb250aCA9IG5vO1xuICAgIGxhc3RZZWFyID0gbm87XG4gICAgbGFzdERheSA9IG5vO1xuICAgIGxhc3REYXlFbGVtZW50ID0gbm87XG4gICAgby5hcHBlbmRUby5hcHBlbmRDaGlsZChjb250YW
 luZXIpO1xuXG4gICAgcmVtb3ZlQ2hpbGRyZW4oY29udGFpbmVyKTtcbiAgICByZW5kZXJlZCA9IGZhbHNlO1xuICAgIHJlZiA9IG8uaW5pdGlhbFZhbHVlID8gby5pbml0aWFsVmFsdWUgOiBtb21lbnR1bS5tb21lbnQoKTtcbiAgICByZWZDYWwgPSByZWYuY2xvbmUoKTtcblxuICAgIGFwaS5jb250YWluZXIgPSBjb250YWluZXI7XG4gICAgYXBpLmRlc3Ryb3llZCA9IGZhbHNlO1xuICAgIGFwaS5kZXN0cm95ID0gZGVzdHJveS5iaW5kKGFwaSwgZmFsc2UpO1xuICAgIGFwaS5lbWl0VmFsdWVzID0gZW1pdFZhbHVlcztcbiAgICBhcGkuZ2V0RGF0ZSA9IGdldERhdGU7XG4gICAgYXBpLmdldERhdGVTdHJpbmcgPSBnZXREYXRlU3RyaW5nO1xuICAgIGFwaS5nZXRNb21lbnQgPSBnZXRNb21lbnQ7XG4gICAgYXBpLmhpZGUgPSBoaWRlO1xuICAgIGFwaS5vcHRpb25zID0gY2hhbmdlT3B0aW9ucztcbiAgICBhcGkub3B0aW9ucy5yZXNldCA9IHJlc2V0T3B0aW9ucztcbiAgICBhcGkucmVmcmVzaCA9IHJlZnJlc2g7XG4gICAgYXBpLnJlc3RvcmUgPSBuYXBpO1xuICAgIGFwaS5zZXRWYWx1ZSA9IHNldFZhbHVlO1xuICAgIGFwaS5zaG93ID0gc2hvdztcblxuICAgIHNob3coKTtcbiAgICBldmVudExpc3RlbmluZygpO1xuICAgIHJlYWR5KCk7XG5cbiAgICByZXR1cm4gYXBpO1xuICB9XG5cbiAgZnVuY3Rpb24gcmVhZHkgKCkge1xuICAgIGFwaS5lbWl0KCdyZWFkeScsIGNsb25lKG8pKTtcbiAgfVxuXG4gIGZ1bmN0aW9
 uIGRlc3Ryb3kgKHNpbGVudCkge1xuICAgIGlmIChjb250YWluZXIpIHtcbiAgICAgIGNvbnRhaW5lci5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKGNvbnRhaW5lcik7XG4gICAgfVxuXG4gICAgaWYgKG8pIHtcbiAgICAgIGV2ZW50TGlzdGVuaW5nKHRydWUpO1xuICAgIH1cblxuICAgIHZhciBkZXN0cm95ZWQgPSBhcGkuZW1pdHRlclNuYXBzaG90KCdkZXN0cm95ZWQnKTtcbiAgICBhcGkuZGVzdHJveWVkID0gdHJ1ZTtcbiAgICBhcGkuZGVzdHJveSA9IG5hcGk7XG4gICAgYXBpLmVtaXRWYWx1ZXMgPSBuYXBpO1xuICAgIGFwaS5nZXREYXRlID0gbm9vcDtcbiAgICBhcGkuZ2V0RGF0ZVN0cmluZyA9IG5vb3A7XG4gICAgYXBpLmdldE1vbWVudCA9IG5vb3A7XG4gICAgYXBpLmhpZGUgPSBuYXBpO1xuICAgIGFwaS5vcHRpb25zID0gbmFwaTtcbiAgICBhcGkub3B0aW9ucy5yZXNldCA9IG5hcGk7XG4gICAgYXBpLnJlZnJlc2ggPSBuYXBpO1xuICAgIGFwaS5yZXN0b3JlID0gaW5pdDtcbiAgICBhcGkuc2V0VmFsdWUgPSBuYXBpO1xuICAgIGFwaS5zaG93ID0gbmFwaTtcbiAgICBhcGkub2ZmKCk7XG5cbiAgICBpZiAoc2lsZW50ICE9PSB0cnVlKSB7XG4gICAgICBkZXN0cm95ZWQoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXBpO1xuICB9XG5cbiAgZnVuY3Rpb24gZXZlbnRMaXN0ZW5pbmcgKHJlbW92ZSkge1xuICAgIHZhciBvcCA9IHJlbW92ZSA/ICdyZW1vdmUnIDogJ2FkZCc7XG4gICAgaWYgKG8uYXV0b0hpZGVP
 bkJsdXIpIHsgZXZlbnRzW29wXShkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQsICdmb2N1cycsIGhpZGVPbkJsdXIsIHRydWUpOyB9XG4gICAgaWYgKG8uYXV0b0hpZGVPbkNsaWNrKSB7IGV2ZW50c1tvcF0oZG9jdW1lbnQsICdjbGljaycsIGhpZGVPbkNsaWNrKTsgfVxuICB9XG5cbiAgZnVuY3Rpb24gY2hhbmdlT3B0aW9ucyAob3B0aW9ucykge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gY2xvbmUobyk7XG4gICAgfVxuICAgIGRlc3Ryb3koKTtcbiAgICBpbml0KG9wdGlvbnMpO1xuICAgIHJldHVybiBhcGk7XG4gIH1cblxuICBmdW5jdGlvbiByZXNldE9wdGlvbnMgKCkge1xuICAgIHJldHVybiBjaGFuZ2VPcHRpb25zKHsgYXBwZW5kVG86IG8uYXBwZW5kVG8gfSk7XG4gIH1cblxuICBmdW5jdGlvbiByZW5kZXIgKCkge1xuICAgIGlmIChyZW5kZXJlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICByZW5kZXJlZCA9IHRydWU7XG4gICAgcmVuZGVyRGF0ZXMoKTtcbiAgICByZW5kZXJUaW1lKCk7XG4gICAgYXBpLmVtaXQoJ3JlbmRlcicpO1xuICB9XG5cbiAgZnVuY3Rpb24gcmVuZGVyRGF0ZXMgKCkge1xuICAgIGlmICghby5kYXRlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHZhciBpO1xuICAgIGNhbGVuZGFyTW9udGhzID0gW107XG5cbiAgICBkYXRld3JhcHBlciA9IGRvbSh7IGNsYXNzTmFtZTogby5zdHlsZXMuZGF0ZSwgcGFyZW50OiBjb250Y
 WluZXIgfSk7XG5cbiAgICBmb3IgKGkgPSAwOyBpIDwgby5tb250aHNJbkNhbGVuZGFyOyBpKyspIHtcbiAgICAgIHJlbmRlck1vbnRoKGkpO1xuICAgIH1cblxuICAgIGV2ZW50cy5hZGQoYmFjaywgJ2NsaWNrJywgc3VidHJhY3RNb250aCk7XG4gICAgZXZlbnRzLmFkZChuZXh0LCAnY2xpY2snLCBhZGRNb250aCk7XG4gICAgZXZlbnRzLmFkZChkYXRld3JhcHBlciwgJ2NsaWNrJywgcGlja0RheSk7XG5cbiAgICBmdW5jdGlvbiByZW5kZXJNb250aCAoaSkge1xuICAgICAgdmFyIG1vbnRoID0gZG9tKHsgY2xhc3NOYW1lOiBvLnN0eWxlcy5tb250aCwgcGFyZW50OiBkYXRld3JhcHBlciB9KTtcbiAgICAgIGlmIChpID09PSAwKSB7XG4gICAgICAgIGJhY2sgPSBkb20oeyB0eXBlOiAnYnV0dG9uJywgY2xhc3NOYW1lOiBvLnN0eWxlcy5iYWNrLCBhdHRyaWJ1dGVzOiB7IHR5cGU6ICdidXR0b24nIH0sIHBhcmVudDogbW9udGggfSk7XG4gICAgICB9XG4gICAgICBpZiAoaSA9PT0gby5tb250aHNJbkNhbGVuZGFyIC0xKSB7XG4gICAgICAgIG5leHQgPSBkb20oeyB0eXBlOiAnYnV0dG9uJywgY2xhc3NOYW1lOiBvLnN0eWxlcy5uZXh0LCBhdHRyaWJ1dGVzOiB7IHR5cGU6ICdidXR0b24nIH0sIHBhcmVudDogbW9udGggfSk7XG4gICAgICB9XG4gICAgICB2YXIgbGFiZWwgPSBkb20oeyBjbGFzc05hbWU6IG8uc3R5bGVzLm1vbnRoTGFiZWwsIHBhcmVudDogbW9udGggfSk7XG4gICAgICB2YXIgZGF0ZSA9IGRvbSh7IH
 R5cGU6ICd0YWJsZScsIGNsYXNzTmFtZTogby5zdHlsZXMuZGF5VGFibGUsIHBhcmVudDogbW9udGggfSk7XG4gICAgICB2YXIgZGF0ZWhlYWQgPSBkb20oeyB0eXBlOiAndGhlYWQnLCBjbGFzc05hbWU6IG8uc3R5bGVzLmRheUhlYWQsIHBhcmVudDogZGF0ZSB9KTtcbiAgICAgIHZhciBkYXRlaGVhZHJvdyA9IGRvbSh7IHR5cGU6ICd0cicsIGNsYXNzTmFtZTogby5zdHlsZXMuZGF5Um93LCBwYXJlbnQ6IGRhdGVoZWFkIH0pO1xuICAgICAgdmFyIGRhdGVib2R5ID0gZG9tKHsgdHlwZTogJ3Rib2R5JywgY2xhc3NOYW1lOiBvLnN0eWxlcy5kYXlCb2R5LCBwYXJlbnQ6IGRhdGUgfSk7XG4gICAgICB2YXIgajtcblxuICAgICAgZm9yIChqID0gMDsgaiA8IHdlZWtkYXlDb3VudDsgaisrKSB7XG4gICAgICAgIGRvbSh7IHR5cGU6ICd0aCcsIGNsYXNzTmFtZTogby5zdHlsZXMuZGF5SGVhZEVsZW0sIHBhcmVudDogZGF0ZWhlYWRyb3csIHRleHQ6IHdlZWtkYXlzW3dlZWtkYXkoaildIH0pO1xuICAgICAgfVxuXG4gICAgICBkYXRlYm9keS5zZXRBdHRyaWJ1dGUobW9udGhPZmZzZXRBdHRyaWJ1dGUsIGkpO1xuICAgICAgY2FsZW5kYXJNb250aHMucHVzaCh7XG4gICAgICAgIGxhYmVsOiBsYWJlbCxcbiAgICAgICAgYm9keTogZGF0ZWJvZHlcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHJlbmRlclRpbWUgKCkge1xuICAgIGlmICghby50aW1lIHx8ICFvLnRpbWVJbnRlcnZhbCkge1xuICAgICAgcmV
 0dXJuO1xuICAgIH1cbiAgICB2YXIgdGltZXdyYXBwZXIgPSBkb20oeyBjbGFzc05hbWU6IG8uc3R5bGVzLnRpbWUsIHBhcmVudDogY29udGFpbmVyIH0pO1xuICAgIHRpbWUgPSBkb20oeyBjbGFzc05hbWU6IG8uc3R5bGVzLnNlbGVjdGVkVGltZSwgcGFyZW50OiB0aW1ld3JhcHBlciwgdGV4dDogcmVmLmZvcm1hdChvLnRpbWVGb3JtYXQpIH0pO1xuICAgIGV2ZW50cy5hZGQodGltZSwgJ2NsaWNrJywgdG9nZ2xlVGltZUxpc3QpO1xuICAgIHRpbWVsaXN0ID0gZG9tKHsgY2xhc3NOYW1lOiBvLnN0eWxlcy50aW1lTGlzdCwgcGFyZW50OiB0aW1ld3JhcHBlciB9KTtcbiAgICBldmVudHMuYWRkKHRpbWVsaXN0LCAnY2xpY2snLCBwaWNrVGltZSk7XG4gICAgdmFyIG5leHQgPSBtb21lbnR1bS5tb21lbnQoJzAwOjAwOjAwJywgJ0hIOm1tOnNzJyk7XG4gICAgdmFyIGxhdGVzdCA9IG5leHQuY2xvbmUoKS5hZGQoMSwgJ2RheXMnKTtcbiAgICB3aGlsZSAobmV4dC5pc0JlZm9yZShsYXRlc3QpKSB7XG4gICAgICBkb20oeyBjbGFzc05hbWU6IG8uc3R5bGVzLnRpbWVPcHRpb24sIHBhcmVudDogdGltZWxpc3QsIHRleHQ6IG5leHQuZm9ybWF0KG8udGltZUZvcm1hdCkgfSk7XG4gICAgICBuZXh0LmFkZChvLnRpbWVJbnRlcnZhbCwgJ3NlY29uZHMnKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiB3ZWVrZGF5IChpbmRleCwgYmFja3dhcmRzKSB7XG4gICAgdmFyIGZhY3RvciA9IGJhY2t3YXJkcyA/IC0xIDogMTtcbiAg
 ICB2YXIgb2Zmc2V0ID0gaW5kZXggKyBvLndlZWtTdGFydCAqIGZhY3RvcjtcbiAgICBpZiAob2Zmc2V0ID49IHdlZWtkYXlDb3VudCB8fCBvZmZzZXQgPCAwKSB7XG4gICAgICBvZmZzZXQgKz0gd2Vla2RheUNvdW50ICogLWZhY3RvcjtcbiAgICB9XG4gICAgcmV0dXJuIG9mZnNldDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGRpc3BsYXlWYWxpZFRpbWVzT25seSAoKSB7XG4gICAgaWYgKCFvLnRpbWUgfHwgIXJlbmRlcmVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHZhciB0aW1lcyA9IHRpbWVsaXN0LmNoaWxkcmVuO1xuICAgIHZhciBsZW5ndGggPSB0aW1lcy5sZW5ndGg7XG4gICAgdmFyIGRhdGU7XG4gICAgdmFyIHRpbWU7XG4gICAgdmFyIGl0ZW07XG4gICAgdmFyIGk7XG4gICAgZm9yIChpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICBpdGVtID0gdGltZXNbaV07XG4gICAgICB0aW1lID0gbW9tZW50dW0ubW9tZW50KHRleHQoaXRlbSksIG8udGltZUZvcm1hdCk7XG4gICAgICBkYXRlID0gc2V0VGltZShyZWYuY2xvbmUoKSwgdGltZSk7XG4gICAgICBpdGVtLnN0eWxlLmRpc3BsYXkgPSBpc0luUmFuZ2UoZGF0ZSwgZmFsc2UsIG8udGltZVZhbGlkYXRvcikgPyAnYmxvY2snIDogJ25vbmUnO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHRvZ2dsZVRpbWVMaXN0IChzaG93KSB7XG4gICAgdmFyIGRpc3BsYXkgPSB0eXBlb2Ygc2hvdyA9PT0gJ2Jvb2xlYW4nID8gc2hvdyA6IHRpbWVsaXN0L
 nN0eWxlLmRpc3BsYXkgPT09ICdub25lJztcbiAgICBpZiAoZGlzcGxheSkge1xuICAgICAgc2hvd1RpbWVMaXN0KCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGhpZGVUaW1lTGlzdCgpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHNob3dUaW1lTGlzdCAoKSB7IGlmICh0aW1lbGlzdCkgeyB0aW1lbGlzdC5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJzsgfSB9XG4gIGZ1bmN0aW9uIGhpZGVUaW1lTGlzdCAoKSB7IGlmICh0aW1lbGlzdCkgeyB0aW1lbGlzdC5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnOyB9IH1cbiAgZnVuY3Rpb24gc2hvd0NhbGVuZGFyICgpIHsgY29udGFpbmVyLnN0eWxlLmRpc3BsYXkgPSAnaW5saW5lLWJsb2NrJzsgYXBpLmVtaXQoJ3Nob3cnKTsgfVxuICBmdW5jdGlvbiBoaWRlQ2FsZW5kYXIgKCkgeyBjb250YWluZXIuc3R5bGUuZGlzcGxheSA9ICdub25lJzsgYXBpLmVtaXQoJ2hpZGUnKTsgfVxuXG4gIGZ1bmN0aW9uIHNob3cgKCkge1xuICAgIHJlbmRlcigpO1xuICAgIHJlZnJlc2goKTtcbiAgICB0b2dnbGVUaW1lTGlzdCghby5kYXRlKTtcbiAgICBzaG93Q2FsZW5kYXIoKTtcbiAgICByZXR1cm4gYXBpO1xuICB9XG5cbiAgZnVuY3Rpb24gaGlkZSAoKSB7XG4gICAgaGlkZVRpbWVMaXN0KCk7XG4gICAgcmFmKGhpZGVDYWxlbmRhcik7XG4gICAgcmV0dXJuIGFwaTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGhpZGVDb25kaXRpb25hbGx5ICgpIHtcbiAgICBoaWRlVGltZUxpc3QoKTtcblxuICAgIH
 ZhciBwb3MgPSBjbGFzc2VzLmNvbnRhaW5zKGNvbnRhaW5lciwgby5zdHlsZXMucG9zaXRpb25lZCk7XG4gICAgaWYgKHBvcykge1xuICAgICAgcmFmKGhpZGVDYWxlbmRhcik7XG4gICAgfVxuICAgIHJldHVybiBhcGk7XG4gIH1cblxuICBmdW5jdGlvbiBjYWxlbmRhckV2ZW50VGFyZ2V0IChlKSB7XG4gICAgdmFyIHRhcmdldCA9IGUudGFyZ2V0O1xuICAgIGlmICh0YXJnZXQgPT09IGFwaS5hc3NvY2lhdGVkKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgd2hpbGUgKHRhcmdldCkge1xuICAgICAgaWYgKHRhcmdldCA9PT0gY29udGFpbmVyKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgICAgdGFyZ2V0ID0gdGFyZ2V0LnBhcmVudE5vZGU7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gaGlkZU9uQmx1ciAoZSkge1xuICAgIGlmIChjYWxlbmRhckV2ZW50VGFyZ2V0KGUpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGhpZGVDb25kaXRpb25hbGx5KCk7XG4gIH1cblxuICBmdW5jdGlvbiBoaWRlT25DbGljayAoZSkge1xuICAgIGlmIChjYWxlbmRhckV2ZW50VGFyZ2V0KGUpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGhpZGVDb25kaXRpb25hbGx5KCk7XG4gIH1cblxuICBmdW5jdGlvbiBzdWJ0cmFjdE1vbnRoICgpIHsgY2hhbmdlTW9udGgoJ3N1YnRyYWN0Jyk7IH1cbiAgZnVuY3Rpb24gYWRkTW9udGggKCkgeyBjaGFuZ2VNb250aCgnYWRkJyk7IH1cbiA
 gZnVuY3Rpb24gY2hhbmdlTW9udGggKG9wKSB7XG4gICAgdmFyIGJvdW5kO1xuICAgIHZhciBkaXJlY3Rpb24gPSBvcCA9PT0gJ2FkZCcgPyAtMSA6IDE7XG4gICAgdmFyIG9mZnNldCA9IG8ubW9udGhzSW5DYWxlbmRhciArIGRpcmVjdGlvbiAqIGdldE1vbnRoT2Zmc2V0KGxhc3REYXlFbGVtZW50KTtcbiAgICByZWZDYWxbb3BdKG9mZnNldCwgJ21vbnRocycpO1xuICAgIGJvdW5kID0gaW5SYW5nZShyZWZDYWwuY2xvbmUoKSk7XG4gICAgcmVmID0gYm91bmQgfHwgcmVmO1xuICAgIGlmIChib3VuZCkgeyByZWZDYWwgPSBib3VuZC5jbG9uZSgpOyB9XG4gICAgdXBkYXRlKCk7XG4gIH1cblxuICBmdW5jdGlvbiB1cGRhdGUgKHNpbGVudCkge1xuICAgIHVwZGF0ZUNhbGVuZGFyKCk7XG4gICAgdXBkYXRlVGltZSgpO1xuICAgIGlmIChzaWxlbnQgIT09IHRydWUpIHsgZW1pdFZhbHVlcygpOyB9XG4gICAgZGlzcGxheVZhbGlkVGltZXNPbmx5KCk7XG4gIH1cblxuICBmdW5jdGlvbiB1cGRhdGVDYWxlbmRhciAoKSB7XG4gICAgaWYgKCFvLmRhdGUgfHwgIXJlbmRlcmVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHZhciB5ID0gcmVmQ2FsLnllYXIoKTtcbiAgICB2YXIgbSA9IHJlZkNhbC5tb250aCgpO1xuICAgIHZhciBkID0gcmVmQ2FsLmRhdGUoKTtcbiAgICBpZiAoZCA9PT0gbGFzdERheSAmJiBtID09PSBsYXN0TW9udGggJiYgeSA9PT0gbGFzdFllYXIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4g
 ICAgdmFyIGNhblN0YXkgPSBpc0Rpc3BsYXllZCgpO1xuICAgIGxhc3REYXkgPSByZWZDYWwuZGF0ZSgpO1xuICAgIGxhc3RNb250aCA9IHJlZkNhbC5tb250aCgpO1xuICAgIGxhc3RZZWFyID0gcmVmQ2FsLnllYXIoKTtcbiAgICBpZiAoY2FuU3RheS

<TRUNCATED>