algorithm_visualizer.js.map 475.3 KB
Newer Older
1
{"version":3,"names":[],"mappings":"","sources":["algorithm_visualizer.js"],"sourcesContent":["/**\n * algorithm-visualizer - Algorithm Visualizer\n * @version v0.1.0\n * @author Jason Park & contributors\n * @link https://github.com/parkjs814/AlgorithmVisualizer#readme\n * @license MIT\n */\n(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){\n'use strict';\n\nvar _$ = $;\nvar extend = _$.extend;\n\n\nvar cache = {\n  lastFileUsed: '',\n  files: {}\n};\n\nvar assertFileName = function assertFileName(name) {\n  if (!name) {\n    throw 'Missing file name';\n  }\n};\n\n/**\n * Global application cache\n */\nmodule.exports = {\n  getCachedFile: function getCachedFile(name) {\n    assertFileName(name);\n    return cache.files[name];\n  },\n  updateCachedFile: function updateCachedFile(name, updates) {\n    assertFileName(name);\n    if (!cache.files[name]) {\n      cache.files[name] = {};\n    }\n    extend(cache.files[name], updates);\n  },\n  getLastFileUsed: function getLastFileUsed() {\n    return cache.lastFileUsed;\n  },\n  setLastFileUsed: function setLastFileUsed(file) {\n    cache.lastFileUsed = file;\n  }\n};\n\n},{}],2:[function(require,module,exports){\n'use strict';\n\nvar Editor = require('../editor');\nvar TracerManager = require('../tracer_manager');\nvar DOM = require('../dom/setup');\n\nvar _require = require('../dom/loading_slider');\n\nvar showLoadingSlider = _require.showLoadingSlider;\nvar hideLoadingSlider = _require.hideLoadingSlider;\n\n\nvar Cache = require('./cache');\n\nvar state = {\n  isLoading: null,\n  editor: null,\n  tracerManager: null,\n  categories: null,\n  loadedScratch: null\n};\n\nvar initState = function initState(tracerManager) {\n  state.isLoading = false;\n  state.editor = new Editor(tracerManager);\n  state.tracerManager = tracerManager;\n  state.categories = {};\n  state.loadedScratch = null;\n};\n\n/**\n * Global application singleton.\n */\nvar App = function App() {\n\n  this.getIsLoading = function () {\n    return state.isLoading;\n  };\n\n  this.setIsLoading = function (loading) {\n    state.isLoading = loading;\n    if (loading) {\n      showLoadingSlider();\n    } else {\n      hideLoadingSlider();\n    }\n  };\n\n  this.getEditor = function () {\n    return state.editor;\n  };\n\n  this.getCategories = function () {\n    return state.categories;\n  };\n\n  this.getCategory = function (name) {\n    return state.categories[name];\n  };\n\n  this.setCategories = function (categories) {\n    state.categories = categories;\n  };\n\n  this.updateCategory = function (name, updates) {\n    $.extend(state.categories[name], updates);\n  };\n\n  this.getTracerManager = function () {\n    return state.tracerManager;\n  };\n\n  this.getLoadedScratch = function () {\n    return state.loadedScratch;\n  };\n\n  this.setLoadedScratch = function (loadedScratch) {\n    state.loadedScratch = loadedScratch;\n  };\n\n  var tracerManager = TracerManager.init();\n\n  initState(tracerManager);\n  DOM.setup(tracerManager);\n};\n\nApp.prototype = Cache;\n\nmodule.exports = App;\n\n},{\"../dom/loading_slider\":7,\"../dom/setup\":8,\"../editor\":27,\"../tracer_manager\":60,\"./cache\":1}],3:[function(require,module,exports){\n'use strict';\n\n/**\n * This is the main application instance.\n * Gets populated on page load. \n */\n\nmodule.exports = {};\n\n},{}],4:[function(require,module,exports){\n'use strict';\n\nvar app = require('../app');\nvar Server = require('../server');\nvar showAlgorithm = require('./show_algorithm');\n\nvar _$ = $;\nvar each = _$.each;\n\n\nvar addAlgorithmToCategoryDOM = function addAlgorithmToCategoryDOM(category, subList, algorithm) {\n  var $algorithm = $('<button class=\"indent collapse\">').append(subList[algorithm]).attr('data-algorithm', algorithm).attr('data-category', category).click(function () {\n    Server.loadAlgorithm(category, algorithm).then(function (data) {\n      showAlgorithm(category, algorithm, data);\n    });\n  });\n\n  $('#list').append($algorithm);\n};\n\nvar addCategoryToDOM = function addCategoryToDOM(category) {\n  var _app$getCategory = app.getCategory(category);\n\n  var categoryName = _app$getCategory.name;\n  var categorySubList = _app$getCategory.list;\n\n\n  var $category = $('<button class=\"category\">').append('<i class=\"fa fa-fw fa-caret-right\">').append(categoryName).attr('data-category', category);\n\n  $category.click(function () {\n    $('.indent[data-category=\"' + category + '\"]').toggleClass('collapse');\n    $(this).find('i.fa').toggleClass('fa-caret-right fa-caret-down');\n  });\n\n  $('#list').append($category);\n\n  each(categorySubList, function (algorithm) {\n    addAlgorithmToCategoryDOM(category, categorySubList, algorithm);\n  });\n};\n\nmodule.exports = function () {\n  each(app.getCategories(), addCategoryToDOM);\n};\n\n},{\"../app\":3,\"../server\":54,\"./show_algorithm\":19}],5:[function(require,module,exports){\n'use strict';\n\nvar Server = require('../server');\n\nvar _$ = $;\nvar each = _$.each;\n\n\nvar addFileToDOM = function addFileToDOM(category, algorithm, file, explanation) {\n  var $file = $('<button>').append(file).attr('data-file', file).click(function () {\n    Server.loadFile(category, algorithm, file, explanation);\n    $('.files_bar > .wrapper > button').removeClass('active');\n    $(this).addClass('active');\n  });\n  $('.files_bar > .wrapper').append($file);\n  return $file;\n};\n\nmodule.exports = function (category, algorithm, files, requestedFile) {\n  $('.files_bar > .wrapper').empty();\n\n  each(files, function (file, explanation) {\n    var $file = addFileToDOM(category, algorithm, file, explanation);\n    if (requestedFile && requestedFile == file) $file.click();\n  });\n\n  if (!requestedFile) $('.files_bar > .wrapper > button').first().click();\n  $('.files_bar > .wrapper').scroll();\n};\n\n},{\"../server\":54}],6:[function(require,module,exports){\n'use strict';\n\nvar showAlgorithm = require('./show_algorithm');\nvar addCategories = require('./add_categories');\nvar showDescription = require('./show_description');\nvar addFiles = require('./add_files');\nvar showFirstAlgorithm = require('./show_first_algorithm');\nvar showRequestedAlgorithm = require('./show_requested_algorithm');\n\nmodule.exports = {\n  showAlgorithm: showAlgorithm,\n  addCategories: addCategories,\n  showDescription: showDescription,\n  addFiles: addFiles,\n  showFirstAlgorithm: showFirstAlgorithm,\n  showRequestedAlgorithm: showRequestedAlgorithm\n};\n\n},{\"./add_categories\":4,\"./add_files\":5,\"./show_algorithm\":19,\"./show_description\":20,\"./show_first_algorithm\":21,\"./show_requested_algorithm\":22}],7:[function(require,module,exports){\n'use strict';\n\nvar showLoadingSlider = function showLoadingSlider() {\n  $('#loading-slider').removeClass('loaded');\n};\n\nvar hideLoadingSlider = function hideLoadingSlider() {\n  $('#loading-slider').addClass('loaded');\n};\n\nmodule.exports = {\n  showLoadingSlider: showLoadingSlider,\n  hideLoadingSlider: hideLoadingSlider\n};\n\n},{}],8:[function(require,module,exports){\n'use strict';\n\nvar setupDividers = require('./setup_dividers');\nvar setupDocument = require('./setup_document');\nvar setupFilesBar = require('./setup_files_bar');\nvar setupInterval = require('./setup_interval');\nvar setupModuleContainer = require('./setup_module_container');\nvar setupPoweredBy = require('./setup_powered_by');\nvar setupScratchPaper = require('./setup_scratch_paper');\nvar setupSideMenu = require('./setup_side_menu');\nvar setupTopMenu = require('./setup_top_menu');\nvar setupWindow = require('./setup_window');\n\n/**\n * Initializes elements once the app loads in the DOM. \n */\nvar setup = function setup() {\n\n  $('.btn input').click(function (e) {\n    e.stopPropagation();\n  });\n\n  // dividers\n  setupDividers();\n\n  // document\n  setupDocument();\n\n  // files bar\n  setupFilesBar();\n\n  // interval\n  setupInterval();\n\n  // module container\n  setupModuleContainer();\n\n  // powered by\n  setupPoweredBy();\n\n  // scratch paper\n  setupScratchPaper();\n\n  // side menu\n  setupSideMenu();\n\n  // top menu\n  setupTopMenu();\n\n  // window\n  setupWindow();\n};\n\nmodule.exports = {\n  setup: setup\n};\n\n},{\"./setup_dividers\":9,\"./setup_document\":10,\"./setup_files_bar\":11,\"./setup_interval\":12,\"./setup_module_container\":13,\"./setup_powered_by\":14,\"./setup_scratch_paper\":15,\"./setup_side_menu\":16,\"./setup_top_menu\":17,\"./setup_window\":18}],9:[function(require,module,exports){\n'use strict';\n\nvar _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i[\"return\"]) _i[\"return\"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError(\"Invalid attempt to destructure non-iterable instance\"); } }; }();\n\nvar app = require('../../app');\n\nvar addDividerToDom = function addDividerToDom(divider) {\n  var _divider = _slicedToArray(divider, 3);\n\n  var vertical = _divider[0];\n  var $first = _divider[1];\n  var $second = _divider[2];\n\n  var $parent = $first.parent();\n  var thickness = 5;\n\n  var $divider = $('<div class=\"divider\">');\n\n  var dragging = false;\n  if (vertical) {\n    (function () {\n      $divider.addClass('vertical');\n\n      var _left = -thickness / 2;\n      $divider.css({\n        top: 0,\n        bottom: 0,\n        left: _left,\n        width: thickness\n      });\n\n      var x = void 0;\n      $divider.mousedown(function (_ref) {\n        var pageX = _ref.pageX;\n\n        x = pageX;\n        dragging = true;\n      });\n\n      $(document).mousemove(function (_ref2) {\n        var pageX = _ref2.pageX;\n\n        if (dragging) {\n          var new_left = $second.position().left + pageX - x;\n          var percent = new_left / $parent.width() * 100;\n          percent = Math.min(90, Math.max(10, percent));\n          $first.css('right', 100 - percent + '%');\n          $second.css('left', percent + '%');\n          x = pageX;\n          app.getTracerManager().resize();\n          $('.files_bar > .wrapper').scroll();\n        }\n      });\n\n      $(document).mouseup(function (e) {\n        dragging = false;\n      });\n    })();\n  } else {\n    (function () {\n\n      $divider.addClass('horizontal');\n      var _top = -thickness / 2;\n      $divider.css({\n        top: _top,\n        height: thickness,\n        left: 0,\n        right: 0\n      });\n\n      var y = void 0;\n      $divider.mousedown(function (_ref3) {\n        var pageY = _ref3.pageY;\n\n        y = pageY;\n        dragging = true;\n      });\n\n      $(document).mousemove(function (_ref4) {\n        var pageY = _ref4.pageY;\n\n        if (dragging) {\n          var new_top = $second.position().top + pageY - y;\n          var percent = new_top / $parent.height() * 100;\n          percent = Math.min(90, Math.max(10, percent));\n          $first.css('bottom', 100 - percent + '%');\n          $second.css('top', percent + '%');\n          y = pageY;\n          app.getTracerManager().resize();\n        }\n      });\n\n      $(document).mouseup(function (e) {\n        dragging = false;\n      });\n    })();\n  }\n\n  $second.append($divider);\n};\n\nmodule.exports = function () {\n  var dividers = [['v', $('.sidemenu'), $('.workspace')], ['v', $('.viewer_container'), $('.editor_container')], ['h', $('.data_container'), $('.code_container')]];\n  for (var i = 0; i < dividers.length; i++) {\n    addDividerToDom(dividers[i]);\n  }\n};\n\n},{\"../../app\":3}],10:[function(require,module,exports){\n'use strict';\n\nvar app = require('../../app');\n\nmodule.exports = function () {\n  $(document).on('click', 'a', function (e) {\n    e.preventDefault();\n    if (!window.open($(this).attr('href'), '_blank')) {\n      alert('Please allow popups for this site');\n    }\n  });\n\n  $(document).mouseup(function (e) {\n    app.getTracerManager().command('mouseup', e);\n  });\n};\n\n},{\"../../app\":3}],11:[function(require,module,exports){\n'use strict';\n\nvar definitelyBigger = function definitelyBigger(x, y) {\n  return x > y + 2;\n};\n\nmodule.exports = function () {\n\n  $('.files_bar > .btn-left').click(function () {\n    var $wrapper = $('.files_bar > .wrapper');\n    var clipWidth = $wrapper.width();\n    var scrollLeft = $wrapper.scrollLeft();\n\n    $($wrapper.children('button').get().reverse()).each(function () {\n      var left = $(this).position().left;\n      var right = left + $(this).outerWidth();\n      if (0 > left) {\n        $wrapper.scrollLeft(scrollLeft + right - clipWidth);\n        return false;\n      }\n    });\n  });\n\n  $('.files_bar > .btn-right').click(function () {\n    var $wrapper = $('.files_bar > .wrapper');\n    var clipWidth = $wrapper.width();\n    var scrollLeft = $wrapper.scrollLeft();\n\n    $wrapper.children('button').each(function () {\n      var left = $(this).position().left;\n      var right = left + $(this).outerWidth();\n      if (clipWidth < right) {\n        $wrapper.scrollLeft(scrollLeft + left);\n        return false;\n      }\n    });\n  });\n\n  $('.files_bar > .wrapper').scroll(function () {\n\n    var $wrapper = $('.files_bar > .wrapper');\n    var clipWidth = $wrapper.width();\n    var $left = $wrapper.children('button:first-child');\n    var $right = $wrapper.children('button:last-child');\n    var left = $left.position().left;\n    var right = $right.position().left + $right.outerWidth();\n\n    if (definitelyBigger(0, left) && definitelyBigger(clipWidth, right)) {\n      var scrollLeft = $wrapper.scrollLeft();\n      $wrapper.scrollLeft(scrollLeft + clipWidth - right);\n      return;\n    }\n\n    var lefter = definitelyBigger(0, left);\n    var righter = definitelyBigger(right, clipWidth);\n    $wrapper.toggleClass('shadow-left', lefter);\n    $wrapper.toggleClass('shadow-right', righter);\n    $('.files_bar > .btn-left').attr('disabled', !lefter);\n    $('.files_bar > .btn-right').attr('disabled', !righter);\n  });\n};\n\n},{}],12:[function(require,module,exports){\n'use strict';\n\nvar _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i[\"return\"]) _i[\"return\"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError(\"Invalid attempt to destructure non-iterable instance\"); } }; }();\n\nvar app = require('../../app');\nvar Toast = require('../toast');\n\nvar parseFloat = Number.parseFloat;\n\n\nvar minInterval = 0.1;\nvar maxInterval = 10;\nvar startInterval = 0.5;\nvar stepInterval = 0.1;\n\nvar normalize = function normalize(sec) {\n\n  var interval = void 0;\n  var message = void 0;\n  if (sec < minInterval) {\n    interval = minInterval;\n    message = 'Interval of ' + sec + ' seconds is too low. Setting to min allowed interval of ' + minInterval + ' second(s).';\n  } else if (sec > maxInterval) {\n    interval = maxInterval;\n    message = 'Interval of ' + sec + ' seconds is too high. Setting to max allowed interval of ' + maxInterval + ' second(s).';\n  } else {\n    interval = sec;\n    message = 'Interval has been set to ' + sec + ' second(s).';\n  }\n\n  return [interval, message];\n};\n\nmodule.exports = function () {\n\n  var $interval = $('#interval');\n  $interval.val(startInterval);\n  $interval.attr({\n    max: maxInterval,\n    min: minInterval,\n    step: stepInterval\n  });\n\n  $('#interval').on('change', function () {\n    var tracerManager = app.getTracerManager();\n\n    var _normalize = normalize(parseFloat($(this).val()));\n\n    var _normalize2 = _slicedToArray(_normalize, 2);\n\n    var seconds = _normalize2[0];\n    var message = _normalize2[1];\n\n\n    $(this).val(seconds);\n    tracerManager.interval = seconds * 1000;\n    Toast.showInfoToast(message);\n  });\n};\n\n},{\"../../app\":3,\"../toast\":23}],13:[function(require,module,exports){\n'use strict';\n\nvar app = require('../../app');\n\nmodule.exports = function () {\n\n  var $module_container = $('.module_container');\n\n  $module_container.on('mousedown', '.module_wrapper', function (e) {\n    app.getTracerManager().findOwner(this).mousedown(e);\n  });\n\n  $module_container.on('mousemove', '.module_wrapper', function (e) {\n    app.getTracerManager().findOwner(this).mousemove(e);\n  });\n\n  $module_container.on('DOMMouseScroll mousewheel', '.module_wrapper', function (e) {\n    app.getTracerManager().findOwner(this).mousewheel(e);\n  });\n};\n\n},{\"../../app\":3}],14:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function () {\n  $('#powered-by').click(function () {\n    $('#powered-by-list button').toggleClass('collapse');\n  });\n};\n\n},{}],15:[function(require,module,exports){\n'use strict';\n\nvar app = require('../../app');\nvar Server = require('../../server');\nvar showAlgorithm = require('../show_algorithm');\n\nmodule.exports = function () {\n  $('#scratch-paper').click(function () {\n    var category = 'scratch';\n    var algorithm = app.getLoadedScratch();\n    Server.loadAlgorithm(category, algorithm).then(function (data) {\n      showAlgorithm(category, algorithm, data);\n    });\n  });\n};\n\n},{\"../../app\":3,\"../../server\":54,\"../show_algorithm\":19}],16:[function(require,module,exports){\n'use strict';\n\nvar app = require('../../app');\n\nvar sidemenu_percent = void 0;\n\nmodule.exports = function () {\n  $('#navigation').click(function () {\n    var $sidemenu = $('.sidemenu');\n    var $workspace = $('.workspace');\n\n    $sidemenu.toggleClass('active');\n    $('.nav-dropdown').toggleClass('fa-caret-down fa-caret-up');\n\n    if ($sidemenu.hasClass('active')) {\n      $sidemenu.css('right', 100 - sidemenu_percent + '%');\n      $workspace.css('left', sidemenu_percent + '%');\n    } else {\n      sidemenu_percent = $workspace.position().left / $('body').width() * 100;\n      $sidemenu.css('right', 0);\n      $workspace.css('left', 0);\n    }\n\n    app.getTracerManager().resize();\n  });\n};\n\n},{\"../../app\":3}],17:[function(require,module,exports){\n'use strict';\n\nvar app = require('../../app');\nvar Server = require('../../server');\nvar Toast = require('../toast');\nvar TopMenu = require('../top_menu');\n\nmodule.exports = function () {\n\n  // shared\n  $('#shared').mouseup(function () {\n    $(this).select();\n  });\n\n  $('#btn_share').click(function () {\n\n    var $icon = $(this).find('.fa-share');\n    $icon.addClass('fa-spin fa-spin-faster');\n\n    Server.shareScratchPaper().then(function (url) {\n      $icon.removeClass('fa-spin fa-spin-faster');\n      $('#shared').removeClass('collapse');\n      $('#shared').val(url);\n      Toast.showInfoToast('Shareable link is created.');\n    });\n  });\n\n  // control\n\n  var $btnRun = $('#btn_run');\n  var $btnTrace = $('#btn_trace');\n  var $btnPause = $('#btn_pause');\n  var $btnPrev = $('#btn_prev');\n  var $btnNext = $('#btn_next');\n  var $btnDesc = $('#btn_desc');\n\n  // initially, control buttons are disabled\n  TopMenu.disableFlowControl();\n\n  $btnRun.click(function () {\n    $btnTrace.click();\n    $btnPause.removeClass('active');\n    $btnRun.addClass('active');\n    TopMenu.enableFlowControl();\n    var err = app.getEditor().execute();\n    if (err) {\n      console.error(err);\n      Toast.showErrorToast(err);\n    }\n  });\n\n  $btnPause.click(function () {\n    $btnRun.toggleClass('active');\n    $btnPause.toggleClass('active');\n    if (app.getTracerManager().isPause()) {\n      app.getTracerManager().resumeStep();\n    } else {\n      app.getTracerManager().pauseStep();\n    }\n  });\n\n  $btnPrev.click(function () {\n    $btnRun.removeClass('active');\n    $btnPause.addClass('active');\n    app.getTracerManager().pauseStep();\n    app.getTracerManager().prevStep();\n  });\n\n  $btnNext.click(function () {\n    $btnRun.removeClass('active');\n    $btnPause.addClass('active');\n    app.getTracerManager().pauseStep();\n    app.getTracerManager().nextStep();\n  });\n\n  // description & trace\n\n  $btnDesc.click(function () {\n    $('.tab_container > .tab').removeClass('active');\n    $('#tab_desc').addClass('active');\n    $('.tab_bar > button').removeClass('active');\n    $btnDesc.addClass('active');\n  });\n\n  $btnTrace.click(function () {\n    $('.tab_container > .tab').removeClass('active');\n    $('#tab_module').addClass('active');\n    $('.tab_bar > button').removeClass('active');\n    $btnTrace.addClass('active');\n  });\n};\n\n},{\"../../app\":3,\"../../server\":54,\"../toast\":23,\"../top_menu\":24}],18:[function(require,module,exports){\n'use strict';\n\nvar app = require('../../app');\n\nmodule.exports = function () {\n  $(window).resize(function () {\n    app.getTracerManager().resize();\n  });\n};\n\n},{\"../../app\":3}],19:[function(require,module,exports){\n'use strict';\n\nvar app = require('../app');\n\nvar _require = require('../utils');\n\nvar isScratchPaper = _require.isScratchPaper;\n\n\nvar showDescription = require('./show_description');\nvar addFiles = require('./add_files');\n\nmodule.exports = function (category, algorithm, data, requestedFile) {\n  var $menu = void 0;\n  var category_name = void 0;\n  var algorithm_name = void 0;\n\n  if (isScratchPaper(category)) {\n    $menu = $('#scratch-paper');\n    category_name = 'Scratch Paper';\n    algorithm_name = algorithm ? 'Shared' : 'Temporary';\n  } else {\n    $menu = $('[data-category=\"' + category + '\"][data-algorithm=\"' + algorithm + '\"]');\n    var categoryObj = app.getCategory(category);\n    category_name = categoryObj.name;\n    algorithm_name = categoryObj.list[algorithm];\n  }\n\n  $('.sidemenu button').removeClass('active');\n  $menu.addClass('active');\n\n  $('#category').html(category_name);\n  $('#algorithm').html(algorithm_name);\n  $('#tab_desc > .wrapper').empty();\n  $('.files_bar > .wrapper').empty();\n  $('#explanation').html('');\n\n  app.setLastFileUsed(null);\n  app.getEditor().clearContent();\n\n  var files = data.files;\n\n\n  delete data.files;\n\n  showDescription(data);\n  addFiles(category, algorithm, files, requestedFile);\n};\n\n},{\"../app\":3,\"../utils\":66,\"./add_files\":5,\"./show_description\":20}],20:[function(require,module,exports){\n'use strict';\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol ? \"symbol\" : typeof obj; };\n\nvar isArray = Array.isArray;\nvar _$ = $;\nvar each = _$.each;\n\n\nmodule.exports = function (data) {\n  var $container = $('#tab_desc > .wrapper');\n  $container.empty();\n\n  each(data, function (key, value) {\n\n    if (key) {\n      $container.append($('<h3>').html(key));\n    }\n\n    if (typeof value === 'string') {\n      $container.append($('<p>').html(value));\n    } else if (isArray(value)) {\n      (function () {\n\n        var $ul = $('<ul class=\"applications\">');\n        $container.append($ul);\n\n        value.forEach(function (li) {\n          $ul.append($('<li>').html(li));\n        });\n      })();\n    } else if ((typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object') {\n      (function () {\n\n        var $ul = $('<ul class=\"complexities\">');\n        $container.append($ul);\n\n        each(value, function (prop) {\n          var $wrapper = $('<div class=\"complexity\">');\n          var $type = $('<span class=\"complexity-type\">').html(prop + ': ');\n          var $value = $('<span class=\"complexity-value\">').html('' + value[prop]);\n\n          $wrapper.append($type).append($value);\n\n          $ul.append($('<li>').append($wrapper));\n        });\n      })();\n    }\n  });\n};\n\n},{}],21:[function(require,module,exports){\n'use strict';\n\n// click the first algorithm in the first category\n\nmodule.exports = function () {\n  $('#list button.category').first().click();\n  $('#list button.category + .indent').first().click();\n};\n\n},{}],22:[function(require,module,exports){\n'use strict';\n\nvar Server = require('../server');\nvar showAlgorithm = require('./show_algorithm');\n\nmodule.exports = function (category, algorithm, file) {\n  $('.category[data-category=\"' + category + '\"]').click();\n  Server.loadAlgorithm(category, algorithm).then(function (data) {\n    showAlgorithm(category, algorithm, data, file);\n  });\n};\n\n},{\"../server\":54,\"./show_algorithm\":19}],23:[function(require,module,exports){\n'use strict';\n\nvar showToast = function showToast(data, type) {\n  var $toast = $('<div class=\"toast ' + type + '\">').append(data);\n\n  $('.toast_container').append($toast);\n  setTimeout(function () {\n    $toast.fadeOut(function () {\n      $toast.remove();\n    });\n  }, 3000);\n};\n\nvar showErrorToast = function showErrorToast(err) {\n  showToast(err, 'error');\n};\n\nvar showInfoToast = function showInfoToast(err) {\n  showToast(err, 'info');\n};\n\nmodule.exports = {\n  showErrorToast: showErrorToast,\n  showInfoToast: showInfoToast\n};\n\n},{}],24:[function(require,module,exports){\n'use strict';\n\nvar flowControlBtns = [$('#btn_pause'), $('#btn_prev'), $('#btn_next')];\nvar setFlowControlState = function setFlowControlState(isDisabled) {\n  flowControlBtns.forEach(function ($btn) {\n    return $btn.attr('disabled', isDisabled);\n  });\n};\n\nvar enableFlowControl = function enableFlowControl() {\n  setFlowControlState(false);\n};\n\nvar disableFlowControl = function disableFlowControl() {\n  setFlowControlState(true);\n};\n\nvar resetTopMenuButtons = function resetTopMenuButtons() {\n  $('.top-menu-buttons button').removeClass('active');\n  disableFlowControl();\n};\n\nmodule.exports = {\n  enableFlowControl: enableFlowControl,\n  disableFlowControl: disableFlowControl,\n  resetTopMenuButtons: resetTopMenuButtons\n};\n\n},{}],25:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function (id) {\n  var editor = ace.edit(id);\n\n  editor.setOptions({\n    enableBasicAutocompletion: true,\n    enableSnippets: true,\n    enableLiveAutocompletion: true\n  });\n\n  editor.setTheme('ace/theme/tomorrow_night_eighties');\n  editor.session.setMode('ace/mode/javascript');\n  editor.$blockScrolling = Infinity;\n\n  return editor;\n};\n\n},{}],26:[function(require,module,exports){\n'use strict';\n\nvar execute = function execute(tracerManager, code) {\n  // all modules available to eval are obtained from window\n  try {\n    tracerManager.deallocateAll();\n    eval(code);\n    tracerManager.visualize();\n  } catch (err) {\n    return err;\n  } finally {\n    tracerManager.removeUnallocated();\n  }\n};\n\nvar executeData = function executeData(tracerManager, algoData) {\n  return execute(tracerManager, algoData);\n};\n\nvar executeDataAndCode = function executeDataAndCode(tracerManager, algoData, algoCode) {\n  return execute(tracerManager, algoData + ';' + algoCode);\n};\n\nmodule.exports = {\n  executeData: executeData,\n  executeDataAndCode: executeDataAndCode\n};\n\n},{}],27:[function(require,module,exports){\n'use strict';\n\nvar app = require('../app');\nvar createEditor = require('./create');\nvar Executor = require('./executor');\n\nfunction Editor(tracerManager) {\n  var _this = this;\n\n  if (!tracerManager) {\n    throw 'Cannot create Editor. Missing the tracerManager';\n  }\n\n  ace.require('ace/ext/language_tools');\n\n  this.dataEditor = createEditor('data');\n  this.codeEditor = createEditor('code');\n\n  // Setting data\n\n  this.setData = function (data) {\n    _this.dataEditor.setValue(data, -1);\n  };\n\n  this.setCode = function (code) {\n    _this.codeEditor.setValue(code, -1);\n  };\n\n  this.setContent = function (_ref) {\n    var data = _ref.data;\n    var code = _ref.code;\n\n    _this.setData(data);\n    _this.setCode(code);\n  };\n\n  // Clearing data\n\n  this.clearData = function () {\n    _this.dataEditor.setValue('');\n  };\n\n  this.clearCode = function () {\n    _this.codeEditor.setValue('');\n  };\n\n  this.clearContent = function () {\n    _this.clearData();\n    _this.clearCode();\n  };\n\n  this.execute = function () {\n    var data = _this.dataEditor.getValue();\n    var code = _this.codeEditor.getValue();\n    return Executor.executeDataAndCode(tracerManager, data, code);\n  };\n\n  // listeners\n\n  this.dataEditor.on('change', function () {\n    var data = _this.dataEditor.getValue();\n    var lastFileUsed = app.getLastFileUsed();\n    if (lastFileUsed) {\n      app.updateCachedFile(lastFileUsed, {\n        data: data\n      });\n    }\n    Executor.executeData(tracerManager, data);\n  });\n\n  this.codeEditor.on('change', function () {\n    var code = _this.codeEditor.getValue();\n    var lastFileUsed = app.getLastFileUsed();\n    if (lastFileUsed) {\n      app.updateCachedFile(lastFileUsed, {\n        code: code\n      });\n    }\n  });\n};\n\nmodule.exports = Editor;\n\n},{\"../app\":3,\"./create\":25,\"./executor\":26}],28:[function(require,module,exports){\n'use strict';\n\nvar RSVP = require('rsvp');\nvar app = require('./app');\nvar AppConstructor = require('./app/constructor');\nvar DOM = require('./dom');\nvar Server = require('./server');\n\nvar modules = require('./module');\n\nvar _$ = $;\nvar extend = _$.extend;\n\n\n$.ajaxSetup({\n  cache: false,\n  dataType: 'text'\n});\n\nvar _require = require('./utils');\n\nvar isScratchPaper = _require.isScratchPaper;\n\nvar _require2 = require('./server/helpers');\n\nvar getPath = _require2.getPath;\n\n// set global promise error handler\n\nRSVP.on('error', function (reason) {\n  console.assert(false, reason);\n});\n\n$(function () {\n\n  // initialize the application and attach in to the instance module\n  var appConstructor = new AppConstructor();\n  extend(true, app, appConstructor);\n\n  // load modules to the global scope so they can be evaled\n  extend(true, window, modules);\n\n  Server.loadCategories().then(function (data) {\n    app.setCategories(data);\n    DOM.addCategories();\n\n    // determine if the app is loading a pre-existing scratch-pad\n    // or the home page\n\n    var _getPath = getPath();\n\n    var category = _getPath.category;\n    var algorithm = _getPath.algorithm;\n    var file = _getPath.file;\n\n    if (isScratchPaper(category)) {\n      if (algorithm) {\n        Server.loadScratchPaper(algorithm).then(function (_ref) {\n          var category = _ref.category;\n          var algorithm = _ref.algorithm;\n          var data = _ref.data;\n\n          DOM.showAlgorithm(category, algorithm, data);\n        });\n      } else {\n        Server.loadAlgorithm(category).then(function (data) {\n          DOM.showAlgorithm(category, null, data);\n        });\n      }\n    } else if (category && algorithm) {\n      DOM.showRequestedAlgorithm(category, algorithm, file);\n    } else {\n      DOM.showFirstAlgorithm();\n    }\n  });\n});\n\n},{\"./app\":3,\"./app/constructor\":2,\"./dom\":6,\"./module\":37,\"./server\":54,\"./server/helpers\":53,\"./utils\":66,\"rsvp\":68}],29:[function(require,module,exports){\n'use strict';\n\nvar Array2D = require('./array2d');\n\nvar random = function random(N, min, max) {\n  return Array2D.random(1, N, min, max)[0];\n};\n\nvar randomSorted = function randomSorted(N, min, max) {\n  return Array2D.randomSorted(1, N, min, max)[0];\n};\n\nmodule.exports = {\n  random: random,\n  randomSorted: randomSorted\n};\n\n},{\"./array2d\":30}],30:[function(require,module,exports){\n\"use strict\";\n\nvar random = function random(N, M, min, max) {\n  if (!N) N = 10;\n  if (!M) M = 10;\n  if (min === undefined) min = 1;\n  if (max === undefined) max = 9;\n  var D = [];\n  for (var i = 0; i < N; i++) {\n    D.push([]);\n    for (var j = 0; j < M; j++) {\n      D[i].push((Math.random() * (max - min + 1) | 0) + min);\n    }\n  }\n  return D;\n};\n\nvar randomSorted = function randomSorted(N, M, min, max) {\n  return random(N, M, min, max).map(function (arr) {\n    return arr.sort(function (a, b) {\n      return a - b;\n    });\n  });\n};\n\nmodule.exports = {\n  random: random,\n  randomSorted: randomSorted\n};\n\n},{}],31:[function(require,module,exports){\n\"use strict\";\n\nvar random = function random(N, min, max) {\n  if (!N) N = 7;\n  if (!min) min = 1;\n  if (!max) max = 10;\n  var C = new Array(N);\n  for (var i = 0; i < N; i++) {\n    C[i] = new Array(2);\n  }for (var i = 0; i < N; i++) {\n    for (var j = 0; j < C[i].length; j++) {\n      C[i][j] = (Math.random() * (max - min + 1) | 0) + min;\n    }\n  }return C;\n};\n\nmodule.exports = {\n  random: random\n};\n\n},{}],32:[function(require,module,exports){\n\"use strict\";\n\nvar random = function random(N, ratio) {\n  if (!N) N = 5;\n  if (!ratio) ratio = .3;\n  var G = new Array(N);\n  for (var i = 0; i < N; i++) {\n    G[i] = new Array(N);\n    for (var j = 0; j < N; j++) {\n      if (i != j) {\n        G[i][j] = (Math.random() * (1 / ratio) | 0) == 0 ? 1 : 0;\n      }\n    }\n  }\n  return G;\n};\n\nmodule.exports = {\n  random: random\n};\n\n},{}],33:[function(require,module,exports){\n'use strict';\n\nvar Array1D = require('./array1d');\nvar Array2D = require('./array2d');\nvar CoordinateSystem = require('./coordinate_system');\nvar DirectedGraph = require('./directed_graph');\nvar UndirectedGraph = require('./undirected_graph');\nvar WeightedDirectedGraph = require('./weighted_directed_graph');\nvar WeightedUndirectedGraph = require('./weighted_undirected_graph');\n\nmodule.exports = {\n  Array1D: Array1D,\n  Array2D: Array2D,\n  CoordinateSystem: CoordinateSystem,\n  DirectedGraph: DirectedGraph,\n  UndirectedGraph: UndirectedGraph,\n  WeightedDirectedGraph: WeightedDirectedGraph,\n  WeightedUndirectedGraph: WeightedUndirectedGraph\n};\n\n},{\"./array1d\":29,\"./array2d\":30,\"./coordinate_system\":31,\"./directed_graph\":32,\"./undirected_graph\":34,\"./weighted_directed_graph\":35,\"./weighted_undirected_graph\":36}],34:[function(require,module,exports){\n\"use strict\";\n\nvar random = function random(N, ratio) {\n  if (!N) N = 5;\n  if (!ratio) ratio = .3;\n  var G = new Array(N);\n  for (var i = 0; i < N; i++) {\n    G[i] = new Array(N);\n  }for (var i = 0; i < N; i++) {\n    for (var j = 0; j < N; j++) {\n      if (i > j) {\n        G[i][j] = G[j][i] = (Math.random() * (1 / ratio) | 0) == 0 ? 1 : 0;\n      }\n    }\n  }\n  return G;\n};\n\nmodule.exports = {\n  random: random\n};\n\n},{}],35:[function(require,module,exports){\n\"use strict\";\n\nvar random = function random(N, ratio, min, max) {\n  if (!N) N = 5;\n  if (!ratio) ratio = .3;\n  if (!min) min = 1;\n  if (!max) max = 5;\n  var G = new Array(N);\n  for (var i = 0; i < N; i++) {\n    G[i] = new Array(N);\n    for (var j = 0; j < N; j++) {\n      if (i != j && (Math.random() * (1 / ratio) | 0) == 0) {\n        G[i][j] = (Math.random() * (max - min + 1) | 0) + min;\n      }\n    }\n  }\n  return G;\n};\n\nmodule.exports = {\n  random: random\n};\n\n},{}],36:[function(require,module,exports){\n\"use strict\";\n\nvar random = function random(N, ratio, min, max) {\n  if (!N) N = 5;\n  if (!ratio) ratio = .3;\n  if (!min) min = 1;\n  if (!max) max = 5;\n  var G = new Array(N);\n  for (var i = 0; i < N; i++) {\n    G[i] = new Array(N);\n  }for (var i = 0; i < N; i++) {\n    for (var j = 0; j < N; j++) {\n      if (i > j && (Math.random() * (1 / ratio) | 0) == 0) {\n        G[i][j] = G[j][i] = (Math.random() * (max - min + 1) | 0) + min;\n      }\n    }\n  }\n  return G;\n};\n\nmodule.exports = {\n  random: random\n};\n\n},{}],37:[function(require,module,exports){\n'use strict';\n\nvar tracers = require('./tracer');\nvar datas = require('./data');\n\nvar _$ = $;\nvar extend = _$.extend;\n\n\nmodule.exports = extend(true, {}, tracers, datas);\n\n},{\"./data\":33,\"./tracer\":43}],38:[function(require,module,exports){\n'use strict';\n\nvar _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\nvar Array2DTracer = require('./array2d');\n\nvar Array1DTracer = function (_Array2DTracer) {\n  _inherits(Array1DTracer, _Array2DTracer);\n\n  _createClass(Array1DTracer, null, [{\n    key: 'getClassName',\n    value: function getClassName() {\n      return 'Array1DTracer';\n    }\n  }]);\n\n  function Array1DTracer(name) {\n    _classCallCheck(this, Array1DTracer);\n\n    return _possibleConstructorReturn(this, Object.getPrototypeOf(Array1DTracer).call(this, name));\n  }\n\n  _createClass(Array1DTracer, [{\n    key: '_notify',\n    value: function _notify(idx, v) {\n      _get(Object.getPrototypeOf(Array1DTracer.prototype), '_notify', this).call(this, 0, idx, v);\n      return this;\n    }\n  }, {\n    key: '_denotify',\n    value: function _denotify(idx) {\n      _get(Object.getPrototypeOf(Array1DTracer.prototype), '_denotify', this).call(this, 0, idx);\n      return this;\n    }\n  }, {\n    key: '_select',\n    value: function _select(s, e) {\n      if (e === undefined) {\n        _get(Object.getPrototypeOf(Array1DTracer.prototype), '_select', this).call(this, 0, s);\n      } else {\n        _get(Object.getPrototypeOf(Array1DTracer.prototype), '_selectRow', this).call(this, 0, s, e);\n      }\n      return this;\n    }\n  }, {\n    key: '_deselect',\n    value: function _deselect(s, e) {\n      if (e === undefined) {\n        _get(Object.getPrototypeOf(Array1DTracer.prototype), '_deselect', this).call(this, 0, s);\n      } else {\n        _get(Object.getPrototypeOf(Array1DTracer.prototype), '_deselectRow', this).call(this, 0, s, e);\n      }\n      return this;\n    }\n  }, {\n    key: 'setData',\n    value: function setData(D) {\n      return _get(Object.getPrototypeOf(Array1DTracer.prototype), 'setData', this).call(this, [D]);\n    }\n  }]);\n\n  return Array1DTracer;\n}(Array2DTracer);\n\nmodule.exports = Array1DTracer;\n\n},{\"./array2d\":39}],39:[function(require,module,exports){\n'use strict';\n\nvar _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\nvar Tracer = require('./tracer');\n\nvar _require = require('../../tracer_manager/util/index');\n\nvar refineByType = _require.refineByType;\n\nvar Array2DTracer = function (_Tracer) {\n  _inherits(Array2DTracer, _Tracer);\n\n  _createClass(Array2DTracer, null, [{\n    key: 'getClassName',\n    value: function getClassName() {\n      return 'Array2DTracer';\n    }\n  }]);\n\n  function Array2DTracer(name) {\n    _classCallCheck(this, Array2DTracer);\n\n    var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(Array2DTracer).call(this, name));\n\n    _this.colorClass = {\n      selected: 'selected',\n      notified: 'notified'\n    };\n\n    if (_this.isNew) initView(_this);\n    return _this;\n  }\n\n  _createClass(Array2DTracer, [{\n    key: '_notify',\n    value: function _notify(x, y, v) {\n      this.manager.pushStep(this.capsule, {\n        type: 'notify',\n        x: x,\n        y: y,\n        v: v\n      });\n      return this;\n    }\n  }, {\n    key: '_denotify',\n    value: function _denotify(x, y) {\n      this.manager.pushStep(this.capsule, {\n        type: 'denotify',\n        x: x,\n        y: y\n      });\n      return this;\n    }\n  }, {\n    key: '_select',\n    value: function _select(sx, sy, ex, ey) {\n      this.pushSelectingStep('select', null, arguments);\n      return this;\n    }\n  }, {\n    key: '_selectRow',\n    value: function _selectRow(x, sy, ey) {\n      this.pushSelectingStep('select', 'row', arguments);\n      return this;\n    }\n  }, {\n    key: '_selectCol',\n    value: function _selectCol(y, sx, ex) {\n      this.pushSelectingStep('select', 'col', arguments);\n      return this;\n    }\n  }, {\n    key: '_deselect',\n    value: function _deselect(sx, sy, ex, ey) {\n      this.pushSelectingStep('deselect', null, arguments);\n      return this;\n    }\n  }, {\n    key: '_deselectRow',\n    value: function _deselectRow(x, sy, ey) {\n      this.pushSelectingStep('deselect', 'row', arguments);\n      return this;\n    }\n  }, {\n    key: '_deselectCol',\n    value: function _deselectCol(y, sx, ex) {\n      this.pushSelectingStep('deselect', 'col', arguments);\n      return this;\n    }\n  }, {\n    key: '_separate',\n    value: function _separate(x, y) {\n      this.manager.pushStep(this.capsule, {\n        type: 'separate',\n        x: x,\n        y: y\n      });\n      return this;\n    }\n  }, {\n    key: '_separateRow',\n    value: function _separateRow(x) {\n      this._separate(x, -1);\n      return this;\n    }\n  }, {\n    key: '_separateCol',\n    value: function _separateCol(y) {\n      this._separate(-1, y);\n      return this;\n    }\n  }, {\n    key: '_deseparate',\n    value: function _deseparate(x, y) {\n      this.manager.pushStep(this.capsule, {\n        type: 'deseparate',\n        x: x,\n        y: y\n      });\n      return this;\n    }\n  }, {\n    key: '_deseparateRow',\n    value: function _deseparateRow(x) {\n      this._deseparate(x, -1);\n      return this;\n    }\n  }, {\n    key: '_deseparateCol',\n    value: function _deseparateCol(y) {\n      this._deseparate(-1, y);\n      return this;\n    }\n  }, {\n    key: 'pushSelectingStep',\n    value: function pushSelectingStep() {\n      var args = Array.prototype.slice.call(arguments);\n      var type = args.shift();\n      var mode = args.shift();\n      args = Array.prototype.slice.call(args.shift());\n      var coord;\n      switch (mode) {\n        case 'row':\n          coord = {\n            x: args[0],\n            sy: args[1],\n            ey: args[2]\n          };\n          break;\n        case 'col':\n          coord = {\n            y: args[0],\n            sx: args[1],\n            ex: args[2]\n          };\n          break;\n        default:\n          if (args[2] === undefined && args[3] === undefined) {\n            coord = {\n              x: args[0],\n              y: args[1]\n            };\n          } else {\n            coord = {\n              sx: args[0],\n              sy: args[1],\n              ex: args[2],\n              ey: args[3]\n            };\n          }\n      }\n      var step = {\n        type: type\n      };\n      $.extend(step, coord);\n      this.manager.pushStep(this.capsule, step);\n    }\n  }, {\n    key: 'processStep',\n    value: function processStep(step, options) {\n      switch (step.type) {\n        case 'notify':\n          if (step.v !== undefined) {\n            var $row = this.$table.find('.mtbl-row').eq(step.x);\n            var $col = $row.find('.mtbl-col').eq(step.y);\n            $col.text(refineByType(step.v));\n          }\n        case 'denotify':\n        case 'select':\n        case 'deselect':\n          var colorClass = step.type == 'select' || step.type == 'deselect' ? this.colorClass.selected : this.colorClass.notified;\n          var addClass = step.type == 'select' || step.type == 'notify';\n          var sx = step.sx;\n          var sy = step.sy;\n          var ex = step.ex;\n          var ey = step.ey;\n          if (sx === undefined) sx = step.x;\n          if (sy === undefined) sy = step.y;\n          if (ex === undefined) ex = step.x;\n          if (ey === undefined) ey = step.y;\n          this.paintColor(sx, sy, ex, ey, colorClass, addClass);\n          break;\n        case 'separate':\n          this.deseparate(step.x, step.y);\n          this.separate(step.x, step.y);\n          break;\n        case 'deseparate':\n          this.deseparate(step.x, step.y);\n          break;\n        default:\n          _get(Object.getPrototypeOf(Array2DTracer.prototype), 'processStep', this).call(this, step, options);\n      }\n    }\n  }, {\n    key: 'setData',\n    value: function setData(D) {\n      this.viewX = this.viewY = 0;\n      this.paddingH = 6;\n      this.paddingV = 3;\n      this.fontSize = 16;\n\n      if (_get(Object.getPrototypeOf(Array2DTracer.prototype), 'setData', this).apply(this, arguments)) {\n        this.$table.find('.mtbl-row').each(function (i) {\n          $(this).find('.mtbl-col').each(function (j) {\n            $(this).text(refineByType(D[i][j]));\n          });\n        });\n        return true;\n      }\n\n      this.$table.empty();\n      for (var i = 0; i < D.length; i++) {\n        var $row = $('<div class=\"mtbl-row\">');\n        this.$table.append($row);\n        for (var j = 0; j < D[i].length; j++) {\n          var $col = $('<div class=\"mtbl-col\">').css(this.getCellCss()).text(refineByType(D[i][j]));\n          $row.append($col);\n        }\n      }\n      this.resize();\n\n      return false;\n    }\n  }, {\n    key: 'resize',\n    value: function resize() {\n      _get(Object.getPrototypeOf(Array2DTracer.prototype), 'resize', this).call(this);\n\n      this.refresh();\n    }\n  }, {\n    key: 'clear',\n    value: function clear() {\n      _get(Object.getPrototypeOf(Array2DTracer.prototype), 'clear', this).call(this);\n\n      this.clearColor();\n      this.deseparateAll();\n    }\n  }, {\n    key: 'getCellCss',\n    value: function getCellCss() {\n      return {\n        padding: this.paddingV.toFixed(1) + 'px ' + this.paddingH.toFixed(1) + 'px',\n        'font-size': this.fontSize.toFixed(1) + 'px'\n      };\n    }\n  }, {\n    key: 'refresh',\n    value: function refresh() {\n      _get(Object.getPrototypeOf(Array2DTracer.prototype), 'refresh', this).call(this);\n\n      var $parent = this.$table.parent();\n      var top = $parent.height() / 2 - this.$table.height() / 2 + this.viewY;\n      var left = $parent.width() / 2 - this.$table.width() / 2 + this.viewX;\n      this.$table.css('margin-top', top);\n      this.$table.css('margin-left', left);\n    }\n  }, {\n    key: 'mousedown',\n    value: function mousedown(e) {\n      _get(Object.getPrototypeOf(Array2DTracer.prototype), 'mousedown', this).call(this, e);\n\n      this.dragX = e.pageX;\n      this.dragY = e.pageY;\n      this.dragging = true;\n    }\n  }, {\n    key: 'mousemove',\n    value: function mousemove(e) {\n      _get(Object.getPrototypeOf(Array2DTracer.prototype), 'mousemove', this).call(this, e);\n\n      if (this.dragging) {\n        this.viewX += e.pageX - this.dragX;\n        this.viewY += e.pageY - this.dragY;\n        this.dragX = e.pageX;\n        this.dragY = e.pageY;\n        this.refresh();\n      }\n    }\n  }, {\n    key: 'mouseup',\n    value: function mouseup(e) {\n      _get(Object.getPrototypeOf(Array2DTracer.prototype), 'mouseup', this).call(this, e);\n\n      this.dragging = false;\n    }\n  }, {\n    key: 'mousewheel',\n    value: function mousewheel(e) {\n      _get(Object.getPrototypeOf(Array2DTracer.prototype), 'mousewheel', this).call(this, e);\n\n      e.preventDefault();\n      e = e.originalEvent;\n      var delta = e.wheelDelta !== undefined && e.wheelDelta || e.detail !== undefined && -e.detail;\n      var weight = 1.01;\n      var ratio = delta > 0 ? 1 / weight : weight;\n      if (this.fontSize < 4 && ratio < 1) return;\n      if (this.fontSize > 40 && ratio > 1) return;\n      this.paddingV *= ratio;\n      this.paddingH *= ratio;\n      this.fontSize *= ratio;\n      this.$table.find('.mtbl-col').css(this.getCellCss());\n      this.refresh();\n    }\n  }, {\n    key: 'paintColor',\n    value: function paintColor(sx, sy, ex, ey, colorClass, addClass) {\n      for (var i = sx; i <= ex; i++) {\n        var $row = this.$table.find('.mtbl-row').eq(i);\n        for (var j = sy; j <= ey; j++) {\n          var $col = $row.find('.mtbl-col').eq(j);\n          if (addClass) $col.addClass(colorClass);else $col.removeClass(colorClass);\n        }\n      }\n    }\n  }, {\n    key: 'clearColor',\n    value: function clearColor() {\n      this.$table.find('.mtbl-col').removeClass(Object.keys(this.colorClass).join(' '));\n    }\n  }, {\n    key: 'separate',\n    value: function separate(x, y) {\n      this.$table.find('.mtbl-row').each(function (i) {\n        var $row = $(this);\n        if (i == x) {\n          $row.after($('<div class=\"mtbl-empty-row\">').attr('data-row', i));\n        }\n        $row.find('.mtbl-col').each(function (j) {\n          var $col = $(this);\n          if (j == y) {\n            $col.after($('<div class=\"mtbl-empty-col\">').attr('data-col', j));\n          }\n        });\n      });\n    }\n  }, {\n    key: 'deseparate',\n    value: function deseparate(x, y) {\n      this.$table.find('[data-row=' + x + ']').remove();\n      this.$table.find('[data-col=' + y + ']').remove();\n    }\n  }, {\n    key: 'deseparateAll',\n    value: function deseparateAll() {\n      this.$table.find('.mtbl-empty-row, .mtbl-empty-col').remove();\n    }\n  }]);\n\n  return Array2DTracer;\n}(Tracer);\n\nvar initView = function initView(tracer) {\n  tracer.$table = tracer.capsule.$table = $('<div class=\"mtbl-table\">');\n  tracer.$container.append(tracer.$table);\n};\n\nmodule.exports = Array2DTracer;\n\n},{\"../../tracer_manager/util/index\":63,\"./tracer\":45}],40:[function(require,module,exports){\n'use strict';\n\nvar _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\nvar Tracer = require('./tracer');\n\nvar ChartTracer = function (_Tracer) {\n  _inherits(ChartTracer, _Tracer);\n\n  _createClass(ChartTracer, null, [{\n    key: 'getClassName',\n    value: function getClassName() {\n      return 'ChartTracer';\n    }\n  }]);\n\n  function ChartTracer(name) {\n    _classCallCheck(this, ChartTracer);\n\n    var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(ChartTracer).call(this, name));\n\n    _this.color = {\n      selected: 'rgba(255, 0, 0, 1)',\n      notified: 'rgba(0, 0, 255, 1)',\n      default: 'rgba(136, 136, 136, 1)'\n    };\n\n    if (_this.isNew) initView(_this);\n    return _this;\n  }\n\n  _createClass(ChartTracer, [{\n    key: 'setData',\n    value: function setData(C) {\n      if (_get(Object.getPrototypeOf(ChartTracer.prototype), 'setData', this).apply(this, arguments)) return true;\n\n      var color = [];\n      for (var i = 0; i < C.length; i++) {\n        color.push(this.color.default);\n      }this.chart.config.data = {\n        labels: C.map(String),\n        datasets: [{\n          backgroundColor: color,\n          data: C\n        }]\n      };\n      this.chart.update();\n    }\n  }, {\n    key: '_notify',\n    value: function _notify(s, v) {\n      this.manager.pushStep(this.capsule, {\n        type: 'notify',\n        s: s,\n        v: v\n      });\n      return this;\n    }\n  }, {\n    key: '_denotify',\n    value: function _denotify(s) {\n      this.manager.pushStep(this.capsule, {\n        type: 'denotify',\n        s: s\n      });\n      return this;\n    }\n  }, {\n    key: '_select',\n    value: function _select(s, e) {\n      this.manager.pushStep(this.capsule, {\n        type: 'select',\n        s: s,\n        e: e\n      });\n      return this;\n    }\n  }, {\n    key: '_deselect',\n    value: function _deselect(s, e) {\n      this.manager.pushStep(this.capsule, {\n        type: 'deselect',\n        s: s,\n        e: e\n      });\n      return this;\n    }\n  }, {\n    key: 'processStep',\n    value: function processStep(step, options) {\n      switch (step.type) {\n        case 'notify':\n          if (step.v !== undefined) {\n            this.chart.config.data.datasets[0].data[step.s] = step.v;\n            this.chart.config.data.labels[step.s] = step.v.toString();\n          }\n        case 'denotify':\n        case 'deselect':\n        case 'select':\n          var color = step.type == 'notify' ? this.color.notified : step.type == 'select' ? this.color.selected : this.color.default;\n          if (step.e !== undefined) for (var i = step.s; i <= step.e; i++) {\n            this.chart.config.data.datasets[0].backgroundColor[i] = color;\n          } else this.chart.config.data.datasets[0].backgroundColor[step.s] = color;\n          this.chart.update();\n          break;\n        default:\n          _get(Object.getPrototypeOf(ChartTracer.prototype), 'processStep', this).call(this, step, options);\n      }\n    }\n  }, {\n    key: 'resize',\n    value: function resize() {\n      _get(Object.getPrototypeOf(ChartTracer.prototype), 'resize', this).call(this);\n\n      this.chart.resize();\n    }\n  }, {\n    key: 'clear',\n    value: function clear() {\n      _get(Object.getPrototypeOf(ChartTracer.prototype), 'clear', this).call(this);\n\n      var data = this.chart.config.data;\n      if (data.datasets.length) {\n        var backgroundColor = data.datasets[0].backgroundColor;\n        for (var i = 0; i < backgroundColor.length; i++) {\n          backgroundColor[i] = this.color.default;\n        }\n        this.chart.update();\n      }\n    }\n  }]);\n\n  return ChartTracer;\n}(Tracer);\n\nvar initView = function initView(tracer) {\n  tracer.$wrapper = tracer.capsule.$wrapper = $('<canvas class=\"mchrt-chart\">');\n  tracer.$container.append(tracer.$wrapper);\n  tracer.chart = tracer.capsule.chart = new Chart(tracer.$wrapper, {\n    type: 'bar',\n    data: {\n      labels: [],\n      datasets: []\n    },\n    options: {\n      scales: {\n        yAxes: [{\n          ticks: {\n            beginAtZero: true\n          }\n        }]\n      },\n      animation: false,\n      legend: false,\n      responsive: true,\n      maintainAspectRatio: false\n    }\n  });\n};\n\nmodule.exports = ChartTracer;\n\n},{\"./tracer\":45}],41:[function(require,module,exports){\n'use strict';\n\nvar _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\nvar DirectedGraphTracer = require('./directed_graph');\n\nvar CoordinateSystemTracer = function (_DirectedGraphTracer) {\n  _inherits(CoordinateSystemTracer, _DirectedGraphTracer);\n\n  _createClass(CoordinateSystemTracer, null, [{\n    key: 'getClassName',\n    value: function getClassName() {\n      return 'CoordinateSystemTracer';\n    }\n  }]);\n\n  function CoordinateSystemTracer(name) {\n    _classCallCheck(this, CoordinateSystemTracer);\n\n    var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(CoordinateSystemTracer).call(this, name));\n\n    if (_this.isNew) initView(_this);\n    return _this;\n  }\n\n  _createClass(CoordinateSystemTracer, [{\n    key: 'setData',\n    value: function setData(C) {\n      if (Tracer.prototype.setData.apply(this, arguments)) return true;\n\n      this.graph.clear();\n      var nodes = [];\n      var edges = [];\n      for (var i = 0; i < C.length; i++) {\n        nodes.push({\n          id: this.n(i),\n          x: C[i][0],\n          y: C[i][1],\n          label: '' + i,\n          size: 1,\n          color: this.color.default\n        });\n      }this.graph.read({\n        nodes: nodes,\n        edges: edges\n      });\n      this.s.camera.goTo({\n        x: 0,\n        y: 0,\n        angle: 0,\n        ratio: 1\n      });\n      this.refresh();\n\n      return false;\n    }\n  }, {\n    key: 'processStep',\n    value: function processStep(step, options) {\n      switch (step.type) {\n        case 'visit':\n        case 'leave':\n          var visit = step.type == 'visit';\n          var targetNode = this.graph.nodes(this.n(step.target));\n          var color = visit ? this.color.visited : this.color.left;\n          targetNode.color = color;\n          if (step.source !== undefined) {\n            var edgeId = this.e(step.source, step.target);\n            if (this.graph.edges(edgeId)) {\n              var edge = this.graph.edges(edgeId);\n              edge.color = color;\n              this.graph.dropEdge(edgeId).addEdge(edge);\n            } else {\n              this.graph.addEdge({\n                id: this.e(step.target, step.source),\n                source: this.n(step.source),\n                target: this.n(step.target),\n                color: color,\n                size: 1\n              });\n            }\n          }\n          if (this.logTracer) {\n            var source = step.source;\n            if (source === undefined) source = '';\n            this.logTracer.print(visit ? source + ' -> ' + step.target : source + ' <- ' + step.target);\n          }\n          break;\n        default:\n          _get(Object.getPrototypeOf(CoordinateSystemTracer.prototype), 'processStep', this).call(this, step, options);\n      }\n    }\n  }, {\n    key: 'e',\n    value: function e(v1, v2) {\n      if (v1 > v2) {\n        var temp = v1;\n        v1 = v2;\n        v2 = temp;\n      }\n      return 'e' + v1 + '_' + v2;\n    }\n  }, {\n    key: 'drawOnHover',\n    value: function drawOnHover(node, context, settings, next) {\n      var tracer = this;\n\n      context.setLineDash([5, 5]);\n      var nodeIdx = node.id.substring(1);\n      this.graph.edges().forEach(function (edge) {\n        var ends = edge.id.substring(1).split(\"_\");\n        if (ends[0] == nodeIdx) {\n          var color = '#0ff';\n          var source = node;\n          var target = tracer.graph.nodes('n' + ends[1]);\n          tracer.drawEdge(edge, source, target, color, context, settings);\n          if (next) next(edge, source, target, color, context, settings);\n        } else if (ends[1] == nodeIdx) {\n          var color = '#0ff';\n          var source = tracer.graph.nodes('n' + ends[0]);\n          var target = node;\n          tracer.drawEdge(edge, source, target, color, context, settings);\n          if (next) next(edge, source, target, color, context, settings);\n        }\n      });\n    }\n  }, {\n    key: 'drawEdge',\n    value: function drawEdge(edge, source, target, color, context, settings) {\n      var prefix = settings('prefix') || '',\n          size = edge[prefix + 'size'] || 1;\n\n      context.strokeStyle = color;\n      context.lineWidth = size;\n      context.beginPath();\n      context.moveTo(source[prefix + 'x'], source[prefix + 'y']);\n      context.lineTo(target[prefix + 'x'], target[prefix + 'y']);\n      context.stroke();\n    }\n  }]);\n\n  return CoordinateSystemTracer;\n}(DirectedGraphTracer);\n\nvar initView = function initView(tracer) {\n  tracer.s.settings({\n    defaultEdgeType: 'def',\n    funcEdgesDef: function funcEdgesDef(edge, source, target, context, settings) {\n      var color = tracer.getColor(edge, source, target, settings);\n      tracer.drawEdge(edge, source, target, color, context, settings);\n    }\n  });\n};\n\nmodule.exports = CoordinateSystemTracer;\n\n},{\"./directed_graph\":42}],42:[function(require,module,exports){\n'use strict';\n\nvar _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\nvar Tracer = require('./tracer');\n\nvar _require = require('../../tracer_manager/util/index');\n\nvar refineByType = _require.refineByType;\n\nvar DirectedGraphTracer = function (_Tracer) {\n  _inherits(DirectedGraphTracer, _Tracer);\n\n  _createClass(DirectedGraphTracer, null, [{\n    key: 'getClassName',\n    value: function getClassName() {\n      return 'DirectedGraphTracer';\n    }\n  }]);\n\n  function DirectedGraphTracer(name) {\n    _classCallCheck(this, DirectedGraphTracer);\n\n    var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(DirectedGraphTracer).call(this, name));\n\n    _this.color = {\n      selected: '#0f0',\n      visited: '#f00',\n      left: '#000',\n      default: '#888'\n    };\n\n    if (_this.isNew) initView(_this);\n    return _this;\n  }\n\n  _createClass(DirectedGraphTracer, [{\n    key: '_setTreeData',\n    value: function _setTreeData(G, root) {\n      this.manager.pushStep(this.capsule, {\n        type: 'setTreeData',\n        arguments: arguments\n      });\n      return this;\n    }\n  }, {\n    key: '_visit',\n    value: function _visit(target, source) {\n      this.manager.pushStep(this.capsule, {\n        type: 'visit',\n        target: target,\n        source: source\n      });\n      return this;\n    }\n  }, {\n    key: '_leave',\n    value: function _leave(target, source) {\n      this.manager.pushStep(this.capsule, {\n        type: 'leave',\n        target: target,\n        source: source\n      });\n      return this;\n    }\n  }, {\n    key: 'processStep',\n    value: function processStep(step, options) {\n      switch (step.type) {\n        case 'setTreeData':\n          this.setTreeData.apply(this, step.arguments);\n          break;\n        case 'visit':\n        case 'leave':\n          var visit = step.type == 'visit';\n          var targetNode = this.graph.nodes(this.n(step.target));\n          var color = visit ? this.color.visited : this.color.left;\n          targetNode.color = color;\n          if (step.source !== undefined) {\n            var edgeId = this.e(step.source, step.target);\n            var edge = this.graph.edges(edgeId);\n            edge.color = color;\n            this.graph.dropEdge(edgeId).addEdge(edge);\n          }\n          if (this.logTracer) {\n            var source = step.source;\n            if (source === undefined) source = '';\n            this.logTracer.print(visit ? source + ' -> ' + step.target : source + ' <- ' + step.target);\n          }\n          break;\n        default:\n          _get(Object.getPrototypeOf(DirectedGraphTracer.prototype), 'processStep', this).call(this, step, options);\n      }\n    }\n  }, {\n    key: 'setTreeData',\n    value: function setTreeData(G, root, undirected) {\n      var tracer = this;\n\n      root = root || 0;\n      var maxDepth = -1;\n\n      var chk = new Array(G.length);\n      var getDepth = function getDepth(node, depth) {\n        if (chk[node]) throw \"the given graph is not a tree because it forms a circuit\";\n        chk[node] = true;\n        if (maxDepth < depth) maxDepth = depth;\n        for (var i = 0; i < G[node].length; i++) {\n          if (G[node][i]) getDepth(i, depth + 1);\n        }\n      };\n      getDepth(root, 1);\n\n      if (this.setData(G, undirected)) return true;\n\n      var place = function place(node, x, y) {\n        var temp = tracer.graph.nodes(tracer.n(node));\n        temp.x = x;\n        temp.y = y;\n      };\n\n      var wgap = 1 / (maxDepth - 1);\n      var dfs = function dfs(node, depth, top, bottom) {\n        place(node, top + bottom, depth * wgap);\n        var children = 0;\n        for (var i = 0; i < G[node].length; i++) {\n          if (G[node][i]) children++;\n        }\n        var vgap = (bottom - top) / children;\n        var cnt = 0;\n        for (var i = 0; i < G[node].length; i++) {\n          if (G[node][i]) dfs(i, depth + 1, top + vgap * cnt, top + vgap * ++cnt);\n        }\n      };\n      dfs(root, 0, 0, 1);\n\n      this.refresh();\n    }\n  }, {\n    key: 'setData',\n    value: function setData(G, undirected) {\n      if (_get(Object.getPrototypeOf(DirectedGraphTracer.prototype), 'setData', this).apply(this, arguments)) return true;\n\n      this.graph.clear();\n      var nodes = [];\n      var edges = [];\n      var unitAngle = 2 * Math.PI / G.length;\n      var currentAngle = 0;\n      for (var i = 0; i < G.length; i++) {\n        currentAngle += unitAngle;\n        nodes.push({\n          id: this.n(i),\n          label: '' + i,\n          x: .5 + Math.sin(currentAngle) / 2,\n          y: .5 + Math.cos(currentAngle) / 2,\n          size: 1,\n          color: this.color.default,\n          weight: 0\n        });\n\n        if (undirected) {\n          for (var j = 0; j <= i; j++) {\n            var value = G[i][j] || G[j][i];\n            if (value) {\n              edges.push({\n                id: this.e(i, j),\n                source: this.n(i),\n                target: this.n(j),\n                color: this.color.default,\n                size: 1,\n                weight: refineByType(value)\n              });\n            }\n          }\n        } else {\n          for (var _j = 0; _j < G[i].length; _j++) {\n            if (G[i][_j]) {\n              edges.push({\n                id: this.e(i, _j),\n                source: this.n(i),\n                target: this.n(_j),\n                color: this.color.default,\n                size: 1,\n                weight: refineByType(G[i][_j])\n              });\n            }\n          }\n        }\n      }\n\n      this.graph.read({\n        nodes: nodes,\n        edges: edges\n      });\n      this.s.camera.goTo({\n        x: 0,\n        y: 0,\n        angle: 0,\n        ratio: 1\n      });\n      this.refresh();\n\n      return false;\n    }\n  }, {\n    key: 'resize',\n    value: function resize() {\n      _get(Object.getPrototypeOf(DirectedGraphTracer.prototype), 'resize', this).call(this);\n\n      this.s.renderers[0].resize();\n      this.refresh();\n    }\n  }, {\n    key: 'refresh',\n    value: function refresh() {\n      _get(Object.getPrototypeOf(DirectedGraphTracer.prototype), 'refresh', this).call(this);\n\n      this.s.refresh();\n    }\n  }, {\n    key: 'clear',\n    value: function clear() {\n      _get(Object.getPrototypeOf(DirectedGraphTracer.prototype), 'clear', this).call(this);\n\n      this.clearGraphColor();\n    }\n  }, {\n    key: 'clearGraphColor',\n    value: function clearGraphColor() {\n      var tracer = this;\n\n      this.graph.nodes().forEach(function (node) {\n        node.color = tracer.color.default;\n      });\n      this.graph.edges().forEach(function (edge) {\n        edge.color = tracer.color.default;\n      });\n    }\n  }, {\n    key: 'n',\n    value: function n(v) {\n      return 'n' + v;\n    }\n  }, {\n    key: 'e',\n    value: function e(v1, v2) {\n      return 'e' + v1 + '_' + v2;\n    }\n  }, {\n    key: 'getColor',\n    value: function getColor(edge, source, target, settings) {\n      var color = edge.color,\n          edgeColor = settings('edgeColor'),\n          defaultNodeColor = settings('defaultNodeColor'),\n          defaultEdgeColor = settings('defaultEdgeColor');\n      if (!color) switch (edgeColor) {\n        case 'source':\n          color = source.color || defaultNodeColor;\n          break;\n        case 'target':\n          color = target.color || defaultNodeColor;\n          break;\n        default:\n          color = defaultEdgeColor;\n          break;\n      }\n\n      return color;\n    }\n  }, {\n    key: 'drawLabel',\n    value: function drawLabel(node, context, settings) {\n      var fontSize,\n          prefix = settings('prefix') || '',\n          size = node[prefix + 'size'];\n\n      if (size < settings('labelThreshold')) return;\n\n      if (!node.label || typeof node.label !== 'string') return;\n\n      fontSize = settings('labelSize') === 'fixed' ? settings('defaultLabelSize') : settings('labelSizeRatio') * size;\n\n      context.font = (settings('fontStyle') ? settings('fontStyle') + ' ' : '') + fontSize + 'px ' + settings('font');\n      context.fillStyle = settings('labelColor') === 'node' ? node.color || settings('defaultNodeColor') : settings('defaultLabelColor');\n\n      context.textAlign = 'center';\n      context.fillText(node.label, Math.round(node[prefix + 'x']), Math.round(node[prefix + 'y'] + fontSize / 3));\n    }\n  }, {\n    key: 'drawArrow',\n    value: function drawArrow(edge, source, target, color, context, settings) {\n      var prefix = settings('prefix') || '',\n          size = edge[prefix + 'size'] || 1,\n          tSize = target[prefix + 'size'],\n          sX = source[prefix + 'x'],\n          sY = source[prefix + 'y'],\n          tX = target[prefix + 'x'],\n          tY = target[prefix + 'y'],\n          angle = Math.atan2(tY - sY, tX - sX),\n          dist = 3;\n      sX += Math.sin(angle) * dist;\n      tX += Math.sin(angle) * dist;\n      sY += -Math.cos(angle) * dist;\n      tY += -Math.cos(angle) * dist;\n      var aSize = Math.max(size * 2.5, settings('minArrowSize')),\n          d = Math.sqrt(Math.pow(tX - sX, 2) + Math.pow(tY - sY, 2)),\n          aX = sX + (tX - sX) * (d - aSize - tSize) / d,\n          aY = sY + (tY - sY) * (d - aSize - tSize) / d,\n          vX = (tX - sX) * aSize / d,\n          vY = (tY - sY) * aSize / d;\n\n      context.strokeStyle = color;\n      context.lineWidth = size;\n      context.beginPath();\n      context.moveTo(sX, sY);\n      context.lineTo(aX, aY);\n      context.stroke();\n\n      context.fillStyle = color;\n      context.beginPath();\n      context.moveTo(aX + vX, aY + vY);\n      context.lineTo(aX + vY * 0.6, aY - vX * 0.6);\n      context.lineTo(aX - vY * 0.6, aY + vX * 0.6);\n      context.lineTo(aX + vX, aY + vY);\n      context.closePath();\n      context.fill();\n    }\n  }, {\n    key: 'drawOnHover',\n    value: function drawOnHover(node, context, settings, next) {\n      var tracer = this;\n\n      context.setLineDash([5, 5]);\n      var nodeIdx = node.id.substring(1);\n      this.graph.edges().forEach(function (edge) {\n        var ends = edge.id.substring(1).split(\"_\");\n        if (ends[0] == nodeIdx) {\n          var color = '#0ff';\n          var source = node;\n          var target = tracer.graph.nodes('n' + ends[1]);\n          tracer.drawArrow(edge, source, target, color, context, settings);\n          if (next) next(edge, source, target, color, context, settings);\n        } else if (ends[1] == nodeIdx) {\n          var color = '#ff0';\n          var source = tracer.graph.nodes('n' + ends[0]);\n          var target = node;\n          tracer.drawArrow(edge, source, target, color, context, settings);\n          if (next) next(edge, source, target, color, context, settings);\n        }\n      });\n    }\n  }]);\n\n  return DirectedGraphTracer;\n}(Tracer);\n\nvar initView = function initView(tracer) {\n  tracer.s = tracer.capsule.s = new sigma({\n    renderer: {\n      container: tracer.$container[0],\n      type: 'canvas'\n    },\n    settings: {\n      minArrowSize: 8,\n      defaultEdgeType: 'arrow',\n      maxEdgeSize: 2.5,\n      labelThreshold: 4,\n      font: 'Roboto',\n      defaultLabelColor: '#fff',\n      zoomMin: 0.6,\n      zoomMax: 1.2,\n      skipErrors: true,\n      minNodeSize: .5,\n      maxNodeSize: 12,\n      labelSize: 'proportional',\n      labelSizeRatio: 1.3,\n      funcLabelsDef: function funcLabelsDef(node, context, settings) {\n        tracer.drawLabel(node, context, settings);\n      },\n      funcHoversDef: function funcHoversDef(node, context, settings, next) {\n        tracer.drawOnHover(node, context, settings, next);\n      },\n      funcEdgesArrow: function funcEdgesArrow(edge, source, target, context, settings) {\n        var color = tracer.getColor(edge, source, target, settings);\n        tracer.drawArrow(edge, source, target, color, context, settings);\n      }\n    }\n  });\n  sigma.plugins.dragNodes(tracer.s, tracer.s.renderers[0]);\n  tracer.graph = tracer.capsule.graph = tracer.s.graph;\n};\n\nsigma.canvas.labels.def = function (node, context, settings) {\n  var func = settings('funcLabelsDef');\n  if (func) {\n    func(node, context, settings);\n  }\n};\nsigma.canvas.hovers.def = function (node, context, settings) {\n  var func = settings('funcHoversDef');\n  if (func) {\n    func(node, context, settings);\n  }\n};\nsigma.canvas.edges.def = function (edge, source, target, context, settings) {\n  var func = settings('funcEdgesDef');\n  if (func) {\n    func(edge, source, target, context, settings);\n  }\n};\nsigma.canvas.edges.arrow = function (edge, source, target, context, settings) {\n  var func = settings('funcEdgesArrow');\n  if (func) {\n    func(edge, source, target, context, settings);\n  }\n};\n\nmodule.exports = DirectedGraphTracer;\n\n},{\"../../tracer_manager/util/index\":63,\"./tracer\":45}],43:[function(require,module,exports){\n'use strict';\n\nvar Tracer = require('./tracer');\nvar LogTracer = require('./log');\nvar Array1DTracer = require('./array1d');\nvar Array2DTracer = require('./array2d');\nvar ChartTracer = require('./chart');\nvar CoordinateSystemTracer = require('./coordinate_system');\nvar DirectedGraphTracer = require('./directed_graph');\nvar UndirectedGraphTracer = require('./undirected_graph');\nvar WeightedDirectedGraphTracer = require('./weighted_directed_graph');\nvar WeightedUndirectedGraphTracer = require('./weighted_undirected_graph');\n\nmodule.exports = {\n  Tracer: Tracer,\n  LogTracer: LogTracer,\n  Array1DTracer: Array1DTracer,\n  Array2DTracer: Array2DTracer,\n  ChartTracer: ChartTracer,\n  CoordinateSystemTracer: CoordinateSystemTracer,\n  DirectedGraphTracer: DirectedGraphTracer,\n  UndirectedGraphTracer: UndirectedGraphTracer,\n  WeightedDirectedGraphTracer: WeightedDirectedGraphTracer,\n  WeightedUndirectedGraphTracer: WeightedUndirectedGraphTracer\n};\n\n},{\"./array1d\":38,\"./array2d\":39,\"./chart\":40,\"./coordinate_system\":41,\"./directed_graph\":42,\"./log\":44,\"./tracer\":45,\"./undirected_graph\":46,\"./weighted_directed_graph\":47,\"./weighted_undirected_graph\":48}],44:[function(require,module,exports){\n'use strict';\n\nvar _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\nvar Tracer = require('./tracer');\n\nvar LogTracer = function (_Tracer) {\n  _inherits(LogTracer, _Tracer);\n\n  _createClass(LogTracer, null, [{\n    key: 'getClassName',\n    value: function getClassName() {\n      return 'LogTracer';\n    }\n  }]);\n\n  function LogTracer(name) {\n    _classCallCheck(this, LogTracer);\n\n    var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(LogTracer).call(this, name));\n\n    if (_this.isNew) initView(_this);\n    return _this;\n  }\n\n  _createClass(LogTracer, [{\n    key: '_print',\n    value: function _print(msg) {\n      this.manager.pushStep(this.capsule, {\n        type: 'print',\n        msg: msg\n      });\n      return this;\n    }\n  }, {\n    key: 'processStep',\n    value: function processStep(step, options) {\n      switch (step.type) {\n        case 'print':\n          this.print(step.msg);\n          break;\n      }\n    }\n  }, {\n    key: 'refresh',\n    value: function refresh() {\n      this.scrollToEnd(Math.min(50, this.interval));\n    }\n  }, {\n    key: 'clear',\n    value: function clear() {\n      _get(Object.getPrototypeOf(LogTracer.prototype), 'clear', this).call(this);\n\n      this.$wrapper.empty();\n    }\n  }, {\n    key: 'print',\n    value: function print(message) {\n      this.$wrapper.append($('<span>').append(message + '<br/>'));\n    }\n  }, {\n    key: 'scrollToEnd',\n    value: function scrollToEnd(duration) {\n      this.$container.animate({\n        scrollTop: this.$container[0].scrollHeight\n      }, duration);\n    }\n  }]);\n\n  return LogTracer;\n}(Tracer);\n\nvar initView = function initView(tracer) {\n  tracer.$wrapper = tracer.capsule.$wrapper = $('<div class=\"wrapper\">');\n  tracer.$container.append(tracer.$wrapper);\n};\n\nmodule.exports = LogTracer;\n\n},{\"./tracer\":45}],45:[function(require,module,exports){\n'use strict';\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nfunction _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar app = require('../../app');\n\nvar _require = require('../../tracer_manager/util/index');\n\nvar toJSON = _require.toJSON;\nvar fromJSON = _require.fromJSON;\n\nvar Tracer = function () {\n  _createClass(Tracer, null, [{\n    key: 'getClassName',\n    value: function getClassName() {\n      return 'Tracer';\n    }\n  }]);\n\n  function Tracer(name) {\n    _classCallCheck(this, Tracer);\n\n    this.module = this.constructor;\n\n    this.manager = app.getTracerManager();\n    this.capsule = this.manager.allocate(this);\n    $.extend(this, this.capsule);\n\n    this.setName(name);\n  }\n\n  _createClass(Tracer, [{\n    key: '_setData',\n    value: function _setData() {\n      for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {\n        args[_key] = arguments[_key];\n      }\n\n      this.manager.pushStep(this.capsule, {\n        type: 'setData',\n        args: toJSON(args)\n      });\n      return this;\n    }\n  }, {\n    key: '_clear',\n    value: function _clear() {\n      this.manager.pushStep(this.capsule, {\n        type: 'clear'\n      });\n      return this;\n    }\n  }, {\n    key: '_wait',\n    value: function _wait() {\n      this.manager.newStep();\n      return this;\n    }\n  }, {\n    key: 'processStep',\n    value: function processStep(step, options) {\n      var type = step.type;\n      var args = step.args;\n\n\n      switch (type) {\n        case 'setData':\n          this.setData.apply(this, _toConsumableArray(fromJSON(args)));\n          break;\n        case 'clear':\n          this.clear();\n          break;\n      }\n    }\n  }, {\n    key: 'setName',\n    value: function setName(name) {\n      var $name = void 0;\n      if (this.isNew) {\n        $name = $('<span class=\"name\">');\n        this.$container.append($name);\n      } else {\n        $name = this.$container.find('span.name');\n      }\n      $name.text(name || this.defaultName);\n    }\n  }, {\n    key: 'setData',\n    value: function setData() {\n      var data = toJSON(arguments);\n      if (!this.isNew && this.lastData === data) {\n        return true;\n      }\n      this.lastData = this.capsule.lastData = data;\n      return false;\n    }\n  }, {\n    key: 'resize',\n    value: function resize() {}\n  }, {\n    key: 'refresh',\n    value: function refresh() {}\n  }, {\n    key: 'clear',\n    value: function clear() {}\n  }, {\n    key: 'attach',\n    value: function attach(tracer) {\n      if (tracer.module === LogTracer) {\n        this.logTracer = tracer;\n      }\n      return this;\n    }\n  }, {\n    key: 'mousedown',\n    value: function mousedown(e) {}\n  }, {\n    key: 'mousemove',\n    value: function mousemove(e) {}\n  }, {\n    key: 'mouseup',\n    value: function mouseup(e) {}\n  }, {\n    key: 'mousewheel',\n    value: function mousewheel(e) {}\n  }]);\n\n  return Tracer;\n}();\n\nmodule.exports = Tracer;\n\n},{\"../../app\":3,\"../../tracer_manager/util/index\":63}],46:[function(require,module,exports){\n'use strict';\n\nvar _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\nvar DirectedGraphTracer = require('./directed_graph');\n\nvar UndirectedGraphTracer = function (_DirectedGraphTracer) {\n  _inherits(UndirectedGraphTracer, _DirectedGraphTracer);\n\n  _createClass(UndirectedGraphTracer, null, [{\n    key: 'getClassName',\n    value: function getClassName() {\n      return 'UndirectedGraphTracer';\n    }\n  }]);\n\n  function UndirectedGraphTracer(name) {\n    _classCallCheck(this, UndirectedGraphTracer);\n\n    var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(UndirectedGraphTracer).call(this, name));\n\n    if (_this.isNew) initView(_this);\n    return _this;\n  }\n\n  _createClass(UndirectedGraphTracer, [{\n    key: 'setTreeData',\n    value: function setTreeData(G, root) {\n      return _get(Object.getPrototypeOf(UndirectedGraphTracer.prototype), 'setTreeData', this).call(this, G, root, true);\n    }\n  }, {\n    key: 'setData',\n    value: function setData(G) {\n      return _get(Object.getPrototypeOf(UndirectedGraphTracer.prototype), 'setData', this).call(this, G, true);\n    }\n  }, {\n    key: 'e',\n    value: function e(v1, v2) {\n      if (v1 > v2) {\n        var temp = v1;\n        v1 = v2;\n        v2 = temp;\n      }\n      return 'e' + v1 + '_' + v2;\n    }\n  }, {\n    key: 'drawOnHover',\n    value: function drawOnHover(node, context, settings, next) {\n      var tracer = this;\n\n      context.setLineDash([5, 5]);\n      var nodeIdx = node.id.substring(1);\n      this.graph.edges().forEach(function (edge) {\n        var ends = edge.id.substring(1).split(\"_\");\n        if (ends[0] == nodeIdx) {\n          var color = '#0ff';\n          var source = node;\n          var target = tracer.graph.nodes('n' + ends[1]);\n          tracer.drawEdge(edge, source, target, color, context, settings);\n          if (next) next(edge, source, target, color, context, settings);\n        } else if (ends[1] == nodeIdx) {\n          var color = '#0ff';\n          var source = tracer.graph.nodes('n' + ends[0]);\n          var target = node;\n          tracer.drawEdge(edge, source, target, color, context, settings);\n          if (next) next(edge, source, target, color, context, settings);\n        }\n      });\n    }\n  }, {\n    key: 'drawEdge',\n    value: function drawEdge(edge, source, target, color, context, settings) {\n      var prefix = settings('prefix') || '',\n          size = edge[prefix + 'size'] || 1;\n\n      context.strokeStyle = color;\n      context.lineWidth = size;\n      context.beginPath();\n      context.moveTo(source[prefix + 'x'], source[prefix + 'y']);\n      context.lineTo(target[prefix + 'x'], target[prefix + 'y']);\n      context.stroke();\n    }\n  }]);\n\n  return UndirectedGraphTracer;\n}(DirectedGraphTracer);\n\nvar initView = function initView(tracer) {\n  tracer.s.settings({\n    defaultEdgeType: 'def',\n    funcEdgesDef: function funcEdgesDef(edge, source, target, context, settings) {\n      var color = tracer.getColor(edge, source, target, settings);\n      tracer.drawEdge(edge, source, target, color, context, settings);\n    }\n  });\n};\n\nmodule.exports = UndirectedGraphTracer;\n\n},{\"./directed_graph\":42}],47:[function(require,module,exports){\n'use strict';\n\nvar _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\nvar DirectedGraphTracer = require('./directed_graph');\n\nvar _require = require('../../tracer_manager/util/index');\n\nvar refineByType = _require.refineByType;\n\nvar WeightedDirectedGraphTracer = function (_DirectedGraphTracer) {\n  _inherits(WeightedDirectedGraphTracer, _DirectedGraphTracer);\n\n  _createClass(WeightedDirectedGraphTracer, null, [{\n    key: 'getClassName',\n    value: function getClassName() {\n      return 'WeightedDirectedGraphTracer';\n    }\n  }]);\n\n  function WeightedDirectedGraphTracer(name) {\n    _classCallCheck(this, WeightedDirectedGraphTracer);\n\n    var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(WeightedDirectedGraphTracer).call(this, name));\n\n    if (_this.isNew) initView(_this);\n    return _this;\n  }\n\n  _createClass(WeightedDirectedGraphTracer, [{\n    key: '_weight',\n    value: function _weight(target, weight) {\n      this.manager.pushStep(this.capsule, {\n        type: 'weight',\n        target: target,\n        weight: weight\n      });\n      return this;\n    }\n  }, {\n    key: '_visit',\n    value: function _visit(target, source, weight) {\n      this.manager.pushStep(this.capsule, {\n        type: 'visit',\n        target: target,\n        source: source,\n        weight: weight\n      });\n      return this;\n    }\n  }, {\n    key: '_leave',\n    value: function _leave(target, source, weight) {\n      this.manager.pushStep(this.capsule, {\n        type: 'leave',\n        target: target,\n        source: source,\n        weight: weight\n      });\n      return this;\n    }\n  }, {\n    key: 'processStep',\n    value: function processStep(step, options) {\n      switch (step.type) {\n        case 'weight':\n          var targetNode = this.graph.nodes(this.n(step.target));\n          if (step.weight !== undefined) targetNode.weight = refineByType(step.weight);\n          break;\n        case 'visit':\n        case 'leave':\n          var visit = step.type == 'visit';\n          var targetNode = this.graph.nodes(this.n(step.target));\n          var color = visit ? step.weight === undefined ? this.color.selected : this.color.visited : this.color.left;\n          targetNode.color = color;\n          if (step.weight !== undefined) targetNode.weight = refineByType(step.weight);\n          if (step.source !== undefined) {\n            var edgeId = this.e(step.source, step.target);\n            var edge = this.graph.edges(edgeId);\n            edge.color = color;\n            this.graph.dropEdge(edgeId).addEdge(edge);\n          }\n          if (this.logTracer) {\n            var source = step.source;\n            if (source === undefined) source = '';\n            this.logTracer.print(visit ? source + ' -> ' + step.target : source + ' <- ' + step.target);\n          }\n          break;\n        default:\n          _get(Object.getPrototypeOf(WeightedDirectedGraphTracer.prototype), 'processStep', this).call(this, step, options);\n      }\n    }\n  }, {\n    key: 'clear',\n    value: function clear() {\n      _get(Object.getPrototypeOf(WeightedDirectedGraphTracer.prototype), 'clear', this).call(this);\n\n      this.clearWeights();\n    }\n  }, {\n    key: 'clearWeights',\n    value: function clearWeights() {\n      this.graph.nodes().forEach(function (node) {\n        node.weight = 0;\n      });\n    }\n  }, {\n    key: 'drawEdgeWeight',\n    value: function drawEdgeWeight(edge, source, target, color, context, settings) {\n      if (source == target) return;\n\n      var prefix = settings('prefix') || '',\n          size = edge[prefix + 'size'] || 1;\n\n      if (size < settings('edgeLabelThreshold')) return;\n\n      if (0 === settings('edgeLabelSizePowRatio')) throw '\"edgeLabelSizePowRatio\" must not be 0.';\n\n      var fontSize,\n          x = (source[prefix + 'x'] + target[prefix + 'x']) / 2,\n          y = (source[prefix + 'y'] + target[prefix + 'y']) / 2,\n          dX = target[prefix + 'x'] - source[prefix + 'x'],\n          dY = target[prefix + 'y'] - source[prefix + 'y'],\n          angle = Math.atan2(dY, dX);\n\n      fontSize = settings('edgeLabelSize') === 'fixed' ? settings('defaultEdgeLabelSize') : settings('defaultEdgeLabelSize') * size * Math.pow(size, -1 / settings('edgeLabelSizePowRatio'));\n\n      context.save();\n\n      if (edge.active) {\n        context.font = [settings('activeFontStyle'), fontSize + 'px', settings('activeFont') || settings('font')].join(' ');\n\n        context.fillStyle = color;\n      } else {\n        context.font = [settings('fontStyle'), fontSize + 'px', settings('font')].join(' ');\n\n        context.fillStyle = color;\n      }\n\n      context.textAlign = 'center';\n      context.textBaseline = 'alphabetic';\n\n      context.translate(x, y);\n      context.rotate(angle);\n      context.fillText(edge.weight, 0, -size / 2 - 3);\n\n      context.restore();\n    }\n  }, {\n    key: 'drawNodeWeight',\n    value: function drawNodeWeight(node, context, settings) {\n      var fontSize,\n          prefix = settings('prefix') || '',\n          size = node[prefix + 'size'];\n\n      if (size < settings('labelThreshold')) return;\n\n      fontSize = settings('labelSize') === 'fixed' ? settings('defaultLabelSize') : settings('labelSizeRatio') * size;\n\n      context.font = (settings('fontStyle') ? settings('fontStyle') + ' ' : '') + fontSize + 'px ' + settings('font');\n      context.fillStyle = settings('labelColor') === 'node' ? node.color || settings('defaultNodeColor') : settings('defaultLabelColor');\n\n      context.textAlign = 'left';\n      context.fillText(node.weight, Math.round(node[prefix + 'x'] + size * 1.5), Math.round(node[prefix + 'y'] + fontSize / 3));\n    }\n  }]);\n\n  return WeightedDirectedGraphTracer;\n}(DirectedGraphTracer);\n\nvar initView = function initView(tracer) {\n  tracer.s.settings({\n    edgeLabelSize: 'proportional',\n    defaultEdgeLabelSize: 20,\n    edgeLabelSizePowRatio: 0.8,\n    funcLabelsDef: function funcLabelsDef(node, context, settings) {\n      tracer.drawNodeWeight(node, context, settings);\n      tracer.drawLabel(node, context, settings);\n    },\n    funcHoversDef: function funcHoversDef(node, context, settings) {\n      tracer.drawOnHover(node, context, settings, tracer.drawEdgeWeight);\n    },\n    funcEdgesArrow: function funcEdgesArrow(edge, source, target, context, settings) {\n      var color = tracer.getColor(edge, source, target, settings);\n      tracer.drawArrow(edge, source, target, color, context, settings);\n      tracer.drawEdgeWeight(edge, source, target, color, context, settings);\n    }\n  });\n};\n\nmodule.exports = WeightedDirectedGraphTracer;\n\n},{\"../../tracer_manager/util/index\":63,\"./directed_graph\":42}],48:[function(require,module,exports){\n'use strict';\n\nvar _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\nvar WeightedDirectedGraphTracer = require('./weighted_directed_graph');\nvar UndirectedGraphTracer = require('./undirected_graph');\n\nvar WeightedUndirectedGraphTracer = function (_WeightedDirectedGrap) {\n  _inherits(WeightedUndirectedGraphTracer, _WeightedDirectedGrap);\n\n  _createClass(WeightedUndirectedGraphTracer, null, [{\n    key: 'getClassName',\n    value: function getClassName() {\n      return 'WeightedUndirectedGraphTracer';\n    }\n  }]);\n\n  function WeightedUndirectedGraphTracer(name) {\n    _classCallCheck(this, WeightedUndirectedGraphTracer);\n\n    var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(WeightedUndirectedGraphTracer).call(this, name));\n\n    _this.e = UndirectedGraphTracer.prototype.e;\n    _this.drawOnHover = UndirectedGraphTracer.prototype.drawOnHover;\n    _this.drawEdge = UndirectedGraphTracer.prototype.drawEdge;\n\n    if (_this.isNew) initView(_this);\n    return _this;\n  }\n\n  _createClass(WeightedUndirectedGraphTracer, [{\n    key: 'setTreeData',\n    value: function setTreeData(G, root) {\n      return _get(Object.getPrototypeOf(WeightedUndirectedGraphTracer.prototype), 'setTreeData', this).call(this, G, root, true);\n    }\n  }, {\n    key: 'setData',\n    value: function setData(G) {\n      return _get(Object.getPrototypeOf(WeightedUndirectedGraphTracer.prototype), 'setData', this).call(this, G, true);\n    }\n  }, {\n    key: 'drawEdgeWeight',\n    value: function drawEdgeWeight(edge, source, target, color, context, settings) {\n      var prefix = settings('prefix') || '';\n      if (source[prefix + 'x'] > target[prefix + 'x']) {\n        var temp = source;\n        source = target;\n        target = temp;\n      }\n      WeightedDirectedGraphTracer.prototype.drawEdgeWeight.call(this, edge, source, target, color, context, settings);\n    }\n  }]);\n\n  return WeightedUndirectedGraphTracer;\n}(WeightedDirectedGraphTracer);\n\nvar initView = function initView(tracer) {\n  tracer.s.settings({\n    defaultEdgeType: 'def',\n    funcEdgesDef: function funcEdgesDef(edge, source, target, context, settings) {\n      var color = tracer.getColor(edge, source, target, settings);\n      tracer.drawEdge(edge, source, target, color, context, settings);\n      tracer.drawEdgeWeight(edge, source, target, color, context, settings);\n    }\n  });\n};\n\nmodule.exports = WeightedUndirectedGraphTracer;\n\n},{\"./undirected_graph\":46,\"./weighted_directed_graph\":47}],49:[function(require,module,exports){\n'use strict';\n\nvar request = require('./request');\n\nmodule.exports = function (url) {\n\n  return request(url, {\n    type: 'GET'\n  });\n};\n\n},{\"./request\":52}],50:[function(require,module,exports){\n'use strict';\n\nvar request = require('./request');\n\nmodule.exports = function (url) {\n  return request(url, {\n    dataType: 'json',\n    type: 'GET'\n  });\n};\n\n},{\"./request\":52}],51:[function(require,module,exports){\n'use strict';\n\nvar request = require('./request');\n\nmodule.exports = function (url, data) {\n  return request(url, {\n    dataType: 'json',\n    type: 'POST',\n    data: JSON.stringify(data)\n  });\n};\n\n},{\"./request\":52}],52:[function(require,module,exports){\n'use strict';\n\nvar RSVP = require('rsvp');\nvar app = require('../../app');\n\nvar _$ = $;\nvar ajax = _$.ajax;\nvar extend = _$.extend;\n\n\nvar defaults = {};\n\nmodule.exports = function (url) {\n  var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n  app.setIsLoading(true);\n\n  return new RSVP.Promise(function (resolve, reject) {\n    var callbacks = {\n      success: function success(response) {\n        app.setIsLoading(false);\n        resolve(response);\n      },\n      error: function error(reason) {\n        app.setIsLoading(false);\n        reject(reason);\n      }\n    };\n\n    var opts = extend({}, defaults, options, callbacks, {\n      url: url\n    });\n\n    ajax(opts);\n  });\n};\n\n},{\"../../app\":3,\"rsvp\":68}],53:[function(require,module,exports){\n'use strict';\n\nvar _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i[\"return\"]) _i[\"return\"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError(\"Invalid attempt to destructure non-iterable instance\"); } }; }();\n\nvar app = require('../app');\nvar Toast = require('../dom/toast');\n\nvar checkLoading = function checkLoading() {\n  if (app.getIsLoading()) {\n    Toast.showErrorToast('Wait until it completes loading of previous file.');\n    return true;\n  }\n  return false;\n};\n\nvar getParameterByName = function getParameterByName(name) {\n  var url = window.location.href;\n  var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)');\n\n  var results = regex.exec(url);\n\n  if (!results || results.length !== 3) {\n    return null;\n  }\n\n  var _results = _slicedToArray(results, 3);\n\n  var id = _results[2];\n\n\n  return id;\n};\n\nvar getHashValue = function getHashValue(key) {\n  if (!key) return null;\n  var hash = window.location.hash.substr(1);\n  var params = hash ? hash.split('&') : [];\n  for (var i = 0; i < params.length; i++) {\n    var pair = params[i].split('=');\n    if (pair[0] === key) {\n      return pair[1];\n    }\n  }\n  return null;\n};\n\nvar setHashValue = function setHashValue(key, value) {\n  if (!key || !value) return;\n  var hash = window.location.hash.substr(1);\n  var params = hash ? hash.split('&') : [];\n\n  var found = false;\n  for (var i = 0; i < params.length && !found; i++) {\n    var pair = params[i].split('=');\n    if (pair[0] === key) {\n      pair[1] = value;\n      params[i] = pair.join('=');\n      found = true;\n    }\n  }\n  if (!found) {\n    params.push([key, value].join('='));\n  }\n\n  var newHash = params.join('&');\n  window.location.hash = '#' + newHash;\n};\n\nvar removeHashValue = function removeHashValue(key) {\n  if (!key) return;\n  var hash = window.location.hash.substr(1);\n  var params = hash ? hash.split('&') : [];\n\n  for (var i = 0; i < params.length; i++) {\n    var pair = params[i].split('=');\n    if (pair[0] === key) {\n      params.splice(i, 1);\n      break;\n    }\n  }\n\n  var newHash = params.join('&');\n  window.location.hash = '#' + newHash;\n};\n\nvar setPath = function setPath(category, algorithm, file) {\n  var path = category ? category + (algorithm ? '/' + algorithm + (file ? '/' + file : '') : '') : '';\n  setHashValue('path', path);\n};\n\nvar getPath = function getPath() {\n  var hash = getHashValue('path');\n  if (hash) {\n    var _hash$split = hash.split('/');\n\n    var _hash$split2 = _slicedToArray(_hash$split, 3);\n\n    var category = _hash$split2[0];\n    var algorithm = _hash$split2[1];\n    var file = _hash$split2[2];\n\n    return { category: category, algorithm: algorithm, file: file };\n  } else {\n    return false;\n  }\n};\n\nmodule.exports = {\n  checkLoading: checkLoading,\n  getParameterByName: getParameterByName,\n  getHashValue: getHashValue,\n  setHashValue: setHashValue,\n  removeHashValue: removeHashValue,\n  setPath: setPath,\n  getPath: getPath\n};\n\n},{\"../app\":3,\"../dom/toast\":23}],54:[function(require,module,exports){\n'use strict';\n\nvar loadAlgorithm = require('./load_algorithm');\nvar loadCategories = require('./load_categories');\nvar loadFile = require('./load_file');\nvar loadScratchPaper = require('./load_scratch_paper');\nvar shareScratchPaper = require('./share_scratch_paper');\n\nmodule.exports = {\n  loadAlgorithm: loadAlgorithm,\n  loadCategories: loadCategories,\n  loadFile: loadFile,\n  loadScratchPaper: loadScratchPaper,\n  shareScratchPaper: shareScratchPaper\n};\n\n},{\"./load_algorithm\":55,\"./load_categories\":56,\"./load_file\":57,\"./load_scratch_paper\":58,\"./share_scratch_paper\":59}],55:[function(require,module,exports){\n'use strict';\n\nvar getJSON = require('./ajax/get_json');\n\nvar _require = require('../utils');\n\nvar getAlgorithmDir = _require.getAlgorithmDir;\n\n\nmodule.exports = function (category, algorithm) {\n  var dir = getAlgorithmDir(category, algorithm);\n  return getJSON(dir + 'desc.json');\n};\n\n},{\"../utils\":66,\"./ajax/get_json\":50}],56:[function(require,module,exports){\n'use strict';\n\nvar getJSON = require('./ajax/get_json');\n\nmodule.exports = function () {\n  return getJSON('./algorithm/category.json');\n};\n\n},{\"./ajax/get_json\":50}],57:[function(require,module,exports){\n'use strict';\n\nvar RSVP = require('rsvp');\n\nvar app = require('../app');\n\nvar _require = require('../utils');\n\nvar getFileDir = _require.getFileDir;\nvar isScratchPaper = _require.isScratchPaper;\n\nvar _require2 = require('./helpers');\n\nvar checkLoading = _require2.checkLoading;\nvar setPath = _require2.setPath;\n\n\nvar get = require('./ajax/get');\n\nvar loadDataAndCode = function loadDataAndCode(dir) {\n  return RSVP.hash({\n    data: get(dir + 'data.js'),\n    code: get(dir + 'code.js')\n  });\n};\n\nvar loadFileAndUpdateContent = function loadFileAndUpdateContent(dir) {\n  app.getEditor().clearContent();\n\n  return loadDataAndCode(dir).then(function (content) {\n    app.updateCachedFile(dir, content);\n    app.getEditor().setContent(content);\n  });\n};\n\nvar cachedContentExists = function cachedContentExists(cachedFile) {\n  return cachedFile && cachedFile.data !== undefined && cachedFile.code !== undefined;\n};\n\nmodule.exports = function (category, algorithm, file, explanation) {\n  return new RSVP.Promise(function (resolve, reject) {\n    if (checkLoading()) {\n      reject();\n    } else {\n      if (isScratchPaper(category)) {\n        setPath(category, app.getLoadedScratch());\n      } else {\n        setPath(category, algorithm, file);\n      }\n      $('#explanation').html(explanation);\n\n      var dir = getFileDir(category, algorithm, file);\n      app.setLastFileUsed(dir);\n      var cachedFile = app.getCachedFile(dir);\n\n      if (cachedContentExists(cachedFile)) {\n        app.getEditor().setContent(cachedFile);\n        resolve();\n      } else {\n        loadFileAndUpdateContent(dir).then(resolve, reject);\n      }\n    }\n  });\n};\n\n},{\"../app\":3,\"../utils\":66,\"./ajax/get\":49,\"./helpers\":53,\"rsvp\":68}],58:[function(require,module,exports){\n'use strict';\n\nvar RSVP = require('rsvp');\nvar app = require('../app');\n\nvar _require = require('../utils');\n\nvar getFileDir = _require.getFileDir;\n\n\nvar getJSON = require('./ajax/get_json');\nvar loadAlgorithm = require('./load_algorithm');\n\nvar extractGistCode = function extractGistCode(files, name) {\n  return files[name + '.js'].content;\n};\n\nmodule.exports = function (gistID) {\n  return new RSVP.Promise(function (resolve, reject) {\n    app.setLoadedScratch(gistID);\n\n    getJSON('https://api.github.com/gists/' + gistID).then(function (_ref) {\n      var files = _ref.files;\n\n\n      var category = 'scratch';\n      var algorithm = gistID;\n\n      loadAlgorithm(category, algorithm).then(function (data) {\n\n        var algoData = extractGistCode(files, 'data');\n        var algoCode = extractGistCode(files, 'code');\n\n        // update scratch paper algo code with the loaded gist code\n        var dir = getFileDir(category, algorithm, 'scratch_paper');\n        app.updateCachedFile(dir, {\n          data: algoData,\n          code: algoCode,\n          'CREDIT.md': 'Shared by an anonymous user from http://parkjs814.github.io/AlgorithmVisualizer'\n        });\n\n        resolve({\n          category: category,\n          algorithm: algorithm,\n          data: data\n        });\n      });\n    });\n  });\n};\n\n},{\"../app\":3,\"../utils\":66,\"./ajax/get_json\":50,\"./load_algorithm\":55,\"rsvp\":68}],59:[function(require,module,exports){\n'use strict';\n\nvar RSVP = require('rsvp');\nvar app = require('../app');\n\nvar postJSON = require('./ajax/post_json');\n\nvar _require = require('./helpers');\n\nvar setPath = _require.setPath;\n\n\nmodule.exports = function () {\n  return new RSVP.Promise(function (resolve, reject) {\n    var _app$getEditor = app.getEditor();\n\n    var dataEditor = _app$getEditor.dataEditor;\n    var codeEditor = _app$getEditor.codeEditor;\n\n\n    var gist = {\n      'description': 'temp',\n      'public': true,\n      'files': {\n        'data.js': {\n          'content': dataEditor.getValue()\n        },\n        'code.js': {\n          'content': codeEditor.getValue()\n        }\n      }\n    };\n\n    postJSON('https://api.github.com/gists', gist).then(function (_ref) {\n      var id = _ref.id;\n\n      app.setLoadedScratch(id);\n      setPath('scratch', id);\n      var _location = location;\n      var href = _location.href;\n\n      $('#algorithm').html('Shared');\n      resolve(href);\n    });\n  });\n};\n\n},{\"../app\":3,\"./ajax/post_json\":51,\"./helpers\":53,\"rsvp\":68}],60:[function(require,module,exports){\n'use strict';\n\nvar TracerManager = require('./manager');\nvar Tracer = require('../module/tracer/tracer');\n\nmodule.exports = {\n  init: function init() {\n    var tm = new TracerManager();\n    Tracer.prototype.manager = tm;\n    return tm;\n  }\n};\n\n},{\"../module/tracer/tracer\":45,\"./manager\":61}],61:[function(require,module,exports){\n'use strict';\n\nvar TopMenu = require('../dom/top_menu');\n\nvar stepLimit = 1e6;\n\nvar TracerManager = function TracerManager() {\n  this.timer = null;\n  this.pause = false;\n  this.capsules = [];\n  this.interval = 500;\n};\n\nTracerManager.prototype = {\n  add: function add(tracer) {\n\n    var $container = $('<section class=\"module_wrapper\">');\n    $('.module_container').append($container);\n\n    var capsule = {\n      module: tracer.module,\n      tracer: tracer,\n      allocated: true,\n      defaultName: null,\n      $container: $container,\n      isNew: true\n    };\n\n    this.capsules.push(capsule);\n    return capsule;\n  },\n  allocate: function allocate(newTracer) {\n    var selectedCapsule = null;\n    var count = 0;\n\n    $.each(this.capsules, function (i, capsule) {\n      if (capsule.module === newTracer.module) {\n        count++;\n        if (!capsule.allocated) {\n          capsule.tracer = newTracer;\n          capsule.allocated = true;\n          capsule.isNew = false;\n          selectedCapsule = capsule;\n          return false;\n        }\n      }\n    });\n\n    if (selectedCapsule === null) {\n      count++;\n      selectedCapsule = this.add(newTracer);\n    }\n\n    var className = newTracer.module.getClassName();\n    selectedCapsule.defaultName = className + ' ' + count;\n    selectedCapsule.order = this.order++;\n    return selectedCapsule;\n  },\n  deallocateAll: function deallocateAll() {\n    this.order = 0;\n    this.reset();\n    $.each(this.capsules, function (i, capsule) {\n      capsule.allocated = false;\n    });\n  },\n  removeUnallocated: function removeUnallocated() {\n    var changed = false;\n\n    this.capsules = $.grep(this.capsules, function (capsule) {\n      var removed = !capsule.allocated;\n\n      if (capsule.isNew || removed) {\n        changed = true;\n      }\n      if (removed) {\n        capsule.$container.remove();\n      }\n\n      return !removed;\n    });\n\n    if (changed) {\n      this.place();\n    }\n  },\n  place: function place() {\n    var capsules = this.capsules;\n\n\n    $.each(capsules, function (i, capsule) {\n      var width = 100;\n      var height = 100 / capsules.length;\n      var top = height * capsule.order;\n\n      capsule.$container.css({\n        top: top + '%',\n        width: width + '%',\n        height: height + '%'\n      });\n\n      capsule.tracer.resize();\n    });\n  },\n  resize: function resize() {\n    this.command('resize');\n  },\n  isPause: function isPause() {\n    return this.pause;\n  },\n  setInterval: function setInterval(interval) {\n    $('#interval').val(interval);\n  },\n  reset: function reset() {\n    this.traces = [];\n    this.traceIndex = -1;\n    this.stepCnt = 0;\n    if (this.timer) {\n      clearTimeout(this.timer);\n    }\n    this.command('clear');\n  },\n  pushStep: function pushStep(capsule, step) {\n    if (this.stepCnt++ > stepLimit) throw \"Tracer's stack overflow\";\n    var len = this.traces.length;\n    var last = [];\n    if (len === 0) {\n      this.traces.push(last);\n    } else {\n      last = this.traces[len - 1];\n    }\n    last.push($.extend(step, {\n      capsule: capsule\n    }));\n  },\n  newStep: function newStep() {\n    this.traces.push([]);\n  },\n  pauseStep: function pauseStep() {\n    if (this.traceIndex < 0) return;\n    this.pause = true;\n    if (this.timer) {\n      clearTimeout(this.timer);\n    }\n    $('#btn_pause').addClass('active');\n  },\n  resumeStep: function resumeStep() {\n    this.pause = false;\n    this.step(this.traceIndex + 1);\n    $('#btn_pause').removeClass('active');\n  },\n  step: function step(i) {\n    var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n    var tracer = this;\n\n    if (isNaN(i) || i >= this.traces.length || i < 0) return;\n\n    this.traceIndex = i;\n    var trace = this.traces[i];\n    trace.forEach(function (step) {\n      step.capsule.tracer.processStep(step, options);\n    });\n\n    if (!options.virtual) {\n      this.command('refresh');\n    }\n\n    if (this.pause) return;\n\n    this.timer = setTimeout(function () {\n      if (!tracer.nextStep(options)) {\n        TopMenu.resetTopMenuButtons();\n      }\n    }, this.interval);\n  },\n  prevStep: function prevStep() {\n    var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];\n\n    this.command('clear');\n\n    var finalIndex = this.traceIndex - 1;\n    if (finalIndex < 0) {\n      this.traceIndex = -1;\n      this.command('refresh');\n      return false;\n    }\n\n    for (var i = 0; i < finalIndex; i++) {\n      this.step(i, $.extend(options, {\n        virtual: true\n      }));\n    }\n\n    this.step(finalIndex);\n    return true;\n  },\n  nextStep: function nextStep() {\n    var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];\n\n    var finalIndex = this.traceIndex + 1;\n    if (finalIndex >= this.traces.length) {\n      this.traceIndex = this.traces.length - 1;\n      return false;\n    }\n\n    this.step(finalIndex, options);\n    return true;\n  },\n  visualize: function visualize() {\n    this.traceIndex = -1;\n    this.resumeStep();\n  },\n  command: function command() {\n    for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    var functionName = args.shift();\n    $.each(this.capsules, function (i, capsule) {\n      if (capsule.allocated) {\n        capsule.tracer.module.prototype[functionName].apply(capsule.tracer, args);\n      }\n    });\n  },\n  findOwner: function findOwner(container) {\n    var selectedCapsule = null;\n    $.each(this.capsules, function (i, capsule) {\n      if (capsule.$container[0] === container) {\n        selectedCapsule = capsule;\n        return false;\n      }\n    });\n    return selectedCapsule.tracer;\n  }\n};\n\nmodule.exports = TracerManager;\n\n},{\"../dom/top_menu\":24}],62:[function(require,module,exports){\n'use strict';\n\nvar parse = JSON.parse;\n\n\nvar fromJSON = function fromJSON(obj) {\n  return parse(obj, function (key, value) {\n    return value === 'Infinity' ? Infinity : value;\n  });\n};\n\nmodule.exports = fromJSON;\n\n},{}],63:[function(require,module,exports){\n'use strict';\n\nvar toJSON = require('./to_json');\nvar fromJSON = require('./from_json');\nvar refineByType = require('./refine_by_type');\n\nmodule.exports = {\n  toJSON: toJSON,\n  fromJSON: fromJSON,\n  refineByType: refineByType\n};\n\n},{\"./from_json\":62,\"./refine_by_type\":64,\"./to_json\":65}],64:[function(require,module,exports){\n'use strict';\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol ? \"symbol\" : typeof obj; };\n\nvar refineByType = function refineByType(item) {\n  switch (typeof item === 'undefined' ? 'undefined' : _typeof(item)) {\n    case 'number':\n      return refineNumber(item);\n    case 'boolean':\n      return refineBoolean(item);\n    default:\n      return refineString(item);\n  }\n};\n\nvar refineString = function refineString(str) {\n  return str === '' ? ' ' : str;\n};\n\nvar refineNumber = function refineNumber(num) {\n  return num === Infinity ? '∞' : num;\n};\n\nvar refineBoolean = function refineBoolean(bool) {\n  return bool ? 'T' : 'F';\n};\n\nmodule.exports = refineByType;\n\n},{}],65:[function(require,module,exports){\n'use strict';\n\nvar stringify = JSON.stringify;\n\n\nvar toJSON = function toJSON(obj) {\n  return stringify(obj, function (key, value) {\n    return value === Infinity ? 'Infinity' : value;\n  });\n};\n\nmodule.exports = toJSON;\n\n},{}],66:[function(require,module,exports){\n'use strict';\n\nvar isScratchPaper = function isScratchPaper(category, algorithm) {\n  return category == 'scratch';\n};\n\nvar getAlgorithmDir = function getAlgorithmDir(category, algorithm) {\n  if (isScratchPaper(category)) return './algorithm/scratch_paper/';\n  return './algorithm/' + category + '/' + algorithm + '/';\n};\n\nvar getFileDir = function getFileDir(category, algorithm, file) {\n  if (isScratchPaper(category)) return './algorithm/scratch_paper/';\n  return './algorithm/' + category + '/' + algorithm + '/' + file + '/';\n};\n\nmodule.exports = {\n  isScratchPaper: isScratchPaper,\n  getAlgorithmDir: getAlgorithmDir,\n  getFileDir: getFileDir\n};\n\n},{}],67:[function(require,module,exports){\n// shim for using process in browser\n\nvar process = module.exports = {};\nvar queue = [];\nvar draining = false;\nvar currentQueue;\nvar queueIndex = -1;\n\nfunction cleanUpNextTick() {\n    if (!draining || !currentQueue) {\n        return;\n    }\n    draining = false;\n    if (currentQueue.length) {\n        queue = currentQueue.concat(queue);\n    } else {\n        queueIndex = -1;\n    }\n    if (queue.length) {\n        drainQueue();\n    }\n}\n\nfunction drainQueue() {\n    if (draining) {\n        return;\n    }\n    var timeout = setTimeout(cleanUpNextTick);\n    draining = true;\n\n    var len = queue.length;\n    while(len) {\n        currentQueue = queue;\n        queue = [];\n        while (++queueIndex < len) {\n            if (currentQueue) {\n                currentQueue[queueIndex].run();\n            }\n        }\n        queueIndex = -1;\n        len = queue.length;\n    }\n    currentQueue = null;\n    draining = false;\n    clearTimeout(timeout);\n}\n\nprocess.nextTick = function (fun) {\n    var args = new Array(arguments.length - 1);\n    if (arguments.length > 1) {\n        for (var i = 1; i < arguments.length; i++) {\n            args[i - 1] = arguments[i];\n        }\n    }\n    queue.push(new Item(fun, args));\n    if (queue.length === 1 && !draining) {\n        setTimeout(drainQueue, 0);\n    }\n};\n\n// v8 likes predictible objects\nfunction Item(fun, array) {\n    this.fun = fun;\n    this.array = array;\n}\nItem.prototype.run = function () {\n    this.fun.apply(null, this.array);\n};\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\nprocess.version = ''; // empty string to avoid regexp issues\nprocess.versions = {};\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\n\nprocess.binding = function (name) {\n    throw new Error('process.binding is not supported');\n};\n\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n    throw new Error('process.chdir is not supported');\n};\nprocess.umask = function() { return 0; };\n\n},{}],68:[function(require,module,exports){\n(function (process,global){\n/*!\n * @overview RSVP - a tiny implementation of Promises/A+.\n * @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors\n * @license   Licensed under MIT license\n *            See https://raw.githubusercontent.com/tildeio/rsvp.js/master/LICENSE\n * @version   3.2.1\n */\n\n(function() {\n    \"use strict\";\n    function lib$rsvp$utils$$objectOrFunction(x) {\n      return typeof x === 'function' || (typeof x === 'object' && x !== null);\n    }\n\n    function lib$rsvp$utils$$isFunction(x) {\n      return typeof x === 'function';\n    }\n\n    function lib$rsvp$utils$$isMaybeThenable(x) {\n      return typeof x === 'object' && x !== null;\n    }\n\n    var lib$rsvp$utils$$_isArray;\n    if (!Array.isArray) {\n      lib$rsvp$utils$$_isArray = function (x) {\n        return Object.prototype.toString.call(x) === '[object Array]';\n      };\n    } else {\n      lib$rsvp$utils$$_isArray = Array.isArray;\n    }\n\n    var lib$rsvp$utils$$isArray = lib$rsvp$utils$$_isArray;\n\n    var lib$rsvp$utils$$now = Date.now || function() { return new Date().getTime(); };\n\n    function lib$rsvp$utils$$F() { }\n\n    var lib$rsvp$utils$$o_create = (Object.create || function (o) {\n      if (arguments.length > 1) {\n        throw new Error('Second argument not supported');\n      }\n      if (typeof o !== 'object') {\n        throw new TypeError('Argument must be an object');\n      }\n      lib$rsvp$utils$$F.prototype = o;\n      return new lib$rsvp$utils$$F();\n    });\n    function lib$rsvp$events$$indexOf(callbacks, callback) {\n      for (var i=0, l=callbacks.length; i<l; i++) {\n        if (callbacks[i] === callback) { return i; }\n      }\n\n      return -1;\n    }\n\n    function lib$rsvp$events$$callbacksFor(object) {\n      var callbacks = object._promiseCallbacks;\n\n      if (!callbacks) {\n        callbacks = object._promiseCallbacks = {};\n      }\n\n      return callbacks;\n    }\n\n    var lib$rsvp$events$$default = {\n\n      /**\n        `RSVP.EventTarget.mixin` extends an object with EventTarget methods. For\n        Example:\n\n        ```javascript\n        var object = {};\n\n        RSVP.EventTarget.mixin(object);\n\n        object.on('finished', function(event) {\n          // handle event\n        });\n\n        object.trigger('finished', { detail: value });\n        ```\n\n        `EventTarget.mixin` also works with prototypes:\n\n        ```javascript\n        var Person = function() {};\n        RSVP.EventTarget.mixin(Person.prototype);\n\n        var yehuda = new Person();\n        var tom = new Person();\n\n        yehuda.on('poke', function(event) {\n          console.log('Yehuda says OW');\n        });\n\n        tom.on('poke', function(event) {\n          console.log('Tom says OW');\n        });\n\n        yehuda.trigger('poke');\n        tom.trigger('poke');\n        ```\n\n        @method mixin\n        @for RSVP.EventTarget\n        @private\n        @param {Object} object object to extend with EventTarget methods\n      */\n      'mixin': function(object) {\n        object['on']      = this['on'];\n        object['off']     = this['off'];\n        object['trigger'] = this['trigger'];\n        object._promiseCallbacks = undefined;\n        return object;\n      },\n\n      /**\n        Registers a callback to be executed when `eventName` is triggered\n\n        ```javascript\n        object.on('event', function(eventInfo){\n          // handle the event\n        });\n\n        object.trigger('event');\n        ```\n\n        @method on\n        @for RSVP.EventTarget\n        @private\n        @param {String} eventName name of the event to listen for\n        @param {Function} callback function to be called when the event is triggered.\n      */\n      'on': function(eventName, callback) {\n        if (typeof callback !== 'function') {\n          throw new TypeError('Callback must be a function');\n        }\n\n        var allCallbacks = lib$rsvp$events$$callbacksFor(this), callbacks;\n\n        callbacks = allCallbacks[eventName];\n\n        if (!callbacks) {\n          callbacks = allCallbacks[eventName] = [];\n        }\n\n        if (lib$rsvp$events$$indexOf(callbacks, callback) === -1) {\n          callbacks.push(callback);\n        }\n      },\n\n      /**\n        You can use `off` to stop firing a particular callback for an event:\n\n        ```javascript\n        function doStuff() { // do stuff! }\n        object.on('stuff', doStuff);\n\n        object.trigger('stuff'); // doStuff will be called\n\n        // Unregister ONLY the doStuff callback\n        object.off('stuff', doStuff);\n        object.trigger('stuff'); // doStuff will NOT be called\n        ```\n\n        If you don't pass a `callback` argument to `off`, ALL callbacks for the\n        event will not be executed when the event fires. For example:\n\n        ```javascript\n        var callback1 = function(){};\n        var callback2 = function(){};\n\n        object.on('stuff', callback1);\n        object.on('stuff', callback2);\n\n        object.trigger('stuff'); // callback1 and callback2 will be executed.\n\n        object.off('stuff');\n        object.trigger('stuff'); // callback1 and callback2 will not be executed!\n        ```\n\n        @method off\n        @for RSVP.EventTarget\n        @private\n        @param {String} eventName event to stop listening to\n        @param {Function} callback optional argument. If given, only the function\n        given will be removed from the event's callback queue. If no `callback`\n        argument is given, all callbacks will be removed from the event's callback\n        queue.\n      */\n      'off': function(eventName, callback) {\n        var allCallbacks = lib$rsvp$events$$callbacksFor(this), callbacks, index;\n\n        if (!callback) {\n          allCallbacks[eventName] = [];\n          return;\n        }\n\n        callbacks = allCallbacks[eventName];\n\n        index = lib$rsvp$events$$indexOf(callbacks, callback);\n\n        if (index !== -1) { callbacks.splice(index, 1); }\n      },\n\n      /**\n        Use `trigger` to fire custom events. For example:\n\n        ```javascript\n        object.on('foo', function(){\n          console.log('foo event happened!');\n        });\n        object.trigger('foo');\n        // 'foo event happened!' logged to the console\n        ```\n\n        You can also pass a value as a second argument to `trigger` that will be\n        passed as an argument to all event listeners for the event:\n\n        ```javascript\n        object.on('foo', function(value){\n          console.log(value.name);\n        });\n\n        object.trigger('foo', { name: 'bar' });\n        // 'bar' logged to the console\n        ```\n\n        @method trigger\n        @for RSVP.EventTarget\n        @private\n        @param {String} eventName name of the event to be triggered\n        @param {*} options optional value to be passed to any event handlers for\n        the given `eventName`\n      */\n      'trigger': function(eventName, options, label) {\n        var allCallbacks = lib$rsvp$events$$callbacksFor(this), callbacks, callback;\n\n        if (callbacks = allCallbacks[eventName]) {\n          // Don't cache the callbacks.length since it may grow\n          for (var i=0; i<callbacks.length; i++) {\n            callback = callbacks[i];\n\n            callback(options, label);\n          }\n        }\n      }\n    };\n\n    var lib$rsvp$config$$config = {\n      instrument: false\n    };\n\n    lib$rsvp$events$$default['mixin'](lib$rsvp$config$$config);\n\n    function lib$rsvp$config$$configure(name, value) {\n      if (name === 'onerror') {\n        // handle for legacy users that expect the actual\n        // error to be passed to their function added via\n        // `RSVP.configure('onerror', someFunctionHere);`\n        lib$rsvp$config$$config['on']('error', value);\n        return;\n      }\n\n      if (arguments.length === 2) {\n        lib$rsvp$config$$config[name] = value;\n      } else {\n        return lib$rsvp$config$$config[name];\n      }\n    }\n\n    var lib$rsvp$instrument$$queue = [];\n\n    function lib$rsvp$instrument$$scheduleFlush() {\n      setTimeout(function() {\n        var entry;\n        for (var i = 0; i < lib$rsvp$instrument$$queue.length; i++) {\n          entry = lib$rsvp$instrument$$queue[i];\n\n          var payload = entry.payload;\n\n          payload.guid = payload.key + payload.id;\n          payload.childGuid = payload.key + payload.childId;\n          if (payload.error) {\n            payload.stack = payload.error.stack;\n          }\n\n          lib$rsvp$config$$config['trigger'](entry.name, entry.payload);\n        }\n        lib$rsvp$instrument$$queue.length = 0;\n      }, 50);\n    }\n\n    function lib$rsvp$instrument$$instrument(eventName, promise, child) {\n      if (1 === lib$rsvp$instrument$$queue.push({\n        name: eventName,\n        payload: {\n          key: promise._guidKey,\n          id:  promise._id,\n          eventName: eventName,\n          detail: promise._result,\n          childId: child && child._id,\n          label: promise._label,\n          timeStamp: lib$rsvp$utils$$now(),\n          error: lib$rsvp$config$$config[\"instrument-with-stack\"] ? new Error(promise._label) : null\n        }})) {\n          lib$rsvp$instrument$$scheduleFlush();\n        }\n      }\n    var lib$rsvp$instrument$$default = lib$rsvp$instrument$$instrument;\n    function lib$rsvp$then$$then(onFulfillment, onRejection, label) {\n      var parent = this;\n      var state = parent._state;\n\n      if (state === lib$rsvp$$internal$$FULFILLED && !onFulfillment || state === lib$rsvp$$internal$$REJECTED && !onRejection) {\n        lib$rsvp$config$$config.instrument && lib$rsvp$instrument$$default('chained', parent, parent);\n        return parent;\n      }\n\n      parent._onError = null;\n\n      var child = new parent.constructor(lib$rsvp$$internal$$noop, label);\n      var result = parent._result;\n\n      lib$rsvp$config$$config.instrument && lib$rsvp$instrument$$default('chained', parent, child);\n\n      if (state) {\n        var callback = arguments[state - 1];\n        lib$rsvp$config$$config.async(function(){\n          lib$rsvp$$internal$$invokeCallback(state, child, callback, result);\n        });\n      } else {\n        lib$rsvp$$internal$$subscribe(parent, child, onFulfillment, onRejection);\n      }\n\n      return child;\n    }\n    var lib$rsvp$then$$default = lib$rsvp$then$$then;\n    function lib$rsvp$promise$resolve$$resolve(object, label) {\n      /*jshint validthis:true */\n      var Constructor = this;\n\n      if (object && typeof object === 'object' && object.constructor === Constructor) {\n        return object;\n      }\n\n      var promise = new Constructor(lib$rsvp$$internal$$noop, label);\n      lib$rsvp$$internal$$resolve(promise, object);\n      return promise;\n    }\n    var lib$rsvp$promise$resolve$$default = lib$rsvp$promise$resolve$$resolve;\n    function lib$rsvp$enumerator$$makeSettledResult(state, position, value) {\n      if (state === lib$rsvp$$internal$$FULFILLED) {\n        return {\n          state: 'fulfilled',\n          value: value\n        };\n      } else {\n         return {\n          state: 'rejected',\n          reason: value\n        };\n      }\n    }\n\n    function lib$rsvp$enumerator$$Enumerator(Constructor, input, abortOnReject, label) {\n      this._instanceConstructor = Constructor;\n      this.promise = new Constructor(lib$rsvp$$internal$$noop, label);\n      this._abortOnReject = abortOnReject;\n\n      if (this._validateInput(input)) {\n        this._input     = input;\n        this.length     = input.length;\n        this._remaining = input.length;\n\n        this._init();\n\n        if (this.length === 0) {\n          lib$rsvp$$internal$$fulfill(this.promise, this._result);\n        } else {\n          this.length = this.length || 0;\n          this._enumerate();\n          if (this._remaining === 0) {\n            lib$rsvp$$internal$$fulfill(this.promise, this._result);\n          }\n        }\n      } else {\n        lib$rsvp$$internal$$reject(this.promise, this._validationError());\n      }\n    }\n\n    var lib$rsvp$enumerator$$default = lib$rsvp$enumerator$$Enumerator;\n\n    lib$rsvp$enumerator$$Enumerator.prototype._validateInput = function(input) {\n      return lib$rsvp$utils$$isArray(input);\n    };\n\n    lib$rsvp$enumerator$$Enumerator.prototype._validationError = function() {\n      return new Error('Array Methods must be provided an Array');\n    };\n\n    lib$rsvp$enumerator$$Enumerator.prototype._init = function() {\n      this._result = new Array(this.length);\n    };\n\n    lib$rsvp$enumerator$$Enumerator.prototype._enumerate = function() {\n      var length     = this.length;\n      var promise    = this.promise;\n      var input      = this._input;\n\n      for (var i = 0; promise._state === lib$rsvp$$internal$$PENDING && i < length; i++) {\n        this._eachEntry(input[i], i);\n      }\n    };\n\n    lib$rsvp$enumerator$$Enumerator.prototype._settleMaybeThenable = function(entry, i) {\n      var c = this._instanceConstructor;\n      var resolve = c.resolve;\n\n      if (resolve === lib$rsvp$promise$resolve$$default) {\n        var then = lib$rsvp$$internal$$getThen(entry);\n\n        if (then === lib$rsvp$then$$default &&\n            entry._state !== lib$rsvp$$internal$$PENDING) {\n          entry._onError = null;\n          this._settledAt(entry._state, i, entry._result);\n        } else if (typeof then !== 'function') {\n          this._remaining--;\n          this._result[i] = this._makeResult(lib$rsvp$$internal$$FULFILLED, i, entry);\n        } else if (c === lib$rsvp$promise$$default) {\n          var promise = new c(lib$rsvp$$internal$$noop);\n          lib$rsvp$$internal$$handleMaybeThenable(promise, entry, then);\n          this._willSettleAt(promise, i);\n        } else {\n          this._willSettleAt(new c(function(resolve) { resolve(entry); }), i);\n        }\n      } else {\n        this._willSettleAt(resolve(entry), i);\n      }\n    };\n\n    lib$rsvp$enumerator$$Enumerator.prototype._eachEntry = function(entry, i) {\n      if (lib$rsvp$utils$$isMaybeThenable(entry)) {\n        this._settleMaybeThenable(entry, i);\n      } else {\n        this._remaining--;\n        this._result[i] = this._makeResult(lib$rsvp$$internal$$FULFILLED, i, entry);\n      }\n    };\n\n    lib$rsvp$enumerator$$Enumerator.prototype._settledAt = function(state, i, value) {\n      var promise = this.promise;\n\n      if (promise._state === lib$rsvp$$internal$$PENDING) {\n        this._remaining--;\n\n        if (this._abortOnReject && state === lib$rsvp$$internal$$REJECTED) {\n          lib$rsvp$$internal$$reject(promise, value);\n        } else {\n          this._result[i] = this._makeResult(state, i, value);\n        }\n      }\n\n      if (this._remaining === 0) {\n        lib$rsvp$$internal$$fulfill(promise, this._result);\n      }\n    };\n\n    lib$rsvp$enumerator$$Enumerator.prototype._makeResult = function(state, i, value) {\n      return value;\n    };\n\n    lib$rsvp$enumerator$$Enumerator.prototype._willSettleAt = function(promise, i) {\n      var enumerator = this;\n\n      lib$rsvp$$internal$$subscribe(promise, undefined, function(value) {\n        enumerator._settledAt(lib$rsvp$$internal$$FULFILLED, i, value);\n      }, function(reason) {\n        enumerator._settledAt(lib$rsvp$$internal$$REJECTED, i, reason);\n      });\n    };\n    function lib$rsvp$promise$all$$all(entries, label) {\n      return new lib$rsvp$enumerator$$default(this, entries, true /* abort on reject */, label).promise;\n    }\n    var lib$rsvp$promise$all$$default = lib$rsvp$promise$all$$all;\n    function lib$rsvp$promise$race$$race(entries, label) {\n      /*jshint validthis:true */\n      var Constructor = this;\n\n      var promise = new Constructor(lib$rsvp$$internal$$noop, label);\n\n      if (!lib$rsvp$utils$$isArray(entries)) {\n        lib$rsvp$$internal$$reject(promise, new TypeError('You must pass an array to race.'));\n        return promise;\n      }\n\n      var length = entries.length;\n\n      function onFulfillment(value) {\n        lib$rsvp$$internal$$resolve(promise, value);\n      }\n\n      function onRejection(reason) {\n        lib$rsvp$$internal$$reject(promise, reason);\n      }\n\n      for (var i = 0; promise._state === lib$rsvp$$internal$$PENDING && i < length; i++) {\n        lib$rsvp$$internal$$subscribe(Constructor.resolve(entries[i]), undefined, onFulfillment, onRejection);\n      }\n\n      return promise;\n    }\n    var lib$rsvp$promise$race$$default = lib$rsvp$promise$race$$race;\n    function lib$rsvp$promise$reject$$reject(reason, label) {\n      /*jshint validthis:true */\n      var Constructor = this;\n      var promise = new Constructor(lib$rsvp$$internal$$noop, label);\n      lib$rsvp$$internal$$reject(promise, reason);\n      return promise;\n    }\n    var lib$rsvp$promise$reject$$default = lib$rsvp$promise$reject$$reject;\n\n    var lib$rsvp$promise$$guidKey = 'rsvp_' + lib$rsvp$utils$$now() + '-';\n    var lib$rsvp$promise$$counter = 0;\n\n    function lib$rsvp$promise$$needsResolver() {\n      throw new TypeError('You must pass a resolver function as the first argument to the promise constructor');\n    }\n\n    function lib$rsvp$promise$$needsNew() {\n      throw new TypeError(\"Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.\");\n    }\n\n    function lib$rsvp$promise$$Promise(resolver, label) {\n      this._id = lib$rsvp$promise$$counter++;\n      this._label = label;\n      this._state = undefined;\n      this._result = undefined;\n      this._subscribers = [];\n\n      lib$rsvp$config$$config.instrument && lib$rsvp$instrument$$default('created', this);\n\n      if (lib$rsvp$$internal$$noop !== resolver) {\n        typeof resolver !== 'function' && lib$rsvp$promise$$needsResolver();\n        this instanceof lib$rsvp$promise$$Promise ? lib$rsvp$$internal$$initializePromise(this, resolver) : lib$rsvp$promise$$needsNew();\n      }\n    }\n\n    var lib$rsvp$promise$$default = lib$rsvp$promise$$Promise;\n\n    // deprecated\n    lib$rsvp$promise$$Promise.cast = lib$rsvp$promise$resolve$$default;\n    lib$rsvp$promise$$Promise.all = lib$rsvp$promise$all$$default;\n    lib$rsvp$promise$$Promise.race = lib$rsvp$promise$race$$default;\n    lib$rsvp$promise$$Promise.resolve = lib$rsvp$promise$resolve$$default;\n    lib$rsvp$promise$$Promise.reject = lib$rsvp$promise$reject$$default;\n\n    lib$rsvp$promise$$Promise.prototype = {\n      constructor: lib$rsvp$promise$$Promise,\n\n      _guidKey: lib$rsvp$promise$$guidKey,\n\n      _onError: function (reason) {\n        var promise = this;\n        lib$rsvp$config$$config.after(function() {\n          if (promise._onError) {\n            lib$rsvp$config$$config['trigger']('error', reason, promise._label);\n          }\n        });\n      },\n\n    /**\n      The primary way of interacting with a promise is through its `then` method,\n      which registers callbacks to receive either a promise's eventual value or the\n      reason why the promise cannot be fulfilled.\n\n      ```js\n      findUser().then(function(user){\n        // user is available\n      }, function(reason){\n        // user is unavailable, and you are given the reason why\n      });\n      ```\n\n      Chaining\n      --------\n\n      The return value of `then` is itself a promise.  This second, 'downstream'\n      promise is resolved with the return value of the first promise's fulfillment\n      or rejection handler, or rejected if the handler throws an exception.\n\n      ```js\n      findUser().then(function (user) {\n        return user.name;\n      }, function (reason) {\n        return 'default name';\n      }).then(function (userName) {\n        // If `findUser` fulfilled, `userName` will be the user's name, otherwise it\n        // will be `'default name'`\n      });\n\n      findUser().then(function (user) {\n        throw new Error('Found user, but still unhappy');\n      }, function (reason) {\n        throw new Error('`findUser` rejected and we're unhappy');\n      }).then(function (value) {\n        // never reached\n      }, function (reason) {\n        // if `findUser` fulfilled, `reason` will be 'Found user, but still unhappy'.\n        // If `findUser` rejected, `reason` will be '`findUser` rejected and we're unhappy'.\n      });\n      ```\n      If the downstream promise does not specify a rejection handler, rejection reasons will be propagated further downstream.\n\n      ```js\n      findUser().then(function (user) {\n        throw new PedagogicalException('Upstream error');\n      }).then(function (value) {\n        // never reached\n      }).then(function (value) {\n        // never reached\n      }, function (reason) {\n        // The `PedgagocialException` is propagated all the way down to here\n      });\n      ```\n\n      Assimilation\n      ------------\n\n      Sometimes the value you want to propagate to a downstream promise can only be\n      retrieved asynchronously. This can be achieved by returning a promise in the\n      fulfillment or rejection handler. The downstream promise will then be pending\n      until the returned promise is settled. This is called *assimilation*.\n\n      ```js\n      findUser().then(function (user) {\n        return findCommentsByAuthor(user);\n      }).then(function (comments) {\n        // The user's comments are now available\n      });\n      ```\n\n      If the assimliated promise rejects, then the downstream promise will also reject.\n\n      ```js\n      findUser().then(function (user) {\n        return findCommentsByAuthor(user);\n      }).then(function (comments) {\n        // If `findCommentsByAuthor` fulfills, we'll have the value here\n      }, function (reason) {\n        // If `findCommentsByAuthor` rejects, we'll have the reason here\n      });\n      ```\n\n      Simple Example\n      --------------\n\n      Synchronous Example\n\n      ```javascript\n      var result;\n\n      try {\n        result = findResult();\n        // success\n      } catch(reason) {\n        // failure\n      }\n      ```\n\n      Errback Example\n\n      ```js\n      findResult(function(result, err){\n        if (err) {\n          // failure\n        } else {\n          // success\n        }\n      });\n      ```\n\n      Promise Example;\n\n      ```javascript\n      findResult().then(function(result){\n        // success\n      }, function(reason){\n        // failure\n      });\n      ```\n\n      Advanced Example\n      --------------\n\n      Synchronous Example\n\n      ```javascript\n      var author, books;\n\n      try {\n        author = findAuthor();\n        books  = findBooksByAuthor(author);\n        // success\n      } catch(reason) {\n        // failure\n      }\n      ```\n\n      Errback Example\n\n      ```js\n\n      function foundBooks(books) {\n\n      }\n\n      function failure(reason) {\n\n      }\n\n      findAuthor(function(author, err){\n        if (err) {\n          failure(err);\n          // failure\n        } else {\n          try {\n            findBoooksByAuthor(author, function(books, err) {\n              if (err) {\n                failure(err);\n              } else {\n                try {\n                  foundBooks(books);\n                } catch(reason) {\n                  failure(reason);\n                }\n              }\n            });\n          } catch(error) {\n            failure(err);\n          }\n          // success\n        }\n      });\n      ```\n\n      Promise Example;\n\n      ```javascript\n      findAuthor().\n        then(findBooksByAuthor).\n        then(function(books){\n          // found books\n      }).catch(function(reason){\n        // something went wrong\n      });\n      ```\n\n      @method then\n      @param {Function} onFulfillment\n      @param {Function} onRejection\n      @param {String} label optional string for labeling the promise.\n      Useful for tooling.\n      @return {Promise}\n    */\n      then: lib$rsvp$then$$default,\n\n    /**\n      `catch` is simply sugar for `then(undefined, onRejection)` which makes it the same\n      as the catch block of a try/catch statement.\n\n      ```js\n      function findAuthor(){\n        throw new Error('couldn't find that author');\n      }\n\n      // synchronous\n      try {\n        findAuthor();\n      } catch(reason) {\n        // something went wrong\n      }\n\n      // async with promises\n      findAuthor().catch(function(reason){\n        // something went wrong\n      });\n      ```\n\n      @method catch\n      @param {Function} onRejection\n      @param {String} label optional string for labeling the promise.\n      Useful for tooling.\n      @return {Promise}\n    */\n      'catch': function(onRejection, label) {\n        return this.then(undefined, onRejection, label);\n      },\n\n    /**\n      `finally` will be invoked regardless of the promise's fate just as native\n      try/catch/finally behaves\n\n      Synchronous example:\n\n      ```js\n      findAuthor() {\n        if (Math.random() > 0.5) {\n          throw new Error();\n        }\n        return new Author();\n      }\n\n      try {\n        return findAuthor(); // succeed or fail\n      } catch(error) {\n        return findOtherAuther();\n      } finally {\n        // always runs\n        // doesn't affect the return value\n      }\n      ```\n\n      Asynchronous example:\n\n      ```js\n      findAuthor().catch(function(reason){\n        return findOtherAuther();\n      }).finally(function(){\n        // author was either found, or not\n      });\n      ```\n\n      @method finally\n      @param {Function} callback\n      @param {String} label optional string for labeling the promise.\n      Useful for tooling.\n      @return {Promise}\n    */\n      'finally': function(callback, label) {\n        var promise = this;\n        var constructor = promise.constructor;\n\n        return promise.then(function(value) {\n          return constructor.resolve(callback()).then(function() {\n            return value;\n          });\n        }, function(reason) {\n          return constructor.resolve(callback()).then(function() {\n            return constructor.reject(reason);\n          });\n        }, label);\n      }\n    };\n    function  lib$rsvp$$internal$$withOwnPromise() {\n      return new TypeError('A promises callback cannot return that same promise.');\n    }\n\n    function lib$rsvp$$internal$$noop() {}\n\n    var lib$rsvp$$internal$$PENDING   = void 0;\n    var lib$rsvp$$internal$$FULFILLED = 1;\n    var lib$rsvp$$internal$$REJECTED  = 2;\n\n    var lib$rsvp$$internal$$GET_THEN_ERROR = new lib$rsvp$$internal$$ErrorObject();\n\n    function lib$rsvp$$internal$$getThen(promise) {\n      try {\n        return promise.then;\n      } catch(error) {\n        lib$rsvp$$internal$$GET_THEN_ERROR.error = error;\n        return lib$rsvp$$internal$$GET_THEN_ERROR;\n      }\n    }\n\n    function lib$rsvp$$internal$$tryThen(then, value, fulfillmentHandler, rejectionHandler) {\n      try {\n        then.call(value, fulfillmentHandler, rejectionHandler);\n      } catch(e) {\n        return e;\n      }\n    }\n\n    function lib$rsvp$$internal$$handleForeignThenable(promise, thenable, then) {\n      lib$rsvp$config$$config.async(function(promise) {\n        var sealed = false;\n        var error = lib$rsvp$$internal$$tryThen(then, thenable, function(value) {\n          if (sealed) { return; }\n          sealed = true;\n          if (thenable !== value) {\n            lib$rsvp$$internal$$resolve(promise, value, undefined);\n          } else {\n            lib$rsvp$$internal$$fulfill(promise, value);\n          }\n        }, function(reason) {\n          if (sealed) { return; }\n          sealed = true;\n\n          lib$rsvp$$internal$$reject(promise, reason);\n        }, 'Settle: ' + (promise._label || ' unknown promise'));\n\n        if (!sealed && error) {\n          sealed = true;\n          lib$rsvp$$internal$$reject(promise, error);\n        }\n      }, promise);\n    }\n\n    function lib$rsvp$$internal$$handleOwnThenable(promise, thenable) {\n      if (thenable._state === lib$rsvp$$internal$$FULFILLED) {\n        lib$rsvp$$internal$$fulfill(promise, thenable._result);\n      } else if (thenable._state === lib$rsvp$$internal$$REJECTED) {\n        thenable._onError = null;\n        lib$rsvp$$internal$$reject(promise, thenable._result);\n      } else {\n        lib$rsvp$$internal$$subscribe(thenable, undefined, function(value) {\n          if (thenable !== value) {\n            lib$rsvp$$internal$$resolve(promise, value, undefined);\n          } else {\n            lib$rsvp$$internal$$fulfill(promise, value);\n          }\n        }, function(reason) {\n          lib$rsvp$$internal$$reject(promise, reason);\n        });\n      }\n    }\n\n    function lib$rsvp$$internal$$handleMaybeThenable(promise, maybeThenable, then) {\n      if (maybeThenable.constructor === promise.constructor &&\n          then === lib$rsvp$then$$default &&\n          constructor.resolve === lib$rsvp$promise$resolve$$default) {\n        lib$rsvp$$internal$$handleOwnThenable(promise, maybeThenable);\n      } else {\n        if (then === lib$rsvp$$internal$$GET_THEN_ERROR) {\n          lib$rsvp$$internal$$reject(promise, lib$rsvp$$internal$$GET_THEN_ERROR.error);\n        } else if (then === undefined) {\n          lib$rsvp$$internal$$fulfill(promise, maybeThenable);\n        } else if (lib$rsvp$utils$$isFunction(then)) {\n          lib$rsvp$$internal$$handleForeignThenable(promise, maybeThenable, then);\n        } else {\n          lib$rsvp$$internal$$fulfill(promise, maybeThenable);\n        }\n      }\n    }\n\n    function lib$rsvp$$internal$$resolve(promise, value) {\n      if (promise === value) {\n        lib$rsvp$$internal$$fulfill(promise, value);\n      } else if (lib$rsvp$utils$$objectOrFunction(value)) {\n        lib$rsvp$$internal$$handleMaybeThenable(promise, value, lib$rsvp$$internal$$getThen(value));\n      } else {\n        lib$rsvp$$internal$$fulfill(promise, value);\n      }\n    }\n\n    function lib$rsvp$$internal$$publishRejection(promise) {\n      if (promise._onError) {\n        promise._onError(promise._result);\n      }\n\n      lib$rsvp$$internal$$publish(promise);\n    }\n\n    function lib$rsvp$$internal$$fulfill(promise, value) {\n      if (promise._state !== lib$rsvp$$internal$$PENDING) { return; }\n\n      promise._result = value;\n      promise._state = lib$rsvp$$internal$$FULFILLED;\n\n      if (promise._subscribers.length === 0) {\n        if (lib$rsvp$config$$config.instrument) {\n          lib$rsvp$instrument$$default('fulfilled', promise);\n        }\n      } else {\n        lib$rsvp$config$$config.async(lib$rsvp$$internal$$publish, promise);\n      }\n    }\n\n    function lib$rsvp$$internal$$reject(promise, reason) {\n      if (promise._state !== lib$rsvp$$internal$$PENDING) { return; }\n      promise._state = lib$rsvp$$internal$$REJECTED;\n      promise._result = reason;\n      lib$rsvp$config$$config.async(lib$rsvp$$internal$$publishRejection, promise);\n    }\n\n    function lib$rsvp$$internal$$subscribe(parent, child, onFulfillment, onRejection) {\n      var subscribers = parent._subscribers;\n      var length = subscribers.length;\n\n      parent._onError = null;\n\n      subscribers[length] = child;\n      subscribers[length + lib$rsvp$$internal$$FULFILLED] = onFulfillment;\n      subscribers[length + lib$rsvp$$internal$$REJECTED]  = onRejection;\n\n      if (length === 0 && parent._state) {\n        lib$rsvp$config$$config.async(lib$rsvp$$internal$$publish, parent);\n      }\n    }\n\n    function lib$rsvp$$internal$$publish(promise) {\n      var subscribers = promise._subscribers;\n      var settled = promise._state;\n\n      if (lib$rsvp$config$$config.instrument) {\n        lib$rsvp$instrument$$default(settled === lib$rsvp$$internal$$FULFILLED ? 'fulfilled' : 'rejected', promise);\n      }\n\n      if (subscribers.length === 0) { return; }\n\n      var child, callback, detail = promise._result;\n\n      for (var i = 0; i < subscribers.length; i += 3) {\n        child = subscribers[i];\n        callback = subscribers[i + settled];\n\n        if (child) {\n          lib$rsvp$$internal$$invokeCallback(settled, child, callback, detail);\n        } else {\n          callback(detail);\n        }\n      }\n\n      promise._subscribers.length = 0;\n    }\n\n    function lib$rsvp$$internal$$ErrorObject() {\n      this.error = null;\n    }\n\n    var lib$rsvp$$internal$$TRY_CATCH_ERROR = new lib$rsvp$$internal$$ErrorObject();\n\n    function lib$rsvp$$internal$$tryCatch(callback, detail) {\n      try {\n        return callback(detail);\n      } catch(e) {\n        lib$rsvp$$internal$$TRY_CATCH_ERROR.error = e;\n        return lib$rsvp$$internal$$TRY_CATCH_ERROR;\n      }\n    }\n\n    function lib$rsvp$$internal$$invokeCallback(settled, promise, callback, detail) {\n      var hasCallback = lib$rsvp$utils$$isFunction(callback),\n          value, error, succeeded, failed;\n\n      if (hasCallback) {\n        value = lib$rsvp$$internal$$tryCatch(callback, detail);\n\n        if (value === lib$rsvp$$internal$$TRY_CATCH_ERROR) {\n          failed = true;\n          error = value.error;\n          value = null;\n        } else {\n          succeeded = true;\n        }\n\n        if (promise === value) {\n          lib$rsvp$$internal$$reject(promise, lib$rsvp$$internal$$withOwnPromise());\n          return;\n        }\n\n      } else {\n        value = detail;\n        succeeded = true;\n      }\n\n      if (promise._state !== lib$rsvp$$internal$$PENDING) {\n        // noop\n      } else if (hasCallback && succeeded) {\n        lib$rsvp$$internal$$resolve(promise, value);\n      } else if (failed) {\n        lib$rsvp$$internal$$reject(promise, error);\n      } else if (settled === lib$rsvp$$internal$$FULFILLED) {\n        lib$rsvp$$internal$$fulfill(promise, value);\n      } else if (settled === lib$rsvp$$internal$$REJECTED) {\n        lib$rsvp$$internal$$reject(promise, value);\n      }\n    }\n\n    function lib$rsvp$$internal$$initializePromise(promise, resolver) {\n      var resolved = false;\n      try {\n        resolver(function resolvePromise(value){\n          if (resolved) { return; }\n          resolved = true;\n          lib$rsvp$$internal$$resolve(promise, value);\n        }, function rejectPromise(reason) {\n          if (resolved) { return; }\n          resolved = true;\n          lib$rsvp$$internal$$reject(promise, reason);\n        });\n      } catch(e) {\n        lib$rsvp$$internal$$reject(promise, e);\n      }\n    }\n\n    function lib$rsvp$all$settled$$AllSettled(Constructor, entries, label) {\n      this._superConstructor(Constructor, entries, false /* don't abort on reject */, label);\n    }\n\n    lib$rsvp$all$settled$$AllSettled.prototype = lib$rsvp$utils$$o_create(lib$rsvp$enumerator$$default.prototype);\n    lib$rsvp$all$settled$$AllSettled.prototype._superConstructor = lib$rsvp$enumerator$$default;\n    lib$rsvp$all$settled$$AllSettled.prototype._makeResult = lib$rsvp$enumerator$$makeSettledResult;\n    lib$rsvp$all$settled$$AllSettled.prototype._validationError = function() {\n      return new Error('allSettled must be called with an array');\n    };\n\n    function lib$rsvp$all$settled$$allSettled(entries, label) {\n      return new lib$rsvp$all$settled$$AllSettled(lib$rsvp$promise$$default, entries, label).promise;\n    }\n    var lib$rsvp$all$settled$$default = lib$rsvp$all$settled$$allSettled;\n    function lib$rsvp$all$$all(array, label) {\n      return lib$rsvp$promise$$default.all(array, label);\n    }\n    var lib$rsvp$all$$default = lib$rsvp$all$$all;\n    var lib$rsvp$asap$$len = 0;\n    var lib$rsvp$asap$$toString = {}.toString;\n    var lib$rsvp$asap$$vertxNext;\n    function lib$rsvp$asap$$asap(callback, arg) {\n      lib$rsvp$asap$$queue[lib$rsvp$asap$$len] = callback;\n      lib$rsvp$asap$$queue[lib$rsvp$asap$$len + 1] = arg;\n      lib$rsvp$asap$$len += 2;\n      if (lib$rsvp$asap$$len === 2) {\n        // If len is 1, that means that we need to schedule an async flush.\n        // If additional callbacks are queued before the queue is flushed, they\n        // will be processed by this flush that we are scheduling.\n        lib$rsvp$asap$$scheduleFlush();\n      }\n    }\n\n    var lib$rsvp$asap$$default = lib$rsvp$asap$$asap;\n\n    var lib$rsvp$asap$$browserWindow = (typeof window !== 'undefined') ? window : undefined;\n    var lib$rsvp$asap$$browserGlobal = lib$rsvp$asap$$browserWindow || {};\n    var lib$rsvp$asap$$BrowserMutationObserver = lib$rsvp$asap$$browserGlobal.MutationObserver || lib$rsvp$asap$$browserGlobal.WebKitMutationObserver;\n    var lib$rsvp$asap$$isNode = typeof self === 'undefined' &&\n      typeof process !== 'undefined' && {}.toString.call(process) === '[object process]';\n\n    // test for web worker but not in IE10\n    var lib$rsvp$asap$$isWorker = typeof Uint8ClampedArray !== 'undefined' &&\n      typeof importScripts !== 'undefined' &&\n      typeof MessageChannel !== 'undefined';\n\n    // node\n    function lib$rsvp$asap$$useNextTick() {\n      var nextTick = process.nextTick;\n      // node version 0.10.x displays a deprecation warning when nextTick is used recursively\n      // setImmediate should be used instead instead\n      var version = process.versions.node.match(/^(?:(\\d+)\\.)?(?:(\\d+)\\.)?(\\*|\\d+)$/);\n      if (Array.isArray(version) && version[1] === '0' && version[2] === '10') {\n        nextTick = setImmediate;\n      }\n      return function() {\n        nextTick(lib$rsvp$asap$$flush);\n      };\n    }\n\n    // vertx\n    function lib$rsvp$asap$$useVertxTimer() {\n      return function() {\n        lib$rsvp$asap$$vertxNext(lib$rsvp$asap$$flush);\n      };\n    }\n\n    function lib$rsvp$asap$$useMutationObserver() {\n      var iterations = 0;\n      var observer = new lib$rsvp$asap$$BrowserMutationObserver(lib$rsvp$asap$$flush);\n      var node = document.createTextNode('');\n      observer.observe(node, { characterData: true });\n\n      return function() {\n        node.data = (iterations = ++iterations % 2);\n      };\n    }\n\n    // web worker\n    function lib$rsvp$asap$$useMessageChannel() {\n      var channel = new MessageChannel();\n      channel.port1.onmessage = lib$rsvp$asap$$flush;\n      return function () {\n        channel.port2.postMessage(0);\n      };\n    }\n\n    function lib$rsvp$asap$$useSetTimeout() {\n      return function() {\n        setTimeout(lib$rsvp$asap$$flush, 1);\n      };\n    }\n\n    var lib$rsvp$asap$$queue = new Array(1000);\n    function lib$rsvp$asap$$flush() {\n      for (var i = 0; i < lib$rsvp$asap$$len; i+=2) {\n        var callback = lib$rsvp$asap$$queue[i];\n        var arg = lib$rsvp$asap$$queue[i+1];\n\n        callback(arg);\n\n        lib$rsvp$asap$$queue[i] = undefined;\n        lib$rsvp$asap$$queue[i+1] = undefined;\n      }\n\n      lib$rsvp$asap$$len = 0;\n    }\n\n    function lib$rsvp$asap$$attemptVertex() {\n      try {\n        var r = require;\n        var vertx = r('vertx');\n        lib$rsvp$asap$$vertxNext = vertx.runOnLoop || vertx.runOnContext;\n        return lib$rsvp$asap$$useVertxTimer();\n      } catch(e) {\n        return lib$rsvp$asap$$useSetTimeout();\n      }\n    }\n\n    var lib$rsvp$asap$$scheduleFlush;\n    // Decide what async method to use to triggering processing of queued callbacks:\n    if (lib$rsvp$asap$$isNode) {\n      lib$rsvp$asap$$scheduleFlush = lib$rsvp$asap$$useNextTick();\n    } else if (lib$rsvp$asap$$BrowserMutationObserver) {\n      lib$rsvp$asap$$scheduleFlush = lib$rsvp$asap$$useMutationObserver();\n    } else if (lib$rsvp$asap$$isWorker) {\n      lib$rsvp$asap$$scheduleFlush = lib$rsvp$asap$$useMessageChannel();\n    } else if (lib$rsvp$asap$$browserWindow === undefined && typeof require === 'function') {\n      lib$rsvp$asap$$scheduleFlush = lib$rsvp$asap$$attemptVertex();\n    } else {\n      lib$rsvp$asap$$scheduleFlush = lib$rsvp$asap$$useSetTimeout();\n    }\n    function lib$rsvp$defer$$defer(label) {\n      var deferred = {};\n\n      deferred['promise'] = new lib$rsvp$promise$$default(function(resolve, reject) {\n        deferred['resolve'] = resolve;\n        deferred['reject'] = reject;\n      }, label);\n\n      return deferred;\n    }\n    var lib$rsvp$defer$$default = lib$rsvp$defer$$defer;\n    function lib$rsvp$filter$$filter(promises, filterFn, label) {\n      return lib$rsvp$promise$$default.all(promises, label).then(function(values) {\n        if (!lib$rsvp$utils$$isFunction(filterFn)) {\n          throw new TypeError(\"You must pass a function as filter's second argument.\");\n        }\n\n        var length = values.length;\n        var filtered = new Array(length);\n\n        for (var i = 0; i < length; i++) {\n          filtered[i] = filterFn(values[i]);\n        }\n\n        return lib$rsvp$promise$$default.all(filtered, label).then(function(filtered) {\n          var results = new Array(length);\n          var newLength = 0;\n\n          for (var i = 0; i < length; i++) {\n            if (filtered[i]) {\n              results[newLength] = values[i];\n              newLength++;\n            }\n          }\n\n          results.length = newLength;\n\n          return results;\n        });\n      });\n    }\n    var lib$rsvp$filter$$default = lib$rsvp$filter$$filter;\n\n    function lib$rsvp$promise$hash$$PromiseHash(Constructor, object, label) {\n      this._superConstructor(Constructor, object, true, label);\n    }\n\n    var lib$rsvp$promise$hash$$default = lib$rsvp$promise$hash$$PromiseHash;\n\n    lib$rsvp$promise$hash$$PromiseHash.prototype = lib$rsvp$utils$$o_create(lib$rsvp$enumerator$$default.prototype);\n    lib$rsvp$promise$hash$$PromiseHash.prototype._superConstructor = lib$rsvp$enumerator$$default;\n    lib$rsvp$promise$hash$$PromiseHash.prototype._init = function() {\n      this._result = {};\n    };\n\n    lib$rsvp$promise$hash$$PromiseHash.prototype._validateInput = function(input) {\n      return input && typeof input === 'object';\n    };\n\n    lib$rsvp$promise$hash$$PromiseHash.prototype._validationError = function() {\n      return new Error('Promise.hash must be called with an object');\n    };\n\n    lib$rsvp$promise$hash$$PromiseHash.prototype._enumerate = function() {\n      var enumerator = this;\n      var promise    = enumerator.promise;\n      var input      = enumerator._input;\n      var results    = [];\n\n      for (var key in input) {\n        if (promise._state === lib$rsvp$$internal$$PENDING && Object.prototype.hasOwnProperty.call(input, key)) {\n          results.push({\n            position: key,\n            entry: input[key]\n          });\n        }\n      }\n\n      var length = results.length;\n      enumerator._remaining = length;\n      var result;\n\n      for (var i = 0; promise._state === lib$rsvp$$internal$$PENDING && i < length; i++) {\n        result = results[i];\n        enumerator._eachEntry(result.entry, result.position);\n      }\n    };\n\n    function lib$rsvp$hash$settled$$HashSettled(Constructor, object, label) {\n      this._superConstructor(Constructor, object, false, label);\n    }\n\n    lib$rsvp$hash$settled$$HashSettled.prototype = lib$rsvp$utils$$o_create(lib$rsvp$promise$hash$$default.prototype);\n    lib$rsvp$hash$settled$$HashSettled.prototype._superConstructor = lib$rsvp$enumerator$$default;\n    lib$rsvp$hash$settled$$HashSettled.prototype._makeResult = lib$rsvp$enumerator$$makeSettledResult;\n\n    lib$rsvp$hash$settled$$HashSettled.prototype._validationError = function() {\n      return new Error('hashSettled must be called with an object');\n    };\n\n    function lib$rsvp$hash$settled$$hashSettled(object, label) {\n      return new lib$rsvp$hash$settled$$HashSettled(lib$rsvp$promise$$default, object, label).promise;\n    }\n    var lib$rsvp$hash$settled$$default = lib$rsvp$hash$settled$$hashSettled;\n    function lib$rsvp$hash$$hash(object, label) {\n      return new lib$rsvp$promise$hash$$default(lib$rsvp$promise$$default, object, label).promise;\n    }\n    var lib$rsvp$hash$$default = lib$rsvp$hash$$hash;\n    function lib$rsvp$map$$map(promises, mapFn, label) {\n      return lib$rsvp$promise$$default.all(promises, label).then(function(values) {\n        if (!lib$rsvp$utils$$isFunction(mapFn)) {\n          throw new TypeError(\"You must pass a function as map's second argument.\");\n        }\n\n        var length = values.length;\n        var results = new Array(length);\n\n        for (var i = 0; i < length; i++) {\n          results[i] = mapFn(values[i]);\n        }\n\n        return lib$rsvp$promise$$default.all(results, label);\n      });\n    }\n    var lib$rsvp$map$$default = lib$rsvp$map$$map;\n\n    function lib$rsvp$node$$Result() {\n      this.value = undefined;\n    }\n\n    var lib$rsvp$node$$ERROR = new lib$rsvp$node$$Result();\n    var lib$rsvp$node$$GET_THEN_ERROR = new lib$rsvp$node$$Result();\n\n    function lib$rsvp$node$$getThen(obj) {\n      try {\n       return obj.then;\n      } catch(error) {\n        lib$rsvp$node$$ERROR.value= error;\n        return lib$rsvp$node$$ERROR;\n      }\n    }\n\n\n    function lib$rsvp$node$$tryApply(f, s, a) {\n      try {\n        f.apply(s, a);\n      } catch(error) {\n        lib$rsvp$node$$ERROR.value = error;\n        return lib$rsvp$node$$ERROR;\n      }\n    }\n\n    function lib$rsvp$node$$makeObject(_, argumentNames) {\n      var obj = {};\n      var name;\n      var i;\n      var length = _.length;\n      var args = new Array(length);\n\n      for (var x = 0; x < length; x++) {\n        args[x] = _[x];\n      }\n\n      for (i = 0; i < argumentNames.length; i++) {\n        name = argumentNames[i];\n        obj[name] = args[i + 1];\n      }\n\n      return obj;\n    }\n\n    function lib$rsvp$node$$arrayResult(_) {\n      var length = _.length;\n      var args = new Array(length - 1);\n\n      for (var i = 1; i < length; i++) {\n        args[i - 1] = _[i];\n      }\n\n      return args;\n    }\n\n    function lib$rsvp$node$$wrapThenable(then, promise) {\n      return {\n        then: function(onFulFillment, onRejection) {\n          return then.call(promise, onFulFillment, onRejection);\n        }\n      };\n    }\n\n    function lib$rsvp$node$$denodeify(nodeFunc, options) {\n      var fn = function() {\n        var self = this;\n        var l = arguments.length;\n        var args = new Array(l + 1);\n        var arg;\n        var promiseInput = false;\n\n        for (var i = 0; i < l; ++i) {\n          arg = arguments[i];\n\n          if (!promiseInput) {\n            // TODO: clean this up\n            promiseInput = lib$rsvp$node$$needsPromiseInput(arg);\n            if (promiseInput === lib$rsvp$node$$GET_THEN_ERROR) {\n              var p = new lib$rsvp$promise$$default(lib$rsvp$$internal$$noop);\n              lib$rsvp$$internal$$reject(p, lib$rsvp$node$$GET_THEN_ERROR.value);\n              return p;\n            } else if (promiseInput && promiseInput !== true) {\n              arg = lib$rsvp$node$$wrapThenable(promiseInput, arg);\n            }\n          }\n          args[i] = arg;\n        }\n\n        var promise = new lib$rsvp$promise$$default(lib$rsvp$$internal$$noop);\n\n        args[l] = function(err, val) {\n          if (err)\n            lib$rsvp$$internal$$reject(promise, err);\n          else if (options === undefined)\n            lib$rsvp$$internal$$resolve(promise, val);\n          else if (options === true)\n            lib$rsvp$$internal$$resolve(promise, lib$rsvp$node$$arrayResult(arguments));\n          else if (lib$rsvp$utils$$isArray(options))\n            lib$rsvp$$internal$$resolve(promise, lib$rsvp$node$$makeObject(arguments, options));\n          else\n            lib$rsvp$$internal$$resolve(promise, val);\n        };\n\n        if (promiseInput) {\n          return lib$rsvp$node$$handlePromiseInput(promise, args, nodeFunc, self);\n        } else {\n          return lib$rsvp$node$$handleValueInput(promise, args, nodeFunc, self);\n        }\n      };\n\n      fn.__proto__ = nodeFunc;\n\n      return fn;\n    }\n\n    var lib$rsvp$node$$default = lib$rsvp$node$$denodeify;\n\n    function lib$rsvp$node$$handleValueInput(promise, args, nodeFunc, self) {\n      var result = lib$rsvp$node$$tryApply(nodeFunc, self, args);\n      if (result === lib$rsvp$node$$ERROR) {\n        lib$rsvp$$internal$$reject(promise, result.value);\n      }\n      return promise;\n    }\n\n    function lib$rsvp$node$$handlePromiseInput(promise, args, nodeFunc, self){\n      return lib$rsvp$promise$$default.all(args).then(function(args){\n        var result = lib$rsvp$node$$tryApply(nodeFunc, self, args);\n        if (result === lib$rsvp$node$$ERROR) {\n          lib$rsvp$$internal$$reject(promise, result.value);\n        }\n        return promise;\n      });\n    }\n\n    function lib$rsvp$node$$needsPromiseInput(arg) {\n      if (arg && typeof arg === 'object') {\n        if (arg.constructor === lib$rsvp$promise$$default) {\n          return true;\n        } else {\n          return lib$rsvp$node$$getThen(arg);\n        }\n      } else {\n        return false;\n      }\n    }\n    var lib$rsvp$platform$$platform;\n\n    /* global self */\n    if (typeof self === 'object') {\n      lib$rsvp$platform$$platform = self;\n\n    /* global global */\n    } else if (typeof global === 'object') {\n      lib$rsvp$platform$$platform = global;\n    } else {\n      throw new Error('no global: `self` or `global` found');\n    }\n\n    var lib$rsvp$platform$$default = lib$rsvp$platform$$platform;\n    function lib$rsvp$race$$race(array, label) {\n      return lib$rsvp$promise$$default.race(array, label);\n    }\n    var lib$rsvp$race$$default = lib$rsvp$race$$race;\n    function lib$rsvp$reject$$reject(reason, label) {\n      return lib$rsvp$promise$$default.reject(reason, label);\n    }\n    var lib$rsvp$reject$$default = lib$rsvp$reject$$reject;\n    function lib$rsvp$resolve$$resolve(value, label) {\n      return lib$rsvp$promise$$default.resolve(value, label);\n    }\n    var lib$rsvp$resolve$$default = lib$rsvp$resolve$$resolve;\n    function lib$rsvp$rethrow$$rethrow(reason) {\n      setTimeout(function() {\n        throw reason;\n      });\n      throw reason;\n    }\n    var lib$rsvp$rethrow$$default = lib$rsvp$rethrow$$rethrow;\n\n    // defaults\n    lib$rsvp$config$$config.async = lib$rsvp$asap$$default;\n    lib$rsvp$config$$config.after = function(cb) {\n      setTimeout(cb, 0);\n    };\n    var lib$rsvp$$cast = lib$rsvp$resolve$$default;\n    function lib$rsvp$$async(callback, arg) {\n      lib$rsvp$config$$config.async(callback, arg);\n    }\n\n    function lib$rsvp$$on() {\n      lib$rsvp$config$$config['on'].apply(lib$rsvp$config$$config, arguments);\n    }\n\n    function lib$rsvp$$off() {\n      lib$rsvp$config$$config['off'].apply(lib$rsvp$config$$config, arguments);\n    }\n\n    // Set up instrumentation through `window.__PROMISE_INTRUMENTATION__`\n    if (typeof window !== 'undefined' && typeof window['__PROMISE_INSTRUMENTATION__'] === 'object') {\n      var lib$rsvp$$callbacks = window['__PROMISE_INSTRUMENTATION__'];\n      lib$rsvp$config$$configure('instrument', true);\n      for (var lib$rsvp$$eventName in lib$rsvp$$callbacks) {\n        if (lib$rsvp$$callbacks.hasOwnProperty(lib$rsvp$$eventName)) {\n          lib$rsvp$$on(lib$rsvp$$eventName, lib$rsvp$$callbacks[lib$rsvp$$eventName]);\n        }\n      }\n    }\n\n    var lib$rsvp$umd$$RSVP = {\n      'race': lib$rsvp$race$$default,\n      'Promise': lib$rsvp$promise$$default,\n      'allSettled': lib$rsvp$all$settled$$default,\n      'hash': lib$rsvp$hash$$default,\n      'hashSettled': lib$rsvp$hash$settled$$default,\n      'denodeify': lib$rsvp$node$$default,\n      'on': lib$rsvp$$on,\n      'off': lib$rsvp$$off,\n      'map': lib$rsvp$map$$default,\n      'filter': lib$rsvp$filter$$default,\n      'resolve': lib$rsvp$resolve$$default,\n      'reject': lib$rsvp$reject$$default,\n      'all': lib$rsvp$all$$default,\n      'rethrow': lib$rsvp$rethrow$$default,\n      'defer': lib$rsvp$defer$$default,\n      'EventTarget': lib$rsvp$events$$default,\n      'configure': lib$rsvp$config$$configure,\n      'async': lib$rsvp$$async\n    };\n\n    /* global define:true module:true window: true */\n    if (typeof define === 'function' && define['amd']) {\n      define(function() { return lib$rsvp$umd$$RSVP; });\n    } else if (typeof module !== 'undefined' && module['exports']) {\n      module['exports'] = lib$rsvp$umd$$RSVP;\n    } else if (typeof lib$rsvp$platform$$default !== 'undefined') {\n      lib$rsvp$platform$$default['RSVP'] = lib$rsvp$umd$$RSVP;\n    }\n}).call(this);\n\n\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n\n},{\"_process\":67}]},{},[28])\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJqcy9hcHAvY2FjaGUuanMiLCJqcy9hcHAvY29uc3RydWN0b3IuanMiLCJqcy9hcHAvaW5kZXguanMiLCJqcy9kb20vYWRkX2NhdGVnb3JpZXMuanMiLCJqcy9kb20vYWRkX2ZpbGVzLmpzIiwianMvZG9tL2luZGV4LmpzIiwianMvZG9tL2xvYWRpbmdfc2xpZGVyLmpzIiwianMvZG9tL3NldHVwL2luZGV4LmpzIiwianMvZG9tL3NldHVwL3NldHVwX2RpdmlkZXJzLmpzIiwianMvZG9tL3NldHVwL3NldHVwX2RvY3VtZW50LmpzIiwianMvZG9tL3NldHVwL3NldHVwX2ZpbGVzX2Jhci5qcyIsImpzL2RvbS9zZXR1cC9zZXR1cF9pbnRlcnZhbC5qcyIsImpzL2RvbS9zZXR1cC9zZXR1cF9tb2R1bGVfY29udGFpbmVyLmpzIiwianMvZG9tL3NldHVwL3NldHVwX3Bvd2VyZWRfYnkuanMiLCJqcy9kb20vc2V0dXAvc2V0dXBfc2NyYXRjaF9wYXBlci5qcyIsImpzL2RvbS9zZXR1cC9zZXR1cF9zaWRlX21lbnUuanMiLCJqcy9kb20vc2V0dXAvc2V0dXBfdG9wX21lbnUuanMiLCJqcy9kb20vc2V0dXAvc2V0dXBfd2luZG93LmpzIiwianMvZG9tL3Nob3dfYWxnb3JpdGhtLmpzIiwianMvZG9tL3Nob3dfZGVzY3JpcHRpb24uanMiLCJqcy9kb20vc2hvd19maXJzdF9hbGdvcml0aG0uanMiLCJqcy9kb20vc2hvd19yZXF1ZXN0ZWRfYWxnb3JpdGhtLmpzIiwianMvZG9tL3RvYXN0LmpzIiwianMvZG9tL3RvcF9tZW51LmpzIiwianMvZWRpdG9yL2NyZWF0ZS5qcyIsImpzL2VkaXRvci9leGVjdXRvci5qcyIsImpzL2VkaXRvci9pbmRleC5qcyIsImpzL2luZGV4LmpzIiwianMvbW9kdWxlL2RhdGEvYXJyYXkxZC5qcyIsImpzL21vZHVsZS9kYXRhL2FycmF5MmQuanMiLCJqcy9tb2R1bGUvZGF0YS9jb29yZGluYXRlX3N5c3RlbS5qcyIsImpzL21vZHVsZS9kYXRhL2RpcmVjdGVkX2dyYXBoLmpzIiwianMvbW9kdWxlL2RhdGEvaW5kZXguanMiLCJqcy9tb2R1bGUvZGF0YS91bmRpcmVjdGVkX2dyYXBoLmpzIiwianMvbW9kdWxlL2RhdGEvd2VpZ2h0ZWRfZGlyZWN0ZWRfZ3JhcGguanMiLCJqcy9tb2R1bGUvZGF0YS93ZWlnaHRlZF91bmRpcmVjdGVkX2dyYXBoLmpzIiwianMvbW9kdWxlL2luZGV4LmpzIiwianMvbW9kdWxlL3RyYWNlci9hcnJheTFkLmpzIiwianMvbW9kdWxlL3RyYWNlci9hcnJheTJkLmpzIiwianMvbW9kdWxlL3RyYWNlci9jaGFydC5qcyIsImpzL21vZHVsZS90cmFjZXIvY29vcmRpbmF0ZV9zeXN0ZW0uanMiLCJqcy9tb2R1bGUvdHJhY2VyL2RpcmVjdGVkX2dyYXBoLmpzIiwianMvbW9kdWxlL3RyYWNlci9pbmRleC5qcyIsImpzL21vZHVsZS90cmFjZXIvbG9nLmpzIiwianMvbW9kdWxlL3RyYWNlci90cmFjZXIuanMiLCJqcy9tb2R1bGUvdHJhY2VyL3VuZGlyZWN0ZWRfZ3JhcGguanMiLCJqcy9tb2R1bGUvdHJhY2VyL3dlaWdodGVkX2RpcmVjdGVkX2dyYXBoLmpzIiwianMvbW9kdWxlL3RyYWNlci93ZWlnaHRlZF91bmRpcmVjdGVkX2dyYXBoLmpzIiwianMvc2VydmVyL2FqYXgvZ2V0LmpzIiwianMvc2VydmVyL2FqYXgvZ2V0X2pzb24uanMiLCJqcy9zZXJ2ZXIvYWpheC9wb3N0X2pzb24uanMiLCJqcy9zZXJ2ZXIvYWpheC9yZXF1ZXN0LmpzIiwianMvc2VydmVyL2hlbHBlcnMuanMiLCJqcy9zZXJ2ZXIvaW5kZXguanMiLCJqcy9zZXJ2ZXIvbG9hZF9hbGdvcml0aG0uanMiLCJqcy9zZXJ2ZXIvbG9hZF9jYXRlZ29yaWVzLmpzIiwianMvc2VydmVyL2xvYWRfZmlsZS5qcyIsImpzL3NlcnZlci9sb2FkX3NjcmF0Y2hfcGFwZXIuanMiLCJqcy9zZXJ2ZXIvc2hhcmVfc2NyYXRjaF9wYXBlci5qcyIsImpzL3RyYWNlcl9tYW5hZ2VyL2luZGV4LmpzIiwianMvdHJhY2VyX21hbmFnZXIvbWFuYWdlci5qcyIsImpzL3RyYWNlcl9tYW5hZ2VyL3V0aWwvZnJvbV9qc29uLmpzIiwianMvdHJhY2VyX21hbmFnZXIvdXRpbC9pbmRleC5qcyIsImpzL3RyYWNlcl9tYW5hZ2VyL3V0aWwvcmVmaW5lX2J5X3R5cGUuanMiLCJqcy90cmFjZXJfbWFuYWdlci91dGlsL3RvX2pzb24uanMiLCJqcy91dGlscy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9wcm9jZXNzL2Jyb3dzZXIuanMiLCJub2RlX21vZHVsZXMvcnN2cC9kaXN0L3JzdnAuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUNBQTs7U0FJSSxDO0lBREYsTSxNQUFBLE07OztBQUdGLElBQU0sUUFBUTtBQUNaLGdCQUFjLEVBREY7QUFFWixTQUFPO0FBRkssQ0FBZDs7QUFLQSxJQUFNLGlCQUFpQixTQUFqQixjQUFpQixDQUFDLElBQUQsRUFBVTtBQUMvQixNQUFJLENBQUMsSUFBTCxFQUFXO0FBQ1QsVUFBTSxtQkFBTjtBQUNEO0FBQ0YsQ0FKRDs7Ozs7QUFVQSxPQUFPLE9BQVAsR0FBaUI7QUFFZixlQUZlLHlCQUVELElBRkMsRUFFSztBQUNsQixtQkFBZSxJQUFmO0FBQ0EsV0FBTyxNQUFNLEtBQU4sQ0FBWSxJQUFaLENBQVA7QUFDRCxHQUxjO0FBT2Ysa0JBUGUsNEJBT0UsSUFQRixFQU9RLE9BUFIsRUFPaUI7QUFDOUIsbUJBQWUsSUFBZjtBQUNBLFFBQUksQ0FBQyxNQUFNLEtBQU4sQ0FBWSxJQUFaLENBQUwsRUFBd0I7QUFDdEIsWUFBTSxLQUFOLENBQVksSUFBWixJQUFvQixFQUFwQjtBQUNEO0FBQ0QsV0FBTyxNQUFNLEtBQU4sQ0FBWSxJQUFaLENBQVAsRUFBMEIsT0FBMUI7QUFDRCxHQWJjO0FBZWYsaUJBZmUsNkJBZUc7QUFDaEIsV0FBTyxNQUFNLFlBQWI7QUFDRCxHQWpCYztB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QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQzlGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsIid1c2Ugc3RyaWN0JztcblxuY29uc3Qge1xuICBleHRlbmRcbn0gPSAkO1xuXG5jb25zdCBjYWNoZSA9IHtcbiAgbGFzdEZpbGVVc2VkOiAnJyxcbiAgZmlsZXM6IHt9XG59O1xuXG5jb25zdCBhc3NlcnRGaWxlTmFtZSA9IChuYW1lKSA9PiB7XG4gIGlmICghbmFtZSkge1xuICAgIHRocm93ICdNaXNzaW5nIGZpbGUgbmFtZSc7XG4gIH1cbn07XG5cblxuLyoqXG4gKiBHbG9iYWwgYXBwbGljYXRpb24gY2FjaGVcbiAqL1xubW9kdWxlLmV4cG9ydHMgPSB7XG5cbiAgZ2V0Q2FjaGVkRmlsZShuYW1lKSB7XG4gICAgYXNzZXJ0RmlsZU5hbWUobmFtZSk7XG4gICAgcmV0dXJuIGNhY2hlLmZpbGVzW25hbWVdO1xuICB9LFxuXG4gIHVwZGF0ZUNhY2hlZEZpbGUobmFtZSwgdXBkYXRlcykge1xuICAgIGFzc2VydEZpbGVOYW1lKG5hbWUpO1xuICAgIGlmICghY2FjaGUuZmlsZXNbbmFtZV0pIHtcbiAgICAgIGNhY2hlLmZpbGVzW25hbWVdID0ge307XG4gICAgfVxuICAgIGV4dGVuZChjYWNoZS5maWxlc1tuYW1lXSwgdXBkYXRlcyk7XG4gIH0sXG5cbiAgZ2V0TGFzdEZpbGVVc2VkKCkge1xuICAgIHJldHVybiBjYWNoZS5sYXN0RmlsZVVzZWQ7XG4gIH0sXG5cbiAgc2V0TGFzdEZpbGVVc2VkKGZpbGUpIHtcbiAgICBjYWNoZS5sYXN0RmlsZVVzZWQgPSBmaWxlO1xuICB9XG59OyIsIid1c2Ugc3RyaWN0JztcblxuY29uc3QgRWRpdG9yID0gcmVxdWlyZSgnLi4vZWRpdG9yJyk7XG5jb25zdCBUcmFjZXJNYW5hZ2VyID0gcmVxdWlyZSgnLi4vdHJhY2VyX21hbmFnZXInKTtcbmNvbnN0IERPTSA9IHJlcXVpcmUoJy4uL2RvbS9zZXR1cCcpO1xuXG5jb25zdCB7XG4gIHNob3dMb2FkaW5nU2xpZGVyLFxuICBoaWRlTG9hZGluZ1NsaWRlclxufSA9IHJlcXVpcmUoJy4uL2RvbS9sb2FkaW5nX3NsaWRlcicpO1xuXG5jb25zdCBDYWNoZSA9IHJlcXVpcmUoJy4vY2FjaGUnKTtcblxuY29uc3Qgc3RhdGUgPSB7XG4gIGlzTG9hZGluZzogbnVsbCxcbiAgZWRpdG9yOiBudWxsLFxuICB0cmFjZXJNYW5hZ2VyOiBudWxsLFxuICBjYXRlZ29yaWVzOiBudWxsLFxuICBsb2FkZWRTY3JhdGNoOiBudWxsXG59O1xuXG5jb25zdCBpbml0U3RhdGUgPSAodHJhY2VyTWFuYWdlcikgPT4ge1xuICBzdGF0ZS5pc0xvYWRpbmcgPSBmYWxzZTtcbiAgc3RhdGUuZWRpdG9yID0gbmV3IEVkaXRvcih0cmFjZXJNYW5hZ2VyKTtcbiAgc3RhdGUudHJhY2VyTWFuYWdlciA9IHRyYWNlck1hbmFnZXI7XG4gIHN0YXRlLmNhdGVnb3JpZXMgPSB7fTtcbiAgc3RhdGUubG9hZGVkU2NyYXRjaCA9IG51bGw7XG59O1xuXG4vKipcbiAqIEdsb2JhbCBhcHBsaWNhdGlvbiBzaW5nbGV0b24uXG4gKi9cbmNvbnN0IEFwcCA9IGZ1bmN0aW9uICgpIHtcblxuICB0aGlzLmdldElzTG9hZGluZyA9ICgpID0+IHtcbiAgICByZXR1cm4gc3RhdGUuaXNMb2FkaW5nO1xuICB9O1xuXG4gIHRoaXMuc2V0SXNMb2FkaW5nID0gKGxvYWRpbmcpID0+IHtcbiAgICBzdGF0ZS5pc0xvYWRpbmcgPSBsb2FkaW5nO1xuICAgIGlmIChsb2FkaW5nKSB7XG4gICAgICBzaG93TG9hZGluZ1NsaWRlcigpO1xuICAgIH0gZWxzZSB7XG4gICAgICBoaWRlTG9hZGluZ1NsaWRlcigpO1xuICAgIH1cbiAgfTtcblxuICB0aGlzLmdldEVkaXRvciA9ICgpID0+IHtcbiAgICByZXR1cm4gc3RhdGUuZWRpdG9yO1xuICB9O1xuXG4gIHRoaXMuZ2V0Q2F0ZWdvcmllcyA9ICgpID0+IHtcbiAgICByZXR1cm4gc3RhdGUuY2F0ZWdvcmllcztcbiAgfTtcblxuICB0aGlzLmdldENhdGVnb3J5ID0gKG5hbWUpID0+IHtcbiAgICByZXR1cm4gc3RhdGUuY2F0ZWdvcmllc1tuYW1lXTtcbiAgfTtcblxuICB0aGlzLnNldENhdGVnb3JpZXMgPSAoY2F0ZWdvcmllcykgPT4ge1xuICAgIHN0YXRlLmNhdGVnb3JpZXMgPSBjYXRlZ29yaWVzO1xuICB9O1xuXG4gIHRoaXMudXBkYXRlQ2F0ZWdvcnkgPSAobmFtZSwgdXBkYXRlcykgPT4ge1xuICAgICQuZXh0ZW5kKHN0YXRlLmNhdGVnb3JpZXNbbmFtZV0sIHVwZGF0ZXMpO1xuICB9O1xuXG4gIHRoaXMuZ2V0VHJhY2VyTWFuYWdlciA9ICgpID0+IHtcbiAgICByZXR1cm4gc3RhdGUudHJhY2VyTWFuYWdlcjtcbiAgfTtcblxuICB0aGlzLmdldExvYWRlZFNjcmF0Y2ggPSAoKSA9PiB7XG4gICAgcmV0dXJuIHN0YXRlLmxvYWRlZFNjcmF0Y2g7XG4gIH07XG5cbiAgdGhpcy5zZXRMb2FkZWRTY3JhdGNoID0gKGxvYWRlZFNjcmF0Y2gpID0+IHtcbiAgICBzdGF0ZS5sb2FkZWRTY3JhdGNoID0gbG9hZGVkU2NyYXRjaDtcbiAgfTtcblxuICBjb25zdCB0cmFjZXJNYW5hZ2VyID0gVHJhY2VyTWFuYWdlci5pbml0KCk7XG5cbiAgaW5pdFN0YXRlKHRyYWNlck1hbmFnZXIpO1xuICBET00uc2V0dXAodHJhY2VyTWFuYWdlcik7XG5cbn07XG5cbkFwcC5wcm90b3R5cGUgPSBDYWNoZTtcblxubW9kdWxlLmV4cG9ydHMgPSBBcHA7XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qKlxuICogVGhpcyBpcyB0aGUgbWFpbiBhcHBsaWNhdGlvbiBpbnN0YW5jZS5cbiAqIEdldHMgcG9wdWxhdGVkIG9uIHBhZ2UgbG9hZC4gXG4gKi9cbm1vZHVsZS5leHBvcnRzID0ge307IiwiJ3VzZSBzdHJpY3QnO1xuXG5jb25zdCBhcHAgPSByZXF1aXJlKCcuLi9hcHAnKTtcbmNvbnN0IFNlcnZlciA9IHJlcXVpcmUoJy4uL3NlcnZlcicpO1xuY29uc3Qgc2hvd0FsZ29yaXRobSA9IHJlcXVpcmUoJy4vc2hvd19hbGdvcml0aG0nKTtcblxuY29uc3Qge1xuICBlYWNoXG59ID0gJDtcblxuY29uc3QgYWRkQWxnb3JpdGhtVG9DYXRlZ29yeURPTSA9IChjYXRlZ29yeSwgc3ViTGlzdCwgYWxnb3JpdGhtKSA9PiB7XG4gIGNvbnN0ICRhbGdvcml0aG0gPSAkKCc8YnV0dG9uIGNsYXNzPVwiaW5kZW50IGNvbGxhcHNlXCI+JylcbiAgICAuYXBwZW5kKHN1Ykxpc3RbYWxnb3JpdGhtXSlcbiAgICAuYXR0cignZGF0YS1hbGdvcml0aG0nLCBhbGdvcml0aG0pXG4gICAgLmF0dHIoJ2RhdGEtY2F0ZWdvcnknLCBjYXRlZ29yeSlcbiAgICAuY2xpY2soZnVuY3Rpb24gKCkge1xuICAgICAgU2VydmVyLmxvYWRBbGdvcml0aG0oY2F0ZWdvcnksIGFsZ29yaXRobSkudGhlbigoZGF0YSkgPT4ge1xuICAgICAgICBzaG93QWxnb3JpdGhtKGNhdGVnb3J5LCBhbGdvcml0aG0sIGRhdGEpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgJCgnI2xpc3QnKS5hcHBlbmQoJGFsZ29yaXRobSk7XG59O1xuXG5jb25zdCBhZGRDYXRlZ29yeVRvRE9NID0gKGNhdGVnb3J5KSA9PiB7XG5cbiAgY29uc3Qge1xuICAgIG5hbWU6IGNhdGVnb3J5TmFtZSxcbiAgICBsaXN0OiBjYXRlZ29yeVN1Ykxpc3RcbiAgfSA9IGFwcC5nZXRDYXRlZ29yeShjYXRlZ29yeSk7XG5cbiAgY29uc3QgJGNhdGVnb3J5ID0gJCgnPGJ1dHRvbiBjbGFzcz1cImNhdGVnb3J5XCI+JylcbiAgICAuYXBwZW5kKCc8aSBjbGFzcz1cImZhIGZhLWZ3IGZhLWNhcmV0LXJpZ2h0XCI+JylcbiAgICAuYXBwZW5kKGNhdGVnb3J5TmFtZSlcbiAgICAuYXR0cignZGF0YS1jYXRlZ29yeScsIGNhdGVnb3J5KTtcblxuICAkY2F0ZWdvcnkuY2xpY2soZnVuY3Rpb24gKCkge1xuICAgICQoYC5pbmRlbnRbZGF0YS1jYXRlZ29yeT1cIiR7Y2F0ZWdvcnl9XCJdYCkudG9nZ2xlQ2xhc3MoJ2NvbGxhcHNlJyk7XG4gICAgJCh0aGlzKS5maW5kKCdpLmZhJykudG9nZ2xlQ2xhc3MoJ2ZhLWNhcmV0LXJpZ2h0IGZhLWNhcmV0LWRvd24nKTtcbiAgfSk7XG5cbiAgJCgnI2xpc3QnKS5hcHBlbmQoJGNhdGVnb3J5KTtcblxuICBlYWNoKGNhdGVnb3J5U3ViTGlzdCwgKGFsZ29yaXRobSkgPT4ge1xuICAgIGFkZEFsZ29yaXRobVRvQ2F0ZWdvcnlET00oY2F0ZWdvcnksIGNhdGVnb3J5U3ViTGlzdCwgYWxnb3JpdGhtKTtcbiAgfSk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9ICgpID0+IHtcbiAgZWFjaChhcHAuZ2V0Q2F0ZWdvcmllcygpLCBhZGRDYXRlZ29yeVRvRE9NKTtcbn07IiwiJ3VzZSBzdHJpY3QnO1xuXG5jb25zdCBTZXJ2ZXIgPSByZXF1aXJlKCcuLi9zZXJ2ZXInKTtcblxuY29uc3Qge1xuICBlYWNoXG59ID0gJDtcblxuY29uc3QgYWRkRmlsZVRvRE9NID0gKGNhdGVnb3J5LCBhbGdvcml0aG0sIGZpbGUsIGV4cGxhbmF0aW9uKSA9PiB7XG4gIHZhciAkZmlsZSA9ICQoJzxidXR0b24+JylcbiAgICAuYXBwZW5kKGZpbGUpXG4gICAgLmF0dHIoJ2RhdGEtZmlsZScsIGZpbGUpXG4gICAgLmNsaWNrKGZ1bmN0aW9uICgpIHtcbiAgICAgIFNlcnZlci5sb2FkRmlsZShjYXRlZ29yeSwgYWxnb3JpdGhtLCBmaWxlLCBleHBsYW5hdGlvbik7XG4gICAgICAkKCcuZmlsZXNfYmFyID4gLndyYXBwZXIgPiBidXR0b24nKS5yZW1vdmVDbGFzcygnYWN0aXZlJyk7XG4gICAgICAkKHRoaXMpLmFkZENsYXNzKCdhY3RpdmUnKTtcbiAgICB9KTtcbiAgJCgnLmZpbGVzX2JhciA+IC53cmFwcGVyJykuYXBwZW5kKCRmaWxlKTtcbiAgcmV0dXJuICRmaWxlO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSAoY2F0ZWdvcnksIGFsZ29yaXRobSwgZmlsZXMsIHJlcXVlc3RlZEZpbGUpID0+IHtcbiAgJCgnLmZpbGVzX2JhciA+IC53cmFwcGVyJykuZW1wdHkoKTtcblxuICBlYWNoKGZpbGVzLCAoZmlsZSwgZXhwbGFuYXRpb24pID0+IHtcbiAgICB2YXIgJGZpbGUgPSBhZGRGaWxlVG9ET00oY2F0ZWdvcnksIGFsZ29yaXRobSwgZmlsZSwgZXhwbGFuYXRpb24pO1xuICAgIGlmIChyZXF1ZXN0ZWRGaWxlICYmIHJlcXVlc3RlZEZpbGUgPT0gZmlsZSkgJGZpbGUuY2xpY2soKTtcbiAgfSk7XG5cbiAgaWYgKCFyZXF1ZXN0ZWRGaWxlKSAkKCcuZmlsZXNfYmFyID4gLndyYXBwZXIgPiBidXR0b24nKS5maXJzdCgpLmNsaWNrKCk7XG4gICQoJy5maWxlc19iYXIgPiAud3JhcHBlcicpLnNjcm9sbCgpO1xufTsiLCIndXNlIHN0cmljdCc7XG5cbmNvbnN0IHNob3dBbGdvcml0aG0gPSByZXF1aXJlKCcuL3Nob3dfYWxnb3JpdGhtJyk7XG5jb25zdCBhZGRDYXRlZ29yaWVzID0gcmVxdWlyZSgnLi9hZGRfY2F0ZWdvcmllcycpO1xuY29uc3Qgc2hvd0Rlc2NyaXB0aW9uID0gcmVxdWlyZSgnLi9zaG93X2Rlc2NyaXB0aW9uJyk7XG5jb25zdCBhZGRGaWxlcyA9IHJlcXVpcmUoJy4vYWRkX2ZpbGVzJyk7XG5jb25zdCBzaG93Rmlyc3RBbGdvcml0aG0gPSByZXF1aXJlKCcuL3Nob3dfZmlyc3RfYWxnb3JpdGhtJyk7XG5jb25zdCBzaG93UmVxdWVzdGVkQWxnb3JpdGhtID0gcmVxdWlyZSgnLi9zaG93X3JlcXVlc3RlZF9hbGdvcml0aG0nKTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHNob3dBbGdvcml0aG0sXG4gIGFkZENhdGVnb3JpZXMsXG4gIHNob3dEZXNjcmlwdGlvbixcbiAgYWRkRmlsZXMsXG4gIHNob3dGaXJzdEFsZ29yaXRobSxcbiAgc2hvd1JlcXVlc3RlZEFsZ29yaXRobVxufTsiLCJcbmNvbnN0IHNob3dMb2FkaW5nU2xpZGVyID0gKCkgPT4ge1xuICAkKCcjbG9hZGluZy1zbGlkZXInKS5yZW1vdmVDbGFzcygnbG9hZGVkJyk7XG59O1xuXG5jb25zdCBoaWRlTG9hZGluZ1NsaWRlciA9ICgpID0+IHtcbiAgJCgnI2xvYWRpbmctc2xpZGVyJykuYWRkQ2xhc3MoJ2xvYWRlZCcpO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHNob3dMb2FkaW5nU2xpZGVyLFxuICBoaWRlTG9hZGluZ1NsaWRlclxufTtcbiIsImNvbnN0IHNldHVwRGl2aWRlcnMgPSByZXF1aXJlKCcuL3NldHVwX2RpdmlkZXJzJyk7XG5jb25zdCBzZXR1cERvY3VtZW50ID0gcmVxdWlyZSgnLi9zZXR1cF9kb2N1bWVudCcpO1xuY29uc3Qgc2V0dXBGaWxlc0JhciA9IHJlcXVpcmUoJy4vc2V0dXBfZmlsZXNfYmFyJyk7XG5jb25zdCBzZXR1cEludGVydmFsID0gcmVxdWlyZSgnLi9zZXR1cF9pbnRlcnZhbCcpO1xuY29uc3Qgc2V0dXBNb2R1bGVDb250YWluZXIgPSByZXF1aXJlKCcuL3NldHVwX21vZHVsZV9jb250YWluZXInKTtcbmNvbnN0IHNldHVwUG93ZXJlZEJ5ID0gcmVxdWlyZSgnLi9zZXR1cF9wb3dlcmVkX2J5Jyk7XG5jb25zdCBzZXR1cFNjcmF0Y2hQYXBlciA9IHJlcXVpcmUoJy4vc2V0dXBfc2NyYXRjaF9wYXBlcicpO1xuY29uc3Qgc2V0dXBTaWRlTWVudSA9IHJlcXVpcmUoJy4vc2V0dXBfc2lkZV9tZW51Jyk7XG5jb25zdCBzZXR1cFRvcE1lbnUgPSByZXF1aXJlKCcuL3NldHVwX3RvcF9tZW51Jyk7XG5jb25zdCBzZXR1cFdpbmRvdyA9IHJlcXVpcmUoJy4vc2V0dXBfd2luZG93Jyk7XG5cbi8qKlxuICogSW5pdGlhbGl6ZXMgZWxlbWVudHMgb25jZSB0aGUgYXBwIGxvYWRzIGluIHRoZSBET00uIFxuICovXG5jb25zdCBzZXR1cCA9ICgpID0+IHtcblxuICAkKCcuYnRuIGlucHV0JykuY2xpY2soKGUpID0+IHtcbiAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICB9KTtcblxuICAvLyBkaXZpZGVyc1xuICBzZXR1cERpdmlkZXJzKCk7XG5cbiAgLy8gZG9jdW1lbnRcbiAgc2V0dXBEb2N1bWVudCgpO1xuXG4gIC8vIGZpbGVzIGJhclxuICBzZXR1cEZpbGVzQmFyKCk7XG5cbiAgLy8gaW50ZXJ2YWxcbiAgc2V0dXBJbnRlcnZhbCgpO1xuXG4gIC8vIG1vZHVsZSBjb250YWluZXJcbiAgc2V0dXBNb2R1bGVDb250YWluZXIoKTtcblxuICAvLyBwb3dlcmVkIGJ5XG4gIHNldHVwUG93ZXJlZEJ5KCk7XG5cbiAgLy8gc2NyYXRjaCBwYXBlclxuICBzZXR1cFNjcmF0Y2hQYXBlcigpO1xuXG4gIC8vIHNpZGUgbWVudVxuICBzZXR1cFNpZGVNZW51KCk7XG5cbiAgLy8gdG9wIG1lbnVcbiAgc2V0dXBUb3BNZW51KCk7XG5cbiAgLy8gd2luZG93XG4gIHNldHVwV2luZG93KCk7XG5cbn07XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBzZXR1cFxufTsiLCJjb25zdCBhcHAgPSByZXF1aXJlKCcuLi8uLi9hcHAnKTtcblxuY29uc3QgYWRkRGl2aWRlclRvRG9tID0gKGRpdmlkZXIpID0+IHtcbiAgY29uc3QgW3ZlcnRpY2FsLCAkZmlyc3QsICRzZWNvbmRdID0gZGl2aWRlcjtcbiAgY29uc3QgJHBhcmVudCA9ICRmaXJzdC5wYXJlbnQoKTtcbiAgY29uc3QgdGhpY2tuZXNzID0gNTtcblxuICBjb25zdCAkZGl2aWRlciA9ICQoJzxkaXYgY2xhc3M9XCJkaXZpZGVyXCI+Jyk7XG5cbiAgbGV0IGRyYWdnaW5nID0gZmFsc2U7XG4gIGlmICh2ZXJ0aWNhbCkge1xuICAgICRkaXZpZGVyLmFkZENsYXNzKCd2ZXJ0aWNhbCcpO1xuXG4gICAgbGV0IF9sZWZ0ID0gLXRoaWNrbmVzcyAvIDI7XG4gICAgJGRpdmlkZXIuY3NzKHtcbiAgICAgIHRvcDogMCxcbiAgICAgIGJvdHRvbTogMCxcbiAgICAgIGxlZnQ6IF9sZWZ0LFxuICAgICAgd2lkdGg6IHRoaWNrbmVzc1xuICAgIH0pO1xuXG4gICAgbGV0IHg7XG4gICAgJGRpdmlkZXIubW91c2Vkb3duKCh7XG4gICAgICBwYWdlWFxuICAgIH0pID0+IHtcbiAgICAgIHggPSBwYWdlWDtcbiAgICAgIGRyYWdnaW5nID0gdHJ1ZTtcbiAgICB9KTtcblxuICAgICQoZG9jdW1lbnQpLm1vdXNlbW92ZSgoe1xuICAgICAgcGFnZVhcbiAgICB9KSA9PiB7XG4gICAgICBpZiAoZHJhZ2dpbmcpIHtcbiAgICAgICAgY29uc3QgbmV3X2xlZnQgPSAkc2Vjb25kLnBvc2l0aW9uKCkubGVmdCArIHBhZ2VYIC0geDtcbiAgICAgICAgbGV0IHBlcmNlbnQgPSBuZXdfbGVmdCAvICRwYXJlbnQud2lkdGgoKSAqIDEwMDtcbiAgICAgICAgcGVyY2VudCA9IE1hdGgubWluKDkwLCBNYXRoLm1heCgxMCwgcGVyY2VudCkpO1xuICAgICAgICAkZmlyc3QuY3NzKCdyaWdodCcsICgxMDAgLSBwZXJjZW50KSArICclJyk7XG4gICAgICAgICRzZWNvbmQuY3NzKCdsZWZ0JywgcGVyY2VudCArICclJyk7XG4gICAgICAgIHggPSBwYWdlWDtcbiAgICAgICAgYXBwLmdldFRyYWNlck1hbmFnZXIoKS5yZXNpemUoKTtcbiAgICAgICAgJCgnLmZpbGVzX2JhciA+IC53cmFwcGVyJykuc2Nyb2xsKCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICAkKGRvY3VtZW50KS5tb3VzZXVwKGZ1bmN0aW9uKGUpIHtcbiAgICAgIGRyYWdnaW5nID0gZmFsc2U7XG4gICAgfSk7XG5cbiAgfSBlbHNlIHtcblxuICAgICRkaXZpZGVyLmFkZENsYXNzKCdob3Jpem9udGFsJyk7XG4gICAgY29uc3QgX3RvcCA9IC10aGlja25lc3MgLyAyO1xuICAgICRkaXZpZGVyLmNzcyh7XG4gICAgICB0b3A6IF90b3AsXG4gICAgICBoZWlnaHQ6IHRoaWNrbmVzcyxcbiAgICAgIGxlZnQ6IDAsXG4gICAgICByaWdodDogMFxuICAgIH0pO1xuXG4gICAgbGV0IHk7XG4gICAgJGRpdmlkZXIubW91c2Vkb3duKGZ1bmN0aW9uKHtcbiAgICAgIHBhZ2VZXG4gICAgfSkge1xuICAgICAgeSA9IHBhZ2VZO1xuICAgICAgZHJhZ2dpbmcgPSB0cnVlO1xuICAgIH0pO1xuXG4gICAgJChkb2N1bWVudCkubW91c2Vtb3ZlKGZ1bmN0aW9uKHtcbiAgICAgIHBhZ2VZXG4gICAgfSkge1xuICAgICAgaWYgKGRyYWdnaW5nKSB7XG4gICAgICAgIGNvbnN0IG5ld190b3AgPSAkc2Vjb25kLnBvc2l0aW9uKCkudG9wICsgcGFnZVkgLSB5O1xuICAgICAgICBsZXQgcGVyY2VudCA9IG5ld190b3AgLyAkcGFyZW50LmhlaWdodCgpICogMTAwO1xuICAgICAgICBwZXJjZW50ID0gTWF0aC5taW4oOTAsIE1hdGgubWF4KDEwLCBwZXJjZW50KSk7XG4gICAgICAgICRmaXJzdC5jc3MoJ2JvdHRvbScsICgxMDAgLSBwZXJjZW50KSArICclJyk7XG4gICAgICAgICRzZWNvbmQuY3NzKCd0b3AnLCBwZXJjZW50ICsgJyUnKTtcbiAgICAgICAgeSA9IHBhZ2VZO1xuICAgICAgICBhcHAuZ2V0VHJhY2VyTWFuYWdlcigpLnJlc2l6ZSgpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgJChkb2N1bWVudCkubW91c2V1cChmdW5jdGlvbihlKSB7XG4gICAgICBkcmFnZ2luZyA9IGZhbHNlO1xuICAgIH0pO1xuICB9XG5cbiAgJHNlY29uZC5hcHBlbmQoJGRpdmlkZXIpO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSAoKSA9PiB7XG4gIGNvbnN0IGRpdmlkZXJzID0gW1xuICAgIFsndicsICQoJy5zaWRlbWVudScpLCAkKCcud29ya3NwYWNlJyldLFxuICAgIFsndicsICQoJy52aWV3ZXJfY29udGFpbmVyJyksICQoJy5lZGl0b3JfY29udGFpbmVyJyldLFxuICAgIFsnaCcsICQoJy5kYXRhX2NvbnRhaW5lcicpLCAkKCcuY29kZV9jb250YWluZXInKV1cbiAgXTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBkaXZpZGVycy5sZW5ndGg7IGkrKykge1xuICAgIGFkZERpdmlkZXJUb0RvbShkaXZpZGVyc1tpXSk7XG4gIH1cbn0iLCJjb25zdCBhcHAgPSByZXF1aXJlKCcuLi8uLi9hcHAnKTtcblxubW9kdWxlLmV4cG9ydHMgPSAoKSA9PiB7XG4gICQoZG9jdW1lbnQpLm9uKCdjbGljaycsICdhJywgZnVuY3Rpb24gKGUpIHtcbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgaWYgKCF3aW5kb3cub3BlbigkKHRoaXMpLmF0dHIoJ2hyZWYnKSwgJ19ibGFuaycpKSB7XG4gICAgICBhbGVydCgnUGxlYXNlIGFsbG93IHBvcHVwcyBmb3IgdGhpcyBzaXRlJyk7XG4gICAgfVxuICB9KTtcblxuICAkKGRvY3VtZW50KS5tb3VzZXVwKGZ1bmN0aW9uIChlKSB7XG4gICAgYXBwLmdldFRyYWNlck1hbmFnZXIoKS5jb21tYW5kKCdtb3VzZXVwJywgZSk7XG4gIH0pO1xufTsiLCJjb25zdCBkZWZpbml0ZWx5QmlnZ2VyID0gKHgsIHkpID0+IHggPiAoeSArIDIpO1xuXG5tb2R1bGUuZXhwb3J0cyA9ICgpID0+IHtcblxuICAkKCcuZmlsZXNfYmFyID4gLmJ0bi1sZWZ0JykuY2xpY2soKCkgPT4ge1xuICAgIGNvbnN0ICR3cmFwcGVyID0gJCgnLmZpbGVzX2JhciA+IC53cmFwcGVyJyk7XG4gICAgY29uc3QgY2xpcFdpZHRoID0gJHdyYXBwZXIud2lkdGgoKTtcbiAgICBjb25zdCBzY3JvbGxMZWZ0ID0gJHdyYXBwZXIuc2Nyb2xsTGVmdCgpO1xuXG4gICAgJCgkd3JhcHBlci5jaGlsZHJlbignYnV0dG9uJykuZ2V0KCkucmV2ZXJzZSgpKS5lYWNoKGZ1bmN0aW9uKCkge1xuICAgICAgY29uc3QgbGVmdCA9ICQodGhpcykucG9zaXRpb24oKS5sZWZ0O1xuICAgICAgY29uc3QgcmlnaHQgPSBsZWZ0ICsgJCh0aGlzKS5vdXRlcldpZHRoKCk7XG4gICAgICBpZiAoMCA+IGxlZnQpIHtcbiAgICAgICAgJHdyYXBwZXIuc2Nyb2xsTGVmdChzY3JvbGxMZWZ0ICsgcmlnaHQgLSBjbGlwV2lkdGgpO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xuXG4gICQoJy5maWxlc19iYXIgPiAuYnRuLXJpZ2h0JykuY2xpY2soKCkgPT4ge1xuICAgIGNvbnN0ICR3cmFwcGVyID0gJCgnLmZpbGVzX2JhciA+IC53cmFwcGVyJyk7XG4gICAgY29uc3QgY2xpcFdpZHRoID0gJHdyYXBwZXIud2lkdGgoKTtcbiAgICBjb25zdCBzY3JvbGxMZWZ0ID0gJHdyYXBwZXIuc2Nyb2xsTGVmdCgpO1xuXG4gICAgJHdyYXBwZXIuY2hpbGRyZW4oJ2J1dHRvbicpLmVhY2goZnVuY3Rpb24oKSB7XG4gICAgICBjb25zdCBsZWZ0ID0gJCh0aGlzKS5wb3NpdGlvbigpLmxlZnQ7XG4gICAgICBjb25zdCByaWdodCA9IGxlZnQgKyAkKHRoaXMpLm91dGVyV2lkdGgoKTtcbiAgICAgIGlmIChjbGlwV2lkdGggPCByaWdodCkge1xuICAgICAgICAkd3JhcHBlci5zY3JvbGxMZWZ0KHNjcm9sbExlZnQgKyBsZWZ0KTtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcblxuICAkKCcuZmlsZXNfYmFyID4gLndyYXBwZXInKS5zY3JvbGwoZnVuY3Rpb24oKSB7XG5cbiAgICBjb25zdCAkd3JhcHBlciA9ICQoJy5maWxlc19iYXIgPiAud3JhcHBlcicpO1xuICAgIGNvbnN0IGNsaXBXaWR0aCA9ICR3cmFwcGVyLndpZHRoKCk7XG4gICAgY29uc3QgJGxlZnQgPSAkd3JhcHBlci5jaGlsZHJlbignYnV0dG9uOmZpcnN0LWNoaWxkJyk7XG4gICAgY29uc3QgJHJpZ2h0ID0gJHdyYXBwZXIuY2hpbGRyZW4oJ2J1dHRvbjpsYXN0LWNoaWxkJyk7XG4gICAgY29uc3QgbGVmdCA9ICRsZWZ0LnBvc2l0aW9uKCkubGVmdDtcbiAgICBjb25zdCByaWdodCA9ICRyaWdodC5wb3NpdGlvbigpLmxlZnQgKyAkcmlnaHQub3V0ZXJXaWR0aCgpO1xuXG4gICAgaWYgKGRlZmluaXRlbHlCaWdnZXIoMCwgbGVmdCkgJiYgZGVmaW5pdGVseUJpZ2dlcihjbGlwV2lkdGgsIHJpZ2h0KSkge1xuICAgICAgY29uc3Qgc2Nyb2xsTGVmdCA9ICR3cmFwcGVyLnNjcm9sbExlZnQoKTtcbiAgICAgICR3cmFwcGVyLnNjcm9sbExlZnQoc2Nyb2xsTGVmdCArIGNsaXBXaWR0aCAtIHJpZ2h0KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBsZWZ0ZXIgPSBkZWZpbml0ZWx5QmlnZ2VyKDAsIGxlZnQpO1xuICAgIGNvbnN0IHJpZ2h0ZXIgPSBkZWZpbml0ZWx5QmlnZ2VyKHJpZ2h0LCBjbGlwV2lkdGgpO1xuICAgICR3cmFwcGVyLnRvZ2dsZUNsYXNzKCdzaGFkb3ctbGVmdCcsIGxlZnRlcik7XG4gICAgJHdyYXBwZXIudG9nZ2xlQ2xhc3MoJ3NoYWRvdy1yaWdodCcsIHJpZ2h0ZXIpO1xuICAgICQoJy5maWxlc19iYXIgPiAuYnRuLWxlZnQnKS5hdHRyKCdkaXNhYmxlZCcsICFsZWZ0ZXIpO1xuICAgICQoJy5maWxlc19iYXIgPiAuYnRuLXJpZ2h0JykuYXR0cignZGlzYWJsZWQnLCAhcmlnaHRlcik7XG4gIH0pO1xufSIsImNvbnN0IGFwcCA9IHJlcXVpcmUoJy4uLy4uL2FwcCcpO1xuY29uc3QgVG9hc3QgPSByZXF1aXJlKCcuLi90b2FzdCcpO1xuXG5jb25zdCB7XG4gIHBhcnNlRmxvYXRcbn0gPSBOdW1iZXI7XG5cbmNvbnN0IG1pbkludGVydmFsID0gMC4xO1xuY29uc3QgbWF4SW50ZXJ2YWwgPSAxMDtcbmNvbnN0IHN0YXJ0SW50ZXJ2YWwgPSAwLjU7XG5jb25zdCBzdGVwSW50ZXJ2YWwgPSAwLjE7XG5cbmNvbnN0IG5vcm1hbGl6ZSA9IChzZWMpID0+IHtcblxuXG4gIGxldCBpbnRlcnZhbDtcbiAgbGV0IG1lc3NhZ2U7XG4gIGlmIChzZWMgPCBtaW5JbnRlcnZhbCkge1xuICAgIGludGVydmFsID0gbWluSW50ZXJ2YWw7XG4gICAgbWVzc2FnZSA9IGBJbnRlcnZhbCBvZiAke3NlY30gc2Vjb25kcyBpcyB0b28gbG93LiBTZXR0aW5nIHRvIG1pbiBhbGxvd2VkIGludGVydmFsIG9mICR7bWluSW50ZXJ2YWx9IHNlY29uZChzKS5gO1xuICB9IGVsc2UgaWYgKHNlYyA+IG1heEludGVydmFsKSB7XG4gICAgaW50ZXJ2YWwgPSBtYXhJbnRlcnZhbDtcbiAgICBtZXNzYWdlID0gYEludGVydmFsIG9mICR7c2VjfSBzZWNvbmRzIGlzIHRvbyBoaWdoLiBTZXR0aW5nIHRvIG1heCBhbGxvd2VkIGludGVydmFsIG9mICR7bWF4SW50ZXJ2YWx9IHNlY29uZChzKS5gO1xuICB9IGVsc2Uge1xuICAgIGludGVydmFsID0gc2VjO1xuICAgIG1lc3NhZ2UgPSBgSW50ZXJ2YWwgaGFzIGJlZW4gc2V0IHRvICR7c2VjfSBzZWNvbmQocykuYFxuICB9XG5cbiAgcmV0dXJuIFtpbnRlcnZhbCwgbWVzc2FnZV07XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9ICgpID0+IHtcblxuICBjb25zdCAkaW50ZXJ2YWwgPSAkKCcjaW50ZXJ2YWwnKTtcbiAgJGludGVydmFsLnZhbChzdGFydEludGVydmFsKTtcbiAgJGludGVydmFsLmF0dHIoe1xuICAgIG1heDogbWF4SW50ZXJ2YWwsXG4gICAgbWluOiBtaW5JbnRlcnZhbCxcbiAgICBzdGVwOiBzdGVwSW50ZXJ2YWxcbiAgfSk7XG5cbiAgJCgnI2ludGVydmFsJykub24oJ2NoYW5nZScsIGZ1bmN0aW9uKCkge1xuICAgIGNvbnN0IHRyYWNlck1hbmFnZXIgPSBhcHAuZ2V0VHJhY2VyTWFuYWdlcigpO1xuICAgIGNvbnN0IFtzZWNvbmRzLCBtZXNzYWdlXSA9IG5vcm1hbGl6ZShwYXJzZUZsb2F0KCQodGhpcykudmFsKCkpKTtcblxuICAgICQodGhpcykudmFsKHNlY29uZHMpO1xuICAgIHRyYWNlck1hbmFnZXIuaW50ZXJ2YWwgPSBzZWNvbmRzICogMTAwMDtcbiAgICBUb2FzdC5zaG93SW5mb1RvYXN0KG1lc3NhZ2UpO1xuICB9KTtcbn07IiwiY29uc3QgYXBwID0gcmVxdWlyZSgnLi4vLi4vYXBwJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gKCkgPT4ge1xuXG4gIGNvbnN0ICRtb2R1bGVfY29udGFpbmVyID0gJCgnLm1vZHVsZV9jb250YWluZXInKTtcblxuICAkbW9kdWxlX2NvbnRhaW5lci5vbignbW91c2Vkb3duJywgJy5tb2R1bGVfd3JhcHBlcicsIGZ1bmN0aW9uKGUpIHtcbiAgICBhcHAuZ2V0VHJhY2VyTWFuYWdlcigpLmZpbmRPd25lcih0aGlzKS5tb3VzZWRvd24oZSk7XG4gIH0pO1xuXG4gICRtb2R1bGVfY29udGFpbmVyLm9uKCdtb3VzZW1vdmUnLCAnLm1vZHVsZV93cmFwcGVyJywgZnVuY3Rpb24oZSkge1xuICAgIGFwcC5nZXRUcmFjZXJNYW5hZ2VyKCkuZmluZE93bmVyKHRoaXMpLm1vdXNlbW92ZShlKTtcbiAgfSk7XG5cbiAgJG1vZHVsZV9jb250YWluZXIub24oJ0RPTU1vdXNlU2Nyb2xsIG1vdXNld2hlZWwnLCAnLm1vZHVsZV93cmFwcGVyJywgZnVuY3Rpb24oZSkge1xuICAgIGFwcC5nZXRUcmFjZXJNYW5hZ2VyKCkuZmluZE93bmVyKHRoaXMpLm1vdXNld2hlZWwoZSk7XG4gIH0pO1xufSIsIm1vZHVsZS5leHBvcnRzID0gKCkgPT4ge1xuICAkKCcjcG93ZXJlZC1ieScpLmNsaWNrKGZ1bmN0aW9uKCkge1xuICAgICQoJyNwb3dlcmVkLWJ5LWxpc3QgYnV0dG9uJykudG9nZ2xlQ2xhc3MoJ2NvbGxhcHNlJyk7XG4gIH0pO1xufTsiLCJjb25zdCBhcHAgPSByZXF1aXJlKCcuLi8uLi9hcHAnKTtcbmNvbnN0IFNlcnZlciA9IHJlcXVpcmUoJy4uLy4uL3NlcnZlcicpO1xuY29uc3Qgc2hvd0FsZ29yaXRobSA9IHJlcXVpcmUoJy4uL3Nob3dfYWxnb3JpdGhtJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gKCkgPT4ge1xuICAkKCcjc2NyYXRjaC1wYXBlcicpLmNsaWNrKGZ1bmN0aW9uKCkge1xuICAgIGNvbnN0IGNhdGVnb3J5ID0gJ3NjcmF0Y2gnO1xuICAgIGNvbnN0IGFsZ29yaXRobSA9IGFwcC5nZXRMb2FkZWRTY3JhdGNoKCk7XG4gICAgU2VydmVyLmxvYWRBbGdvcml0aG0oY2F0ZWdvcnksIGFsZ29yaXRobSkudGhlbigoZGF0YSkgPT4ge1xuICAgICAgc2hvd0FsZ29yaXRobShjYXRlZ29yeSwgYWxnb3JpdGhtLCBkYXRhKTtcbiAgICB9KTtcbiAgfSk7XG59OyIsImNvbnN0IGFwcCA9IHJlcXVpcmUoJy4uLy4uL2FwcCcpO1xuXG5sZXQgc2lkZW1lbnVfcGVyY2VudDtcblxubW9kdWxlLmV4cG9ydHMgPSAoKSA9PiB7XG4gICQoJyNuYXZpZ2F0aW9uJykuY2xpY2soKCkgPT4ge1xuICAgIGNvbnN0ICRzaWRlbWVudSA9ICQoJy5zaWRlbWVudScpO1xuICAgIGNvbnN0ICR3b3Jrc3BhY2UgPSAkKCcud29ya3NwYWNlJyk7XG5cbiAgICAkc2lkZW1lbnUudG9nZ2xlQ2xhc3MoJ2FjdGl2ZScpO1xuICAgICQoJy5uYXYtZHJvcGRvd24nKS50b2dnbGVDbGFzcygnZmEtY2FyZXQtZG93biBmYS1jYXJldC11cCcpO1xuXG4gICAgaWYgKCRzaWRlbWVudS5oYXNDbGFzcygnYWN0aXZlJykpIHtcbiAgICAgICRzaWRlbWVudS5jc3MoJ3JpZ2h0JywgKDEwMCAtIHNpZGVtZW51X3BlcmNlbnQpICsgJyUnKTtcbiAgICAgICR3b3Jrc3BhY2UuY3NzKCdsZWZ0Jywgc2lkZW1lbnVfcGVyY2VudCArICclJyk7XG5cbiAgICB9IGVsc2Uge1xuICAgICAgc2lkZW1lbnVfcGVyY2VudCA9ICR3b3Jrc3BhY2UucG9zaXRpb24oKS5sZWZ0IC8gJCgnYm9keScpLndpZHRoKCkgKiAxMDA7XG4gICAgICAkc2lkZW1lbnUuY3NzKCdyaWdodCcsIDApO1xuICAgICAgJHdvcmtzcGFjZS5jc3MoJ2xlZnQnLCAwKTtcbiAgICB9XG5cbiAgICBhcHAuZ2V0VHJhY2VyTWFuYWdlcigpLnJlc2l6ZSgpO1xuICB9KTtcbn0iLCJjb25zdCBhcHAgPSByZXF1aXJlKCcuLi8uLi9hcHAnKTtcbmNvbnN0IFNlcnZlciA9IHJlcXVpcmUoJy4uLy4uL3NlcnZlcicpO1xuY29uc3QgVG9hc3QgPSByZXF1aXJlKCcuLi90b2FzdCcpO1xuY29uc3QgVG9wTWVudSA9IHJlcXVpcmUoJy4uL3RvcF9tZW51Jyk7XG5cbm1vZHVsZS5leHBvcnRzID0gKCkgPT4ge1xuXG4gIC8vIHNoYXJlZFxuICAkKCcjc2hhcmVkJykubW91c2V1cChmdW5jdGlvbigpIHtcbiAgICAkKHRoaXMpLnNlbGVjdCgpO1xuICB9KTtcblxuICAkKCcjYnRuX3NoYXJlJykuY2xpY2soZnVuY3Rpb24oKSB7XG5cbiAgICBjb25zdCAkaWNvbiA9ICQodGhpcykuZmluZCgnLmZhLXNoYXJlJyk7XG4gICAgJGljb24uYWRkQ2xhc3MoJ2ZhLXNwaW4gZmEtc3Bpbi1mYXN0ZXInKTtcblxuICAgIFNlcnZlci5zaGFyZVNjcmF0Y2hQYXBlcigpLnRoZW4oKHVybCkgPT4ge1xuICAgICAgJGljb24ucmVtb3ZlQ2xhc3MoJ2ZhLXNwaW4gZmEtc3Bpbi1mYXN0ZXInKTtcbiAgICAgICQoJyNzaGFyZWQnKS5yZW1vdmVDbGFzcygnY29sbGFwc2UnKTtcbiAgICAgICQoJyNzaGFyZWQnKS52YWwodXJsKTtcbiAgICAgIFRvYXN0LnNob3dJbmZvVG9hc3QoJ1NoYXJlYWJsZSBsaW5rIGlzIGNyZWF0ZWQuJyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIC8vIGNvbnRyb2xcblxuICBjb25zdCAkYnRuUnVuICAgPSAkKCcjYnRuX3J1bicpO1xuICBjb25zdCAkYnRuVHJhY2UgPSAkKCcjYnRuX3RyYWNlJyk7XG4gIGNvbnN0ICRidG5QYXVzZSA9ICQoJyNidG5fcGF1c2UnKTtcbiAgY29uc3QgJGJ0blByZXYgID0gJCgnI2J0bl9wcmV2Jyk7XG4gIGNvbnN0ICRidG5OZXh0ICA9ICQoJyNidG5fbmV4dCcpO1xuICBjb25zdCAkYnRuRGVzYyAgPSAkKCcjYnRuX2Rlc2MnKTtcblxuICAvLyBpbml0aWFsbHksIGNvbnRyb2wgYnV0dG9ucyBhcmUgZGlzYWJsZWRcbiAgVG9wTWVudS5kaXNhYmxlRmxvd0NvbnRyb2woKTtcblxuICAkYnRuUnVuLmNsaWNrKCgpID0+IHtcbiAgICAkYnRuVHJhY2UuY2xpY2soKTtcbiAgICAkYnRuUGF1c2UucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpO1xuICAgICRidG5SdW4uYWRkQ2xhc3MoJ2FjdGl2ZScpO1xuICAgIFRvcE1lbnUuZW5hYmxlRmxvd0NvbnRyb2woKTtcbiAgICB2YXIgZXJyID0gYXBwLmdldEVkaXRvcigpLmV4ZWN1dGUoKTtcbiAgICBpZiAoZXJyKSB7XG4gICAgICBjb25zb2xlLmVycm9yKGVycik7XG4gICAgICBUb2FzdC5zaG93RXJyb3JUb2FzdChlcnIpO1xuICAgIH1cbiAgfSk7XG5cbiAgJGJ0blBhdXNlLmNsaWNrKCgpID0+IHtcbiAgICAkYnRuUnVuLnRvZ2dsZUNsYXNzKCdhY3RpdmUnKTtcbiAgICAkYnRuUGF1c2UudG9nZ2xlQ2xhc3MoJ2FjdGl2ZScpO1xuICAgIGlmIChhcHAuZ2V0VHJhY2VyTWFuYWdlcigpLmlzUGF1c2UoKSkge1xuICAgICAgYXBwLmdldFRyYWNlck1hbmFnZXIoKS5yZXN1bWVTdGVwKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFwcC5nZXRUcmFjZXJNYW5hZ2VyKCkucGF1c2VTdGVwKCk7XG4gICAgfVxuICB9KTtcblxuICAkYnRuUHJldi5jbGljaygoKSA9PiB7XG4gICAgJGJ0blJ1bi5yZW1vdmVDbGFzcygnYWN0aXZlJyk7XG4gICAgJGJ0blBhdXNlLmFkZENsYXNzKCdhY3RpdmUnKTtcbiAgICBhcHAuZ2V0VHJhY2VyTWFuYWdlcigpLnBhdXNlU3RlcCgpO1xuICAgIGFwcC5nZXRUcmFjZXJNYW5hZ2VyKCkucHJldlN0ZXAoKTtcbiAgfSk7XG5cbiAgJGJ0bk5leHQuY2xpY2soKCkgPT4ge1xuICAgICRidG5SdW4ucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpO1xuICAgICRidG5QYXVzZS5hZGRDbGFzcygnYWN0aXZlJyk7XG4gICAgYXBwLmdldFRyYWNlck1hbmFnZXIoKS5wYXVzZVN0ZXAoKTtcbiAgICBhcHAuZ2V0VHJhY2VyTWFuYWdlcigpLm5leHRTdGVwKCk7XG4gIH0pO1xuXG4gIC8vIGRlc2NyaXB0aW9uICYgdHJhY2VcblxuICAkYnRuRGVzYy5jbGljaygoKSA9PiB7XG4gICAgJCgnLnRhYl9jb250YWluZXIgPiAudGFiJykucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpO1xuICAgICQoJyN0YWJfZGVzYycpLmFkZENsYXNzKCdhY3RpdmUnKTtcbiAgICAkKCcudGFiX2JhciA+IGJ1dHRvbicpLnJlbW92ZUNsYXNzKCdhY3RpdmUnKTtcbiAgICAkYnRuRGVzYy5hZGRDbGFzcygnYWN0aXZlJyk7XG4gIH0pO1xuXG4gICRidG5UcmFjZS5jbGljaygoKSA9PiB7XG4gICAgJCgnLnRhYl9jb250YWluZXIgPiAudGFiJykucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpO1xuICAgICQoJyN0YWJfbW9kdWxlJykuYWRkQ2xhc3MoJ2FjdGl2ZScpO1xuICAgICQoJy50YWJfYmFyID4gYnV0dG9uJykucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpO1xuICAgICRidG5UcmFjZS5hZGRDbGFzcygnYWN0aXZlJyk7XG4gIH0pO1xuXG59O1xuIiwiY29uc3QgYXBwID0gcmVxdWlyZSgnLi4vLi4vYXBwJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oKSB7XG4gICQod2luZG93KS5yZXNpemUoZnVuY3Rpb24oKSB7XG4gICAgYXBwLmdldFRyYWNlck1hbmFnZXIoKS5yZXNpemUoKTtcbiAgfSk7XG59OyIsIid1c2Ugc3RyaWN0JztcblxuY29uc3QgYXBwID0gcmVxdWlyZSgnLi4vYXBwJyk7XG5cbmNvbnN0IHtcbiAgaXNTY3JhdGNoUGFwZXJcbn0gPSByZXF1aXJlKCcuLi91dGlscycpO1xuXG5jb25zdCBzaG93RGVzY3JpcHRpb24gPSByZXF1aXJlKCcuL3Nob3dfZGVzY3JpcHRpb24nKTtcbmNvbnN0IGFkZEZpbGVzID0gcmVxdWlyZSgnLi9hZGRfZmlsZXMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSAoY2F0ZWdvcnksIGFsZ29yaXRobSwgZGF0YSwgcmVxdWVzdGVkRmlsZSkgPT4ge1xuICBsZXQgJG1lbnU7XG4gIGxldCBjYXRlZ29yeV9uYW1lO1xuICBsZXQgYWxnb3JpdGhtX25hbWU7XG5cbiAgaWYgKGlzU2NyYXRjaFBhcGVyKGNhdGVnb3J5KSkge1xuICAgICRtZW51ID0gJCgnI3NjcmF0Y2gtcGFwZXInKTtcbiAgICBjYXRlZ29yeV9uYW1lID0gJ1NjcmF0Y2ggUGFwZXInO1xuICAgIGFsZ29yaXRobV9uYW1lID0gYWxnb3JpdGhtID8gJ1NoYXJlZCcgOiAnVGVtcG9yYXJ5JztcbiAgfSBlbHNlIHtcbiAgICAkbWVudSA9ICQoYFtkYXRhLWNhdGVnb3J5PVwiJHtjYXRlZ29yeX1cIl1bZGF0YS1hbGdvcml0aG09XCIke2FsZ29yaXRobX1cIl1gKTtcbiAgICBjb25zdCBjYXRlZ29yeU9iaiA9IGFwcC5nZXRDYXRlZ29yeShjYXRlZ29yeSk7XG4gICAgY2F0ZWdvcnlfbmFtZSA9IGNhdGVnb3J5T2JqLm5hbWU7XG4gICAgYWxnb3JpdGhtX25hbWUgPSBjYXRlZ29yeU9iai5saXN0W2FsZ29yaXRobV07XG4gIH1cblxuICAkKCcuc2lkZW1lbnUgYnV0dG9uJykucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpO1xuICAkbWVudS5hZGRDbGFzcygnYWN0aXZlJyk7XG5cbiAgJCgnI2NhdGVnb3J5JykuaHRtbChjYXRlZ29yeV9uYW1lKTtcbiAgJCgnI2FsZ29yaXRobScpLmh0bWwoYWxnb3JpdGhtX25hbWUpO1xuICAkKCcjdGFiX2Rlc2MgPiAud3JhcHBlcicpLmVtcHR5KCk7XG4gICQoJy5maWxlc19iYXIgPiAud3JhcHBlcicpLmVtcHR5KCk7XG4gICQoJyNleHBsYW5hdGlvbicpLmh0bWwoJycpO1xuXG4gIGFwcC5zZXRMYXN0RmlsZVVzZWQobnVsbCk7XG4gIGFwcC5nZXRFZGl0b3IoKS5jbGVhckNvbnRlbnQoKTtcblxuICBjb25zdCB7XG4gICAgZmlsZXNcbiAgfSA9IGRhdGE7XG5cbiAgZGVsZXRlIGRhdGEuZmlsZXM7XG5cbiAgc2hvd0Rlc2NyaXB0aW9uKGRhdGEpO1xuICBhZGRGaWxlcyhjYXRlZ29yeSwgYWxnb3JpdGhtLCBmaWxlcywgcmVxdWVzdGVkRmlsZSk7XG59OyIsIid1c2Ugc3RyaWN0JztcblxuY29uc3Qge1xuICBpc0FycmF5XG59ID0gQXJyYXk7XG5cbmNvbnN0IHtcbiAgZWFjaFxufSA9ICQ7XG5cbm1vZHVsZS5leHBvcnRzID0gKGRhdGEpID0+IHtcbiAgY29uc3QgJGNvbnRhaW5lciA9ICQoJyN0YWJfZGVzYyA+IC53cmFwcGVyJyk7XG4gICRjb250YWluZXIuZW1wdHkoKTtcblxuICBlYWNoKGRhdGEsIChrZXksIHZhbHVlKSA9PiB7XG5cbiAgICBpZiAoa2V5KSB7XG4gICAgICAkY29udGFpbmVyLmFwcGVuZCgkKCc8aDM+JykuaHRtbChrZXkpKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgICAgJGNvbnRhaW5lci5hcHBlbmQoJCgnPHA+JykuaHRtbCh2YWx1ZSkpO1xuXG4gICAgfSBlbHNlIGlmIChpc0FycmF5KHZhbHVlKSkge1xuXG4gICAgICBjb25zdCAkdWwgPSAkKCc8dWwgY2xhc3M9XCJhcHBsaWNhdGlvbnNcIj4nKTtcbiAgICAgICRjb250YWluZXIuYXBwZW5kKCR1bCk7XG5cbiAgICAgIHZhbHVlLmZvckVhY2goKGxpKSA9PiB7XG4gICAgICAgICR1bC5hcHBlbmQoJCgnPGxpPicpLmh0bWwobGkpKTtcbiAgICAgIH0pO1xuXG4gICAgfSBlbHNlIGlmICh0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnKSB7XG5cbiAgICAgIGNvbnN0ICR1bCA9ICQoJzx1bCBjbGFzcz1cImNvbXBsZXhpdGllc1wiPicpO1xuICAgICAgJGNvbnRhaW5lci5hcHBlbmQoJHVsKTtcblxuICAgICAgZWFjaCh2YWx1ZSwgKHByb3ApID0+IHtcbiAgICAgICAgY29uc3QgJHdyYXBwZXIgPSAkKCc8ZGl2IGNsYXNzPVwiY29tcGxleGl0eVwiPicpO1xuICAgICAgICBjb25zdCAkdHlwZSA9ICQoJzxzcGFuIGNsYXNzPVwiY29tcGxleGl0eS10eXBlXCI+JykuaHRtbChgJHtwcm9wfTogYCk7XG4gICAgICAgIGNvbnN0ICR2YWx1ZSA9ICQoJzxzcGFuIGNsYXNzPVwiY29tcGxleGl0eS12YWx1ZVwiPicpLmh0bWwoYCR7dmFsdWVbcHJvcF19YCk7XG5cbiAgICAgICAgJHdyYXBwZXIuYXBwZW5kKCR0eXBlKS5hcHBlbmQoJHZhbHVlKTtcblxuICAgICAgICAkdWwuYXBwZW5kKCQoJzxsaT4nKS5hcHBlbmQoJHdyYXBwZXIpKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfSk7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vLyBjbGljayB0aGUgZmlyc3QgYWxnb3JpdGhtIGluIHRoZSBmaXJzdCBjYXRlZ29yeVxubW9kdWxlLmV4cG9ydHMgPSAoKSA9PiB7XG4gICQoJyNsaXN0IGJ1dHRvbi5jYXRlZ29yeScpLmZpcnN0KCkuY2xpY2soKTtcbiAgJCgnI2xpc3QgYnV0dG9uLmNhdGVnb3J5ICsgLmluZGVudCcpLmZpcnN0KCkuY2xpY2soKTtcbn07IiwiJ3VzZSBzdHJpY3QnO1xuXG5jb25zdCBTZXJ2ZXIgPSByZXF1aXJlKCcuLi9zZXJ2ZXInKTtcbmNvbnN0IHNob3dBbGdvcml0aG0gPSByZXF1aXJlKCcuL3Nob3dfYWxnb3JpdGhtJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gKGNhdGVnb3J5LCBhbGdvcml0aG0sIGZpbGUpID0+IHtcbiAgJChgLmNhdGVnb3J5W2RhdGEtY2F0ZWdvcnk9XCIke2NhdGVnb3J5fVwiXWApLmNsaWNrKCk7XG4gIFNlcnZlci5sb2FkQWxnb3JpdGhtKGNhdGVnb3J5LCBhbGdvcml0aG0pLnRoZW4oKGRhdGEpID0+IHtcbiAgICBzaG93QWxnb3JpdGhtKGNhdGVnb3J5LCBhbGdvcml0aG0sIGRhdGEsIGZpbGUpO1xuICB9KTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbmNvbnN0IHNob3dUb2FzdCA9IChkYXRhLCB0eXBlKSA9PiB7XG4gIGNvbnN0ICR0b2FzdCA9ICQoYDxkaXYgY2xhc3M9XCJ0b2FzdCAke3R5cGV9XCI+YCkuYXBwZW5kKGRhdGEpO1xuXG4gICQoJy50b2FzdF9jb250YWluZXInKS5hcHBlbmQoJHRvYXN0KTtcbiAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgJHRvYXN0LmZhZGVPdXQoKCkgPT4ge1xuICAgICAgJHRvYXN0LnJlbW92ZSgpO1xuICAgIH0pO1xuICB9LCAzMDAwKTtcbn07XG5cbmNvbnN0IHNob3dFcnJvclRvYXN0ID0gKGVycikgPT4ge1xuICBzaG93VG9hc3QoZXJyLCAnZXJyb3InKTtcbn07XG5cbmNvbnN0IHNob3dJbmZvVG9hc3QgPSAoZXJyKSA9PiB7XG4gIHNob3dUb2FzdChlcnIsICdpbmZvJyk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgc2hvd0Vycm9yVG9hc3QsXG4gIHNob3dJbmZvVG9hc3Rcbn07IiwiJ3VzZSBzdHJpY3QnO1xuXG5jb25zdCBmbG93Q29udHJvbEJ0bnMgPSBbICQoJyNidG5fcGF1c2UnKSwgJCgnI2J0bl9wcmV2JyksICQoJyNidG5fbmV4dCcpIF07XG5jb25zdCBzZXRGbG93Q29udHJvbFN0YXRlID0gKGlzRGlzYWJsZWQpID0+IHtcbiAgZmxvd0NvbnRyb2xCdG5zLmZvckVhY2goJGJ0biA9PiAkYnRuLmF0dHIoJ2Rpc2FibGVkJywgaXNEaXNhYmxlZCkpO1xufTtcblxuY29uc3QgZW5hYmxlRmxvd0NvbnRyb2wgPSAoKSA9PiB7XG4gIHNldEZsb3dDb250cm9sU3RhdGUoZmFsc2UpO1xufTtcblxuY29uc3QgZGlzYWJsZUZsb3dDb250cm9sID0gKCkgPT4ge1xuICBzZXRGbG93Q29udHJvbFN0YXRlKHRydWUpO1xufTtcblxuY29uc3QgcmVzZXRUb3BNZW51QnV0dG9ucyA9ICgpID0+IHtcbiAgJCgnLnRvcC1tZW51LWJ1dHRvbnMgYnV0dG9uJykucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpO1xuICBkaXNhYmxlRmxvd0NvbnRyb2woKTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBlbmFibGVGbG93Q29udHJvbCxcbiAgZGlzYWJsZUZsb3dDb250cm9sLFxuICByZXNldFRvcE1lbnVCdXR0b25zXG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGlkKSB7XG4gIGNvbnN0IGVkaXRvciA9IGFjZS5lZGl0KGlkKTtcblxuICBlZGl0b3Iuc2V0T3B0aW9ucyh7XG4gICAgZW5hYmxlQmFzaWNBdXRvY29tcGxldGlvbjogdHJ1ZSxcbiAgICBlbmFibGVTbmlwcGV0czogdHJ1ZSxcbiAgICBlbmFibGVMaXZlQXV0b2NvbXBsZXRpb246IHRydWVcbiAgfSk7XG5cbiAgZWRpdG9yLnNldFRoZW1lKCdhY2UvdGhlbWUvdG9tb3Jyb3dfbmlnaHRfZWlnaHRpZXMnKTtcbiAgZWRpdG9yLnNlc3Npb24uc2V0TW9kZSgnYWNlL21vZGUvamF2YXNjcmlwdCcpO1xuICBlZGl0b3IuJGJsb2NrU2Nyb2xsaW5nID0gSW5maW5pdHk7XG5cbiAgcmV0dXJuIGVkaXRvcjtcbn07IiwiJ3VzZSBzdHJpY3QnO1xuXG5jb25zdCBleGVjdXRlID0gKHRyYWNlck1hbmFnZXIsIGNvZGUpID0+IHtcbiAgLy8gYWxsIG1vZHVsZXMgYXZhaWxhYmxlIHRvIGV2YWwgYXJlIG9idGFpbmVkIGZyb20gd2luZG93XG4gIHRyeSB7XG4gICAgdHJhY2VyTWFuYWdlci5kZWFsbG9jYXRlQWxsKCk7XG4gICAgZXZhbChjb2RlKTtcbiAgICB0cmFjZXJNYW5hZ2VyLnZpc3VhbGl6ZSgpO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICByZXR1cm4gZXJyO1xuICB9IGZpbmFsbHkge1xuICAgIHRyYWNlck1hbmFnZXIucmVtb3ZlVW5hbGxvY2F0ZWQoKTtcbiAgfVxufTtcblxuY29uc3QgZXhlY3V0ZURhdGEgPSAodHJhY2VyTWFuYWdlciwgYWxnb0RhdGEpID0+IHtcbiAgcmV0dXJuIGV4ZWN1dGUodHJhY2VyTWFuYWdlciwgYWxnb0RhdGEpO1xufTtcblxuY29uc3QgZXhlY3V0ZURhdGFBbmRDb2RlID0gKHRyYWNlck1hbmFnZXIsIGFsZ29EYXRhLCBhbGdvQ29kZSkgPT4ge1xuICByZXR1cm4gZXhlY3V0ZSh0cmFjZXJNYW5hZ2VyLCBgJHthbGdvRGF0YX07JHthbGdvQ29kZX1gKTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBleGVjdXRlRGF0YSxcbiAgZXhlY3V0ZURhdGFBbmRDb2RlXG59OyIsIid1c2Ugc3RyaWN0JztcblxuY29uc3QgYXBwID0gcmVxdWlyZSgnLi4vYXBwJyk7XG5jb25zdCBjcmVhdGVFZGl0b3IgPSByZXF1aXJlKCcuL2NyZWF0ZScpO1xuY29uc3QgRXhlY3V0b3IgPSByZXF1aXJlKCcuL2V4ZWN1dG9yJyk7XG5cbmZ1bmN0aW9uIEVkaXRvcih0cmFjZXJNYW5hZ2VyKSB7XG4gIGlmICghdHJhY2VyTWFuYWdlcikge1xuICAgIHRocm93ICdDYW5ub3QgY3JlYXRlIEVkaXRvci4gTWlzc2luZyB0aGUgdHJhY2VyTWFuYWdlcic7XG4gIH1cblxuICBhY2UucmVxdWlyZSgnYWNlL2V4dC9sYW5ndWFnZV90b29scycpO1xuXG4gIHRoaXMuZGF0YUVkaXRvciA9IGNyZWF0ZUVkaXRvcignZGF0YScpO1xuICB0aGlzLmNvZGVFZGl0b3IgPSBjcmVhdGVFZGl0b3IoJ2NvZGUnKTtcblxuICAvLyBTZXR0aW5nIGRhdGFcblxuICB0aGlzLnNldERhdGEgPSAoZGF0YSkgPT4ge1xuICAgIHRoaXMuZGF0YUVkaXRvci5zZXRWYWx1ZShkYXRhLCAtMSk7XG4gIH07XG5cbiAgdGhpcy5zZXRDb2RlID0gKGNvZGUpID0+IHtcbiAgICB0aGlzLmNvZGVFZGl0b3Iuc2V0VmFsdWUoY29kZSwgLTEpO1xuICB9O1xuXG4gIHRoaXMuc2V0Q29udGVudCA9ICgoe1xuICAgIGRhdGEsXG4gICAgY29kZVxuICB9KSA9PiB7XG4gICAgdGhpcy5zZXREYXRhKGRhdGEpO1xuICAgIHRoaXMuc2V0Q29kZShjb2RlKTtcbiAgfSk7XG5cbiAgLy8gQ2xlYXJpbmcgZGF0YVxuXG4gIHRoaXMuY2xlYXJEYXRhID0gKCkgPT4ge1xuICAgIHRoaXMuZGF0YUVkaXRvci5zZXRWYWx1ZSgnJyk7XG4gIH07XG5cbiAgdGhpcy5jbGVhckNvZGUgPSAoKSA9PiB7XG4gICAgdGhpcy5jb2RlRWRpdG9yLnNldFZhbHVlKCcnKTtcbiAgfTtcblxuICB0aGlzLmNsZWFyQ29udGVudCA9ICgpID0+IHtcbiAgICB0aGlzLmNsZWFyRGF0YSgpO1xuICAgIHRoaXMuY2xlYXJDb2RlKCk7XG4gIH07XG5cbiAgdGhpcy5leGVjdXRlID0gKCkgPT4ge1xuICAgIGNvbnN0IGRhdGEgPSB0aGlzLmRhdGFFZGl0b3IuZ2V0VmFsdWUoKTtcbiAgICBjb25zdCBjb2RlID0gdGhpcy5jb2RlRWRpdG9yLmdldFZhbHVlKCk7XG4gICAgcmV0dXJuIEV4ZWN1dG9yLmV4ZWN1dGVEYXRhQW5kQ29kZSh0cmFjZXJNYW5hZ2VyLCBkYXRhLCBjb2RlKTtcbiAgfTtcblxuICAvLyBsaXN0ZW5lcnNcblxuICB0aGlzLmRhdGFFZGl0b3Iub24oJ2NoYW5nZScsICgpID0+IHtcbiAgICBjb25zdCBkYXRhID0gdGhpcy5kYXRhRWRpdG9yLmdldFZhbHVlKCk7XG4gICAgY29uc3QgbGFzdEZpbGVVc2VkID0gYXBwLmdldExhc3RGaWxlVXNlZCgpO1xuICAgIGlmIChsYXN0RmlsZVVzZWQpIHtcbiAgICAgIGFwcC51cGRhdGVDYWNoZWRGaWxlKGxhc3RGaWxlVXNlZCwge1xuICAgICAgICBkYXRhXG4gICAgICB9KTtcbiAgICB9XG4gICAgRXhlY3V0b3IuZXhlY3V0ZURhdGEodHJhY2VyTWFuYWdlciwgZGF0YSk7XG4gIH0pO1xuXG4gIHRoaXMuY29kZUVkaXRvci5vbignY2hhbmdlJywgKCkgPT4ge1xuICAgIGNvbnN0IGNvZGUgPSB0aGlzLmNvZGVFZGl0b3IuZ2V0VmFsdWUoKTtcbiAgICBjb25zdCBsYXN0RmlsZVVzZWQgPSBhcHAuZ2V0TGFzdEZpbGVVc2VkKCk7XG4gICAgaWYgKGxhc3RGaWxlVXNlZCkge1xuICAgICAgYXBwLnVwZGF0ZUNhY2hlZEZpbGUobGFzdEZpbGVVc2VkLCB7XG4gICAgICAgIGNvZGVcbiAgICAgIH0pO1xuICAgIH1cbiAgfSk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IEVkaXRvcjsiLCIndXNlIHN0cmljdCc7XG5cbmNvbnN0IFJTVlAgPSByZXF1aXJlKCdyc3ZwJyk7XG5jb25zdCBhcHAgPSByZXF1aXJlKCcuL2FwcCcpO1xuY29uc3QgQXBwQ29uc3RydWN0b3IgPSByZXF1aXJlKCcuL2FwcC9jb25zdHJ1Y3RvcicpO1xuY29uc3QgRE9NID0gcmVxdWlyZSgnLi9kb20nKTtcbmNvbnN0IFNlcnZlciA9IHJlcXVpcmUoJy4vc2VydmVyJyk7XG5cbmNvbnN0IG1vZHVsZXMgPSByZXF1aXJlKCcuL21vZHVsZScpO1xuXG5jb25zdCB7XG4gIGV4dGVuZFxufSA9ICQ7XG5cbiQuYWpheFNldHVwKHtcbiAgY2FjaGU6IGZhbHNlLFxuICBkYXRhVHlwZTogJ3RleHQnXG59KTtcblxuY29uc3Qge1xuICBpc1NjcmF0Y2hQYXBlclxufSA9IHJlcXVpcmUoJy4vdXRpbHMnKTtcblxuY29uc3Qge1xuICBnZXRQYXRoXG59ID0gcmVxdWlyZSgnLi9zZXJ2ZXIvaGVscGVycycpO1xuXG4vLyBzZXQgZ2xvYmFsIHByb21pc2UgZXJyb3IgaGFuZGxlclxuUlNWUC5vbignZXJyb3InLCBmdW5jdGlvbiAocmVhc29uKSB7XG4gIGNvbnNvbGUuYXNzZXJ0KGZhbHNlLCByZWFzb24pO1xufSk7XG5cbiQoKCkgPT4ge1xuXG4gIC8vIGluaXRpYWxpemUgdGhlIGFwcGxpY2F0aW9uIGFuZCBhdHRhY2ggaW4gdG8gdGhlIGluc3RhbmNlIG1vZHVsZVxuICBjb25zdCBhcHBDb25zdHJ1Y3RvciA9IG5ldyBBcHBDb25zdHJ1Y3RvcigpO1xuICBleHRlbmQodHJ1ZSwgYXBwLCBhcHBDb25zdHJ1Y3Rvcik7XG5cbiAgLy8gbG9hZCBtb2R1bGVzIHRvIHRoZSBnbG9iYWwgc2NvcGUgc28gdGhleSBjYW4gYmUgZXZhbGVkXG4gIGV4dGVuZCh0cnVlLCB3aW5kb3csIG1vZHVsZXMpO1xuXG4gIFNlcnZlci5sb2FkQ2F0ZWdvcmllcygpLnRoZW4oKGRhdGEpID0+IHtcbiAgICBhcHAuc2V0Q2F0ZWdvcmllcyhkYXRhKTtcbiAgICBET00uYWRkQ2F0ZWdvcmllcygpO1xuXG4gICAgLy8gZGV0ZXJtaW5lIGlmIHRoZSBhcHAgaXMgbG9hZGluZyBhIHByZS1leGlzdGluZyBzY3JhdGNoLXBhZFxuICAgIC8vIG9yIHRoZSBob21lIHBhZ2VcbiAgICBjb25zdCB7XG4gICAgICBjYXRlZ29yeSxcbiAgICAgIGFsZ29yaXRobSxcbiAgICAgIGZpbGVcbiAgICB9ID0gZ2V0UGF0aCgpO1xuICAgIGlmIChpc1NjcmF0Y2hQYXBlcihjYXRlZ29yeSkpIHtcbiAgICAgIGlmIChhbGdvcml0aG0pIHtcbiAgICAgICAgU2VydmVyLmxvYWRTY3JhdGNoUGFwZXIoYWxnb3JpdGhtKS50aGVuKCh7Y2F0ZWdvcnksIGFsZ29yaXRobSwgZGF0YX0pID0+IHtcbiAgICAgICAgICBET00uc2hvd0FsZ29yaXRobShjYXRlZ29yeSwgYWxnb3JpdGhtLCBkYXRhKTtcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBTZXJ2ZXIubG9hZEFsZ29yaXRobShjYXRlZ29yeSkudGhlbigoZGF0YSkgPT4ge1xuICAgICAgICAgIERPTS5zaG93QWxnb3JpdGhtKGNhdGVnb3J5LCBudWxsLCBkYXRhKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChjYXRlZ29yeSAmJiBhbGdvcml0aG0pIHtcbiAgICAgIERPTS5zaG93UmVxdWVzdGVkQWxnb3JpdGhtKGNhdGVnb3J5LCBhbGdvcml0aG0sIGZpbGUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBET00uc2hvd0ZpcnN0QWxnb3JpdGhtKCk7XG4gICAgfVxuXG4gIH0pO1xufSk7IiwiY29uc3QgQXJyYXkyRCA9IHJlcXVpcmUoJy4vYXJyYXkyZCcpO1xuXG5jb25zdCByYW5kb20gPSAoTiwgbWluLCBtYXgpID0+IHtcbiAgcmV0dXJuIEFycmF5MkQucmFuZG9tKDEsIE4sIG1pbiwgbWF4KVswXTtcbn07XG5cbmNvbnN0IHJhbmRvbVNvcnRlZCA9IChOLCBtaW4sIG1heCk9PiB7XG4gIHJldHVybiBBcnJheTJELnJhbmRvbVNvcnRlZCgxLCBOLCBtaW4sIG1heClbMF07XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgcmFuZG9tLFxuICByYW5kb21Tb3J0ZWRcbn07XG4iLCJjb25zdCByYW5kb20gPSAoTiwgTSwgbWluLCBtYXgpID0+IHtcbiAgaWYgKCFOKSBOID0gMTA7XG4gIGlmICghTSkgTSA9IDEwO1xuICBpZiAobWluID09PSB1bmRlZmluZWQpIG1pbiA9IDE7XG4gIGlmIChtYXggPT09IHVuZGVmaW5lZCkgbWF4ID0gOTtcbiAgdmFyIEQgPSBbXTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBOOyBpKyspIHtcbiAgICBELnB1c2goW10pO1xuICAgIGZvciAodmFyIGogPSAwOyBqIDwgTTsgaisrKSB7XG4gICAgICBEW2ldLnB1c2goKE1hdGgucmFuZG9tKCkgKiAobWF4IC0gbWluICsgMSkgfCAwKSArIG1pbik7XG4gICAgfVxuICB9XG4gIHJldHVybiBEO1xufTtcblxuY29uc3QgcmFuZG9tU29ydGVkID0gKE4sIE0sIG1pbiwgbWF4KSA9PiB7XG4gIHJldHVybiByYW5kb20oTiwgTSwgbWluLCBtYXgpLm1hcChmdW5jdGlvbiAoYXJyKSB7XG4gICAgcmV0dXJuIGFyci5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgICByZXR1cm4gYSAtIGI7XG4gICAgfSk7XG4gIH0pO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHJhbmRvbSxcbiAgcmFuZG9tU29ydGVkXG59OyIsImNvbnN0IHJhbmRvbSA9IChOLCBtaW4sIG1heCkgPT4ge1xuICBpZiAoIU4pIE4gPSA3O1xuICBpZiAoIW1pbikgbWluID0gMTtcbiAgaWYgKCFtYXgpIG1heCA9IDEwO1xuICB2YXIgQyA9IG5ldyBBcnJheShOKTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBOOyBpKyspIENbaV0gPSBuZXcgQXJyYXkoMik7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgTjsgaSsrKVxuICAgIGZvciAodmFyIGogPSAwOyBqIDwgQ1tpXS5sZW5ndGg7IGorKylcbiAgICAgIENbaV1bal0gPSAoTWF0aC5yYW5kb20oKSAqIChtYXggLSBtaW4gKyAxKSB8IDApICsgbWluO1xuICByZXR1cm4gQztcbn07XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICByYW5kb21cbn07IiwiY29uc3QgcmFuZG9tID0gKE4sIHJhdGlvKSA9PiB7XG4gIGlmICghTikgTiA9IDU7XG4gIGlmICghcmF0aW8pIHJhdGlvID0gLjM7XG4gIHZhciBHID0gbmV3IEFycmF5KE4pO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IE47IGkrKykge1xuICAgIEdbaV0gPSBuZXcgQXJyYXkoTik7XG4gICAgZm9yICh2YXIgaiA9IDA7IGogPCBOOyBqKyspIHtcbiAgICAgIGlmIChpICE9IGopIHtcbiAgICAgICAgR1tpXVtqXSA9IChNYXRoLnJhbmRvbSgpICogKDEgLyByYXRpbykgfCAwKSA9PSAwID8gMSA6IDA7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiBHO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHJhbmRvbVxufTsiLCIndXNlIHN0cmljdCc7XG5cbmNvbnN0IEFycmF5MUQgPSByZXF1aXJlKCcuL2FycmF5MWQnKTtcbmNvbnN0IEFycmF5MkQgPSByZXF1aXJlKCcuL2FycmF5MmQnKTtcbmNvbnN0IENvb3JkaW5hdGVTeXN0ZW0gPSByZXF1aXJlKCcuL2Nvb3JkaW5hdGVfc3lzdGVtJyk7XG5jb25zdCBEaXJlY3RlZEdyYXBoID0gcmVxdWlyZSgnLi9kaXJlY3RlZF9ncmFwaCcpO1xuY29uc3QgVW5kaXJlY3RlZEdyYXBoID0gcmVxdWlyZSgnLi91bmRpcmVjdGVkX2dyYXBoJyk7XG5jb25zdCBXZWlnaHRlZERpcmVjdGVkR3JhcGggPSByZXF1aXJlKCcuL3dlaWdodGVkX2RpcmVjdGVkX2dyYXBoJyk7XG5jb25zdCBXZWlnaHRlZFVuZGlyZWN0ZWRHcmFwaCA9IHJlcXVpcmUoJy4vd2VpZ2h0ZWRfdW5kaXJlY3RlZF9ncmFwaCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgQXJyYXkxRCxcbiAgQXJyYXkyRCxcbiAgQ29vcmRpbmF0ZVN5c3RlbSxcbiAgRGlyZWN0ZWRHcmFwaCxcbiAgVW5kaXJlY3RlZEdyYXBoLFxuICBXZWlnaHRlZERpcmVjdGVkR3JhcGgsXG4gIFdlaWdodGVkVW5kaXJlY3RlZEdyYXBoXG59OyIsImNvbnN0IHJhbmRvbSA9IChOLCByYXRpbykgPT4ge1xuICBpZiAoIU4pIE4gPSA1O1xuICBpZiAoIXJhdGlvKSByYXRpbyA9IC4zO1xuICB2YXIgRyA9IG5ldyBBcnJheShOKTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBOOyBpKyspIEdbaV0gPSBuZXcgQXJyYXkoTik7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgTjsgaSsrKSB7XG4gICAgZm9yICh2YXIgaiA9IDA7IGogPCBOOyBqKyspIHtcbiAgICAgIGlmIChpID4gaikge1xuICAgICAgICBHW2ldW2pdID0gR1tqXVtpXSA9IChNYXRoLnJhbmRvbSgpICogKDEgLyByYXRpbykgfCAwKSA9PSAwID8gMSA6IDA7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiBHO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHJhbmRvbVxufTsiLCJjb25zdCByYW5kb20gPSAoTiwgcmF0aW8sIG1pbiwgbWF4KSA9PiB7XG4gIGlmICghTikgTiA9IDU7XG4gIGlmICghcmF0aW8pIHJhdGlvID0gLjM7XG4gIGlmICghbWluKSBtaW4gPSAxO1xuICBpZiAoIW1heCkgbWF4ID0gNTtcbiAgdmFyIEcgPSBuZXcgQXJyYXkoTik7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgTjsgaSsrKSB7XG4gICAgR1tpXSA9IG5ldyBBcnJheShOKTtcbiAgICBmb3IgKHZhciBqID0gMDsgaiA8IE47IGorKykge1xuICAgICAgaWYgKGkgIT0gaiAmJiAoTWF0aC5yYW5kb20oKSAqICgxIC8gcmF0aW8pIHwgMCkgPT0gMCkge1xuICAgICAgICBHW2ldW2pdID0gKE1hdGgucmFuZG9tKCkgKiAobWF4IC0gbWluICsgMSkgfCAwKSArIG1pbjtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIEc7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgcmFuZG9tXG59OyIsImNvbnN0IHJhbmRvbSA9IChOLCByYXRpbywgbWluLCBtYXgpID0+IHtcbiAgaWYgKCFOKSBOID0gNTtcbiAgaWYgKCFyYXRpbykgcmF0aW8gPSAuMztcbiAgaWYgKCFtaW4pIG1pbiA9IDE7XG4gIGlmICghbWF4KSBtYXggPSA1O1xuICB2YXIgRyA9IG5ldyBBcnJheShOKTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBOOyBpKyspIEdbaV0gPSBuZXcgQXJyYXkoTik7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgTjsgaSsrKSB7XG4gICAgZm9yICh2YXIgaiA9IDA7IGogPCBOOyBqKyspIHtcbiAgICAgIGlmIChpID4gaiAmJiAoTWF0aC5yYW5kb20oKSAqICgxIC8gcmF0aW8pIHwgMCkgPT0gMCkge1xuICAgICAgICBHW2ldW2pdID0gR1tqXVtpXSA9IChNYXRoLnJhbmRvbSgpICogKG1heCAtIG1pbiArIDEpIHwgMCkgKyBtaW47XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiBHO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHJhbmRvbVxufTsiLCIndXNlIHN0cmljdCc7XG5cbnZhciB0cmFjZXJzID0gcmVxdWlyZSgnLi90cmFjZXInKTtcbnZhciBkYXRhcyA9IHJlcXVpcmUoJy4vZGF0YScpO1xuXG5jb25zdCB7XG4gIGV4dGVuZFxufSA9ICQ7XG5cbm1vZHVsZS5leHBvcnRzID0gZXh0ZW5kKHRydWUsIHt9LCB0cmFjZXJzLCBkYXRhcyk7IiwiY29uc3QgQXJyYXkyRFRyYWNlciA9IHJlcXVpcmUoJy4vYXJyYXkyZCcpO1xuXG5jbGFzcyBBcnJheTFEVHJhY2VyIGV4dGVuZHMgQXJyYXkyRFRyYWNlciB7XG4gIHN0YXRpYyBnZXRDbGFzc05hbWUoKSB7XG4gICAgcmV0dXJuICdBcnJheTFEVHJhY2VyJztcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKG5hbWUpIHtcbiAgICBzdXBlcihuYW1lKTtcbiAgfVxuXG4gIF9ub3RpZnkoaWR4LCB2KSB7XG4gICAgc3VwZXIuX25vdGlmeSgwLCBpZHgsIHYpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgX2Rlbm90aWZ5KGlkeCkge1xuICAgIHN1cGVyLl9kZW5vdGlmeSgwLCBpZHgpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgX3NlbGVjdChzLCBlKSB7XG4gICAgaWYgKGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgc3VwZXIuX3NlbGVjdCgwLCBzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc3VwZXIuX3NlbGVjdFJvdygwLCBzLCBlKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBfZGVzZWxlY3QocywgZSkge1xuICAgIGlmIChlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHN1cGVyLl9kZXNlbGVjdCgwLCBzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc3VwZXIuX2Rlc2VsZWN0Um93KDAsIHMsIGUpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHNldERhdGEoRCkge1xuICAgIHJldHVybiBzdXBlci5zZXREYXRhKFtEXSk7XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBBcnJheTFEVHJhY2VyOyIsImNvbnN0IFRyYWNlciA9IHJlcXVpcmUoJy4vdHJhY2VyJyk7XG5cbmNvbnN0IHtcbiAgcmVmaW5lQnlUeXBlXG59ID0gcmVxdWlyZSgnLi4vLi4vdHJhY2VyX21hbmFnZXIvdXRpbC9pbmRleCcpO1xuXG5jbGFzcyBBcnJheTJEVHJhY2VyIGV4dGVuZHMgVHJhY2VyIHtcbiAgc3RhdGljIGdldENsYXNzTmFtZSgpIHtcbiAgICByZXR1cm4gJ0FycmF5MkRUcmFjZXInO1xuICB9XG5cbiAgY29uc3RydWN0b3IobmFtZSkge1xuICAgIHN1cGVyKG5hbWUpO1xuXG4gICAgdGhpcy5jb2xvckNsYXNzID0ge1xuICAgICAgc2VsZWN0ZWQ6ICdzZWxlY3RlZCcsXG4gICAgICBub3RpZmllZDogJ25vdGlmaWVkJ1xuICAgIH07XG5cbiAgICBpZiAodGhpcy5pc05ldykgaW5pdFZpZXcodGhpcyk7XG4gIH1cblxuICBfbm90aWZ5KHgsIHksIHYpIHtcbiAgICB0aGlzLm1hbmFnZXIucHVzaFN0ZXAodGhpcy5jYXBzdWxlLCB7XG4gICAgICB0eXBlOiAnbm90aWZ5JyxcbiAgICAgIHg6IHgsXG4gICAgICB5OiB5LFxuICAgICAgdjogdlxuICAgIH0pO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgX2Rlbm90aWZ5KHgsIHkpIHtcbiAgICB0aGlzLm1hbmFnZXIucHVzaFN0ZXAodGhpcy5jYXBzdWxlLCB7XG4gICAgICB0eXBlOiAnZGVub3RpZnknLFxuICAgICAgeDogeCxcbiAgICAgIHk6IHlcbiAgICB9KTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIF9zZWxlY3Qoc3gsIHN5LCBleCwgZXkpIHtcbiAgICB0aGlzLnB1c2hTZWxlY3RpbmdTdGVwKCdzZWxlY3QnLCBudWxsLCBhcmd1bWVudHMpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgX3NlbGVjdFJvdyh4LCBzeSwgZXkpIHtcbiAgICB0aGlzLnB1c2hTZWxlY3RpbmdTdGVwKCdzZWxlY3QnLCAncm93JywgYXJndW1lbnRzKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIF9zZWxlY3RDb2woeSwgc3gsIGV4KSB7XG4gICAgdGhpcy5wdXNoU2VsZWN0aW5nU3RlcCgnc2VsZWN0JywgJ2NvbCcsIGFyZ3VtZW50cyk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBfZGVzZWxlY3Qoc3gsIHN5LCBleCwgZXkpIHtcbiAgICB0aGlzLnB1c2hTZWxlY3RpbmdTdGVwKCdkZXNlbGVjdCcsIG51bGwsIGFyZ3VtZW50cyk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBfZGVzZWxlY3RSb3coeCwgc3ksIGV5KSB7XG4gICAgdGhpcy5wdXNoU2VsZWN0aW5nU3RlcCgnZGVzZWxlY3QnLCAncm93JywgYXJndW1lbnRzKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIF9kZXNlbGVjdENvbCh5LCBzeCwgZXgpIHtcbiAgICB0aGlzLnB1c2hTZWxlY3RpbmdTdGVwKCdkZXNlbGVjdCcsICdjb2wnLCBhcmd1bWVudHMpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgX3NlcGFyYXRlKHgsIHkpIHtcbiAgICB0aGlzLm1hbmFnZXIucHVzaFN0ZXAodGhpcy5jYXBzdWxlLCB7XG4gICAgICB0eXBlOiAnc2VwYXJhdGUnLFxuICAgICAgeDogeCxcbiAgICAgIHk6IHlcbiAgICB9KTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIF9zZXBhcmF0ZVJvdyh4KSB7XG4gICAgdGhpcy5fc2VwYXJhdGUoeCwgLTEpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgX3NlcGFyYXRlQ29sKHkpIHtcbiAgICB0aGlzLl9zZXBhcmF0ZSgtMSwgeSk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBfZGVzZXBhcmF0ZSh4LCB5KSB7XG4gICAgdGhpcy5tYW5hZ2VyLnB1c2hTdGVwKHRoaXMuY2Fwc3VsZSwge1xuICAgICAgdHlwZTogJ2Rlc2VwYXJhdGUnLFxuICAgICAgeDogeCxcbiAgICAgIHk6IHlcbiAgICB9KTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIF9kZXNlcGFyYXRlUm93KHgpIHtcbiAgICB0aGlzLl9kZXNlcGFyYXRlKHgsIC0xKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIF9kZXNlcGFyYXRlQ29sKHkpIHtcbiAgICB0aGlzLl9kZXNlcGFyYXRlKC0xLCB5KTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHB1c2hTZWxlY3RpbmdTdGVwKCkge1xuICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKTtcbiAgICB2YXIgdHlwZSA9IGFyZ3Muc2hpZnQoKTtcbiAgICB2YXIgbW9kZSA9IGFyZ3Muc2hpZnQoKTtcbiAgICBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJncy5zaGlmdCgpKTtcbiAgICB2YXIgY29vcmQ7XG4gICAgc3dpdGNoIChtb2RlKSB7XG4gICAgICBjYXNlICdyb3cnOlxuICAgICAgICBjb29yZCA9IHtcbiAgICAgICAgICB4OiBhcmdzWzBdLFxuICAgICAgICAgIHN5OiBhcmdzWzFdLFxuICAgICAgICAgIGV5OiBhcmdzWzJdXG4gICAgICAgIH07XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnY29sJzpcbiAgICAgICAgY29vcmQgPSB7XG4gICAgICAgICAgeTogYXJnc1swXSxcbiAgICAgICAgICBzeDogYXJnc1sxXSxcbiAgICAgICAgICBleDogYXJnc1syXVxuICAgICAgICB9O1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGlmIChhcmdzWzJdID09PSB1bmRlZmluZWQgJiYgYXJnc1szXSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgY29vcmQgPSB7XG4gICAgICAgICAgICB4OiBhcmdzWzBdLFxuICAgICAgICAgICAgeTogYXJnc1sxXVxuICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29vcmQgPSB7XG4gICAgICAgICAgICBzeDogYXJnc1swXSxcbiAgICAgICAgICAgIHN5OiBhcmdzWzFdLFxuICAgICAgICAgICAgZXg6IGFyZ3NbMl0sXG4gICAgICAgICAgICBleTogYXJnc1szXVxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICB9XG4gICAgdmFyIHN0ZXAgPSB7XG4gICAgICB0eXBlOiB0eXBlXG4gICAgfTtcbiAgICAkLmV4dGVuZChzdGVwLCBjb29yZCk7XG4gICAgdGhpcy5tYW5hZ2VyLnB1c2hTdGVwKHRoaXMuY2Fwc3VsZSwgc3RlcCk7XG4gIH1cblxuICBwcm9jZXNzU3RlcChzdGVwLCBvcHRpb25zKSB7XG4gICAgc3dpdGNoIChzdGVwLnR5cGUpIHtcbiAgICAgIGNhc2UgJ25vdGlmeSc6XG4gICAgICAgIGlmIChzdGVwLnYgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHZhciAkcm93ID0gdGhpcy4kdGFibGUuZmluZCgnLm10Ymwtcm93JykuZXEoc3RlcC54KTtcbiAgICAgICAgICB2YXIgJGNvbCA9ICRyb3cuZmluZCgnLm10YmwtY29sJykuZXEoc3RlcC55KTtcbiAgICAgICAgICAkY29sLnRleHQocmVmaW5lQnlUeXBlKHN0ZXAudikpO1xuICAgICAgICB9XG4gICAgICBjYXNlICdkZW5vdGlmeSc6XG4gICAgICBjYXNlICdzZWxlY3QnOlxuICAgICAgY2FzZSAnZGVzZWxlY3QnOlxuICAgICAgICB2YXIgY29sb3JDbGFzcyA9IHN0ZXAudHlwZSA9PSAnc2VsZWN0JyB8fCBzdGVwLnR5cGUgPT0gJ2Rlc2VsZWN0JyA/IHRoaXMuY29sb3JDbGFzcy5zZWxlY3RlZCA6IHRoaXMuY29sb3JDbGFzcy5ub3RpZmllZDtcbiAgICAgICAgdmFyIGFkZENsYXNzID0gc3RlcC50eXBlID09ICdzZWxlY3QnIHx8IHN0ZXAudHlwZSA9PSAnbm90aWZ5JztcbiAgICAgICAgdmFyIHN4ID0gc3RlcC5zeDtcbiAgICAgICAgdmFyIHN5ID0gc3RlcC5zeTtcbiAgICAgICAgdmFyIGV4ID0gc3RlcC5leDtcbiAgICAgICAgdmFyIGV5ID0gc3RlcC5leTtcbiAgICAgICAgaWYgKHN4ID09PSB1bmRlZmluZWQpIHN4ID0gc3RlcC54O1xuICAgICAgICBpZiAoc3kgPT09IHVuZGVmaW5lZCkgc3kgPSBzdGVwLnk7XG4gICAgICAgIGlmIChleCA9PT0gdW5kZWZpbmVkKSBleCA9IHN0ZXAueDtcbiAgICAgICAgaWYgKGV5ID09PSB1bmRlZmluZWQpIGV5ID0gc3RlcC55O1xuICAgICAgICB0aGlzLnBhaW50Q29sb3Ioc3gsIHN5LCBleCwgZXksIGNvbG9yQ2xhc3MsIGFkZENsYXNzKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdzZXBhcmF0ZSc6XG4gICAgICAgIHRoaXMuZGVzZXBhcmF0ZShzdGVwLngsIHN0ZXAueSk7XG4gICAgICAgIHRoaXMuc2VwYXJhdGUoc3RlcC54LCBzdGVwLnkpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2Rlc2VwYXJhdGUnOlxuICAgICAgICB0aGlzLmRlc2VwYXJhdGUoc3RlcC54LCBzdGVwLnkpO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHN1cGVyLnByb2Nlc3NTdGVwKHN0ZXAsIG9wdGlvbnMpO1xuICAgIH1cbiAgfVxuXG4gIHNldERhdGEoRCkge1xuICAgIHRoaXMudmlld1ggPSB0aGlzLnZpZXdZID0gMDtcbiAgICB0aGlzLnBhZGRpbmdIID0gNjtcbiAgICB0aGlzLnBhZGRpbmdWID0gMztcbiAgICB0aGlzLmZvbnRTaXplID0gMTY7XG5cbiAgICBpZiAoc3VwZXIuc2V0RGF0YS5hcHBseSh0aGlzLCBhcmd1bWVudHMpKSB7XG4gICAgICB0aGlzLiR0YWJsZS5maW5kKCcubXRibC1yb3cnKS5lYWNoKGZ1bmN0aW9uIChpKSB7XG4gICAgICAgICQodGhpcykuZmluZCgnLm10YmwtY29sJykuZWFjaChmdW5jdGlvbiAoaikge1xuICAgICAgICAgICQodGhpcykudGV4dChyZWZpbmVCeVR5cGUoRFtpXVtqXSkpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgdGhpcy4kdGFibGUuZW1wdHkoKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IEQubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciAkcm93ID0gJCgnPGRpdiBjbGFzcz1cIm10Ymwtcm93XCI+Jyk7XG4gICAgICB0aGlzLiR0YWJsZS5hcHBlbmQoJHJvdyk7XG4gICAgICBmb3IgKHZhciBqID0gMDsgaiA8IERbaV0ubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgdmFyICRjb2wgPSAkKCc8ZGl2IGNsYXNzPVwibXRibC1jb2xcIj4nKVxuICAgICAgICAgIC5jc3ModGhpcy5nZXRDZWxsQ3NzKCkpXG4gICAgICAgICAgLnRleHQocmVmaW5lQnlUeXBlKERbaV1bal0pKTtcbiAgICAgICAgJHJvdy5hcHBlbmQoJGNvbCk7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMucmVzaXplKCk7XG5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXNpemUoKSB7XG4gICAgc3VwZXIucmVzaXplKCk7XG5cbiAgICB0aGlzLnJlZnJlc2goKTtcbiAgfVxuXG4gIGNsZWFyKCkge1xuICAgIHN1cGVyLmNsZWFyKCk7XG5cbiAgICB0aGlzLmNsZWFyQ29sb3IoKTtcbiAgICB0aGlzLmRlc2VwYXJhdGVBbGwoKTtcbiAgfVxuXG4gIGdldENlbGxDc3MoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHBhZGRpbmc6IHRoaXMucGFkZGluZ1YudG9GaXhlZCgxKSArICdweCAnICsgdGhpcy5wYWRkaW5nSC50b0ZpeGVkKDEpICsgJ3B4JyxcbiAgICAgICdmb250LXNpemUnOiB0aGlzLmZvbnRTaXplLnRvRml4ZWQoMSkgKyAncHgnXG4gICAgfTtcbiAgfVxuXG4gIHJlZnJlc2goKSB7XG4gICAgc3VwZXIucmVmcmVzaCgpO1xuXG4gICAgdmFyICRwYXJlbnQgPSB0aGlzLiR0YWJsZS5wYXJlbnQoKTtcbiAgICB2YXIgdG9wID0gJHBhcmVudC5oZWlnaHQoKSAvIDIgLSB0aGlzLiR0YWJsZS5oZWlnaHQoKSAvIDIgKyB0aGlzLnZpZXdZO1xuICAgIHZhciBsZWZ0ID0gJHBhcmVudC53aWR0aCgpIC8gMiAtIHRoaXMuJHRhYmxlLndpZHRoKCkgLyAyICsgdGhpcy52aWV3WDtcbiAgICB0aGlzLiR0YWJsZS5jc3MoJ21hcmdpbi10b3AnLCB0b3ApO1xuICAgIHRoaXMuJHRhYmxlLmNzcygnbWFyZ2luLWxlZnQnLCBsZWZ0KTtcbiAgfVxuXG4gIG1vdXNlZG93bihlKSB7XG4gICAgc3VwZXIubW91c2Vkb3duKGUpO1xuXG4gICAgdGhpcy5kcmFnWCA9IGUucGFnZVg7XG4gICAgdGhpcy5kcmFnWSA9IGUucGFnZVk7XG4gICAgdGhpcy5kcmFnZ2luZyA9IHRydWU7XG4gIH1cblxuICBtb3VzZW1vdmUoZSkge1xuICAgIHN1cGVyLm1vdXNlbW92ZShlKTtcblxuICAgIGlmICh0aGlzLmRyYWdnaW5nKSB7XG4gICAgICB0aGlzLnZpZXdYICs9IGUucGFnZVggLSB0aGlzLmRyYWdYO1xuICAgICAgdGhpcy52aWV3WSArPSBlLnBhZ2VZIC0gdGhpcy5kcmFnWTtcbiAgICAgIHRoaXMuZHJhZ1ggPSBlLnBhZ2VYO1xuICAgICAgdGhpcy5kcmFnWSA9IGUucGFnZVk7XG4gICAgICB0aGlzLnJlZnJlc2goKTtcbiAgICB9XG4gIH1cblxuICBtb3VzZXVwKGUpIHtcbiAgICBzdXBlci5tb3VzZXVwKGUpO1xuXG4gICAgdGhpcy5kcmFnZ2luZyA9IGZhbHNlO1xuICB9XG5cbiAgbW91c2V3aGVlbChlKSB7XG4gICAgc3VwZXIubW91c2V3aGVlbChlKTtcblxuICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICBlID0gZS5vcmlnaW5hbEV2ZW50O1xuICAgIHZhciBkZWx0YSA9IChlLndoZWVsRGVsdGEgIT09IHVuZGVmaW5lZCAmJiBlLndoZWVsRGVsdGEpIHx8XG4gICAgICAoZS5kZXRhaWwgIT09IHVuZGVmaW5lZCAmJiAtZS5kZXRhaWwpO1xuICAgIHZhciB3ZWlnaHQgPSAxLjAxO1xuICAgIHZhciByYXRpbyA9IGRlbHRhID4gMCA/IDEgLyB3ZWlnaHQgOiB3ZWlnaHQ7XG4gICAgaWYgKHRoaXMuZm9udFNpemUgPCA0ICYmIHJhdGlvIDwgMSkgcmV0dXJuO1xuICAgIGlmICh0aGlzLmZvbnRTaXplID4gNDAgJiYgcmF0aW8gPiAxKSByZXR1cm47XG4gICAgdGhpcy5wYWRkaW5nViAqPSByYXRpbztcbiAgICB0aGlzLnBhZGRpbmdIICo9IHJhdGlvO1xuICAgIHRoaXMuZm9udFNpemUgKj0gcmF0aW87XG4gICAgdGhpcy4kdGFibGUuZmluZCgnLm10YmwtY29sJykuY3NzKHRoaXMuZ2V0Q2VsbENzcygpKTtcbiAgICB0aGlzLnJlZnJlc2goKTtcbiAgfVxuXG4gIHBhaW50Q29sb3Ioc3gsIHN5LCBleCwgZXksIGNvbG9yQ2xhc3MsIGFkZENsYXNzKSB7XG4gICAgZm9yICh2YXIgaSA9IHN4OyBpIDw9IGV4OyBpKyspIHtcbiAgICAgIHZhciAkcm93ID0gdGhpcy4kdGFibGUuZmluZCgnLm10Ymwtcm93JykuZXEoaSk7XG4gICAgICBmb3IgKHZhciBqID0gc3k7IGogPD0gZXk7IGorKykge1xuICAgICAgICB2YXIgJGNvbCA9ICRyb3cuZmluZCgnLm10YmwtY29sJykuZXEoaik7XG4gICAgICAgIGlmIChhZGRDbGFzcykgJGNvbC5hZGRDbGFzcyhjb2xvckNsYXNzKTtcbiAgICAgICAgZWxzZSAkY29sLnJlbW92ZUNsYXNzKGNvbG9yQ2xhc3MpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGNsZWFyQ29sb3IoKSB7XG4gICAgdGhpcy4kdGFibGUuZmluZCgnLm10YmwtY29sJykucmVtb3ZlQ2xhc3MoT2JqZWN0LmtleXModGhpcy5jb2xvckNsYXNzKS5qb2luKCcgJykpO1xuICB9XG5cbiAgc2VwYXJhdGUoeCwgeSkge1xuICAgIHRoaXMuJHRhYmxlLmZpbmQoJy5tdGJsLXJvdycpLmVhY2goZnVuY3Rpb24gKGkpIHtcbiAgICAgIHZhciAkcm93ID0gJCh0aGlzKTtcbiAgICAgIGlmIChpID09IHgpIHtcbiAgICAgICAgJHJvdy5hZnRlcigkKCc8ZGl2IGNsYXNzPVwibXRibC1lbXB0eS1yb3dcIj4nKS5hdHRyKCdkYXRhLXJvdycsIGkpKVxuICAgICAgfVxuICAgICAgJHJvdy5maW5kKCcubXRibC1jb2wnKS5lYWNoKGZ1bmN0aW9uIChqKSB7XG4gICAgICAgIHZhciAkY29sID0gJCh0aGlzKTtcbiAgICAgICAgaWYgKGogPT0geSkge1xuICAgICAgICAgICRjb2wuYWZ0ZXIoJCgnPGRpdiBjbGFzcz1cIm10YmwtZW1wdHktY29sXCI+JykuYXR0cignZGF0YS1jb2wnLCBqKSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgZGVzZXBhcmF0ZSh4LCB5KSB7XG4gICAgdGhpcy4kdGFibGUuZmluZCgnW2RhdGEtcm93PScgKyB4ICsgJ10nKS5yZW1vdmUoKTtcbiAgICB0aGlzLiR0YWJsZS5maW5kKCdbZGF0YS1jb2w9JyArIHkgKyAnXScpLnJlbW92ZSgpO1xuICB9XG5cbiAgZGVzZXBhcmF0ZUFsbCgpIHtcbiAgICB0aGlzLiR0YWJsZS5maW5kKCcubXRibC1lbXB0eS1yb3csIC5tdGJsLWVtcHR5LWNvbCcpLnJlbW92ZSgpO1xuICB9XG59XG5cbmNvbnN0IGluaXRWaWV3ID0gKHRyYWNlcikgPT4ge1xuICB0cmFjZXIuJHRhYmxlID0gdHJhY2VyLmNhcHN1bGUuJHRhYmxlID0gJCgnPGRpdiBjbGFzcz1cIm10YmwtdGFibGVcIj4nKTtcbiAgdHJhY2VyLiRjb250YWluZXIuYXBwZW5kKHRyYWNlci4kdGFibGUpO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBBcnJheTJEVHJhY2VyOyIsImNvbnN0IFRyYWNlciA9IHJlcXVpcmUoJy4vdHJhY2VyJyk7XG5cbmNsYXNzIENoYXJ0VHJhY2VyIGV4dGVuZHMgVHJhY2VyIHtcbiAgc3RhdGljIGdldENsYXNzTmFtZSgpIHtcbiAgICByZXR1cm4gJ0NoYXJ0VHJhY2VyJztcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKG5hbWUpIHtcbiAgICBzdXBlcihuYW1lKTtcblxuICAgIHRoaXMuY29sb3IgPSB7XG4gICAgICBzZWxlY3RlZDogJ3JnYmEoMjU1LCAwLCAwLCAxKScsXG4gICAgICBub3RpZmllZDogJ3JnYmEoMCwgMCwgMjU1LCAxKScsXG4gICAgICBkZWZhdWx0OiAncmdiYSgxMzYsIDEzNiwgMTM2LCAxKSdcbiAgICB9O1xuXG4gICAgaWYgKHRoaXMuaXNOZXcpIGluaXRWaWV3KHRoaXMpO1xuICB9XG5cbiAgc2V0RGF0YShDKSB7XG4gICAgaWYgKHN1cGVyLnNldERhdGEuYXBwbHkodGhpcywgYXJndW1lbnRzKSkgcmV0dXJuIHRydWU7XG5cbiAgICB2YXIgY29sb3IgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IEMubGVuZ3RoOyBpKyspIGNvbG9yLnB1c2godGhpcy5jb2xvci5kZWZhdWx0KTtcbiAgICB0aGlzLmNoYXJ0LmNvbmZpZy5kYXRhID0ge1xuICAgICAgbGFiZWxzOiBDLm1hcChTdHJpbmcpLFxuICAgICAgZGF0YXNldHM6IFt7XG4gICAgICAgIGJhY2tncm91bmRDb2xvcjogY29sb3IsXG4gICAgICAgIGRhdGE6IENcbiAgICAgIH1dXG4gICAgfTtcbiAgICB0aGlzLmNoYXJ0LnVwZGF0ZSgpO1xuICB9XG5cbiAgX25vdGlmeShzLCB2KSB7XG4gICAgdGhpcy5tYW5hZ2VyLnB1c2hTdGVwKHRoaXMuY2Fwc3VsZSwge1xuICAgICAgdHlwZTogJ25vdGlmeScsXG4gICAgICBzOiBzLFxuICAgICAgdjogdlxuICAgIH0pO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgX2Rlbm90aWZ5KHMpIHtcbiAgICB0aGlzLm1hbmFnZXIucHVzaFN0ZXAodGhpcy5jYXBzdWxlLCB7XG4gICAgICB0eXBlOiAnZGVub3RpZnknLFxuICAgICAgczogc1xuICAgIH0pO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgX3NlbGVjdChzLCBlKSB7XG4gICAgdGhpcy5tYW5hZ2VyLnB1c2hTdGVwKHRoaXMuY2Fwc3VsZSwge1xuICAgICAgdHlwZTogJ3NlbGVjdCcsXG4gICAgICBzOiBzLFxuICAgICAgZTogZVxuICAgIH0pO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgX2Rlc2VsZWN0KHMsIGUpIHtcbiAgICB0aGlzLm1hbmFnZXIucHVzaFN0ZXAodGhpcy5jYXBzdWxlLCB7XG4gICAgICB0eXBlOiAnZGVzZWxlY3QnLFxuICAgICAgczogcyxcbiAgICAgIGU6IGVcbiAgICB9KTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHByb2Nlc3NTdGVwKHN0ZXAsIG9wdGlvbnMpIHtcbiAgICBzd2l0Y2ggKHN0ZXAudHlwZSkge1xuICAgICAgY2FzZSAnbm90aWZ5JzpcbiAgICAgICAgaWYgKHN0ZXAudiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdGhpcy5jaGFydC5jb25maWcuZGF0YS5kYXRhc2V0c1swXS5kYXRhW3N0ZXAuc10gPSBzdGVwLnY7XG4gICAgICAgICAgdGhpcy5jaGFydC5jb25maWcuZGF0YS5sYWJlbHNbc3RlcC5zXSA9IHN0ZXAudi50b1N0cmluZygpO1xuICAgICAgICB9XG4gICAgICBjYXNlICdkZW5vdGlmeSc6XG4gICAgICBjYXNlICdkZXNlbGVjdCc6XG4gICAgICBjYXNlICdzZWxlY3QnOlxuICAgICAgICBsZXQgY29sb3IgPSBzdGVwLnR5cGUgPT0gJ25vdGlmeScgPyB0aGlzLmNvbG9yLm5vdGlmaWVkIDogc3RlcC50eXBlID09ICdzZWxlY3QnID8gdGhpcy5jb2xvci5zZWxlY3RlZCA6IHRoaXMuY29sb3IuZGVmYXVsdDtcbiAgICAgICAgaWYgKHN0ZXAuZSAhPT0gdW5kZWZpbmVkKVxuICAgICAgICAgIGZvciAodmFyIGkgPSBzdGVwLnM7IGkgPD0gc3RlcC5lOyBpKyspXG4gICAgICAgICAgICB0aGlzLmNoYXJ0LmNvbmZpZy5kYXRhLmRhdGFzZXRzWzBdLmJhY2tncm91bmRDb2xvcltpXSA9IGNvbG9yO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgdGhpcy5jaGFydC5jb25maWcuZGF0YS5kYXRhc2V0c1swXS5iYWNrZ3JvdW5kQ29sb3Jbc3RlcC5zXSA9IGNvbG9yO1xuICAgICAgICB0aGlzLmNoYXJ0LnVwZGF0ZSgpO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHN1cGVyLnByb2Nlc3NTdGVwKHN0ZXAsIG9wdGlvbnMpO1xuICAgIH1cbiAgfVxuXG4gIHJlc2l6ZSgpIHtcbiAgICBzdXBlci5yZXNpemUoKTtcblxuICAgIHRoaXMuY2hhcnQucmVzaXplKCk7XG4gIH1cblxuICBjbGVhcigpIHtcbiAgICBzdXBlci5jbGVhcigpO1xuXG4gICAgY29uc3QgZGF0YSA9IHRoaXMuY2hhcnQuY29uZmlnLmRhdGE7XG4gICAgaWYgKGRhdGEuZGF0YXNldHMubGVuZ3RoKSB7XG4gICAgICBjb25zdCBiYWNrZ3JvdW5kQ29sb3IgPSBkYXRhLmRhdGFzZXRzWzBdLmJhY2tncm91bmRDb2xvcjtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYmFja2dyb3VuZENvbG9yLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGJhY2tncm91bmRDb2xvcltpXSA9IHRoaXMuY29sb3IuZGVmYXVsdDtcbiAgICAgIH1cbiAgICAgIHRoaXMuY2hhcnQudXBkYXRlKCk7XG4gICAgfVxuICB9XG59XG5cbmNvbnN0IGluaXRWaWV3ID0gKHRyYWNlcikgPT4ge1xuICB0cmFjZXIuJHdyYXBwZXIgPSB0cmFjZXIuY2Fwc3VsZS4kd3JhcHBlciA9ICQoJzxjYW52YXMgY2xhc3M9XCJtY2hydC1jaGFydFwiPicpO1xuICB0cmFjZXIuJGNvbnRhaW5lci5hcHBlbmQodHJhY2VyLiR3cmFwcGVyKTtcbiAgdHJhY2VyLmNoYXJ0ID0gdHJhY2VyLmNhcHN1bGUuY2hhcnQgPSBuZXcgQ2hhcnQodHJhY2VyLiR3cmFwcGVyLCB7XG4gICAgdHlwZTogJ2JhcicsXG4gICAgZGF0YToge1xuICAgICAgbGFiZWxzOiBbXSxcbiAgICAgIGRhdGFzZXRzOiBbXVxuICAgIH0sXG4gICAgb3B0aW9uczoge1xuICAgICAgc2NhbGVzOiB7XG4gICAgICAgIHlBeGVzOiBbe1xuICAgICAgICAgIHRpY2tzOiB7XG4gICAgICAgICAgICBiZWdpbkF0WmVybzogdHJ1ZVxuICAgICAgICAgIH1cbiAgICAgICAgfV1cbiAgICAgIH0sXG4gICAgICBhbmltYXRpb246IGZhbHNlLFxuICAgICAgbGVnZW5kOiBmYWxzZSxcbiAgICAgIHJlc3BvbnNpdmU6IHRydWUsXG4gICAgICBtYWludGFpbkFzcGVjdFJhdGlvOiBmYWxzZVxuICAgIH1cbiAgfSk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IENoYXJ0VHJhY2VyOyIsImNvbnN0IERpcmVjdGVkR3JhcGhUcmFjZXIgPSByZXF1aXJlKCcuL2RpcmVjdGVkX2dyYXBoJyk7XG5cbmNsYXNzIENvb3JkaW5hdGVTeXN0ZW1UcmFjZXIgZXh0ZW5kcyBEaXJlY3RlZEdyYXBoVHJhY2VyIHtcbiAgc3RhdGljIGdldENsYXNzTmFtZSgpIHtcbiAgICByZXR1cm4gJ0Nvb3JkaW5hdGVTeXN0ZW1UcmFjZXInO1xuICB9XG5cbiAgY29uc3RydWN0b3IobmFtZSkge1xuICAgIHN1cGVyKG5hbWUpO1xuXG4gICAgaWYgKHRoaXMuaXNOZXcpIGluaXRWaWV3KHRoaXMpO1xuICB9XG5cbiAgc2V0RGF0YShDKSB7XG4gICAgaWYgKFRyYWNlci5wcm90b3R5cGUuc2V0RGF0YS5hcHBseSh0aGlzLCBhcmd1bWVudHMpKSByZXR1cm4gdHJ1ZTtcblxuICAgIHRoaXMuZ3JhcGguY2xlYXIoKTtcbiAgICB2YXIgbm9kZXMgPSBbXTtcbiAgICB2YXIgZWRnZXMgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IEMubGVuZ3RoOyBpKyspXG4gICAgICBub2Rlcy5wdXNoKHtcbiAgICAgICAgaWQ6IHRoaXMubihpKSxcbiAgICAgICAgeDogQ1tpXVswXSxcbiAgICAgICAgeTogQ1tpXVsxXSxcbiAgICAgICAgbGFiZWw6ICcnICsgaSxcbiAgICAgICAgc2l6ZTogMSxcbiAgICAgICAgY29sb3I6IHRoaXMuY29sb3IuZGVmYXVsdFxuICAgICAgfSk7XG4gICAgdGhpcy5ncmFwaC5yZWFkKHtcbiAgICAgIG5vZGVzOiBub2RlcyxcbiAgICAgIGVkZ2VzOiBlZGdlc1xuICAgIH0pO1xuICAgIHRoaXMucy5jYW1lcmEuZ29Ubyh7XG4gICAgICB4OiAwLFxuICAgICAgeTogMCxcbiAgICAgIGFuZ2xlOiAwLFxuICAgICAgcmF0aW86IDFcbiAgICB9KTtcbiAgICB0aGlzLnJlZnJlc2goKTtcblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHByb2Nlc3NTdGVwKHN0ZXAsIG9wdGlvbnMpIHtcbiAgICBzd2l0Y2ggKHN0ZXAudHlwZSkge1xuICAgICAgY2FzZSAndmlzaXQnOlxuICAgICAgY2FzZSAnbGVhdmUnOlxuICAgICAgICB2YXIgdmlzaXQgPSBzdGVwLnR5cGUgPT0gJ3Zpc2l0JztcbiAgICAgICAgdmFyIHRhcmdldE5vZGUgPSB0aGlzLmdyYXBoLm5vZGVzKHRoaXMubihzdGVwLnRhcmdldCkpO1xuICAgICAgICB2YXIgY29sb3IgPSB2aXNpdCA/IHRoaXMuY29sb3IudmlzaXRlZCA6IHRoaXMuY29sb3IubGVmdDtcbiAgICAgICAgdGFyZ2V0Tm9kZS5jb2xvciA9IGNvbG9yO1xuICAgICAgICBpZiAoc3RlcC5zb3VyY2UgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHZhciBlZGdlSWQgPSB0aGlzLmUoc3RlcC5zb3VyY2UsIHN0ZXAudGFyZ2V0KTtcbiAgICAgICAgICBpZiAodGhpcy5ncmFwaC5lZGdlcyhlZGdlSWQpKSB7XG4gICAgICAgICAgICB2YXIgZWRnZSA9IHRoaXMuZ3JhcGguZWRnZXMoZWRnZUlkKTtcbiAgICAgICAgICAgIGVkZ2UuY29sb3IgPSBjb2xvcjtcbiAgICAgICAgICAgIHRoaXMuZ3JhcGguZHJvcEVkZ2UoZWRnZUlkKS5hZGRFZGdlKGVkZ2UpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmdyYXBoLmFkZEVkZ2Uoe1xuICAgICAgICAgICAgICBpZDogdGhpcy5lKHN0ZXAudGFyZ2V0LCBzdGVwLnNvdXJjZSksXG4gICAgICAgICAgICAgIHNvdXJjZTogdGhpcy5uKHN0ZXAuc291cmNlKSxcbiAgICAgICAgICAgICAgdGFyZ2V0OiB0aGlzLm4oc3RlcC50YXJnZXQpLFxuICAgICAgICAgICAgICBjb2xvcjogY29sb3IsXG4gICAgICAgICAgICAgIHNpemU6IDFcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5sb2dUcmFjZXIpIHtcbiAgICAgICAgICB2YXIgc291cmNlID0gc3RlcC5zb3VyY2U7XG4gICAgICAgICAgaWYgKHNvdXJjZSA9PT0gdW5kZWZpbmVkKSBzb3VyY2UgPSAnJztcbiAgICAgICAgICB0aGlzLmxvZ1RyYWNlci5wcmludCh2aXNpdCA/IHNvdXJjZSArICcgLT4gJyArIHN0ZXAudGFyZ2V0IDogc291cmNlICsgJyA8LSAnICsgc3RlcC50YXJnZXQpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgc3VwZXIucHJvY2Vzc1N0ZXAoc3RlcCwgb3B0aW9ucyk7XG4gICAgfVxuICB9XG5cbiAgZSh2MSwgdjIpIHtcbiAgICBpZiAodjEgPiB2Mikge1xuICAgICAgdmFyIHRlbXAgPSB2MTtcbiAgICAgIHYxID0gdjI7XG4gICAgICB2MiA9IHRlbXA7XG4gICAgfVxuICAgIHJldHVybiAnZScgKyB2MSArICdfJyArIHYyO1xuICB9XG5cbiAgZHJhd09uSG92ZXIobm9kZSwgY29udGV4dCwgc2V0dGluZ3MsIG5leHQpIHtcbiAgICB2YXIgdHJhY2VyID0gdGhpcztcblxuICAgIGNvbnRleHQuc2V0TGluZURhc2goWzUsIDVdKTtcbiAgICB2YXIgbm9kZUlkeCA9IG5vZGUuaWQuc3Vic3RyaW5nKDEpO1xuICAgIHRoaXMuZ3JhcGguZWRnZXMoKS5mb3JFYWNoKGZ1bmN0aW9uIChlZGdlKSB7XG4gICAgICB2YXIgZW5kcyA9IGVkZ2UuaWQuc3Vic3RyaW5nKDEpLnNwbGl0KFwiX1wiKTtcbiAgICAgIGlmIChlbmRzWzBdID09IG5vZGVJZHgpIHtcbiAgICAgICAgdmFyIGNvbG9yID0gJyMwZmYnO1xuICAgICAgICB2YXIgc291cmNlID0gbm9kZTtcbiAgICAgICAgdmFyIHRhcmdldCA9IHRyYWNlci5ncmFwaC5ub2RlcygnbicgKyBlbmRzWzFdKTtcbiAgICAgICAgdHJhY2VyLmRyYXdFZGdlKGVkZ2UsIHNvdXJjZSwgdGFyZ2V0LCBjb2xvciwgY29udGV4dCwgc2V0dGluZ3MpO1xuICAgICAgICBpZiAobmV4dCkgbmV4dChlZGdlLCBzb3VyY2UsIHRhcmdldCwgY29sb3IsIGNvbnRleHQsIHNldHRpbmdzKTtcbiAgICAgIH0gZWxzZSBpZiAoZW5kc1sxXSA9PSBub2RlSWR4KSB7XG4gICAgICAgIHZhciBjb2xvciA9ICcjMGZmJztcbiAgICAgICAgdmFyIHNvdXJjZSA9IHRyYWNlci5ncmFwaC5ub2RlcygnbicgKyBlbmRzWzBdKTtcbiAgICAgICAgdmFyIHRhcmdldCA9IG5vZGU7XG4gICAgICAgIHRyYWNlci5kcmF3RWRnZShlZGdlLCBzb3VyY2UsIHRhcmdldCwgY29sb3IsIGNvbnRleHQsIHNldHRpbmdzKTtcbiAgICAgICAgaWYgKG5leHQpIG5leHQoZWRnZSwgc291cmNlLCB0YXJnZXQsIGNvbG9yLCBjb250ZXh0LCBzZXR0aW5ncyk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBkcmF3RWRnZShlZGdlLCBzb3VyY2UsIHRhcmdldCwgY29sb3IsIGNvbnRleHQsIHNldHRpbmdzKSB7XG4gICAgdmFyIHByZWZpeCA9IHNldHRpbmdzKCdwcmVmaXgnKSB8fCAnJyxcbiAgICAgIHNpemUgPSBlZGdlW3ByZWZpeCArICdzaXplJ10gfHwgMTtcblxuICAgIGNvbnRleHQuc3Ryb2tlU3R5bGUgPSBjb2xvcjtcbiAgICBjb250ZXh0LmxpbmVXaWR0aCA9IHNpemU7XG4gICAgY29udGV4dC5iZWdpblBhdGgoKTtcbiAgICBjb250ZXh0Lm1vdmVUbyhcbiAgICAgIHNvdXJjZVtwcmVmaXggKyAneCddLFxuICAgICAgc291cmNlW3ByZWZpeCArICd5J11cbiAgICApO1xuICAgIGNvbnRleHQubGluZVRvKFxuICAgICAgdGFyZ2V0W3ByZWZpeCArICd4J10sXG4gICAgICB0YXJnZXRbcHJlZml4ICsgJ3knXVxuICAgICk7XG4gICAgY29udGV4dC5zdHJva2UoKTtcbiAgfVxufVxuXG5jb25zdCBpbml0VmlldyA9ICh0cmFjZXIpID0+IHtcbiAgdHJhY2VyLnMuc2V0dGluZ3Moe1xuICAgIGRlZmF1bHRFZGdlVHlwZTogJ2RlZicsXG4gICAgZnVuY0VkZ2VzRGVmKGVkZ2UsIHNvdXJjZSwgdGFyZ2V0LCBjb250ZXh0LCBzZXR0aW5ncykge1xuICAgICAgdmFyIGNvbG9yID0gdHJhY2VyLmdldENvbG9yKGVkZ2UsIHNvdXJjZSwgdGFyZ2V0LCBzZXR0aW5ncyk7XG4gICAgICB0cmFjZXIuZHJhd0VkZ2UoZWRnZSwgc291cmNlLCB0YXJnZXQsIGNvbG9yLCBjb250ZXh0LCBzZXR0aW5ncyk7XG4gICAgfVxuICB9KTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gQ29vcmRpbmF0ZVN5c3RlbVRyYWNlcjsiLCJjb25zdCBUcmFjZXIgPSByZXF1aXJlKCcuL3RyYWNlcicpO1xuXG5jb25zdCB7XG4gIHJlZmluZUJ5VHlwZVxufSA9IHJlcXVpcmUoJy4uLy4uL3RyYWNlcl9tYW5hZ2VyL3V0aWwvaW5kZXgnKTtcblxuY2xhc3MgRGlyZWN0ZWRHcmFwaFRyYWNlciBleHRlbmRzIFRyYWNlciB7XG4gIHN0YXRpYyBnZXRDbGFzc05hbWUoKSB7XG4gICAgcmV0dXJuICdEaXJlY3RlZEdyYXBoVHJhY2VyJztcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKG5hbWUpIHtcbiAgICBzdXBlcihuYW1lKTtcblxuICAgIHRoaXMuY29sb3IgPSB7XG4gICAgICBzZWxlY3RlZDogJyMwZjAnLFxuICAgICAgdmlzaXRlZDogJyNmMDAnLFxuICAgICAgbGVmdDogJyMwMDAnLFxuICAgICAgZGVmYXVsdDogJyM4ODgnXG4gICAgfTtcblxuICAgIGlmICh0aGlzLmlzTmV3KSBpbml0Vmlldyh0aGlzKTtcbiAgfVxuXG4gIF9zZXRUcmVlRGF0YShHLCByb290KSB7XG4gICAgdGhpcy5tYW5hZ2VyLnB1c2hTdGVwKHRoaXMuY2Fwc3VsZSwge1xuICAgICAgdHlwZTogJ3NldFRyZWVEYXRhJyxcbiAgICAgIGFyZ3VtZW50czogYXJndW1lbnRzXG4gICAgfSk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBfdmlzaXQodGFyZ2V0LCBzb3VyY2UpIHtcbiAgICB0aGlzLm1hbmFnZXIucHVzaFN0ZXAodGhpcy5jYXBzdWxlLCB7XG4gICAgICB0eXBlOiAndmlzaXQnLFxuICAgICAgdGFyZ2V0OiB0YXJnZXQsXG4gICAgICBzb3VyY2U6IHNvdXJjZVxuICAgIH0pO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgX2xlYXZlKHRhcmdldCwgc291cmNlKSB7XG4gICAgdGhpcy5tYW5hZ2VyLnB1c2hTdGVwKHRoaXMuY2Fwc3VsZSwge1xuICAgICAgdHlwZTogJ2xlYXZlJyxcbiAgICAgIHRhcmdldDogdGFyZ2V0LFxuICAgICAgc291cmNlOiBzb3VyY2VcbiAgICB9KTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHByb2Nlc3NTdGVwKHN0ZXAsIG9wdGlvbnMpIHtcbiAgICBzd2l0Y2ggKHN0ZXAudHlwZSkge1xuICAgICAgY2FzZSAnc2V0VHJlZURhdGEnOlxuICAgICAgICB0aGlzLnNldFRyZWVEYXRhLmFwcGx5KHRoaXMsIHN0ZXAuYXJndW1lbnRzKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICd2aXNpdCc6XG4gICAgICBjYXNlICdsZWF2ZSc6XG4gICAgICAgIHZhciB2aXNpdCA9IHN0ZXAudHlwZSA9PSAndmlzaXQnO1xuICAgICAgICB2YXIgdGFyZ2V0Tm9kZSA9IHRoaXMuZ3JhcGgubm9kZXModGhpcy5uKHN0ZXAudGFyZ2V0KSk7XG4gICAgICAgIHZhciBjb2xvciA9IHZpc2l0ID8gdGhpcy5jb2xvci52aXNpdGVkIDogdGhpcy5jb2xvci5sZWZ0O1xuICAgICAgICB0YXJnZXROb2RlLmNvbG9yID0gY29sb3I7XG4gICAgICAgIGlmIChzdGVwLnNvdXJjZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdmFyIGVkZ2VJZCA9IHRoaXMuZShzdGVwLnNvdXJjZSwgc3RlcC50YXJnZXQpO1xuICAgICAgICAgIHZhciBlZGdlID0gdGhpcy5ncmFwaC5lZGdlcyhlZGdlSWQpO1xuICAgICAgICAgIGVkZ2UuY29sb3IgPSBjb2xvcjtcbiAgICAgICAgICB0aGlzLmdyYXBoLmRyb3BFZGdlKGVkZ2VJZCkuYWRkRWRnZShlZGdlKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5sb2dUcmFjZXIpIHtcbiAgICAgICAgICB2YXIgc291cmNlID0gc3RlcC5zb3VyY2U7XG4gICAgICAgICAgaWYgKHNvdXJjZSA9PT0gdW5kZWZpbmVkKSBzb3VyY2UgPSAnJztcbiAgICAgICAgICB0aGlzLmxvZ1RyYWNlci5wcmludCh2aXNpdCA/IHNvdXJjZSArICcgLT4gJyArIHN0ZXAudGFyZ2V0IDogc291cmNlICsgJyA8LSAnICsgc3RlcC50YXJnZXQpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgc3VwZXIucHJvY2Vzc1N0ZXAoc3RlcCwgb3B0aW9ucyk7XG4gICAgfVxuICB9XG5cbiAgc2V0VHJlZURhdGEoRywgcm9vdCwgdW5kaXJlY3RlZCkge1xuICAgIHZhciB0cmFjZXIgPSB0aGlzO1xuXG4gICAgcm9vdCA9IHJvb3QgfHwgMDtcbiAgICB2YXIgbWF4RGVwdGggPSAtMTtcblxuICAgIHZhciBjaGsgPSBuZXcgQXJyYXkoRy5sZW5ndGgpO1xuICAgIHZhciBnZXREZXB0aCA9IGZ1bmN0aW9uIChub2RlLCBkZXB0aCkge1xuICAgICAgaWYgKGNoa1tub2RlXSkgdGhyb3cgXCJ0aGUgZ2l2ZW4gZ3JhcGggaXMgbm90IGEgdHJlZSBiZWNhdXNlIGl0IGZvcm1zIGEgY2lyY3VpdFwiO1xuICAgICAgY2hrW25vZGVdID0gdHJ1ZTtcbiAgICAgIGlmIChtYXhEZXB0aCA8IGRlcHRoKSBtYXhEZXB0aCA9IGRlcHRoO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBHW25vZGVdLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmIChHW25vZGVdW2ldKSBnZXREZXB0aChpLCBkZXB0aCArIDEpO1xuICAgICAgfVxuICAgIH07XG4gICAgZ2V0RGVwdGgocm9vdCwgMSk7XG5cbiAgICBpZiAodGhpcy5zZXREYXRhKEcsIHVuZGlyZWN0ZWQpKSByZXR1cm4gdHJ1ZTtcblxuICAgIHZhciBwbGFjZSA9IGZ1bmN0aW9uIChub2RlLCB4LCB5KSB7XG4gICAgICB2YXIgdGVtcCA9IHRyYWNlci5ncmFwaC5ub2Rlcyh0cmFjZXIubihub2RlKSk7XG4gICAgICB0ZW1wLnggPSB4O1xuICAgICAgdGVtcC55ID0geTtcbiAgICB9O1xuXG4gICAgdmFyIHdnYXAgPSAxIC8gKG1heERlcHRoIC0gMSk7XG4gICAgdmFyIGRmcyA9IGZ1bmN0aW9uIChub2RlLCBkZXB0aCwgdG9wLCBib3R0b20pIHtcbiAgICAgIHBsYWNlKG5vZGUsIHRvcCArIGJvdHRvbSwgZGVwdGggKiB3Z2FwKTtcbiAgICAgIHZhciBjaGlsZHJlbiA9IDA7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IEdbbm9kZV0ubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKEdbbm9kZV1baV0pIGNoaWxkcmVuKys7XG4gICAgICB9XG4gICAgICB2YXIgdmdhcCA9IChib3R0b20gLSB0b3ApIC8gY2hpbGRyZW47XG4gICAgICB2YXIgY250ID0gMDtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgR1tub2RlXS5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoR1tub2RlXVtpXSkgZGZzKGksIGRlcHRoICsgMSwgdG9wICsgdmdhcCAqIGNudCwgdG9wICsgdmdhcCAqICsrY250KTtcbiAgICAgIH1cbiAgICB9O1xuICAgIGRmcyhyb290LCAwLCAwLCAxKTtcblxuICAgIHRoaXMucmVmcmVzaCgpO1xuICB9XG5cbiAgc2V0RGF0YShHLCB1bmRpcmVjdGVkKSB7XG4gICAgaWYgKHN1cGVyLnNldERhdGEuYXBwbHkodGhpcywgYXJndW1lbnRzKSkgcmV0dXJuIHRydWU7XG5cbiAgICB0aGlzLmdyYXBoLmNsZWFyKCk7XG4gICAgY29uc3Qgbm9kZXMgPSBbXTtcbiAgICBjb25zdCBlZGdlcyA9IFtdO1xuICAgIGNvbnN0IHVuaXRBbmdsZSA9IDIgKiBNYXRoLlBJIC8gRy5sZW5ndGg7XG4gICAgbGV0IGN1cnJlbnRBbmdsZSA9IDA7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBHLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjdXJyZW50QW5nbGUgKz0gdW5pdEFuZ2xlO1xuICAgICAgbm9kZXMucHVzaCh7XG4gICAgICAgIGlkOiB0aGlzLm4oaSksXG4gICAgICAgIGxhYmVsOiAnJyArIGksXG4gICAgICAgIHg6IC41ICsgTWF0aC5zaW4oY3VycmVudEFuZ2xlKSAvIDIsXG4gICAgICAgIHk6IC41ICsgTWF0aC5jb3MoY3VycmVudEFuZ2xlKSAvIDIsXG4gICAgICAgIHNpemU6IDEsXG4gICAgICAgIGNvbG9yOiB0aGlzLmNvbG9yLmRlZmF1bHQsXG4gICAgICAgIHdlaWdodDogMFxuICAgICAgfSk7XG5cbiAgICAgIGlmICh1bmRpcmVjdGVkKSB7XG4gICAgICAgIGZvciAobGV0IGogPSAwOyBqIDw9IGk7IGorKykge1xuICAgICAgICAgIGNvbnN0IHZhbHVlID0gR1tpXVtqXSB8fCBHW2pdW2ldO1xuICAgICAgICAgIGlmICh2YWx1ZSkge1xuICAgICAgICAgICAgZWRnZXMucHVzaCh7XG4gICAgICAgICAgICAgIGlkOiB0aGlzLmUoaSwgaiksXG4gICAgICAgICAgICAgIHNvdXJjZTogdGhpcy5uKGkpLFxuICAgICAgICAgICAgICB0YXJnZXQ6IHRoaXMubihqKSxcbiAgICAgICAgICAgICAgY29sb3I6IHRoaXMuY29sb3IuZGVmYXVsdCxcbiAgICAgICAgICAgICAgc2l6ZTogMSxcbiAgICAgICAgICAgICAgd2VpZ2h0OiByZWZpbmVCeVR5cGUodmFsdWUpXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgR1tpXS5sZW5ndGg7IGorKykge1xuICAgICAgICAgIGlmIChHW2ldW2pdKSB7XG4gICAgICAgICAgICBlZGdlcy5wdXNoKHtcbiAgICAgICAgICAgICAgaWQ6IHRoaXMuZShpLCBqKSxcbiAgICAgICAgICAgICAgc291cmNlOiB0aGlzLm4oaSksXG4gICAgICAgICAgICAgIHRhcmdldDogdGhpcy5uKGopLFxuICAgICAgICAgICAgICBjb2xvcjogdGhpcy5jb2xvci5kZWZhdWx0LFxuICAgICAgICAgICAgICBzaXplOiAxLFxuICAgICAgICAgICAgICB3ZWlnaHQ6IHJlZmluZUJ5VHlwZShHW2ldW2pdKVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5ncmFwaC5yZWFkKHtcbiAgICAgIG5vZGVzOiBub2RlcyxcbiAgICAgIGVkZ2VzOiBlZGdlc1xuICAgIH0pO1xuICAgIHRoaXMucy5jYW1lcmEuZ29Ubyh7XG4gICAgICB4OiAwLFxuICAgICAgeTogMCxcbiAgICAgIGFuZ2xlOiAwLFxuICAgICAgcmF0aW86IDFcbiAgICB9KTtcbiAgICB0aGlzLnJlZnJlc2goKTtcblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHJlc2l6ZSgpIHtcbiAgICBzdXBlci5yZXNpemUoKTtcblxuICAgIHRoaXMucy5yZW5kZXJlcnNbMF0ucmVzaXplKCk7XG4gICAgdGhpcy5yZWZyZXNoKCk7XG4gIH1cblxuICByZWZyZXNoKCkge1xuICAgIHN1cGVyLnJlZnJlc2goKTtcblxuICAgIHRoaXMucy5yZWZyZXNoKCk7XG4gIH1cblxuICBjbGVhcigpIHtcbiAgICBzdXBlci5jbGVhcigpO1xuXG4gICAgdGhpcy5jbGVhckdyYXBoQ29sb3IoKTtcbiAgfVxuXG4gIGNsZWFyR3JhcGhDb2xvcigpIHtcbiAgICB2YXIgdHJhY2VyID0gdGhpcztcblxuICAgIHRoaXMuZ3JhcGgubm9kZXMoKS5mb3JFYWNoKGZ1bmN0aW9uIChub2RlKSB7XG4gICAgICBub2RlLmNvbG9yID0gdHJhY2VyLmNvbG9yLmRlZmF1bHQ7XG4gICAgfSk7XG4gICAgdGhpcy5ncmFwaC5lZGdlcygpLmZvckVhY2goZnVuY3Rpb24gKGVkZ2UpIHtcbiAgICAgIGVkZ2UuY29sb3IgPSB0cmFjZXIuY29sb3IuZGVmYXVsdDtcbiAgICB9KTtcbiAgfVxuXG4gIG4odikge1xuICAgIHJldHVybiAnbicgKyB2O1xuICB9XG5cbiAgZSh2MSwgdjIpIHtcbiAgICByZXR1cm4gJ2UnICsgdjEgKyAnXycgKyB2MjtcbiAgfVxuXG4gIGdldENvbG9yKGVkZ2UsIHNvdXJjZSwgdGFyZ2V0LCBzZXR0aW5ncykge1xuICAgIHZhciBjb2xvciA9IGVkZ2UuY29sb3IsXG4gICAgICBlZGdlQ29sb3IgPSBzZXR0aW5ncygnZWRnZUNvbG9yJyksXG4gICAgICBkZWZhdWx0Tm9kZUNvbG9yID0gc2V0dGluZ3MoJ2RlZmF1bHROb2RlQ29sb3InKSxcbiAgICAgIGRlZmF1bHRFZGdlQ29sb3IgPSBzZXR0aW5ncygnZGVmYXVsdEVkZ2VDb2xvcicpO1xuICAgIGlmICghY29sb3IpXG4gICAgICBzd2l0Y2ggKGVkZ2VDb2xvcikge1xuICAgICAgICBjYXNlICdzb3VyY2UnOlxuICAgICAgICAgIGNvbG9yID0gc291cmNlLmNvbG9yIHx8IGRlZmF1bHROb2RlQ29sb3I7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ3RhcmdldCc6XG4gICAgICAgICAgY29sb3IgPSB0YXJnZXQuY29sb3IgfHwgZGVmYXVsdE5vZGVDb2xvcjtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICBjb2xvciA9IGRlZmF1bHRFZGdlQ29sb3I7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICByZXR1cm4gY29sb3I7XG4gIH1cblxuICBkcmF3TGFiZWwobm9kZSwgY29udGV4dCwgc2V0dGluZ3MpIHtcbiAgICB2YXIgZm9udFNpemUsXG4gICAgICBwcmVmaXggPSBzZXR0aW5ncygncHJlZml4JykgfHwgJycsXG4gICAgICBzaXplID0gbm9kZVtwcmVmaXggKyAnc2l6ZSddO1xuXG4gICAgaWYgKHNpemUgPCBzZXR0aW5ncygnbGFiZWxUaHJlc2hvbGQnKSlcbiAgICAgIHJldHVybjtcblxuICAgIGlmICghbm9kZS5sYWJlbCB8fCB0eXBlb2Ygbm9kZS5sYWJlbCAhPT0gJ3N0cmluZycpXG4gICAgICByZXR1cm47XG5cbiAgICBmb250U2l6ZSA9IChzZXR0aW5ncygnbGFiZWxTaXplJykgPT09ICdmaXhlZCcpID9cbiAgICAgIHNldHRpbmdzKCdkZWZhdWx0TGFiZWxTaXplJykgOlxuICAgIHNldHRpbmdzKCdsYWJlbFNpemVSYXRpbycpICogc2l6ZTtcblxuICAgIGNvbnRleHQuZm9udCA9IChzZXR0aW5ncygnZm9udFN0eWxlJykgPyBzZXR0aW5ncygnZm9udFN0eWxlJykgKyAnICcgOiAnJykgK1xuICAgICAgZm9udFNpemUgKyAncHggJyArIHNldHRpbmdzKCdmb250Jyk7XG4gICAgY29udGV4dC5maWxsU3R5bGUgPSAoc2V0dGluZ3MoJ2xhYmVsQ29sb3InKSA9PT0gJ25vZGUnKSA/XG4gICAgICAobm9kZS5jb2xvciB8fCBzZXR0aW5ncygnZGVmYXVsdE5vZGVDb2xvcicpKSA6XG4gICAgICBzZXR0aW5ncygnZGVmYXVsdExhYmVsQ29sb3InKTtcblxuICAgIGNvbnRleHQudGV4dEFsaWduID0gJ2NlbnRlcic7XG4gICAgY29udGV4dC5maWxsVGV4dChcbiAgICAgIG5vZGUubGFiZWwsXG4gICAgICBNYXRoLnJvdW5kKG5vZGVbcHJlZml4ICsgJ3gnXSksXG4gICAgICBNYXRoLnJvdW5kKG5vZGVbcHJlZml4ICsgJ3knXSArIGZvbnRTaXplIC8gMylcbiAgICApO1xuICB9XG5cbiAgZHJhd0Fycm93KGVkZ2UsIHNvdXJjZSwgdGFyZ2V0LCBjb2xvciwgY29udGV4dCwgc2V0dGluZ3MpIHtcbiAgICB2YXIgcHJlZml4ID0gc2V0dGluZ3MoJ3ByZWZpeCcpIHx8ICcnLFxuICAgICAgc2l6ZSA9IGVkZ2VbcHJlZml4ICsgJ3NpemUnXSB8fCAxLFxuICAgICAgdFNpemUgPSB0YXJnZXRbcHJlZml4ICsgJ3NpemUnXSxcbiAgICAgIHNYID0gc291cmNlW3ByZWZpeCArICd4J10sXG4gICAgICBzWSA9IHNvdXJjZVtwcmVmaXggKyAneSddLFxuICAgICAgdFggPSB0YXJnZXRbcHJlZml4ICsgJ3gnXSxcbiAgICAgIHRZID0gdGFyZ2V0W3ByZWZpeCArICd5J10sXG4gICAgICBhbmdsZSA9IE1hdGguYXRhbjIodFkgLSBzWSwgdFggLSBzWCksXG4gICAgICBkaXN0ID0gMztcbiAgICBzWCArPSBNYXRoLnNpbihhbmdsZSkgKiBkaXN0O1xuICAgIHRYICs9IE1hdGguc2luKGFuZ2xlKSAqIGRpc3Q7XG4gICAgc1kgKz0gLU1hdGguY29zKGFuZ2xlKSAqIGRpc3Q7XG4gICAgdFkgKz0gLU1hdGguY29zKGFuZ2xlKSAqIGRpc3Q7XG4gICAgdmFyIGFTaXplID0gTWF0aC5tYXgoc2l6ZSAqIDIuNSwgc2V0dGluZ3MoJ21pbkFycm93U2l6ZScpKSxcbiAgICAgIGQgPSBNYXRoLnNxcnQoTWF0aC5wb3codFggLSBzWCwgMikgKyBNYXRoLnBvdyh0WSAtIHNZLCAyKSksXG4gICAgICBhWCA9IHNYICsgKHRYIC0gc1gpICogKGQgLSBhU2l6ZSAtIHRTaXplKSAvIGQsXG4gICAgICBhWSA9IHNZICsgKHRZIC0gc1kpICogKGQgLSBhU2l6ZSAtIHRTaXplKSAvIGQsXG4gICAgICB2WCA9ICh0WCAtIHNYKSAqIGFTaXplIC8gZCxcbiAgICAgIHZZID0gKHRZIC0gc1kpICogYVNpemUgLyBkO1xuXG4gICAgY29udGV4dC5zdHJva2VTdHlsZSA9IGNvbG9yO1xuICAgIGNvbnRleHQubGluZVdpZHRoID0gc2l6ZTtcbiAgICBjb250ZXh0LmJlZ2luUGF0aCgpO1xuICAgIGNvbnRleHQubW92ZVRvKHNYLCBzWSk7XG4gICAgY29udGV4dC5saW5lVG8oXG4gICAgICBhWCxcbiAgICAgIGFZXG4gICAgKTtcbiAgICBjb250ZXh0LnN0cm9rZSgpO1xuXG4gICAgY29udGV4dC5maWxsU3R5bGUgPSBjb2xvcjtcbiAgICBjb250ZXh0LmJlZ2luUGF0aCgpO1xuICAgIGNvbnRleHQubW92ZVRvKGFYICsgdlgsIGFZICsgdlkpO1xuICAgIGNvbnRleHQubGluZVRvKGFYICsgdlkgKiAwLjYsIGFZIC0gdlggKiAwLjYpO1xuICAgIGNvbnRleHQubGluZVRvKGFYIC0gdlkgKiAwLjYsIGFZICsgdlggKiAwLjYpO1xuICAgIGNvbnRleHQubGluZVRvKGFYICsgdlgsIGFZICsgdlkpO1xuICAgIGNvbnRleHQuY2xvc2VQYXRoKCk7XG4gICAgY29udGV4dC5maWxsKCk7XG4gIH1cblxuICBkcmF3T25Ib3Zlcihub2RlLCBjb250ZXh0LCBzZXR0aW5ncywgbmV4dCkge1xuICAgIHZhciB0cmFjZXIgPSB0aGlzO1xuXG4gICAgY29udGV4dC5zZXRMaW5lRGFzaChbNSwgNV0pO1xuICAgIHZhciBub2RlSWR4ID0gbm9kZS5pZC5zdWJzdHJpbmcoMSk7XG4gICAgdGhpcy5ncmFwaC5lZGdlcygpLmZvckVhY2goZnVuY3Rpb24gKGVkZ2UpIHtcbiAgICAgIHZhciBlbmRzID0gZWRnZS5pZC5zdWJzdHJpbmcoMSkuc3BsaXQoXCJfXCIpO1xuICAgICAgaWYgKGVuZHNbMF0gPT0gbm9kZUlkeCkge1xuICAgICAgICB2YXIgY29sb3IgPSAnIzBmZic7XG4gICAgICAgIHZhciBzb3VyY2UgPSBub2RlO1xuICAgICAgICB2YXIgdGFyZ2V0ID0gdHJhY2VyLmdyYXBoLm5vZGVzKCduJyArIGVuZHNbMV0pO1xuICAgICAgICB0cmFjZXIuZHJhd0Fycm93KGVkZ2UsIHNvdXJjZSwgdGFyZ2V0LCBjb2xvciwgY29udGV4dCwgc2V0dGluZ3MpO1xuICAgICAgICBpZiAobmV4dCkgbmV4dChlZGdlLCBzb3VyY2UsIHRhcmdldCwgY29sb3IsIGNvbnRleHQsIHNldHRpbmdzKTtcbiAgICAgIH0gZWxzZSBpZiAoZW5kc1sxXSA9PSBub2RlSWR4KSB7XG4gICAgICAgIHZhciBjb2xvciA9ICcjZmYwJztcbiAgICAgICAgdmFyIHNvdXJjZSA9IHRyYWNlci5ncmFwaC5ub2RlcygnbicgKyBlbmRzWzBdKTtcbiAgICAgICAgdmFyIHRhcmdldCA9IG5vZGU7XG4gICAgICAgIHRyYWNlci5kcmF3QXJyb3coZWRnZSwgc291cmNlLCB0YXJnZXQsIGNvbG9yLCBjb250ZXh0LCBzZXR0aW5ncyk7XG4gICAgICAgIGlmIChuZXh0KSBuZXh0KGVkZ2UsIHNvdXJjZSwgdGFyZ2V0LCBjb2xvciwgY29udGV4dCwgc2V0dGluZ3MpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG59XG5cbmNvbnN0IGluaXRWaWV3ID0gKHRyYWNlcikgPT4ge1xuICB0cmFjZXIucyA9IHRyYWNlci5jYXBzdWxlLnMgPSBuZXcgc2lnbWEoe1xuICAgIHJlbmRlcmVyOiB7XG4gICAgICBjb250YWluZXI6IHRyYWNlci4kY29udGFpbmVyWzBdLFxuICAgICAgdHlwZTogJ2NhbnZhcydcbiAgICB9LFxuICAgIHNldHRpbmdzOiB7XG4gICAgICBtaW5BcnJvd1NpemU6IDgsXG4gICAgICBkZWZhdWx0RWRnZVR5cGU6ICdhcnJvdycsXG4gICAgICBtYXhFZGdlU2l6ZTogMi41LFxuICAgICAgbGFiZWxUaHJlc2hvbGQ6IDQsXG4gICAgICBmb250OiAnUm9ib3RvJyxcbiAgICAgIGRlZmF1bHRMYWJlbENvbG9yOiAnI2ZmZicsXG4gICAgICB6b29tTWluOiAwLjYsXG4gICAgICB6b29tTWF4OiAxLjIsXG4gICAgICBza2lwRXJyb3JzOiB0cnVlLFxuICAgICAgbWluTm9kZVNpemU6IC41LFxuICAgICAgbWF4Tm9kZVNpemU6IDEyLFxuICAgICAgbGFiZWxTaXplOiAncHJvcG9ydGlvbmFsJyxcbiAgICAgIGxhYmVsU2l6ZVJhdGlvOiAxLjMsXG4gICAgICBmdW5jTGFiZWxzRGVmKG5vZGUsIGNvbnRleHQsIHNldHRpbmdzKSB7XG4gICAgICAgIHRyYWNlci5kcmF3TGFiZWwobm9kZSwgY29udGV4dCwgc2V0dGluZ3MpO1xuICAgICAgfSxcbiAgICAgIGZ1bmNIb3ZlcnNEZWYobm9kZSwgY29udGV4dCwgc2V0dGluZ3MsIG5leHQpIHtcbiAgICAgICAgdHJhY2VyLmRyYXdPbkhvdmVyKG5vZGUsIGNvbnRleHQsIHNldHRpbmdzLCBuZXh0KTtcbiAgICAgIH0sXG4gICAgICBmdW5jRWRnZXNBcnJvdyhlZGdlLCBzb3VyY2UsIHRhcmdldCwgY29udGV4dCwgc2V0dGluZ3MpIHtcbiAgICAgICAgdmFyIGNvbG9yID0gdHJhY2VyLmdldENvbG9yKGVkZ2UsIHNvdXJjZSwgdGFyZ2V0LCBzZXR0aW5ncyk7XG4gICAgICAgIHRyYWNlci5kcmF3QXJyb3coZWRnZSwgc291cmNlLCB0YXJnZXQsIGNvbG9yLCBjb250ZXh0LCBzZXR0aW5ncyk7XG4gICAgICB9XG4gICAgfVxuICB9KTtcbiAgc2lnbWEucGx1Z2lucy5kcmFnTm9kZXModHJhY2VyLnMsIHRyYWNlci5zLnJlbmRlcmVyc1swXSk7XG4gIHRyYWNlci5ncmFwaCA9IHRyYWNlci5jYXBzdWxlLmdyYXBoID0gdHJhY2VyLnMuZ3JhcGg7XG59O1xuXG5zaWdtYS5jYW52YXMubGFiZWxzLmRlZiA9IGZ1bmN0aW9uIChub2RlLCBjb250ZXh0LCBzZXR0aW5ncykge1xuICB2YXIgZnVuYyA9IHNldHRpbmdzKCdmdW5jTGFiZWxzRGVmJyk7XG4gIGlmIChmdW5jKSB7XG4gICAgZnVuYyhub2RlLCBjb250ZXh0LCBzZXR0aW5ncyk7XG4gIH1cbn07XG5zaWdtYS5jYW52YXMuaG92ZXJzLmRlZiA9IGZ1bmN0aW9uIChub2RlLCBjb250ZXh0LCBzZXR0aW5ncykge1xuICB2YXIgZnVuYyA9IHNldHRpbmdzKCdmdW5jSG92ZXJzRGVmJyk7XG4gIGlmIChmdW5jKSB7XG4gICAgZnVuYyhub2RlLCBjb250ZXh0LCBzZXR0aW5ncyk7XG4gIH1cbn07XG5zaWdtYS5jYW52YXMuZWRnZXMuZGVmID0gZnVuY3Rpb24gKGVkZ2UsIHNvdXJjZSwgdGFyZ2V0LCBjb250ZXh0LCBzZXR0aW5ncykge1xuICB2YXIgZnVuYyA9IHNldHRpbmdzKCdmdW5jRWRnZXNEZWYnKTtcbiAgaWYgKGZ1bmMpIHtcbiAgICBmdW5jKGVkZ2UsIHNvdXJjZSwgdGFyZ2V0LCBjb250ZXh0LCBzZXR0aW5ncyk7XG4gIH1cbn07XG5zaWdtYS5jYW52YXMuZWRnZXMuYXJyb3cgPSBmdW5jdGlvbiAoZWRnZSwgc291cmNlLCB0YXJnZXQsIGNvbnRleHQsIHNldHRpbmdzKSB7XG4gIHZhciBmdW5jID0gc2V0dGluZ3MoJ2Z1bmNFZGdlc0Fycm93Jyk7XG4gIGlmIChmdW5jKSB7XG4gICAgZnVuYyhlZGdlLCBzb3VyY2UsIHRhcmdldCwgY29udGV4dCwgc2V0dGluZ3MpO1xuICB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IERpcmVjdGVkR3JhcGhUcmFjZXI7IiwiJ3VzZSBzdHJpY3QnO1xuXG5jb25zdCBUcmFjZXIgPSByZXF1aXJlKCcuL3RyYWNlcicpO1xuY29uc3QgTG9nVHJhY2VyID0gcmVxdWlyZSgnLi9sb2cnKTtcbmNvbnN0IEFycmF5MURUcmFjZXIgPSByZXF1aXJlKCcuL2FycmF5MWQnKTtcbmNvbnN0IEFycmF5MkRUcmFjZXIgPSByZXF1aXJlKCcuL2FycmF5MmQnKTtcbmNvbnN0IENoYXJ0VHJhY2VyID0gcmVxdWlyZSgnLi9jaGFydCcpO1xuY29uc3QgQ29vcmRpbmF0ZVN5c3RlbVRyYWNlciA9IHJlcXVpcmUoJy4vY29vcmRpbmF0ZV9zeXN0ZW0nKTtcbmNvbnN0IERpcmVjdGVkR3JhcGhUcmFjZXIgPSByZXF1aXJlKCcuL2RpcmVjdGVkX2dyYXBoJyk7XG5jb25zdCBVbmRpcmVjdGVkR3JhcGhUcmFjZXIgPSByZXF1aXJlKCcuL3VuZGlyZWN0ZWRfZ3JhcGgnKTtcbmNvbnN0IFdlaWdodGVkRGlyZWN0ZWRHcmFwaFRyYWNlciA9IHJlcXVpcmUoJy4vd2VpZ2h0ZWRfZGlyZWN0ZWRfZ3JhcGgnKTtcbmNvbnN0IFdlaWdodGVkVW5kaXJlY3RlZEdyYXBoVHJhY2VyID0gcmVxdWlyZSgnLi93ZWlnaHRlZF91bmRpcmVjdGVkX2dyYXBoJyk7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBUcmFjZXIsXG4gIExvZ1RyYWNlcixcbiAgQXJyYXkxRFRyYWNlcixcbiAgQXJyYXkyRFRyYWNlcixcbiAgQ2hhcnRUcmFjZXIsXG4gIENvb3JkaW5hdGVTeXN0ZW1UcmFjZXIsXG4gIERpcmVjdGVkR3JhcGhUcmFjZXIsXG4gIFVuZGlyZWN0ZWRHcmFwaFRyYWNlcixcbiAgV2VpZ2h0ZWREaXJlY3RlZEdyYXBoVHJhY2VyLFxuICBXZWlnaHRlZFVuZGlyZWN0ZWRHcmFwaFRyYWNlclxufTsiLCJjb25zdCBUcmFjZXIgPSByZXF1aXJlKCcuL3RyYWNlcicpO1xuXG5jbGFzcyBMb2dUcmFjZXIgZXh0ZW5kcyBUcmFjZXIge1xuICBzdGF0aWMgZ2V0Q2xhc3NOYW1lKCkge1xuICAgIHJldHVybiAnTG9nVHJhY2VyJztcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKG5hbWUpIHtcbiAgICBzdXBlcihuYW1lKTtcblxuICAgIGlmICh0aGlzLmlzTmV3KSBpbml0Vmlldyh0aGlzKTtcbiAgfVxuXG4gIF9wcmludChtc2cpIHtcbiAgICB0aGlzLm1hbmFnZXIucHVzaFN0ZXAodGhpcy5jYXBzdWxlLCB7XG4gICAgICB0eXBlOiAncHJpbnQnLFxuICAgICAgbXNnOiBtc2dcbiAgICB9KTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHByb2Nlc3NTdGVwKHN0ZXAsIG9wdGlvbnMpIHtcbiAgICBzd2l0Y2ggKHN0ZXAudHlwZSkge1xuICAgICAgY2FzZSAncHJpbnQnOlxuICAgICAgICB0aGlzLnByaW50KHN0ZXAubXNnKTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgcmVmcmVzaCgpIHtcbiAgICB0aGlzLnNjcm9sbFRvRW5kKE1hdGgubWluKDUwLCB0aGlzLmludGVydmFsKSk7XG4gIH1cblxuICBjbGVhcigpIHtcbiAgICBzdXBlci5jbGVhcigpO1xuXG4gICAgdGhpcy4kd3JhcHBlci5lbXB0eSgpO1xuICB9XG5cbiAgcHJpbnQobWVzc2FnZSkge1xuICAgIHRoaXMuJHdyYXBwZXIuYXBwZW5kKCQoJzxzcGFuPicpLmFwcGVuZChtZXNzYWdlICsgJzxici8+JykpO1xuICB9XG5cbiAgc2Nyb2xsVG9FbmQoZHVyYXRpb24pIHtcbiAgICB0aGlzLiRjb250YWluZXIuYW5pbWF0ZSh7XG4gICAgICBzY3JvbGxUb3A6IHRoaXMuJGNvbnRhaW5lclswXS5zY3JvbGxIZWlnaHRcbiAgICB9LCBkdXJhdGlvbik7XG4gIH1cbn1cblxuY29uc3QgaW5pdFZpZXcgPSAodHJhY2VyKSA9PiB7XG4gIHRyYWNlci4kd3JhcHBlciA9IHRyYWNlci5jYXBzdWxlLiR3cmFwcGVyID0gJCgnPGRpdiBjbGFzcz1cIndyYXBwZXJcIj4nKTtcbiAgdHJhY2VyLiRjb250YWluZXIuYXBwZW5kKHRyYWNlci4kd3JhcHBlcik7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IExvZ1RyYWNlcjsiLCJjb25zdCBhcHAgPSByZXF1aXJlKCcuLi8uLi9hcHAnKTtcblxuY29uc3Qge1xuICB0b0pTT04sXG4gIGZyb21KU09OXG59ID0gcmVxdWlyZSgnLi4vLi4vdHJhY2VyX21hbmFnZXIvdXRpbC9pbmRleCcpO1xuXG5jbGFzcyBUcmFjZXIge1xuICBzdGF0aWMgZ2V0Q2xhc3NOYW1lKCkge1xuICAgIHJldHVybiAnVHJhY2VyJztcbiAgfVxuICBcbiAgY29uc3RydWN0b3IobmFtZSkge1xuICAgIHRoaXMubW9kdWxlID0gdGhpcy5jb25zdHJ1Y3RvcjtcblxuICAgIHRoaXMubWFuYWdlciA9IGFwcC5nZXRUcmFjZXJNYW5hZ2VyKCk7XG4gICAgdGhpcy5jYXBzdWxlID0gdGhpcy5tYW5hZ2VyLmFsbG9jYXRlKHRoaXMpO1xuICAgICQuZXh0ZW5kKHRoaXMsIHRoaXMuY2Fwc3VsZSk7XG5cbiAgICB0aGlzLnNldE5hbWUobmFtZSk7XG4gIH1cblxuICBfc2V0RGF0YSguLi5hcmdzKSB7XG4gICAgdGhpcy5tYW5hZ2VyLnB1c2hTdGVwKHRoaXMuY2Fwc3VsZSwge1xuICAgICAgdHlwZTogJ3NldERhdGEnLFxuICAgICAgYXJnczogdG9KU09OKGFyZ3MpXG4gICAgfSk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBfY2xlYXIoKSB7XG4gICAgdGhpcy5tYW5hZ2VyLnB1c2hTdGVwKHRoaXMuY2Fwc3VsZSwge1xuICAgICAgdHlwZTogJ2NsZWFyJ1xuICAgIH0pO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgX3dhaXQoKSB7XG4gICAgdGhpcy5tYW5hZ2VyLm5ld1N0ZXAoKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHByb2Nlc3NTdGVwKHN0ZXAsIG9wdGlvbnMpIHtcbiAgICBjb25zdCB7XG4gICAgICB0eXBlLFxuICAgICAgYXJnc1xuICAgIH0gPSBzdGVwO1xuXG4gICAgc3dpdGNoICh0eXBlKSB7XG4gICAgICBjYXNlICdzZXREYXRhJzpcbiAgICAgICAgdGhpcy5zZXREYXRhKC4uLmZyb21KU09OKGFyZ3MpKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdjbGVhcic6XG4gICAgICAgIHRoaXMuY2xlYXIoKTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgc2V0TmFtZShuYW1lKSB7XG4gICAgbGV0ICRuYW1lO1xuICAgIGlmICh0aGlzLmlzTmV3KSB7XG4gICAgICAkbmFtZSA9ICQoJzxzcGFuIGNsYXNzPVwibmFtZVwiPicpO1xuICAgICAgdGhpcy4kY29udGFpbmVyLmFwcGVuZCgkbmFtZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICRuYW1lID0gdGhpcy4kY29udGFpbmVyLmZpbmQoJ3NwYW4ubmFtZScpO1xuICAgIH1cbiAgICAkbmFtZS50ZXh0KG5hbWUgfHwgdGhpcy5kZWZhdWx0TmFtZSk7XG4gIH1cblxuICBzZXREYXRhKCkge1xuICAgIGNvbnN0IGRhdGEgPSB0b0pTT04oYXJndW1lbnRzKTtcbiAgICBpZiAoIXRoaXMuaXNOZXcgJiYgdGhpcy5sYXN0RGF0YSA9PT0gZGF0YSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHRoaXMubGFzdERhdGEgPSB0aGlzLmNhcHN1bGUubGFzdERhdGEgPSBkYXRhO1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHJlc2l6ZSgpIHtcbiAgfVxuXG4gIHJlZnJlc2goKSB7XG4gIH1cblxuICBjbGVhcigpIHtcbiAgfVxuXG4gIGF0dGFjaCh0cmFjZXIpIHtcbiAgICBpZiAodHJhY2VyLm1vZHVsZSA9PT0gTG9nVHJhY2VyKSB7XG4gICAgICB0aGlzLmxvZ1RyYWNlciA9IHRyYWNlcjtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBtb3VzZWRvd24oZSkge1xuICB9XG5cbiAgbW91c2Vtb3ZlKGUpIHtcbiAgfVxuXG4gIG1vdXNldXAoZSkge1xuICB9XG5cbiAgbW91c2V3aGVlbChlKSB7XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBUcmFjZXI7IiwiY29uc3QgRGlyZWN0ZWRHcmFwaFRyYWNlciA9IHJlcXVpcmUoJy4vZGlyZWN0ZWRfZ3JhcGgnKTtcblxuY2xhc3MgVW5kaXJlY3RlZEdyYXBoVHJhY2VyIGV4dGVuZHMgRGlyZWN0ZWRHcmFwaFRyYWNlciB7XG4gIHN0YXRpYyBnZXRDbGFzc05hbWUoKSB7XG4gICAgcmV0dXJuICdVbmRpcmVjdGVkR3JhcGhUcmFjZXInO1xuICB9XG5cbiAgY29uc3RydWN0b3IobmFtZSkge1xuICAgIHN1cGVyKG5hbWUpO1xuXG4gICAgaWYgKHRoaXMuaXNOZXcpIGluaXRWaWV3KHRoaXMpO1xuICB9XG5cbiAgc2V0VHJlZURhdGEoRywgcm9vdCkge1xuICAgIHJldHVybiBzdXBlci5zZXRUcmVlRGF0YShHLCByb290LCB0cnVlKTtcbiAgfVxuXG4gIHNldERhdGEoRykge1xuICAgIHJldHVybiBzdXBlci5zZXREYXRhKEcsIHRydWUpO1xuICB9XG5cbiAgZSh2MSwgdjIpIHtcbiAgICBpZiAodjEgPiB2Mikge1xuICAgICAgdmFyIHRlbXAgPSB2MTtcbiAgICAgIHYxID0gdjI7XG4gICAgICB2MiA9IHRlbXA7XG4gICAgfVxuICAgIHJldHVybiAnZScgKyB2MSArICdfJyArIHYyO1xuICB9XG5cbiAgZHJhd09uSG92ZXIobm9kZSwgY29udGV4dCwgc2V0dGluZ3MsIG5leHQpIHtcbiAgICB2YXIgdHJhY2VyID0gdGhpcztcblxuICAgIGNvbnRleHQuc2V0TGluZURhc2goWzUsIDVdKTtcbiAgICB2YXIgbm9kZUlkeCA9IG5vZGUuaWQuc3Vic3RyaW5nKDEpO1xuICAgIHRoaXMuZ3JhcGguZWRnZXMoKS5mb3JFYWNoKGZ1bmN0aW9uIChlZGdlKSB7XG4gICAgICB2YXIgZW5kcyA9IGVkZ2UuaWQuc3Vic3RyaW5nKDEpLnNwbGl0KFwiX1wiKTtcbiAgICAgIGlmIChlbmRzWzBdID09IG5vZGVJZHgpIHtcbiAgICAgICAgdmFyIGNvbG9yID0gJyMwZmYnO1xuICAgICAgICB2YXIgc291cmNlID0gbm9kZTtcbiAgICAgICAgdmFyIHRhcmdldCA9IHRyYWNlci5ncmFwaC5ub2RlcygnbicgKyBlbmRzWzFdKTtcbiAgICAgICAgdHJhY2VyLmRyYXdFZGdlKGVkZ2UsIHNvdXJjZSwgdGFyZ2V0LCBjb2xvciwgY29udGV4dCwgc2V0dGluZ3MpO1xuICAgICAgICBpZiAobmV4dCkgbmV4dChlZGdlLCBzb3VyY2UsIHRhcmdldCwgY29sb3IsIGNvbnRleHQsIHNldHRpbmdzKTtcbiAgICAgIH0gZWxzZSBpZiAoZW5kc1sxXSA9PSBub2RlSWR4KSB7XG4gICAgICAgIHZhciBjb2xvciA9ICcjMGZmJztcbiAgICAgICAgdmFyIHNvdXJjZSA9IHRyYWNlci5ncmFwaC5ub2RlcygnbicgKyBlbmRzWzBdKTtcbiAgICAgICAgdmFyIHRhcmdldCA9IG5vZGU7XG4gICAgICAgIHRyYWNlci5kcmF3RWRnZShlZGdlLCBzb3VyY2UsIHRhcmdldCwgY29sb3IsIGNvbnRleHQsIHNldHRpbmdzKTtcbiAgICAgICAgaWYgKG5leHQpIG5leHQoZWRnZSwgc291cmNlLCB0YXJnZXQsIGNvbG9yLCBjb250ZXh0LCBzZXR0aW5ncyk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBkcmF3RWRnZShlZGdlLCBzb3VyY2UsIHRhcmdldCwgY29sb3IsIGNvbnRleHQsIHNldHRpbmdzKSB7XG4gICAgdmFyIHByZWZpeCA9IHNldHRpbmdzKCdwcmVmaXgnKSB8fCAnJyxcbiAgICAgIHNpemUgPSBlZGdlW3ByZWZpeCArICdzaXplJ10gfHwgMTtcblxuICAgIGNvbnRleHQuc3Ryb2tlU3R5bGUgPSBjb2xvcjtcbiAgICBjb250ZXh0LmxpbmVXaWR0aCA9IHNpemU7XG4gICAgY29udGV4dC5iZWdpblBhdGgoKTtcbiAgICBjb250ZXh0Lm1vdmVUbyhcbiAgICAgIHNvdXJjZVtwcmVmaXggKyAneCddLFxuICAgICAgc291cmNlW3ByZWZpeCArICd5J11cbiAgICApO1xuICAgIGNvbnRleHQubGluZVRvKFxuICAgICAgdGFyZ2V0W3ByZWZpeCArICd4J10sXG4gICAgICB0YXJnZXRbcHJlZml4ICsgJ3knXVxuICAgICk7XG4gICAgY29udGV4dC5zdHJva2UoKTtcbiAgfVxufVxuXG5jb25zdCBpbml0VmlldyA9ICh0cmFjZXIpID0+IHtcbiAgdHJhY2VyLnMuc2V0dGluZ3Moe1xuICAgIGRlZmF1bHRFZGdlVHlwZTogJ2RlZicsXG4gICAgZnVuY0VkZ2VzRGVmKGVkZ2UsIHNvdXJjZSwgdGFyZ2V0LCBjb250ZXh0LCBzZXR0aW5ncykge1xuICAgICAgdmFyIGNvbG9yID0gdHJhY2VyLmdldENvbG9yKGVkZ2UsIHNvdXJjZSwgdGFyZ2V0LCBzZXR0aW5ncyk7XG4gICAgICB0cmFjZXIuZHJhd0VkZ2UoZWRnZSwgc291cmNlLCB0YXJnZXQsIGNvbG9yLCBjb250ZXh0LCBzZXR0aW5ncyk7XG4gICAgfVxuICB9KTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gVW5kaXJlY3RlZEdyYXBoVHJhY2VyOyIsImNvbnN0IERpcmVjdGVkR3JhcGhUcmFjZXIgPSByZXF1aXJlKCcuL2RpcmVjdGVkX2dyYXBoJyk7XG5cbmNvbnN0IHtcbiAgcmVmaW5lQnlUeXBlXG59ID0gcmVxdWlyZSgnLi4vLi4vdHJhY2VyX21hbmFnZXIvdXRpbC9pbmRleCcpO1xuXG5jbGFzcyBXZWlnaHRlZERpcmVjdGVkR3JhcGhUcmFjZXIgZXh0ZW5kcyBEaXJlY3RlZEdyYXBoVHJhY2VyIHtcbiAgc3RhdGljIGdldENsYXNzTmFtZSgpIHtcbiAgICByZXR1cm4gJ1dlaWdodGVkRGlyZWN0ZWRHcmFwaFRyYWNlcic7XG4gIH1cblxuICBjb25zdHJ1Y3RvcihuYW1lKSB7XG4gICAgc3VwZXIobmFtZSk7XG5cbiAgICBpZiAodGhpcy5pc05ldykgaW5pdFZpZXcodGhpcyk7XG4gIH1cblxuICBfd2VpZ2h0KHRhcmdldCwgd2VpZ2h0KSB7XG4gICAgdGhpcy5tYW5hZ2VyLnB1c2hTdGVwKHRoaXMuY2Fwc3VsZSwge1xuICAgICAgdHlwZTogJ3dlaWdodCcsXG4gICAgICB0YXJnZXQ6IHRhcmdldCxcbiAgICAgIHdlaWdodDogd2VpZ2h0XG4gICAgfSk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBfdmlzaXQodGFyZ2V0LCBzb3VyY2UsIHdlaWdodCkge1xuICAgIHRoaXMubWFuYWdlci5wdXNoU3RlcCh0aGlzLmNhcHN1bGUsIHtcbiAgICAgIHR5cGU6ICd2aXNpdCcsXG4gICAgICB0YXJnZXQ6IHRhcmdldCxcbiAgICAgIHNvdXJjZTogc291cmNlLFxuICAgICAgd2VpZ2h0OiB3ZWlnaHRcbiAgICB9KTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIF9sZWF2ZSh0YXJnZXQsIHNvdXJjZSwgd2VpZ2h0KSB7XG4gICAgdGhpcy5tYW5hZ2VyLnB1c2hTdGVwKHRoaXMuY2Fwc3VsZSwge1xuICAgICAgdHlwZTogJ2xlYXZlJyxcbiAgICAgIHRhcmdldDogdGFyZ2V0LFxuICAgICAgc291cmNlOiBzb3VyY2UsXG4gICAgICB3ZWlnaHQ6IHdlaWdodFxuICAgIH0pO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgcHJvY2Vzc1N0ZXAoc3RlcCwgb3B0aW9ucykge1xuICAgIHN3aXRjaCAoc3RlcC50eXBlKSB7XG4gICAgICBjYXNlICd3ZWlnaHQnOlxuICAgICAgICB2YXIgdGFyZ2V0Tm9kZSA9IHRoaXMuZ3JhcGgubm9kZXModGhpcy5uKHN0ZXAudGFyZ2V0KSk7XG4gICAgICAgIGlmIChzdGVwLndlaWdodCAhPT0gdW5kZWZpbmVkKSB0YXJnZXROb2RlLndlaWdodCA9IHJlZmluZUJ5VHlwZShzdGVwLndlaWdodCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAndmlzaXQnOlxuICAgICAgY2FzZSAnbGVhdmUnOlxuICAgICAgICB2YXIgdmlzaXQgPSBzdGVwLnR5cGUgPT0gJ3Zpc2l0JztcbiAgICAgICAgdmFyIHRhcmdldE5vZGUgPSB0aGlzLmdyYXBoLm5vZGVzKHRoaXMubihzdGVwLnRhcmdldCkpO1xuICAgICAgICB2YXIgY29sb3IgPSB2aXNpdCA/IHN0ZXAud2VpZ2h0ID09PSB1bmRlZmluZWQgPyB0aGlzLmNvbG9yLnNlbGVjdGVkIDogdGhpcy5jb2xvci52aXNpdGVkIDogdGhpcy5jb2xvci5sZWZ0O1xuICAgICAgICB0YXJnZXROb2RlLmNvbG9yID0gY29sb3I7XG4gICAgICAgIGlmIChzdGVwLndlaWdodCAhPT0gdW5kZWZpbmVkKSB0YXJnZXROb2RlLndlaWdodCA9IHJlZmluZUJ5VHlwZShzdGVwLndlaWdodCk7XG4gICAgICAgIGlmIChzdGVwLnNvdXJjZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdmFyIGVkZ2VJZCA9IHRoaXMuZShzdGVwLnNvdXJjZSwgc3RlcC50YXJnZXQpO1xuICAgICAgICAgIHZhciBlZGdlID0gdGhpcy5ncmFwaC5lZGdlcyhlZGdlSWQpO1xuICAgICAgICAgIGVkZ2UuY29sb3IgPSBjb2xvcjtcbiAgICAgICAgICB0aGlzLmdyYXBoLmRyb3BFZGdlKGVkZ2VJZCkuYWRkRWRnZShlZGdlKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5sb2dUcmFjZXIpIHtcbiAgICAgICAgICB2YXIgc291cmNlID0gc3RlcC5zb3VyY2U7XG4gICAgICAgICAgaWYgKHNvdXJjZSA9PT0gdW5kZWZpbmVkKSBzb3VyY2UgPSAnJztcbiAgICAgICAgICB0aGlzLmxvZ1RyYWNlci5wcmludCh2aXNpdCA/IHNvdXJjZSArICcgLT4gJyArIHN0ZXAudGFyZ2V0IDogc291cmNlICsgJyA8LSAnICsgc3RlcC50YXJnZXQpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgc3VwZXIucHJvY2Vzc1N0ZXAoc3RlcCwgb3B0aW9ucyk7XG4gICAgfVxuICB9XG5cbiAgY2xlYXIoKSB7XG4gICAgc3VwZXIuY2xlYXIoKTtcblxuICAgIHRoaXMuY2xlYXJXZWlnaHRzKCk7XG4gIH1cblxuICBjbGVhcldlaWdodHMoKSB7XG4gICAgdGhpcy5ncmFwaC5ub2RlcygpLmZvckVhY2goZnVuY3Rpb24gKG5vZGUpIHtcbiAgICAgIG5vZGUud2VpZ2h0ID0gMDtcbiAgICB9KTtcbiAgfVxuXG4gIGRyYXdFZGdlV2VpZ2h0KGVkZ2UsIHNvdXJjZSwgdGFyZ2V0LCBjb2xvciwgY29udGV4dCwgc2V0dGluZ3MpIHtcbiAgICBpZiAoc291cmNlID09IHRhcmdldClcbiAgICAgIHJldHVybjtcblxuICAgIHZhciBwcmVmaXggPSBzZXR0aW5ncygncHJlZml4JykgfHwgJycsXG4gICAgICBzaXplID0gZWRnZVtwcmVmaXggKyAnc2l6ZSddIHx8IDE7XG5cbiAgICBpZiAoc2l6ZSA8IHNldHRpbmdzKCdlZGdlTGFiZWxUaHJlc2hvbGQnKSlcbiAgICAgIHJldHVybjtcblxuICAgIGlmICgwID09PSBzZXR0aW5ncygnZWRnZUxhYmVsU2l6ZVBvd1JhdGlvJykpXG4gICAgICB0aHJvdyAnXCJlZGdlTGFiZWxTaXplUG93UmF0aW9cIiBtdXN0IG5vdCBiZSAwLic7XG5cbiAgICB2YXIgZm9udFNpemUsXG4gICAgICB4ID0gKHNvdXJjZVtwcmVmaXggKyAneCddICsgdGFyZ2V0W3ByZWZpeCArICd4J10pIC8gMixcbiAgICAgIHkgPSAoc291cmNlW3ByZWZpeCArICd5J10gKyB0YXJnZXRbcHJlZml4ICsgJ3knXSkgLyAyLFxuICAgICAgZFggPSB0YXJnZXRbcHJlZml4ICsgJ3gnXSAtIHNvdXJjZVtwcmVmaXggKyAneCddLFxuICAgICAgZFkgPSB0YXJnZXRbcHJlZml4ICsgJ3knXSAtIHNvdXJjZVtwcmVmaXggKyAneSddLFxuICAgICAgYW5nbGUgPSBNYXRoLmF0YW4yKGRZLCBkWCk7XG5cbiAgICBmb250U2l6ZSA9IChzZXR0aW5ncygnZWRnZUxhYmVsU2l6ZScpID09PSAnZml4ZWQnKSA/XG4gICAgICBzZXR0aW5ncygnZGVmYXVsdEVkZ2VMYWJlbFNpemUnKSA6XG4gICAgc2V0dGluZ3MoJ2RlZmF1bHRFZGdlTGFiZWxTaXplJykgKlxuICAgIHNpemUgKlxuICAgIE1hdGgucG93KHNpemUsIC0xIC8gc2V0dGluZ3MoJ2VkZ2VMYWJlbFNpemVQb3dSYXRpbycpKTtcblxuICAgIGNvbnRleHQuc2F2ZSgpO1xuXG4gICAgaWYgKGVkZ2UuYWN0aXZlKSB7XG4gICAgICBjb250ZXh0LmZvbnQgPSBbXG4gICAgICAgIHNldHRpbmdzKCdhY3RpdmVGb250U3R5bGUnKSxcbiAgICAgICAgZm9udFNpemUgKyAncHgnLFxuICAgICAgICBzZXR0aW5ncygnYWN0aXZlRm9udCcpIHx8IHNldHRpbmdzKCdmb250JylcbiAgICAgIF0uam9pbignICcpO1xuXG4gICAgICBjb250ZXh0LmZpbGxTdHlsZSA9IGNvbG9yO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb250ZXh0LmZvbnQgPSBbXG4gICAgICAgIHNldHRpbmdzKCdmb250U3R5bGUnKSxcbiAgICAgICAgZm9udFNpemUgKyAncHgnLFxuICAgICAgICBzZXR0aW5ncygnZm9udCcpXG4gICAgICBdLmpvaW4oJyAnKTtcblxuICAgICAgY29udGV4dC5maWxsU3R5bGUgPSBjb2xvcjtcbiAgICB9XG5cbiAgICBjb250ZXh0LnRleHRBbGlnbiA9ICdjZW50ZXInO1xuICAgIGNvbnRleHQudGV4dEJhc2VsaW5lID0gJ2FscGhhYmV0aWMnO1xuXG4gICAgY29udGV4dC50cmFuc2xhdGUoeCwgeSk7XG4gICAgY29udGV4dC5yb3RhdGUoYW5nbGUpO1xuICAgIGNvbnRleHQuZmlsbFRleHQoXG4gICAgICBlZGdlLndlaWdodCxcbiAgICAgIDAsXG4gICAgICAoLXNpemUgLyAyKSAtIDNcbiAgICApO1xuXG4gICAgY29udGV4dC5yZXN0b3JlKCk7XG4gIH1cblxuICBkcmF3Tm9kZVdlaWdodChub2RlLCBjb250ZXh0LCBzZXR0aW5ncykge1xuICAgIHZhciBmb250U2l6ZSxcbiAgICAgIHByZWZpeCA9IHNldHRpbmdzKCdwcmVmaXgnKSB8fCAnJyxcbiAgICAgIHNpemUgPSBub2RlW3ByZWZpeCArICdzaXplJ107XG5cbiAgICBpZiAoc2l6ZSA8IHNldHRpbmdzKCdsYWJlbFRocmVzaG9sZCcpKVxuICAgICAgcmV0dXJuO1xuXG4gICAgZm9udFNpemUgPSAoc2V0dGluZ3MoJ2xhYmVsU2l6ZScpID09PSAnZml4ZWQnKSA/XG4gICAgICBzZXR0aW5ncygnZGVmYXVsdExhYmVsU2l6ZScpIDpcbiAgICBzZXR0aW5ncygnbGFiZWxTaXplUmF0aW8nKSAqIHNpemU7XG5cbiAgICBjb250ZXh0LmZvbnQgPSAoc2V0dGluZ3MoJ2ZvbnRTdHlsZScpID8gc2V0dGluZ3MoJ2ZvbnRTdHlsZScpICsgJyAnIDogJycpICtcbiAgICAgIGZvbnRTaXplICsgJ3B4ICcgKyBzZXR0aW5ncygnZm9udCcpO1xuICAgIGNvbnRleHQuZmlsbFN0eWxlID0gKHNldHRpbmdzKCdsYWJlbENvbG9yJykgPT09ICdub2RlJykgP1xuICAgICAgKG5vZGUuY29sb3IgfHwgc2V0dGluZ3MoJ2RlZmF1bHROb2RlQ29sb3InKSkgOlxuICAgICAgc2V0dGluZ3MoJ2RlZmF1bHRMYWJlbENvbG9yJyk7XG5cbiAgICBjb250ZXh0LnRleHRBbGlnbiA9ICdsZWZ0JztcbiAgICBjb250ZXh0LmZpbGxUZXh0KFxuICAgICAgbm9kZS53ZWlnaHQsXG4gICAgICBNYXRoLnJvdW5kKG5vZGVbcHJlZml4ICsgJ3gnXSArIHNpemUgKiAxLjUpLFxuICAgICAgTWF0aC5yb3VuZChub2RlW3ByZWZpeCArICd5J10gKyBmb250U2l6ZSAvIDMpXG4gICAgKTtcbiAgfVxufVxuXG5jb25zdCBpbml0VmlldyA9ICh0cmFjZXIpID0+IHtcbiAgdHJhY2VyLnMuc2V0dGluZ3Moe1xuICAgIGVkZ2VMYWJlbFNpemU6ICdwcm9wb3J0aW9uYWwnLFxuICAgIGRlZmF1bHRFZGdlTGFiZWxTaXplOiAyMCxcbiAgICBlZGdlTGFiZWxTaXplUG93UmF0aW86IDAuOCxcbiAgICBmdW5jTGFiZWxzRGVmKG5vZGUsIGNvbnRleHQsIHNldHRpbmdzKSB7XG4gICAgICB0cmFjZXIuZHJhd05vZGVXZWlnaHQobm9kZSwgY29udGV4dCwgc2V0dGluZ3MpO1xuICAgICAgdHJhY2VyLmRyYXdMYWJlbChub2RlLCBjb250ZXh0LCBzZXR0aW5ncyk7XG4gICAgfSxcbiAgICBmdW5jSG92ZXJzRGVmKG5vZGUsIGNvbnRleHQsIHNldHRpbmdzKSB7XG4gICAgICB0cmFjZXIuZHJhd09uSG92ZXIobm9kZSwgY29udGV4dCwgc2V0dGluZ3MsIHRyYWNlci5kcmF3RWRnZVdlaWdodCk7XG4gICAgfSxcbiAgICBmdW5jRWRnZXNBcnJvdyhlZGdlLCBzb3VyY2UsIHRhcmdldCwgY29udGV4dCwgc2V0dGluZ3MpIHtcbiAgICAgIHZhciBjb2xvciA9IHRyYWNlci5nZXRDb2xvcihlZGdlLCBzb3VyY2UsIHRhcmdldCwgc2V0dGluZ3MpO1xuICAgICAgdHJhY2VyLmRyYXdBcnJvdyhlZGdlLCBzb3VyY2UsIHRhcmdldCwgY29sb3IsIGNvbnRleHQsIHNldHRpbmdzKTtcbiAgICAgIHRyYWNlci5kcmF3RWRnZVdlaWdodChlZGdlLCBzb3VyY2UsIHRhcmdldCwgY29sb3IsIGNvbnRleHQsIHNldHRpbmdzKTtcbiAgICB9XG4gIH0pO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBXZWlnaHRlZERpcmVjdGVkR3JhcGhUcmFjZXI7IiwiY29uc3QgV2VpZ2h0ZWREaXJlY3RlZEdyYXBoVHJhY2VyID0gcmVxdWlyZSgnLi93ZWlnaHRlZF9kaXJlY3RlZF9ncmFwaCcpO1xuY29uc3QgVW5kaXJlY3RlZEdyYXBoVHJhY2VyID0gcmVxdWlyZSgnLi91bmRpcmVjdGVkX2dyYXBoJyk7XG5cbmNsYXNzIFdlaWdodGVkVW5kaXJlY3RlZEdyYXBoVHJhY2VyIGV4dGVuZHMgV2VpZ2h0ZWREaXJlY3RlZEdyYXBoVHJhY2VyIHtcbiAgc3RhdGljIGdldENsYXNzTmFtZSgpIHtcbiAgICByZXR1cm4gJ1dlaWdodGVkVW5kaXJlY3RlZEdyYXBoVHJhY2VyJztcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKG5hbWUpIHtcbiAgICBzdXBlcihuYW1lKTtcblxuICAgIHRoaXMuZSA9IFVuZGlyZWN0ZWRHcmFwaFRyYWNlci5wcm90b3R5cGUuZTtcbiAgICB0aGlzLmRyYXdPbkhvdmVyID0gVW5kaXJlY3RlZEdyYXBoVHJhY2VyLnByb3RvdHlwZS5kcmF3T25Ib3ZlcjtcbiAgICB0aGlzLmRyYXdFZGdlID0gVW5kaXJlY3RlZEdyYXBoVHJhY2VyLnByb3RvdHlwZS5kcmF3RWRnZTtcblxuICAgIGlmICh0aGlzLmlzTmV3KSBpbml0Vmlldyh0aGlzKTtcbiAgfVxuXG4gIHNldFRyZWVEYXRhKEcsIHJvb3QpIHtcbiAgICByZXR1cm4gc3VwZXIuc2V0VHJlZURhdGEoRywgcm9vdCwgdHJ1ZSk7XG4gIH1cblxuICBzZXREYXRhKEcpIHtcbiAgICByZXR1cm4gc3VwZXIuc2V0RGF0YShHLCB0cnVlKTtcbiAgfVxuXG4gIGRyYXdFZGdlV2VpZ2h0KGVkZ2UsIHNvdXJjZSwgdGFyZ2V0LCBjb2xvciwgY29udGV4dCwgc2V0dGluZ3MpIHtcbiAgICB2YXIgcHJlZml4ID0gc2V0dGluZ3MoJ3ByZWZpeCcpIHx8ICcnO1xuICAgIGlmIChzb3VyY2VbcHJlZml4ICsgJ3gnXSA+IHRhcmdldFtwcmVmaXggKyAneCddKSB7XG4gICAgICB2YXIgdGVtcCA9IHNvdXJjZTtcbiAgICAgIHNvdXJjZSA9IHRhcmdldDtcbiAgICAgIHRhcmdldCA9IHRlbXA7XG4gICAgfVxuICAgIFdlaWdodGVkRGlyZWN0ZWRHcmFwaFRyYWNlci5wcm90b3R5cGUuZHJhd0VkZ2VXZWlnaHQuY2FsbCh0aGlzLCBlZGdlLCBzb3VyY2UsIHRhcmdldCwgY29sb3IsIGNvbnRleHQsIHNldHRpbmdzKTtcbiAgfVxufVxuXG5jb25zdCBpbml0VmlldyA9ICh0cmFjZXIpID0+IHtcbiAgdHJhY2VyLnMuc2V0dGluZ3Moe1xuICAgIGRlZmF1bHRFZGdlVHlwZTogJ2RlZicsXG4gICAgZnVuY0VkZ2VzRGVmKGVkZ2UsIHNvdXJjZSwgdGFyZ2V0LCBjb250ZXh0LCBzZXR0aW5ncykge1xuICAgICAgdmFyIGNvbG9yID0gdHJhY2VyLmdldENvbG9yKGVkZ2UsIHNvdXJjZSwgdGFyZ2V0LCBzZXR0aW5ncyk7XG4gICAgICB0cmFjZXIuZHJhd0VkZ2UoZWRnZSwgc291cmNlLCB0YXJnZXQsIGNvbG9yLCBjb250ZXh0LCBzZXR0aW5ncyk7XG4gICAgICB0cmFjZXIuZHJhd0VkZ2VXZWlnaHQoZWRnZSwgc291cmNlLCB0YXJnZXQsIGNvbG9yLCBjb250ZXh0LCBzZXR0aW5ncyk7XG4gICAgfVxuICB9KTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gV2VpZ2h0ZWRVbmRpcmVjdGVkR3JhcGhUcmFjZXI7IiwiJ3VzZSBzdHJpY3QnO1xuXG5jb25zdCByZXF1ZXN0ID0gcmVxdWlyZSgnLi9yZXF1ZXN0Jyk7XG5cbm1vZHVsZS5leHBvcnRzID0gKHVybCkgPT4ge1xuXG4gIHJldHVybiByZXF1ZXN0KHVybCwge1xuICAgIHR5cGU6ICdHRVQnXG4gIH0pO1xufTsiLCIndXNlIHN0cmljdCc7XG5cbmNvbnN0IHJlcXVlc3QgPSByZXF1aXJlKCcuL3JlcXVlc3QnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbih1cmwpIHtcbiAgcmV0dXJuIHJlcXVlc3QodXJsLCB7XG4gICAgZGF0YVR5cGU6ICdqc29uJyxcbiAgICB0eXBlOiAnR0VUJ1xuICB9KTtcbn07IiwiJ3VzZSBzdHJpY3QnO1xuXG5jb25zdCByZXF1ZXN0ID0gcmVxdWlyZSgnLi9yZXF1ZXN0Jyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24odXJsLCBkYXRhKSB7XG4gIHJldHVybiByZXF1ZXN0KHVybCwge1xuICAgIGRhdGFUeXBlOiAnanNvbicsXG4gICAgdHlwZTogJ1BPU1QnLFxuICAgIGRhdGE6IEpTT04uc3RyaW5naWZ5KGRhdGEpLFxuICB9KTtcbn07IiwiJ3VzZSBzdHJpY3QnO1xuXG5jb25zdCBSU1ZQID0gcmVxdWlyZSgncnN2cCcpO1xuY29uc3QgYXBwID0gcmVxdWlyZSgnLi4vLi4vYXBwJyk7XG5cbmNvbnN0IHtcbiAgYWpheCxcbiAgZXh0ZW5kXG59ID0gJDtcblxuY29uc3QgZGVmYXVsdHMgPSB7XG5cbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24odXJsLCBvcHRpb25zID0ge30pIHtcbiAgYXBwLnNldElzTG9hZGluZyh0cnVlKTtcblxuICByZXR1cm4gbmV3IFJTVlAuUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgY29uc3QgY2FsbGJhY2tzID0ge1xuICAgICAgc3VjY2VzcyhyZXNwb25zZSkge1xuICAgICAgICBhcHAuc2V0SXNMb2FkaW5nKGZhbHNlKTtcbiAgICAgICAgcmVzb2x2ZShyZXNwb25zZSk7XG4gICAgICB9LFxuICAgICAgZXJyb3IocmVhc29uKSB7XG4gICAgICAgIGFwcC5zZXRJc0xvYWRpbmcoZmFsc2UpO1xuICAgICAgICByZWplY3QocmVhc29uKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgY29uc3Qgb3B0cyA9IGV4dGVuZCh7fSwgZGVmYXVsdHMsIG9wdGlvbnMsIGNhbGxiYWNrcywge1xuICAgICAgdXJsXG4gICAgfSk7XG5cbiAgICBhamF4KG9wdHMpO1xuICB9KTtcbn07IiwiJ3VzZSBzdHJpY3QnO1xuXG5jb25zdCBhcHAgPSByZXF1aXJlKCcuLi9hcHAnKTtcbmNvbnN0IFRvYXN0ID0gcmVxdWlyZSgnLi4vZG9tL3RvYXN0Jyk7XG5cbmNvbnN0IGNoZWNrTG9hZGluZyA9ICgpID0+IHtcbiAgaWYgKGFwcC5nZXRJc0xvYWRpbmcoKSkge1xuICAgIFRvYXN0LnNob3dFcnJvclRvYXN0KCdXYWl0IHVudGlsIGl0IGNvbXBsZXRlcyBsb2FkaW5nIG9mIHByZXZpb3VzIGZpbGUuJyk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufTtcblxuY29uc3QgZ2V0UGFyYW1ldGVyQnlOYW1lID0gKG5hbWUpID0+IHtcbiAgY29uc3QgdXJsID0gd2luZG93LmxvY2F0aW9uLmhyZWY7XG4gIGNvbnN0IHJlZ2V4ID0gbmV3IFJlZ0V4cChgWz8mXSR7bmFtZX0oPShbXiYjXSopfCZ8I3wkKWApO1xuXG4gIGNvbnN0IHJlc3VsdHMgPSByZWdleC5leGVjKHVybCk7XG5cbiAgaWYgKCFyZXN1bHRzIHx8IHJlc3VsdHMubGVuZ3RoICE9PSAzKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBjb25zdCBbLCAsIGlkXSA9IHJlc3VsdHM7XG5cbiAgcmV0dXJuIGlkO1xufTtcblxuY29uc3QgZ2V0SGFzaFZhbHVlID0gKGtleSk9PiB7XG4gIGlmICgha2V5KSByZXR1cm4gbnVsbDtcbiAgY29uc3QgaGFzaCA9IHdpbmRvdy5sb2NhdGlvbi5oYXNoLnN1YnN0cigxKTtcbiAgY29uc3QgcGFyYW1zID0gaGFzaCA/IGhhc2guc3BsaXQoJyYnKSA6IFtdO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHBhcmFtcy5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IHBhaXIgPSBwYXJhbXNbaV0uc3BsaXQoJz0nKTtcbiAgICBpZiAocGFpclswXSA9PT0ga2V5KSB7XG4gICAgICByZXR1cm4gcGFpclsxXTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG51bGw7XG59O1xuXG5jb25zdCBzZXRIYXNoVmFsdWUgPSAoa2V5LCB2YWx1ZSk9PiB7XG4gIGlmICgha2V5IHx8ICF2YWx1ZSkgcmV0dXJuO1xuICBjb25zdCBoYXNoID0gd2luZG93LmxvY2F0aW9uLmhhc2guc3Vic3RyKDEpO1xuICBjb25zdCBwYXJhbXMgPSBoYXNoID8gaGFzaC5zcGxpdCgnJicpIDogW107XG5cbiAgbGV0IGZvdW5kID0gZmFsc2U7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgcGFyYW1zLmxlbmd0aCAmJiAhZm91bmQ7IGkrKykge1xuICAgIGNvbnN0IHBhaXIgPSBwYXJhbXNbaV0uc3BsaXQoJz0nKTtcbiAgICBpZiAocGFpclswXSA9PT0ga2V5KSB7XG4gICAgICBwYWlyWzFdID0gdmFsdWU7XG4gICAgICBwYXJhbXNbaV0gPSBwYWlyLmpvaW4oJz0nKTtcbiAgICAgIGZvdW5kID0gdHJ1ZTtcbiAgICB9XG4gIH1cbiAgaWYgKCFmb3VuZCkge1xuICAgIHBhcmFtcy5wdXNoKFtrZXksIHZhbHVlXS5qb2luKCc9JykpO1xuICB9XG5cbiAgY29uc3QgbmV3SGFzaCA9IHBhcmFtcy5qb2luKCcmJyk7XG4gIHdpbmRvdy5sb2NhdGlvbi5oYXNoID0gYCMke25ld0hhc2h9YDtcbn07XG5cbmNvbnN0IHJlbW92ZUhhc2hWYWx1ZSA9IChrZXkpID0+IHtcbiAgaWYgKCFrZXkpIHJldHVybjtcbiAgY29uc3QgaGFzaCA9IHdpbmRvdy5sb2NhdGlvbi5oYXNoLnN1YnN0cigxKTtcbiAgY29uc3QgcGFyYW1zID0gaGFzaCA/IGhhc2guc3BsaXQoJyYnKSA6IFtdO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgcGFyYW1zLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3QgcGFpciA9IHBhcmFtc1tpXS5zcGxpdCgnPScpO1xuICAgIGlmIChwYWlyWzBdID09PSBrZXkpIHtcbiAgICAgIHBhcmFtcy5zcGxpY2UoaSwgMSk7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICBjb25zdCBuZXdIYXNoID0gcGFyYW1zLmpvaW4oJyYnKTtcbiAgd2luZG93LmxvY2F0aW9uLmhhc2ggPSBgIyR7bmV3SGFzaH1gO1xufTtcblxuY29uc3Qgc2V0UGF0aCA9IChjYXRlZ29yeSwgYWxnb3JpdGhtLCBmaWxlKSA9PiB7XG4gIGNvbnN0IHBhdGggPSBjYXRlZ29yeSA/IGNhdGVnb3J5ICsgKGFsZ29yaXRobSA/IGAvJHthbGdvcml0aG19YCArIChmaWxlID8gYC8ke2ZpbGV9YCA6ICcnKSA6ICcnKSA6ICcnO1xuICBzZXRIYXNoVmFsdWUoJ3BhdGgnLCBwYXRoKTtcbn07XG5cbmNvbnN0IGdldFBhdGggPSAoKSA9PiB7XG4gIGNvbnN0IGhhc2ggPSBnZXRIYXNoVmFsdWUoJ3BhdGgnKTtcbiAgaWYgKGhhc2gpIHtcbiAgICBjb25zdCBbIGNhdGVnb3J5LCBhbGdvcml0aG0sIGZpbGUgXSA9IGhhc2guc3BsaXQoJy8nKTtcbiAgICByZXR1cm4geyBjYXRlZ29yeSwgYWxnb3JpdGhtLCBmaWxlIH07XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgY2hlY2tMb2FkaW5nLFxuICBnZXRQYXJhbWV0ZXJCeU5hbWUsXG4gIGdldEhhc2hWYWx1ZSxcbiAgc2V0SGFzaFZhbHVlLFxuICByZW1vdmVIYXNoVmFsdWUsXG4gIHNldFBhdGgsXG4gIGdldFBhdGhcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbmNvbnN0IGxvYWRBbGdvcml0aG0gPSByZXF1aXJlKCcuL2xvYWRfYWxnb3JpdGhtJyk7XG5jb25zdCBsb2FkQ2F0ZWdvcmllcyA9IHJlcXVpcmUoJy4vbG9hZF9jYXRlZ29yaWVzJyk7XG5jb25zdCBsb2FkRmlsZSA9IHJlcXVpcmUoJy4vbG9hZF9maWxlJyk7XG5jb25zdCBsb2FkU2NyYXRjaFBhcGVyID0gcmVxdWlyZSgnLi9sb2FkX3NjcmF0Y2hfcGFwZXInKTtcbmNvbnN0IHNoYXJlU2NyYXRjaFBhcGVyID0gcmVxdWlyZSgnLi9zaGFyZV9zY3JhdGNoX3BhcGVyJyk7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBsb2FkQWxnb3JpdGhtLFxuICBsb2FkQ2F0ZWdvcmllcyxcbiAgbG9hZEZpbGUsXG4gIGxvYWRTY3JhdGNoUGFwZXIsXG4gIHNoYXJlU2NyYXRjaFBhcGVyXG59OyIsIid1c2Ugc3RyaWN0JztcblxuY29uc3QgZ2V0SlNPTiA9IHJlcXVpcmUoJy4vYWpheC9nZXRfanNvbicpO1xuXG5jb25zdCB7XG4gIGdldEFsZ29yaXRobURpclxufSA9IHJlcXVpcmUoJy4uL3V0aWxzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gKGNhdGVnb3J5LCBhbGdvcml0aG0pID0+IHtcbiAgY29uc3QgZGlyID0gZ2V0QWxnb3JpdGhtRGlyKGNhdGVnb3J5LCBhbGdvcml0aG0pO1xuICByZXR1cm4gZ2V0SlNPTihgJHtkaXJ9ZGVzYy5qc29uYCk7XG59OyIsIid1c2Ugc3RyaWN0JztcblxuY29uc3QgZ2V0SlNPTiA9IHJlcXVpcmUoJy4vYWpheC9nZXRfanNvbicpO1xuXG5tb2R1bGUuZXhwb3J0cyA9ICgpID0+IHtcbiAgcmV0dXJuIGdldEpTT04oJy4vYWxnb3JpdGhtL2NhdGVnb3J5Lmpzb24nKTtcbn07IiwiJ3VzZSBzdHJpY3QnO1xuXG5jb25zdCBSU1ZQID0gcmVxdWlyZSgncnN2cCcpO1xuXG5jb25zdCBhcHAgPSByZXF1aXJlKCcuLi9hcHAnKTtcblxuY29uc3Qge1xuICBnZXRGaWxlRGlyLFxuICBpc1NjcmF0Y2hQYXBlclxufSA9IHJlcXVpcmUoJy4uL3V0aWxzJyk7XG5cbmNvbnN0IHtcbiAgY2hlY2tMb2FkaW5nLFxuICBzZXRQYXRoXG59ID0gcmVxdWlyZSgnLi9oZWxwZXJzJyk7XG5cbmNvbnN0IGdldCA9IHJlcXVpcmUoJy4vYWpheC9nZXQnKTtcblxuY29uc3QgbG9hZERhdGFBbmRDb2RlID0gKGRpcikgPT4ge1xuICByZXR1cm4gUlNWUC5oYXNoKHtcbiAgICBkYXRhOiBnZXQoYCR7ZGlyfWRhdGEuanNgKSxcbiAgICBjb2RlOiBnZXQoYCR7ZGlyfWNvZGUuanNgKVxuICB9KTtcbn07XG5cbmNvbnN0IGxvYWRGaWxlQW5kVXBkYXRlQ29udGVudCA9IChkaXIpID0+IHtcbiAgYXBwLmdldEVkaXRvcigpLmNsZWFyQ29udGVudCgpO1xuXG4gIHJldHVybiBsb2FkRGF0YUFuZENvZGUoZGlyKS50aGVuKChjb250ZW50KSA9PiB7XG4gICAgYXBwLnVwZGF0ZUNhY2hlZEZpbGUoZGlyLCBjb250ZW50KTtcbiAgICBhcHAuZ2V0RWRpdG9yKCkuc2V0Q29udGVudChjb250ZW50KTtcbiAgfSk7XG59O1xuXG5jb25zdCBjYWNoZWRDb250ZW50RXhpc3RzID0gKGNhY2hlZEZpbGUpID0+IHtcbiAgcmV0dXJuIGNhY2hlZEZpbGUgJiZcbiAgICBjYWNoZWRGaWxlLmRhdGEgIT09IHVuZGVmaW5lZCAmJlxuICAgIGNhY2hlZEZpbGUuY29kZSAhPT0gdW5kZWZpbmVkO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSAoY2F0ZWdvcnksIGFsZ29yaXRobSwgZmlsZSwgZXhwbGFuYXRpb24pID0+IHtcbiAgcmV0dXJuIG5ldyBSU1ZQLlByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGlmIChjaGVja0xvYWRpbmcoKSkge1xuICAgICAgcmVqZWN0KCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChpc1NjcmF0Y2hQYXBlcihjYXRlZ29yeSkpIHtcbiAgICAgICAgc2V0UGF0aChjYXRlZ29yeSwgYXBwLmdldExvYWRlZFNjcmF0Y2goKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzZXRQYXRoKGNhdGVnb3J5LCBhbGdvcml0aG0sIGZpbGUpO1xuICAgICAgfVxuICAgICAgJCgnI2V4cGxhbmF0aW9uJykuaHRtbChleHBsYW5hdGlvbik7XG5cbiAgICAgIGxldCBkaXIgPSBnZXRGaWxlRGlyKGNhdGVnb3J5LCBhbGdvcml0aG0sIGZpbGUpO1xuICAgICAgYXBwLnNldExhc3RGaWxlVXNlZChkaXIpO1xuICAgICAgY29uc3QgY2FjaGVkRmlsZSA9IGFwcC5nZXRDYWNoZWRGaWxlKGRpcik7XG5cbiAgICAgIGlmIChjYWNoZWRDb250ZW50RXhpc3RzKGNhY2hlZEZpbGUpKSB7XG4gICAgICAgIGFwcC5nZXRFZGl0b3IoKS5zZXRDb250ZW50KGNhY2hlZEZpbGUpO1xuICAgICAgICByZXNvbHZlKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsb2FkRmlsZUFuZFVwZGF0ZUNvbnRlbnQoZGlyKS50aGVuKHJlc29sdmUsIHJlamVjdCk7XG4gICAgICB9XG4gICAgfVxuICB9KTtcbn07IiwiJ3VzZSBzdHJpY3QnO1xuXG5jb25zdCBSU1ZQID0gcmVxdWlyZSgncnN2cCcpO1xuY29uc3QgYXBwID0gcmVxdWlyZSgnLi4vYXBwJyk7XG5cbmNvbnN0IHtcbiAgZ2V0RmlsZURpclxufSA9IHJlcXVpcmUoJy4uL3V0aWxzJyk7XG5cbmNvbnN0IGdldEpTT04gPSByZXF1aXJlKCcuL2FqYXgvZ2V0X2pzb24nKTtcbmNvbnN0IGxvYWRBbGdvcml0aG0gPSByZXF1aXJlKCcuL2xvYWRfYWxnb3JpdGhtJyk7XG5cbmNvbnN0IGV4dHJhY3RHaXN0Q29kZSA9IChmaWxlcywgbmFtZSkgPT4gZmlsZXNbYCR7bmFtZX0uanNgXS5jb250ZW50O1xuXG5tb2R1bGUuZXhwb3J0cyA9IChnaXN0SUQpID0+IHtcbiAgcmV0dXJuIG5ldyBSU1ZQLlByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGFwcC5zZXRMb2FkZWRTY3JhdGNoKGdpc3RJRCk7XG5cbiAgICBnZXRKU09OKGBodHRwczovL2FwaS5naXRodWIuY29tL2dpc3RzLyR7Z2lzdElEfWApLnRoZW4oKHtcbiAgICAgIGZpbGVzXG4gICAgfSkgPT4ge1xuXG4gICAgICBjb25zdCBjYXRlZ29yeSA9ICdzY3JhdGNoJztcbiAgICAgIGNvbnN0IGFsZ29yaXRobSA9IGdpc3RJRDtcblxuICAgICAgbG9hZEFsZ29yaXRobShjYXRlZ29yeSwgYWxnb3JpdGhtKS50aGVuKChkYXRhKSA9PiB7XG5cbiAgICAgICAgY29uc3QgYWxnb0RhdGEgPSBleHRyYWN0R2lzdENvZGUoZmlsZXMsICdkYXRhJyk7XG4gICAgICAgIGNvbnN0IGFsZ29Db2RlID0gZXh0cmFjdEdpc3RDb2RlKGZpbGVzLCAnY29kZScpO1xuXG4gICAgICAgIC8vIHVwZGF0ZSBzY3JhdGNoIHBhcGVyIGFsZ28gY29kZSB3aXRoIHRoZSBsb2FkZWQgZ2lzdCBjb2RlXG4gICAgICAgIGNvbnN0IGRpciA9IGdldEZpbGVEaXIoY2F0ZWdvcnksIGFsZ29yaXRobSwgJ3NjcmF0Y2hfcGFwZXInKTtcbiAgICAgICAgYXBwLnVwZGF0ZUNhY2hlZEZpbGUoZGlyLCB7XG4gICAgICAgICAgZGF0YTogYWxnb0RhdGEsXG4gICAgICAgICAgY29kZTogYWxnb0NvZGUsXG4gICAgICAgICAgJ0NSRURJVC5tZCc6ICdTaGFyZWQgYnkgYW4gYW5vbnltb3VzIHVzZXIgZnJvbSBodHRwOi8vcGFya2pzODE0LmdpdGh1Yi5pby9BbGdvcml0aG1WaXN1YWxpemVyJ1xuICAgICAgICB9KTtcblxuICAgICAgICByZXNvbHZlKHtcbiAgICAgICAgICBjYXRlZ29yeSxcbiAgICAgICAgICBhbGdvcml0aG0sXG4gICAgICAgICAgZGF0YVxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxufTsiLCIndXNlIHN0cmljdCc7XG5cbmNvbnN0IFJTVlAgPSByZXF1aXJlKCdyc3ZwJyk7XG5jb25zdCBhcHAgPSByZXF1aXJlKCcuLi9hcHAnKTtcblxuY29uc3QgcG9zdEpTT04gPSByZXF1aXJlKCcuL2FqYXgvcG9zdF9qc29uJyk7XG5cbmNvbnN0IHtcbiAgc2V0UGF0aFxufSA9IHJlcXVpcmUoJy4vaGVscGVycycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9ICgpID0+IHtcbiAgcmV0dXJuIG5ldyBSU1ZQLlByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXG4gICAgY29uc3Qge1xuICAgICAgZGF0YUVkaXRvcixcbiAgICAgIGNvZGVFZGl0b3JcbiAgICB9ID0gYXBwLmdldEVkaXRvcigpO1xuXG4gICAgY29uc3QgZ2lzdCA9IHtcbiAgICAgICdkZXNjcmlwdGlvbic6ICd0ZW1wJyxcbiAgICAgICdwdWJsaWMnOiB0cnVlLFxuICAgICAgJ2ZpbGVzJzoge1xuICAgICAgICAnZGF0YS5qcyc6IHtcbiAgICAgICAgICAnY29udGVudCc6IGRhdGFFZGl0b3IuZ2V0VmFsdWUoKVxuICAgICAgICB9LFxuICAgICAgICAnY29kZS5qcyc6IHtcbiAgICAgICAgICAnY29udGVudCc6IGNvZGVFZGl0b3IuZ2V0VmFsdWUoKVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfTtcblxuICAgIHBvc3RKU09OKCdodHRwczovL2FwaS5naXRodWIuY29tL2dpc3RzJywgZ2lzdCkudGhlbigoe1xuICAgICAgaWRcbiAgICB9KSA9PiB7XG4gICAgICBhcHAuc2V0TG9hZGVkU2NyYXRjaChpZCk7XG4gICAgICBzZXRQYXRoKCdzY3JhdGNoJywgaWQpO1xuICAgICAgY29uc3Qge1xuICAgICAgICBocmVmXG4gICAgICB9ID0gbG9jYXRpb247XG4gICAgICAkKCcjYWxnb3JpdGhtJykuaHRtbCgnU2hhcmVkJyk7XG4gICAgICByZXNvbHZlKGhyZWYpO1xuICAgIH0pO1xuICB9KTtcbn07IiwiJ3VzZSBzdHJpY3QnO1xuXG5jb25zdCBUcmFjZXJNYW5hZ2VyID0gcmVxdWlyZSgnLi9tYW5hZ2VyJyk7XG5jb25zdCBUcmFjZXIgPSByZXF1aXJlKCcuLi9tb2R1bGUvdHJhY2VyL3RyYWNlcicpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcblxuICBpbml0KCkge1xuICAgIGNvbnN0IHRtID0gbmV3IFRyYWNlck1hbmFnZXIoKTtcbiAgICBUcmFjZXIucHJvdG90eXBlLm1hbmFnZXIgPSB0bTtcbiAgICByZXR1cm4gdG07XG4gIH1cblxufTsiLCIndXNlIHN0cmljdCc7XG5cbmNvbnN0IFRvcE1lbnUgPSByZXF1aXJlKCcuLi9kb20vdG9wX21lbnUnKTtcblxuY29uc3Qgc3RlcExpbWl0ID0gMWU2O1xuXG5jb25zdCBUcmFjZXJNYW5hZ2VyID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLnRpbWVyID0gbnVsbDtcbiAgdGhpcy5wYXVzZSA9IGZhbHNlO1xuICB0aGlzLmNhcHN1bGVzID0gW107XG4gIHRoaXMuaW50ZXJ2YWwgPSA1MDA7XG59O1xuXG5UcmFjZXJNYW5hZ2VyLnByb3RvdHlwZSA9IHtcblxuICBhZGQodHJhY2VyKSB7XG5cbiAgICBjb25zdCAkY29udGFpbmVyID0gJCgnPHNlY3Rpb24gY2xhc3M9XCJtb2R1bGVfd3JhcHBlclwiPicpO1xuICAgICQoJy5tb2R1bGVfY29udGFpbmVyJykuYXBwZW5kKCRjb250YWluZXIpO1xuXG4gICAgY29uc3QgY2Fwc3VsZSA9IHtcbiAgICAgIG1vZHVsZTogdHJhY2VyLm1vZHVsZSxcbiAgICAgIHRyYWNlcixcbiAgICAgIGFsbG9jYXRlZDogdHJ1ZSxcbiAgICAgIGRlZmF1bHROYW1lOiBudWxsLFxuICAgICAgJGNvbnRhaW5lcixcbiAgICAgIGlzTmV3OiB0cnVlXG4gICAgfTtcblxuICAgIHRoaXMuY2Fwc3VsZXMucHVzaChjYXBzdWxlKTtcbiAgICByZXR1cm4gY2Fwc3VsZTtcbiAgfSxcblxuICBhbGxvY2F0ZShuZXdUcmFjZXIpIHtcbiAgICBsZXQgc2VsZWN0ZWRDYXBzdWxlID0gbnVsbDtcbiAgICBsZXQgY291bnQgPSAwO1xuXG4gICAgJC5lYWNoKHRoaXMuY2Fwc3VsZXMsIChpLCBjYXBzdWxlKSA9PiB7XG4gICAgICBpZiAoY2Fwc3VsZS5tb2R1bGUgPT09IG5ld1RyYWNlci5tb2R1bGUpIHtcbiAgICAgICAgY291bnQrKztcbiAgICAgICAgaWYgKCFjYXBzdWxlLmFsbG9jYXRlZCkge1xuICAgICAgICAgIGNhcHN1bGUudHJhY2VyID0gbmV3VHJhY2VyO1xuICAgICAgICAgIGNhcHN1bGUuYWxsb2NhdGVkID0gdHJ1ZTtcbiAgICAgICAgICBjYXBzdWxlLmlzTmV3ID0gZmFsc2U7XG4gICAgICAgICAgc2VsZWN0ZWRDYXBzdWxlID0gY2Fwc3VsZTtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGlmIChzZWxlY3RlZENhcHN1bGUgPT09IG51bGwpIHtcbiAgICAgIGNvdW50Kys7XG4gICAgICBzZWxlY3RlZENhcHN1bGUgPSB0aGlzLmFkZChuZXdUcmFjZXIpO1xuICAgIH1cblxuICAgIGNvbnN0IGNsYXNzTmFtZSA9IG5ld1RyYWNlci5tb2R1bGUuZ2V0Q2xhc3NOYW1lKCk7XG4gICAgc2VsZWN0ZWRDYXBzdWxlLmRlZmF1bHROYW1lID0gYCR7Y2xhc3NOYW1lfSAke2NvdW50fWA7XG4gICAgc2VsZWN0ZWRDYXBzdWxlLm9yZGVyID0gdGhpcy5vcmRlcisrO1xuICAgIHJldHVybiBzZWxlY3RlZENhcHN1bGU7XG4gIH0sXG5cbiAgZGVhbGxvY2F0ZUFsbCgpIHtcbiAgICB0aGlzLm9yZGVyID0gMDtcbiAgICB0aGlzLnJlc2V0KCk7XG4gICAgJC5lYWNoKHRoaXMuY2Fwc3VsZXMsIChpLCBjYXBzdWxlKSA9PiB7XG4gICAgICBjYXBzdWxlLmFsbG9jYXRlZCA9IGZhbHNlO1xuICAgIH0pO1xuICB9LFxuXG4gIHJlbW92ZVVuYWxsb2NhdGVkKCkge1xuICAgIGxldCBjaGFuZ2VkID0gZmFsc2U7XG5cbiAgICB0aGlzLmNhcHN1bGVzID0gJC5ncmVwKHRoaXMuY2Fwc3VsZXMsIChjYXBzdWxlKSA9PiB7XG4gICAgICBsZXQgcmVtb3ZlZCA9ICFjYXBzdWxlLmFsbG9jYXRlZDtcblxuICAgICAgaWYgKGNhcHN1bGUuaXNOZXcgfHwgcmVtb3ZlZCkge1xuICAgICAgICBjaGFuZ2VkID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIGlmIChyZW1vdmVkKSB7XG4gICAgICAgIGNhcHN1bGUuJGNvbnRhaW5lci5yZW1vdmUoKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuICFyZW1vdmVkO1xuICAgIH0pO1xuXG4gICAgaWYgKGNoYW5nZWQpIHtcbiAgICAgIHRoaXMucGxhY2UoKTtcbiAgICB9XG4gIH0sXG5cbiAgcGxhY2UoKSB7XG4gICAgY29uc3Qge1xuICAgICAgY2Fwc3VsZXNcbiAgICB9ID0gdGhpcztcblxuICAgICQuZWFjaChjYXBzdWxlcywgKGksIGNhcHN1bGUpID0+IHtcbiAgICAgIGxldCB3aWR0aCA9IDEwMDtcbiAgICAgIGxldCBoZWlnaHQgPSAoMTAwIC8gY2Fwc3VsZXMubGVuZ3RoKTtcbiAgICAgIGxldCB0b3AgPSBoZWlnaHQgKiBjYXBzdWxlLm9yZGVyO1xuXG4gICAgICBjYXBzdWxlLiRjb250YWluZXIuY3NzKHtcbiAgICAgICAgdG9wOiBgJHt0b3B9JWAsXG4gICAgICAgIHdpZHRoOiBgJHt3aWR0aH0lYCxcbiAgICAgICAgaGVpZ2h0OiBgJHtoZWlnaHR9JWBcbiAgICAgIH0pO1xuXG4gICAgICBjYXBzdWxlLnRyYWNlci5yZXNpemUoKTtcbiAgICB9KTtcbiAgfSxcblxuICByZXNpemUoKSB7XG4gICAgdGhpcy5jb21tYW5kKCdyZXNpemUnKTtcbiAgfSxcblxuICBpc1BhdXNlKCkge1xuICAgIHJldHVybiB0aGlzLnBhdXNlO1xuICB9LFxuXG4gIHNldEludGVydmFsKGludGVydmFsKSB7XG4gICAgJCgnI2ludGVydmFsJykudmFsKGludGVydmFsKTtcbiAgfSxcblxuICByZXNldCgpIHtcbiAgICB0aGlzLnRyYWNlcyA9IFtdO1xuICAgIHRoaXMudHJhY2VJbmRleCA9IC0xO1xuICAgIHRoaXMuc3RlcENudCA9IDA7XG4gICAgaWYgKHRoaXMudGltZXIpIHtcbiAgICAgIGNsZWFyVGltZW91dCh0aGlzLnRpbWVyKTtcbiAgICB9XG4gICAgdGhpcy5jb21tYW5kKCdjbGVhcicpO1xuICB9LFxuXG4gIHB1c2hTdGVwKGNhcHN1bGUsIHN0ZXApIHtcbiAgICBpZiAodGhpcy5zdGVwQ250KysgPiBzdGVwTGltaXQpIHRocm93IFwiVHJhY2VyJ3Mgc3RhY2sgb3ZlcmZsb3dcIjtcbiAgICBsZXQgbGVuID0gdGhpcy50cmFjZXMubGVuZ3RoO1xuICAgIGxldCBsYXN0ID0gW107XG4gICAgaWYgKGxlbiA9PT0gMCkge1xuICAgICAgdGhpcy50cmFjZXMucHVzaChsYXN0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgbGFzdCA9IHRoaXMudHJhY2VzW2xlbiAtIDFdO1xuICAgIH1cbiAgICBsYXN0LnB1c2goJC5leHRlbmQoc3RlcCwge1xuICAgICAgY2Fwc3VsZVxuICAgIH0pKTtcbiAgfSxcblxuICBuZXdTdGVwKCkge1xuICAgIHRoaXMudHJhY2VzLnB1c2goW10pO1xuICB9LFxuXG4gIHBhdXNlU3RlcCgpIHtcbiAgICBpZiAodGhpcy50cmFjZUluZGV4IDwgMCkgcmV0dXJuO1xuICAgIHRoaXMucGF1c2UgPSB0cnVlO1xuICAgIGlmICh0aGlzLnRpbWVyKSB7XG4gICAgICBjbGVhclRpbWVvdXQodGhpcy50aW1lcik7XG4gICAgfVxuICAgICQoJyNidG5fcGF1c2UnKS5hZGRDbGFzcygnYWN0aXZlJyk7XG4gIH0sXG5cbiAgcmVzdW1lU3RlcCgpIHtcbiAgICB0aGlzLnBhdXNlID0gZmFsc2U7XG4gICAgdGhpcy5zdGVwKHRoaXMudHJhY2VJbmRleCArIDEpO1xuICAgICQoJyNidG5fcGF1c2UnKS5yZW1vdmVDbGFzcygnYWN0aXZlJyk7XG4gIH0sXG5cbiAgc3RlcChpLCBvcHRpb25zID0ge30pIHtcbiAgICBjb25zdCB0cmFjZXIgPSB0aGlzO1xuXG4gICAgaWYgKGlzTmFOKGkpIHx8IGkgPj0gdGhpcy50cmFjZXMubGVuZ3RoIHx8IGkgPCAwKSByZXR1cm47XG5cbiAgICB0aGlzLnRyYWNlSW5kZXggPSBpO1xuICAgIGNvbnN0IHRyYWNlID0gdGhpcy50cmFjZXNbaV07XG4gICAgdHJhY2UuZm9yRWFjaCgoc3RlcCkgPT4ge1xuICAgICAgc3RlcC5jYXBzdWxlLnRyYWNlci5wcm9jZXNzU3RlcChzdGVwLCBvcHRpb25zKTtcbiAgICB9KTtcblxuICAgIGlmICghb3B0aW9ucy52aXJ0dWFsKSB7XG4gICAgICB0aGlzLmNvbW1hbmQoJ3JlZnJlc2gnKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5wYXVzZSkgcmV0dXJuO1xuXG4gICAgdGhpcy50aW1lciA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgaWYgKCF0cmFjZXIubmV4dFN0ZXAob3B0aW9ucykpIHtcbiAgICAgICAgVG9wTWVudS5yZXNldFRvcE1lbnVCdXR0b25zKCk7XG4gICAgICB9XG4gICAgfSwgdGhpcy5pbnRlcnZhbCk7XG4gIH0sXG5cbiAgcHJldlN0ZXAob3B0aW9ucyA9IHt9KSB7XG4gICAgdGhpcy5jb21tYW5kKCdjbGVhcicpO1xuXG4gICAgY29uc3QgZmluYWxJbmRleCA9IHRoaXMudHJhY2VJbmRleCAtIDE7XG4gICAgaWYgKGZpbmFsSW5kZXggPCAwKSB7XG4gICAgICB0aGlzLnRyYWNlSW5kZXggPSAtMTtcbiAgICAgIHRoaXMuY29tbWFuZCgncmVmcmVzaCcpO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZmluYWxJbmRleDsgaSsrKSB7XG4gICAgICB0aGlzLnN0ZXAoaSwgJC5leHRlbmQob3B0aW9ucywge1xuICAgICAgICB2aXJ0dWFsOiB0cnVlXG4gICAgICB9KSk7XG4gICAgfVxuXG4gICAgdGhpcy5zdGVwKGZpbmFsSW5kZXgpO1xuICAgIHJldHVybiB0cnVlO1xuICB9LFxuXG4gIG5leHRTdGVwKG9wdGlvbnMgPSB7fSkge1xuICAgIGNvbnN0IGZpbmFsSW5kZXggPSB0aGlzLnRyYWNlSW5kZXggKyAxO1xuICAgIGlmIChmaW5hbEluZGV4ID49IHRoaXMudHJhY2VzLmxlbmd0aCkge1xuICAgICAgdGhpcy50cmFjZUluZGV4ID0gdGhpcy50cmFjZXMubGVuZ3RoIC0gMTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICB0aGlzLnN0ZXAoZmluYWxJbmRleCwgb3B0aW9ucyk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH0sXG5cbiAgdmlzdWFsaXplKCkge1xuICAgIHRoaXMudHJhY2VJbmRleCA9IC0xO1xuICAgIHRoaXMucmVzdW1lU3RlcCgpO1xuICB9LFxuXG4gIGNvbW1hbmQoLi4uYXJncykge1xuICAgIGNvbnN0IGZ1bmN0aW9uTmFtZSA9IGFyZ3Muc2hpZnQoKTtcbiAgICAkLmVhY2godGhpcy5jYXBzdWxlcywgKGksIGNhcHN1bGUpID0+IHtcbiAgICAgIGlmIChjYXBzdWxlLmFsbG9jYXRlZCkge1xuICAgICAgICBjYXBzdWxlLnRyYWNlci5tb2R1bGUucHJvdG90eXBlW2Z1bmN0aW9uTmFtZV0uYXBwbHkoY2Fwc3VsZS50cmFjZXIsIGFyZ3MpO1xuICAgICAgfVxuICAgIH0pO1xuICB9LFxuXG4gIGZpbmRPd25lcihjb250YWluZXIpIHtcbiAgICBsZXQgc2VsZWN0ZWRDYXBzdWxlID0gbnVsbDtcbiAgICAkLmVhY2godGhpcy5jYXBzdWxlcywgKGksIGNhcHN1bGUpID0+IHtcbiAgICAgIGlmIChjYXBzdWxlLiRjb250YWluZXJbMF0gPT09IGNvbnRhaW5lcikge1xuICAgICAgICBzZWxlY3RlZENhcHN1bGUgPSBjYXBzdWxlO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHNlbGVjdGVkQ2Fwc3VsZS50cmFjZXI7XG4gIH1cbn07XG5cbm1vZHVsZS5leHBvcnRzID0gVHJhY2VyTWFuYWdlcjtcbiIsImNvbnN0IHtcbiAgcGFyc2Vcbn0gPSBKU09OO1xuXG5jb25zdCBmcm9tSlNPTiA9IChvYmopID0+IHtcbiAgcmV0dXJuIHBhcnNlKG9iaiwgKGtleSwgdmFsdWUpID0+IHtcbiAgICByZXR1cm4gdmFsdWUgPT09ICdJbmZpbml0eScgPyBJbmZpbml0eSA6IHZhbHVlO1xuICB9KTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZnJvbUpTT047IiwiY29uc3QgdG9KU09OID0gcmVxdWlyZSgnLi90b19qc29uJyk7XG5jb25zdCBmcm9tSlNPTiA9IHJlcXVpcmUoJy4vZnJvbV9qc29uJyk7XG5jb25zdCByZWZpbmVCeVR5cGUgPSByZXF1aXJlKCcuL3JlZmluZV9ieV90eXBlJyk7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICB0b0pTT04sXG4gIGZyb21KU09OLFxuICByZWZpbmVCeVR5cGVcbn07IiwiY29uc3QgcmVmaW5lQnlUeXBlID0gKGl0ZW0pID0+IHtcbiAgc3dpdGNoICh0eXBlb2YoaXRlbSkpIHtcbiAgICBjYXNlICdudW1iZXInOlxuICAgICAgcmV0dXJuIHJlZmluZU51bWJlcihpdGVtKTtcbiAgICBjYXNlICdib29sZWFuJzpcbiAgICAgIHJldHVybiByZWZpbmVCb29sZWFuKGl0ZW0pO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gcmVmaW5lU3RyaW5nKGl0ZW0pO1xuICB9XG59O1xuXG5jb25zdCByZWZpbmVTdHJpbmcgPSAoc3RyKSA9PiB7XG4gIHJldHVybiBzdHIgPT09ICcnID8gJyAnIDogc3RyO1xufTtcblxuY29uc3QgcmVmaW5lTnVtYmVyID0gKG51bSkgPT4ge1xuICByZXR1cm4gbnVtID09PSBJbmZpbml0eSA/ICfiiJ4nIDogbnVtO1xufTtcblxuY29uc3QgcmVmaW5lQm9vbGVhbiA9IChib29sKSA9PiB7XG4gIHJldHVybiBib29sID8gJ1QnIDogJ0YnO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSByZWZpbmVCeVR5cGU7XG4iLCJjb25zdCB7XG4gIHN0cmluZ2lmeVxufSA9IEpTT047XG5cbmNvbnN0IHRvSlNPTiA9IChvYmopID0+IHtcbiAgcmV0dXJuIHN0cmluZ2lmeShvYmosIChrZXksIHZhbHVlKSA9PiB7XG4gICAgcmV0dXJuIHZhbHVlID09PSBJbmZpbml0eSA/ICdJbmZpbml0eScgOiB2YWx1ZTtcbiAgfSk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHRvSlNPTjsiLCIndXNlIHN0cmljdCc7XG5cbmNvbnN0IGlzU2NyYXRjaFBhcGVyID0gKGNhdGVnb3J5LCBhbGdvcml0aG0pID0+IHtcbiAgcmV0dXJuIGNhdGVnb3J5ID09ICdzY3JhdGNoJztcbn07XG5cbmNvbnN0IGdldEFsZ29yaXRobURpciA9IChjYXRlZ29yeSwgYWxnb3JpdGhtKSA9PiB7XG4gIGlmIChpc1NjcmF0Y2hQYXBlcihjYXRlZ29yeSkpIHJldHVybiAnLi9hbGdvcml0aG0vc2NyYXRjaF9wYXBlci8nO1xuICByZXR1cm4gYC4vYWxnb3JpdGhtLyR7Y2F0ZWdvcnl9LyR7YWxnb3JpdGhtfS9gO1xufTtcblxuY29uc3QgZ2V0RmlsZURpciA9IChjYXRlZ29yeSwgYWxnb3JpdGhtLCBmaWxlKSA9PiB7XG4gIGlmIChpc1NjcmF0Y2hQYXBlcihjYXRlZ29yeSkpIHJldHVybiAnLi9hbGdvcml0aG0vc2NyYXRjaF9wYXBlci8nO1xuICByZXR1cm4gYC4vYWxnb3JpdGhtLyR7Y2F0ZWdvcnl9LyR7YWxnb3JpdGhtfS8ke2ZpbGV9L2A7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgaXNTY3JhdGNoUGFwZXIsXG4gIGdldEFsZ29yaXRobURpcixcbiAgZ2V0RmlsZURpclxufTsiLCIvLyBzaGltIGZvciB1c2luZyBwcm9jZXNzIGluIGJyb3dzZXJcblxudmFyIHByb2Nlc3MgPSBtb2R1bGUuZXhwb3J0cyA9IHt9O1xudmFyIHF1ZXVlID0gW107XG52YXIgZHJhaW5pbmcgPSBmYWxzZTtcbnZhciBjdXJyZW50UXVldWU7XG52YXIgcXVldWVJbmRleCA9IC0xO1xuXG5mdW5jdGlvbiBjbGVhblVwTmV4dFRpY2soKSB7XG4gICAgaWYgKCFkcmFpbmluZyB8fCAhY3VycmVudFF1ZXVlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZHJhaW5pbmcgPSBmYWxzZTtcbiAgICBpZiAoY3VycmVudFF1ZXVlLmxlbmd0aCkge1xuICAgICAgICBxdWV1ZSA9IGN1cnJlbnRRdWV1ZS5jb25jYXQocXVldWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHF1ZXVlSW5kZXggPSAtMTtcbiAgICB9XG4gICAgaWYgKHF1ZXVlLmxlbmd0aCkge1xuICAgICAgICBkcmFpblF1ZXVlKCk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBkcmFpblF1ZXVlKCkge1xuICAgIGlmIChkcmFpbmluZykge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIHZhciB0aW1lb3V0ID0gc2V0VGltZW91dChjbGVhblVwTmV4dFRpY2spO1xuICAgIGRyYWluaW5nID0gdHJ1ZTtcblxuICAgIHZhciBsZW4gPSBxdWV1ZS5sZW5ndGg7XG4gICAgd2hpbGUobGVuKSB7XG4gICAgICAgIGN1cnJlbnRRdWV1ZSA9IHF1ZXVlO1xuICAgICAgICBxdWV1ZSA9IFtdO1xuICAgICAgICB3aGlsZSAoKytxdWV1ZUluZGV4IDwgbGVuKSB7XG4gICAgICAgICAgICBpZiAoY3VycmVudFF1ZXVlKSB7XG4gICAgICAgICAgICAgICAgY3VycmVudFF1ZXVlW3F1ZXVlSW5kZXhdLnJ1bigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHF1ZXVlSW5kZXggPSAtMTtcbiAgICAgICAgbGVuID0gcXVldWUubGVuZ3RoO1xuICAgIH1cbiAgICBjdXJyZW50UXVldWUgPSBudWxsO1xuICAgIGRyYWluaW5nID0gZmFsc2U7XG4gICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xufVxuXG5wcm9jZXNzLm5leHRUaWNrID0gZnVuY3Rpb24gKGZ1bikge1xuICAgIHZhciBhcmdzID0gbmV3IEFycmF5KGFyZ3VtZW50cy5sZW5ndGggLSAxKTtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGFyZ3NbaSAtIDFdID0gYXJndW1lbnRzW2ldO1xuICAgICAgICB9XG4gICAgfVxuICAgIHF1ZXVlLnB1c2gobmV3IEl0ZW0oZnVuLCBhcmdzKSk7XG4gICAgaWYgKHF1ZXVlLmxlbmd0aCA9PT0gMSAmJiAhZHJhaW5pbmcpIHtcbiAgICAgICAgc2V0VGltZW91dChkcmFpblF1ZXVlLCAwKTtcbiAgICB9XG59O1xuXG4vLyB2OCBsaWtlcyBwcmVkaWN0aWJsZSBvYmplY3RzXG5mdW5jdGlvbiBJdGVtKGZ1biwgYXJyYXkpIHtcbiAgICB0aGlzLmZ1biA9IGZ1bjtcbiAgICB0aGlzLmFycmF5ID0gYXJyYXk7XG59XG5JdGVtLnByb3RvdHlwZS5ydW4gPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5mdW4uYXBwbHkobnVsbCwgdGhpcy5hcnJheSk7XG59O1xucHJvY2Vzcy50aXRsZSA9ICdicm93c2VyJztcbnByb2Nlc3MuYnJvd3NlciA9IHRydWU7XG5wcm9jZXNzLmVudiA9IHt9O1xucHJvY2Vzcy5hcmd2ID0gW107XG5wcm9jZXNzLnZlcnNpb24gPSAnJzsgLy8gZW1wdHkgc3RyaW5nIHRvIGF2b2lkIHJlZ2V4cCBpc3N1ZXNcbnByb2Nlc3MudmVyc2lvbnMgPSB7fTtcblxuZnVuY3Rpb24gbm9vcCgpIHt9XG5cbnByb2Nlc3Mub24gPSBub29wO1xucHJvY2Vzcy5hZGRMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLm9uY2UgPSBub29wO1xucHJvY2Vzcy5vZmYgPSBub29wO1xucHJvY2Vzcy5yZW1vdmVMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLnJlbW92ZUFsbExpc3RlbmVycyA9IG5vb3A7XG5wcm9jZXNzLmVtaXQgPSBub29wO1xuXG5wcm9jZXNzLmJpbmRpbmcgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5iaW5kaW5nIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn07XG5cbnByb2Nlc3MuY3dkID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gJy8nIH07XG5wcm9jZXNzLmNoZGlyID0gZnVuY3Rpb24gKGRpcikge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5jaGRpciBpcyBub3Qgc3VwcG9ydGVkJyk7XG59O1xucHJvY2Vzcy51bWFzayA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gMDsgfTtcbiIsIi8qIVxuICogQG92ZXJ2aWV3IFJTVlAgLSBhIHRpbnkgaW1wbGVtZW50YXRpb24gb2YgUHJvbWlzZXMvQSsuXG4gKiBAY29weXJpZ2h0IENvcHlyaWdodCAoYykgMjAxNCBZZWh1ZGEgS2F0eiwgVG9tIERhbGUsIFN0ZWZhbiBQZW5uZXIgYW5kIGNvbnRyaWJ1dG9yc1xuICogQGxpY2Vuc2UgICBMaWNlbnNlZCB1bmRlciBNSVQgbGljZW5zZVxuICogICAgICAgICAgICBTZWUgaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL3RpbGRlaW8vcnN2cC5qcy9tYXN0ZXIvTElDRU5TRVxuICogQHZlcnNpb24gICAzLjIuMVxuICovXG5cbihmdW5jdGlvbigpIHtcbiAgICBcInVzZSBzdHJpY3RcIjtcbiAgICBmdW5jdGlvbiBsaWIkcnN2cCR1dGlscyQkb2JqZWN0T3JGdW5jdGlvbih4KSB7XG4gICAgICByZXR1cm4gdHlwZW9mIHggPT09ICdmdW5jdGlvbicgfHwgKHR5cGVvZiB4ID09PSAnb2JqZWN0JyAmJiB4ICE9PSBudWxsKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBsaWIkcnN2cCR1dGlscyQkaXNGdW5jdGlvbih4KSB7XG4gICAgICByZXR1cm4gdHlwZW9mIHggPT09ICdmdW5jdGlvbic7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbGliJHJzdnAkdXRpbHMkJGlzTWF5YmVUaGVuYWJsZSh4KSB7XG4gICAgICByZXR1cm4gdHlwZW9mIHggPT09ICdvYmplY3QnICYmIHggIT09IG51bGw7XG4gICAgfVxuXG4gICAgdmFyIGxpYiRyc3ZwJHV0aWxzJCRfaXNBcnJheTtcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkpIHtcbiAgICAgIGxpYiRyc3ZwJHV0aWxzJCRfaXNBcnJheSA9IGZ1bmN0aW9uICh4KSB7XG4gICAgICAgIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoeCkgPT09ICdbb2JqZWN0IEFycmF5XSc7XG4gICAgICB9O1xuICAgIH0gZWxzZSB7XG4gICAgICBsaWIkcnN2cCR1dGlscyQkX2lzQXJyYXkgPSBBcnJheS5pc0FycmF5O1xuICAgIH1cblxuICAgIHZhciBsaWIkcnN2cCR1dGlscyQkaXNBcnJheSA9IGxpYiRyc3ZwJHV0aWxzJCRfaXNBcnJheTtcblxuICAgIHZhciBsaWIkcnN2cCR1dGlscyQkbm93ID0gRGF0ZS5ub3cgfHwgZnVuY3Rpb24oKSB7IHJldHVybiBuZXcgRGF0ZSgpLmdldFRpbWUoKTsgfTtcblxuICAgIGZ1bmN0aW9uIGxpYiRyc3ZwJHV0aWxzJCRGKCkgeyB9XG5cbiAgICB2YXIgbGliJHJzdnAkdXRpbHMkJG9fY3JlYXRlID0gKE9iamVjdC5jcmVhdGUgfHwgZnVuY3Rpb24gKG8pIHtcbiAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1NlY29uZCBhcmd1bWVudCBub3Qgc3VwcG9ydGVkJyk7XG4gICAgICB9XG4gICAgICBpZiAodHlwZW9mIG8gIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50IG11c3QgYmUgYW4gb2JqZWN0Jyk7XG4gICAgICB9XG4gICAgICBsaWIkcnN2cCR1dGlscyQkRi5wcm90b3R5cGUgPSBvO1xuICAgICAgcmV0dXJuIG5ldyBsaWIkcnN2cCR1dGlscyQkRigpO1xuICAgIH0pO1xuICAgIGZ1bmN0aW9uIGxpYiRyc3ZwJGV2ZW50cyQkaW5kZXhPZihjYWxsYmFja3MsIGNhbGxiYWNrKSB7XG4gICAgICBmb3IgKHZhciBpPTAsIGw9Y2FsbGJhY2tzLmxlbmd0aDsgaTxsOyBpKyspIHtcbiAgICAgICAgaWYgKGNhbGxiYWNrc1tpXSA9PT0gY2FsbGJhY2spIHsgcmV0dXJuIGk7IH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIC0xO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGxpYiRyc3ZwJGV2ZW50cyQkY2FsbGJhY2tzRm9yKG9iamVjdCkge1xuICAgICAgdmFyIGNhbGxiYWNrcyA9IG9iamVjdC5fcHJvbWlzZUNhbGxiYWNrcztcblxuICAgICAgaWYgKCFjYWxsYmFja3MpIHtcbiAgICAgICAgY2FsbGJhY2tzID0gb2JqZWN0Ll9wcm9taXNlQ2FsbGJhY2tzID0ge307XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBjYWxsYmFja3M7XG4gICAgfVxuXG4gICAgdmFyIGxpYiRyc3ZwJGV2ZW50cyQkZGVmYXVsdCA9IHtcblxuICAgICAgLyoqXG4gICAgICAgIGBSU1ZQLkV2ZW50VGFyZ2V0Lm1peGluYCBleHRlbmRzIGFuIG9iamVjdCB3aXRoIEV2ZW50VGFyZ2V0IG1ldGhvZHMuIEZvclxuICAgICAgICBFeGFtcGxlOlxuXG4gICAgICAgIGBgYGphdmFzY3JpcHRcbiAgICAgICAgdmFyIG9iamVjdCA9IHt9O1xuXG4gICAgICAgIFJTVlAuRXZlbnRUYXJnZXQubWl4aW4ob2JqZWN0KTtcblxuICAgICAgICBvYmplY3Qub24oJ2ZpbmlzaGVkJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICAgICAgICAvLyBoYW5kbGUgZXZlbnRcbiAgICAgICAgfSk7XG5cbiAgICAgICAgb2JqZWN0LnRyaWdnZXIoJ2ZpbmlzaGVkJywgeyBkZXRhaWw6IHZhbHVlIH0pO1xuICAgICAgICBgYGBcblxuICAgICAgICBgRXZlbnRUYXJnZXQubWl4aW5gIGFsc28gd29ya3Mgd2l0aCBwcm90b3R5cGVzOlxuXG4gICAgICAgIGBgYGphdmFzY3JpcHRcbiAgICAgICAgdmFyIFBlcnNvbiA9IGZ1bmN0aW9uKCkge307XG4gICAgICAgIFJTVlAuRXZlbnRUYXJnZXQubWl4aW4oUGVyc29uLnByb3RvdHlwZSk7XG5cbiAgICAgICAgdmFyIHllaHVkYSA9IG5ldyBQZXJzb24oKTtcbiAgICAgICAgdmFyIHRvbSA9IG5ldyBQZXJzb24oKTtcblxuICAgICAgICB5ZWh1ZGEub24oJ3Bva2UnLCBmdW5jdGlvbihldmVudCkge1xuICAgICAgICAgIGNvbnNvbGUubG9nKCdZZWh1ZGEgc2F5cyBPVycpO1xuICAgICAgICB9KTtcblxuICAgICAgICB0b20ub24oJ3Bva2UnLCBmdW5jdGlvbihldmVudCkge1xuICAgICAgICAgIGNvbnNvbGUubG9nKCdUb20gc2F5cyBPVycpO1xuICAgICAgICB9KTtcblxuICAgICAgICB5ZWh1ZGEudHJpZ2dlcigncG9rZScpO1xuICAgICAgICB0b20udHJpZ2dlcigncG9rZScpO1xuICAgICAgICBgYGBcblxuICAgICAgICBAbWV0aG9kIG1peGluXG4gICAgICAgIEBmb3IgUlNWUC5FdmVudFRhcmdldFxuICAgICAgICBAcHJpdmF0ZVxuICAgICAgICBAcGFyYW0ge09iamVjdH0gb2JqZWN0IG9iamVjdCB0byBleHRlbmQgd2l0aCBFdmVudFRhcmdldCBtZXRob2RzXG4gICAgICAqL1xuICAgICAgJ21peGluJzogZnVuY3Rpb24ob2JqZWN0KSB7XG4gICAgICAgIG9iamVjdFsnb24nXSAgICAgID0gdGhpc1snb24nXTtcbiAgICAgICAgb2JqZWN0WydvZmYnXSAgICAgPSB0aGlzWydvZmYnXTtcbiAgICAgICAgb2JqZWN0Wyd0cmlnZ2VyJ10gPSB0aGlzWyd0cmlnZ2VyJ107XG4gICAgICAgIG9iamVjdC5fcHJvbWlzZUNhbGxiYWNrcyA9IHVuZGVmaW5lZDtcbiAgICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICAgIH0sXG5cbiAgICAgIC8qKlxuICAgICAgICBSZWdpc3RlcnMgYSBjYWxsYmFjayB0byBiZSBleGVjdXRlZCB3aGVuIGBldmVudE5hbWVgIGlzIHRyaWdnZXJlZFxuXG4gICAgICAgIGBgYGphdmFzY3JpcHRcbiAgICAgICAgb2JqZWN0Lm9uKCdldmVudCcsIGZ1bmN0aW9uKGV2ZW50SW5mbyl7XG4gICAgICAgICAgLy8gaGFuZGxlIHRoZSBldmVudFxuICAgICAgICB9KTtcblxuICAgICAgICBvYmplY3QudHJpZ2dlcignZXZlbnQnKTtcbiAgICAgICAgYGBgXG5cbiAgICAgICAgQG1ldGhvZCBvblxuICAgICAgICBAZm9yIFJTVlAuRXZlbnRUYXJnZXRcbiAgICAgICAgQHByaXZhdGVcbiAgICAgICAgQHBhcmFtIHtTdHJpbmd9IGV2ZW50TmFtZSBuYW1lIG9mIHRoZSBldmVudCB0byBsaXN0ZW4gZm9yXG4gICAgICAgIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIGZ1bmN0aW9uIHRvIGJlIGNhbGxlZCB3aGVuIHRoZSBldmVudCBpcyB0cmlnZ2VyZWQuXG4gICAgICAqL1xuICAgICAgJ29uJzogZnVuY3Rpb24oZXZlbnROYW1lLCBjYWxsYmFjaykge1xuICAgICAgICBpZiAodHlwZW9mIGNhbGxiYWNrICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQ2FsbGJhY2sgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgYWxsQ2FsbGJhY2tzID0gbGliJHJzdnAkZXZlbnRzJCRjYWxsYmFja3NGb3IodGhpcyksIGNhbGxiYWNrcztcblxuICAgICAgICBjYWxsYmFja3MgPSBhbGxDYWxsYmFja3NbZXZlbnROYW1lXTtcblxuICAgICAgICBpZiAoIWNhbGxiYWNrcykge1xuICAgICAgICAgIGNhbGxiYWNrcyA9IGFsbENhbGxiYWNrc1tldmVudE5hbWVdID0gW107XG4gICAgICAgIH1cblxuICAgICAgICBpZiAobGliJHJzdnAkZXZlbnRzJCRpbmRleE9mKGNhbGxiYWNrcywgY2FsbGJhY2spID09PSAtMSkge1xuICAgICAgICAgIGNhbGxiYWNrcy5wdXNoKGNhbGxiYWNrKTtcbiAgICAgICAgfVxuICAgICAgfSxcblxuICAgICAgLyoqXG4gICAgICAgIFlvdSBjYW4gdXNlIGBvZmZgIHRvIHN0b3AgZmlyaW5nIGEgcGFydGljdWxhciBjYWxsYmFjayBmb3IgYW4gZXZlbnQ6XG5cbiAgICAgICAgYGBgamF2YXNjcmlwdFxuICAgICAgICBmdW5jdGlvbiBkb1N0dWZmKCkgeyAvLyBkbyBzdHVmZiEgfVxuICAgICAgICBvYmplY3Qub24oJ3N0dWZmJywgZG9TdHVmZik7XG5cbiAgICAgICAgb2JqZWN0LnRyaWdnZXIoJ3N0dWZmJyk7IC8vIGRvU3R1ZmYgd2lsbCBiZSBjYWxsZWRcblxuICAgICAgICAvLyBVbnJlZ2lzdGVyIE9OTFkgdGhlIGRvU3R1ZmYgY2FsbGJhY2tcbiAgICAgICAgb2JqZWN0Lm9mZignc3R1ZmYnLCBkb1N0dWZmKTtcbiAgICAgICAgb2JqZWN0LnRyaWdnZXIoJ3N0dWZmJyk7IC8vIGRvU3R1ZmYgd2lsbCBOT1QgYmUgY2FsbGVkXG4gICAgICAgIGBgYFxuXG4gICAgICAgIElmIHlvdSBkb24ndCBwYXNzIGEgYGNhbGxiYWNrYCBhcmd1bWVudCB0byBgb2ZmYCwgQUxMIGNhbGxiYWNrcyBmb3IgdGhlXG4gICAgICAgIGV2ZW50IHdpbGwgbm90IGJlIGV4ZWN1dGVkIHdoZW4gdGhlIGV2ZW50IGZpcmVzLiBGb3IgZXhhbXBsZTpcblxuICAgICAgICBgYGBqYXZhc2NyaXB0XG4gICAgICAgIHZhciBjYWxsYmFjazEgPSBmdW5jdGlvbigpe307XG4gICAgICAgIHZhciBjYWxsYmFjazIgPSBmdW5jdGlvbigpe307XG5cbiAgICAgICAgb2JqZWN0Lm9uKCdzdHVmZicsIGNhbGxiYWNrMSk7XG4gICAgICAgIG9iamVjdC5vbignc3R1ZmYnLCBjYWxsYmFjazIpO1xuXG4gICAgICAgIG9iamVjdC50cmlnZ2VyKCdzdHVmZicpOyAvLyBjYWxsYmFjazEgYW5kIGNhbGxiYWNrMiB3aWxsIGJlIGV4ZWN1dGVkLlxuXG4gICAgICAgIG9iamVjdC5vZmYoJ3N0dWZmJyk7XG4gICAgICAgIG9iamVjdC50cmlnZ2VyKCdzdHVmZicpOyAvLyBjYWxsYmFjazEgYW5kIGNhbGxiYWNrMiB3aWxsIG5vdCBiZSBleGVjdXRlZCFcbiAgICAgICAgYGBgXG5cbiAgICAgICAgQG1ldGhvZCBvZmZcbiAgICAgICAgQGZvciBSU1ZQLkV2ZW50VGFyZ2V0XG4gICAgICAgIEBwcml2YXRlXG4gICAgICAgIEBwYXJhbSB7U3RyaW5nfSBldmVudE5hbWUgZXZlbnQgdG8gc3RvcCBsaXN0ZW5pbmcgdG9cbiAgICAgICAgQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgb3B0aW9uYWwgYXJndW1lbnQuIElmIGdpdmVuLCBvbmx5IHRoZSBmdW5jdGlvblxuICAgICAgICBnaXZlbiB3aWxsIGJlIHJlbW92ZWQgZnJvbSB0aGUgZXZlbnQncyBjYWxsYmFjayBxdWV1ZS4gSWYgbm8gYGNhbGxiYWNrYFxuICAgICAgICBhcmd1bWVudCBpcyBnaXZlbiwgYWxsIGNhbGxiYWNrcyB3aWxsIGJlIHJlbW92ZWQgZnJvbSB0aGUgZXZlbnQncyBjYWxsYmFja1xuICAgICAgICBxdWV1ZS5cbiAgICAgICovXG4gICAgICAnb2ZmJzogZnVuY3Rpb24oZXZlbnROYW1lLCBjYWxsYmFjaykge1xuICAgICAgICB2YXIgYWxsQ2FsbGJhY2tzID0gbGliJHJzdnAkZXZlbnRzJCRjYWxsYmFja3NGb3IodGhpcyksIGNhbGxiYWNrcywgaW5kZXg7XG5cbiAgICAgICAgaWYgKCFjYWxsYmFjaykge1xuICAgICAgICAgIGFsbENhbGxiYWNrc1tldmVudE5hbWVdID0gW107XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY2FsbGJhY2tzID0gYWxsQ2FsbGJhY2tzW2V2ZW50TmFtZV07XG5cbiAgICAgICAgaW5kZXggPSBsaWIkcnN2cCRldmVudHMkJGluZGV4T2YoY2FsbGJhY2tzLCBjYWxsYmFjayk7XG5cbiAgICAgICAgaWYgKGluZGV4ICE9PSAtMSkgeyBjYWxsYmFja3Muc3BsaWNlKGluZGV4LCAxKTsgfVxuICAgICAgfSxcblxuICAgICAgLyoqXG4gICAgICAgIFVzZSBgdHJpZ2dlcmAgdG8gZmlyZSBjdXN0b20gZXZlbnRzLiBGb3IgZXhhbXBsZTpcblxuICAgICAgICBgYGBqYXZhc2NyaXB0XG4gICAgICAgIG9iamVjdC5vbignZm9vJywgZnVuY3Rpb24oKXtcbiAgICAgICAgICBjb25zb2xlLmxvZygnZm9vIGV2ZW50IGhhcHBlbmVkIScpO1xuICAgICAgICB9KTtcbiAgICAgICAgb2JqZWN0LnRyaWdnZXIoJ2ZvbycpO1xuICAgICAgICAvLyAnZm9vIGV2ZW50IGhhcHBlbmVkIScgbG9nZ2VkIHRvIHRoZSBjb25zb2xlXG4gICAgICAgIGBgYFxuXG4gICAgICAgIFlvdSBjYW4gYWxzbyBwYXNzIGEgdmFsdWUgYXMgYSBzZWNvbmQgYXJndW1lbnQgdG8gYHRyaWdnZXJgIHRoYXQgd2lsbCBiZVxuICAgICAgICBwYXNzZWQgYXMgYW4gYXJndW1lbnQgdG8gYWxsIGV2ZW50IGxpc3RlbmVycyBmb3IgdGhlIGV2ZW50OlxuXG4gICAgICAgIGBgYGphdmFzY3JpcHRcbiAgICAgICAgb2JqZWN0Lm9uKCdmb28nLCBmdW5jdGlvbih2YWx1ZSl7XG4gICAgICAgICAgY29uc29sZS5sb2codmFsdWUubmFtZSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIG9iamVjdC50cmlnZ2VyKCdmb28nLCB7IG5hbWU6ICdiYXInIH0pO1xuICAgICAgICAvLyAnYmFyJyBsb2dnZWQgdG8gdGhlIGNvbnNvbGVcbiAgICAgICAgYGBgXG5cbiAgICAgICAgQG1ldGhvZCB0cmlnZ2VyXG4gICAgICAgIEBmb3IgUlNWUC5FdmVudFRhcmdldFxuICAgICAgICBAcHJpdmF0ZVxuICAgICAgICBAcGFyYW0ge1N0cmluZ30gZXZlbnROYW1lIG5hbWUgb2YgdGhlIGV2ZW50IHRvIGJlIHRyaWdnZXJlZFxuICAgICAgICBAcGFyYW0geyp9IG9wdGlvbnMgb3B0aW9uYWwgdmFsdWUgdG8gYmUgcGFzc2VkIHRvIGFueSBldmVudCBoYW5kbGVycyBmb3JcbiAgICAgICAgdGhlIGdpdmVuIGBldmVudE5hbWVgXG4gICAgICAqL1xuICAgICAgJ3RyaWdnZXInOiBmdW5jdGlvbihldmVudE5hbWUsIG9wdGlvbnMsIGxhYmVsKSB7XG4gICAgICAgIHZhciBhbGxDYWxsYmFja3MgPSBsaWIkcnN2cCRldmVudHMkJGNhbGxiYWNrc0Zvcih0aGlzKSwgY2FsbGJhY2tzLCBjYWxsYmFjaztcblxuICAgICAgICBpZiAoY2FsbGJhY2tzID0gYWxsQ2FsbGJhY2tzW2V2ZW50TmFtZV0pIHtcbiAgICAgICAgICAvLyBEb24ndCBjYWNoZSB0aGUgY2FsbGJhY2tzLmxlbmd0aCBzaW5jZSBpdCBtYXkgZ3Jvd1xuICAgICAgICAgIGZvciAodmFyIGk9MDsgaTxjYWxsYmFja3MubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGNhbGxiYWNrID0gY2FsbGJhY2tzW2ldO1xuXG4gICAgICAgICAgICBjYWxsYmFjayhvcHRpb25zLCBsYWJlbCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfTtcblxuICAgIHZhciBsaWIkcnN2cCRjb25maWckJGNvbmZpZyA9IHtcbiAgICAgIGluc3RydW1lbnQ6IGZhbHNlXG4gICAgfTtcblxuICAgIGxpYiRyc3ZwJGV2ZW50cyQkZGVmYXVsdFsnbWl4aW4nXShsaWIkcnN2cCRjb25maWckJGNvbmZpZyk7XG5cbiAgICBmdW5jdGlvbiBsaWIkcnN2cCRjb25maWckJGNvbmZpZ3VyZShuYW1lLCB2YWx1ZSkge1xuICAgICAgaWYgKG5hbWUgPT09ICdvbmVycm9yJykge1xuICAgICAgICAvLyBoYW5kbGUgZm9yIGxlZ2FjeSB1c2VycyB0aGF0IGV4cGVjdCB0aGUgYWN0dWFsXG4gICAgICAgIC8vIGVycm9yIHRvIGJlIHBhc3NlZCB0byB0aGVpciBmdW5jdGlvbiBhZGRlZCB2aWFcbiAgICAgICAgLy8gYFJTVlAuY29uZmlndXJlKCdvbmVycm9yJywgc29tZUZ1bmN0aW9uSGVyZSk7YFxuICAgICAgICBsaWIkcnN2cCRjb25maWckJGNvbmZpZ1snb24nXSgnZXJyb3InLCB2YWx1ZSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDIpIHtcbiAgICAgICAgbGliJHJzdnAkY29uZmlnJCRjb25maWdbbmFtZV0gPSB2YWx1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBsaWIkcnN2cCRjb25maWckJGNvbmZpZ1tuYW1lXTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgbGliJHJzdnAkaW5zdHJ1bWVudCQkcXVldWUgPSBbXTtcblxuICAgIGZ1bmN0aW9uIGxpYiRyc3ZwJGluc3RydW1lbnQkJHNjaGVkdWxlRmx1c2goKSB7XG4gICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgZW50cnk7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGliJHJzdnAkaW5zdHJ1bWVudCQkcXVldWUubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICBlbnRyeSA9IGxpYiRyc3ZwJGluc3RydW1lbnQkJHF1ZXVlW2ldO1xuXG4gICAgICAgICAgdmFyIHBheWxvYWQgPSBlbnRyeS5wYXlsb2FkO1xuXG4gICAgICAgICAgcGF5bG9hZC5ndWlkID0gcGF5bG9hZC5rZXkgKyBwYXlsb2FkLmlkO1xuICAgICAgICAgIHBheWxvYWQuY2hpbGRHdWlkID0gcGF5bG9hZC5rZXkgKyBwYXlsb2FkLmNoaWxkSWQ7XG4gICAgICAgICAgaWYgKHBheWxvYWQuZXJyb3IpIHtcbiAgICAgICAgICAgIHBheWxvYWQuc3RhY2sgPSBwYXlsb2FkLmVycm9yLnN0YWNrO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGxpYiRyc3ZwJGNvbmZpZyQkY29uZmlnWyd0cmlnZ2VyJ10oZW50cnkubmFtZSwgZW50cnkucGF5bG9hZCk7XG4gICAgICAgIH1cbiAgICAgICAgbGliJHJzdnAkaW5zdHJ1bWVudCQkcXVldWUubGVuZ3RoID0gMDtcbiAgICAgIH0sIDUwKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBsaWIkcnN2cCRpbnN0cnVtZW50JCRpbnN0cnVtZW50KGV2ZW50TmFtZSwgcHJvbWlzZSwgY2hpbGQpIHtcbiAgICAgIGlmICgxID09PSBsaWIkcnN2cCRpbnN0cnVtZW50JCRxdWV1ZS5wdXNoKHtcbiAgICAgICAgbmFtZTogZXZlbnROYW1lLFxuICAgICAgICBwYXlsb2FkOiB7XG4gICAgICAgICAga2V5OiBwcm9taXNlLl9ndWlkS2V5LFxuICAgICAgICAgIGlkOiAgcHJvbWlzZS5faWQsXG4gICAgICAgICAgZXZlbnROYW1lOiBldmVudE5hbWUsXG4gICAgICAgICAgZGV0YWlsOiBwcm9taXNlLl9yZXN1bHQsXG4gICAgICAgICAgY2hpbGRJZDogY2hpbGQgJiYgY2hpbGQuX2lkLFxuICAgICAgICAgIGxhYmVsOiBwcm9taXNlLl9sYWJlbCxcbiAgICAgICAgICB0aW1lU3RhbXA6IGxpYiRyc3ZwJHV0aWxzJCRub3coKSxcbiAgICAgICAgICBlcnJvcjogbGliJHJzdnAkY29uZmlnJCRjb25maWdbXCJpbnN0cnVtZW50LXdpdGgtc3RhY2tcIl0gPyBuZXcgRXJyb3IocHJvbWlzZS5fbGFiZWwpIDogbnVsbFxuICAgICAgICB9fSkpIHtcbiAgICAgICAgICBsaWIkcnN2cCRpbnN0cnVtZW50JCRzY2hlZHVsZUZsdXNoKCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB2YXIgbGliJHJzdnAkaW5zdHJ1bWVudCQkZGVmYXVsdCA9IGxpYiRyc3ZwJGluc3RydW1lbnQkJGluc3RydW1lbnQ7XG4gICAgZnVuY3Rpb24gbGliJHJzdnAkdGhlbiQkdGhlbihvbkZ1bGZpbGxtZW50LCBvblJlamVjdGlvbiwgbGFiZWwpIHtcbiAgICAgIHZhciBwYXJlbnQgPSB0aGlzO1xuICAgICAgdmFyIHN0YXRlID0gcGFyZW50Ll9zdGF0ZTtcblxuICAgICAgaWYgKHN0YXRlID09PSBsaWIkcnN2cCQkaW50ZXJuYWwkJEZVTEZJTExFRCAmJiAhb25GdWxmaWxsbWVudCB8fCBzdGF0ZSA9PT0gbGliJHJzdnAkJGludGVybmFsJCRSRUpFQ1RFRCAmJiAhb25SZWplY3Rpb24pIHtcbiAgICAgICAgbGliJHJzdnAkY29uZmlnJCRjb25maWcuaW5zdHJ1bWVudCAmJiBsaWIkcnN2cCRpbnN0cnVtZW50JCRkZWZhdWx0KCdjaGFpbmVkJywgcGFyZW50LCBwYXJlbnQpO1xuICAgICAgICByZXR1cm4gcGFyZW50O1xuICAgICAgfVxuXG4gICAgICBwYXJlbnQuX29uRXJyb3IgPSBudWxsO1xuXG4gICAgICB2YXIgY2hpbGQgPSBuZXcgcGFyZW50LmNvbnN0cnVjdG9yKGxpYiRyc3ZwJCRpbnRlcm5hbCQkbm9vcCwgbGFiZWwpO1xuICAgICAgdmFyIHJlc3VsdCA9IHBhcmVudC5fcmVzdWx0O1xuXG4gICAgICBsaWIkcnN2cCRjb25maWckJGNvbmZpZy5pbnN0cnVtZW50ICYmIGxpYiRyc3ZwJGluc3RydW1lbnQkJGRlZmF1bHQoJ2NoYWluZWQnLCBwYXJlbnQsIGNoaWxkKTtcblxuICAgICAgaWYgKHN0YXRlKSB7XG4gICAgICAgIHZhciBjYWxsYmFjayA9IGFyZ3VtZW50c1tzdGF0ZSAtIDFdO1xuICAgICAgICBsaWIkcnN2cCRjb25maWckJGNvbmZpZy5hc3luYyhmdW5jdGlvbigpe1xuICAgICAgICAgIGxpYiRyc3ZwJCRpbnRlcm5hbCQkaW52b2tlQ2FsbGJhY2soc3RhdGUsIGNoaWxkLCBjYWxsYmFjaywgcmVzdWx0KTtcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsaWIkcnN2cCQkaW50ZXJuYWwkJHN1YnNjcmliZShwYXJlbnQsIGNoaWxkLCBvbkZ1bGZpbGxtZW50LCBvblJlamVjdGlvbik7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBjaGlsZDtcbiAgICB9XG4gICAgdmFyIGxpYiRyc3ZwJHRoZW4kJGRlZmF1bHQgPSBsaWIkcnN2cCR0aGVuJCR0aGVuO1xuICAgIGZ1bmN0aW9uIGxpYiRyc3ZwJHByb21pc2UkcmVzb2x2ZSQkcmVzb2x2ZShvYmplY3QsIGxhYmVsKSB7XG4gICAgICAvKmpzaGludCB2YWxpZHRoaXM6dHJ1ZSAqL1xuICAgICAgdmFyIENvbnN0cnVjdG9yID0gdGhpcztcblxuICAgICAgaWYgKG9iamVjdCAmJiB0eXBlb2Ygb2JqZWN0ID09PSAnb2JqZWN0JyAmJiBvYmplY3QuY29uc3RydWN0b3IgPT09IENvbnN0cnVjdG9yKSB7XG4gICAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgICB9XG5cbiAgICAgIHZhciBwcm9taXNlID0gbmV3IENvbnN0cnVjdG9yKGxpYiRyc3ZwJCRpbnRlcm5hbCQkbm9vcCwgbGFiZWwpO1xuICAgICAgbGliJHJzdnAkJGludGVybmFsJCRyZXNvbHZlKHByb21pc2UsIG9iamVjdCk7XG4gICAgICByZXR1cm4gcHJvbWlzZTtcbiAgICB9XG4gICAgdmFyIGxpYiRyc3ZwJHByb21pc2UkcmVzb2x2ZSQkZGVmYXVsdCA9IGxpYiRyc3ZwJHByb21pc2UkcmVzb2x2ZSQkcmVzb2x2ZTtcbiAgICBmdW5jdGlvbiBsaWIkcnN2cCRlbnVtZXJhdG9yJCRtYWtlU2V0dGxlZFJlc3VsdChzdGF0ZSwgcG9zaXRpb24sIHZhbHVlKSB7XG4gICAgICBpZiAoc3RhdGUgPT09IGxpYiRyc3ZwJCRpbnRlcm5hbCQkRlVMRklMTEVEKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgc3RhdGU6ICdmdWxmaWxsZWQnLFxuICAgICAgICAgIHZhbHVlOiB2YWx1ZVxuICAgICAgICB9O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgc3RhdGU6ICdyZWplY3RlZCcsXG4gICAgICAgICAgcmVhc29uOiB2YWx1ZVxuICAgICAgICB9O1xuICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGxpYiRyc3ZwJGVudW1lcmF0b3IkJEVudW1lcmF0b3IoQ29uc3RydWN0b3IsIGlucHV0LCBhYm9ydE9uUmVqZWN0LCBsYWJlbCkge1xuICAgICAgdGhpcy5faW5zdGFuY2VDb25zdHJ1Y3RvciA9IENvbnN0cnVjdG9yO1xuICAgICAgdGhpcy5wcm9taXNlID0gbmV3IENvbnN0cnVjdG9yKGxpYiRyc3ZwJCRpbnRlcm5hbCQkbm9vcCwgbGFiZWwpO1xuICAgICAgdGhpcy5fYWJvcnRPblJlamVjdCA9IGFib3J0T25SZWplY3Q7XG5cbiAgICAgIGlmICh0aGlzLl92YWxpZGF0ZUlucHV0KGlucHV0KSkge1xuICAgICAgICB0aGlzLl9pbnB1dCAgICAgPSBpbnB1dDtcbiAgICAgICAgdGhpcy5sZW5ndGggICAgID0gaW5wdXQubGVuZ3RoO1xuICAgICAgICB0aGlzLl9yZW1haW5pbmcgPSBpbnB1dC5sZW5ndGg7XG5cbiAgICAgICAgdGhpcy5faW5pdCgpO1xuXG4gICAgICAgIGlmICh0aGlzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIGxpYiRyc3ZwJCRpbnRlcm5hbCQkZnVsZmlsbCh0aGlzLnByb21pc2UsIHRoaXMuX3Jlc3VsdCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5sZW5ndGggPSB0aGlzLmxlbmd0aCB8fCAwO1xuICAgICAgICAgIHRoaXMuX2VudW1lcmF0ZSgpO1xuICAgICAgICAgIGlmICh0aGlzLl9yZW1haW5pbmcgPT09IDApIHtcbiAgICAgICAgICAgIGxpYiRyc3ZwJCRpbnRlcm5hbCQkZnVsZmlsbCh0aGlzLnByb21pc2UsIHRoaXMuX3Jlc3VsdCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsaWIkcnN2cCQkaW50ZXJuYWwkJHJlamVjdCh0aGlzLnByb21pc2UsIHRoaXMuX3ZhbGlkYXRpb25FcnJvcigpKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgbGliJHJzdnAkZW51bWVyYXRvciQkZGVmYXVsdCA9IGxpYiRyc3ZwJGVudW1lcmF0b3IkJEVudW1lcmF0b3I7XG5cbiAgICBsaWIkcnN2cCRlbnVtZXJhdG9yJCRFbnVtZXJhdG9yLnByb3RvdHlwZS5fdmFsaWRhdGVJbnB1dCA9IGZ1bmN0aW9uKGlucHV0KSB7XG4gICAgICByZXR1cm4gbGliJHJzdnAkdXRpbHMkJGlzQXJyYXkoaW5wdXQpO1xuICAgIH07XG5cbiAgICBsaWIkcnN2cCRlbnVtZXJhdG9yJCRFbnVtZXJhdG9yLnByb3RvdHlwZS5fdmFsaWRhdGlvbkVycm9yID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gbmV3IEVycm9yKCdBcnJheSBNZXRob2RzIG11c3QgYmUgcHJvdmlkZWQgYW4gQXJyYXknKTtcbiAgICB9O1xuXG4gICAgbGliJHJzdnAkZW51bWVyYXRvciQkRW51bWVyYXRvci5wcm90b3R5cGUuX2luaXQgPSBmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMuX3Jlc3VsdCA9IG5ldyBBcnJheSh0aGlzLmxlbmd0aCk7XG4gICAgfTtcblxuICAgIGxpYiRyc3ZwJGVudW1lcmF0b3IkJEVudW1lcmF0b3IucHJvdG90eXBlLl9lbnVtZXJhdGUgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBsZW5ndGggICAgID0gdGhpcy5sZW5ndGg7XG4gICAgICB2YXIgcHJvbWlzZSAgICA9IHRoaXMucHJvbWlzZTtcbiAgICAgIHZhciBpbnB1dCAgICAgID0gdGhpcy5faW5wdXQ7XG5cbiAgICAgIGZvciAodmFyIGkgPSAwOyBwcm9taXNlLl9zdGF0ZSA9PT0gbGliJHJzdnAkJGludGVybmFsJCRQRU5ESU5HICYmIGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgICB0aGlzLl9lYWNoRW50cnkoaW5wdXRbaV0sIGkpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBsaWIkcnN2cCRlbnVtZXJhdG9yJCRFbnVtZXJhdG9yLnByb3RvdHlwZS5fc2V0dGxlTWF5YmVUaGVuYWJsZSA9IGZ1bmN0aW9uKGVudHJ5LCBpKSB7XG4gICAgICB2YXIgYyA9IHRoaXMuX2luc3RhbmNlQ29uc3RydWN0b3I7XG4gICAgICB2YXIgcmVzb2x2ZSA9IGMucmVzb2x2ZTtcblxuICAgICAgaWYgKHJlc29sdmUgPT09IGxpYiRyc3ZwJHByb21pc2UkcmVzb2x2ZSQkZGVmYXVsdCkge1xuICAgICAgICB2YXIgdGhlbiA9IGxpYiRyc3ZwJCRpbnRlcm5hbCQkZ2V0VGhlbihlbnRyeSk7XG5cbiAgICAgICAgaWYgKHRoZW4gPT09IGxpYiRyc3ZwJHRoZW4kJGRlZmF1bHQgJiZcbiAgICAgICAgICAgIGVudHJ5Ll9zdGF0ZSAhPT0gbGliJHJzdnAkJGludGVybmFsJCRQRU5ESU5HKSB7XG4gICAgICAgICAgZW50cnkuX29uRXJyb3IgPSBudWxsO1xuICAgICAgICAgIHRoaXMuX3NldHRsZWRBdChlbnRyeS5fc3RhdGUsIGksIGVudHJ5Ll9yZXN1bHQpO1xuICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiB0aGVuICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgdGhpcy5fcmVtYWluaW5nLS07XG4gICAgICAgICAgdGhpcy5fcmVzdWx0W2ldID0gdGhpcy5fbWFrZVJlc3VsdChsaWIkcnN2cCQkaW50ZXJuYWwkJEZVTEZJTExFRCwgaSwgZW50cnkpO1xuICAgICAgICB9IGVsc2UgaWYgKGMgPT09IGxpYiRyc3ZwJHByb21pc2UkJGRlZmF1bHQpIHtcbiAgICAgICAgICB2YXIgcHJvbWlzZSA9IG5ldyBjKGxpYiRyc3ZwJCRpbnRlcm5hbCQkbm9vcCk7XG4gICAgICAgICAgbGliJHJzdnAkJGludGVybmFsJCRoYW5kbGVNYXliZVRoZW5hYmxlKHByb21pc2UsIGVudHJ5LCB0aGVuKTtcbiAgICAgICAgICB0aGlzLl93aWxsU2V0dGxlQXQocHJvbWlzZSwgaSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5fd2lsbFNldHRsZUF0KG5ldyBjKGZ1bmN0aW9uKHJlc29sdmUpIHsgcmVzb2x2ZShlbnRyeSk7IH0pLCBpKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5fd2lsbFNldHRsZUF0KHJlc29sdmUoZW50cnkpLCBpKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgbGliJHJzdnAkZW51bWVyYXRvciQkRW51bWVyYXRvci5wcm90b3R5cGUuX2VhY2hFbnRyeSA9IGZ1bmN0aW9uKGVudHJ5LCBpKSB7XG4gICAgICBpZiAobGliJHJzdnAkdXRpbHMkJGlzTWF5YmVUaGVuYWJsZShlbnRyeSkpIHtcbiAgICAgICAgdGhpcy5fc2V0dGxlTWF5YmVUaGVuYWJsZShlbnRyeSwgaSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLl9yZW1haW5pbmctLTtcbiAgICAgICAgdGhpcy5fcmVzdWx0W2ldID0gdGhpcy5fbWFrZVJlc3VsdChsaWIkcnN2cCQkaW50ZXJuYWwkJEZVTEZJTExFRCwgaSwgZW50cnkpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBsaWIkcnN2cCRlbnVtZXJhdG9yJCRFbnVtZXJhdG9yLnByb3RvdHlwZS5fc2V0dGxlZEF0ID0gZnVuY3Rpb24oc3RhdGUsIGksIHZhbHVlKSB7XG4gICAgICB2YXIgcHJvbWlzZSA9IHRoaXMucHJvbWlzZTtcblxuICAgICAgaWYgKHByb21pc2UuX3N0YXRlID09PSBsaWIkcnN2cCQkaW50ZXJuYWwkJFBFTkRJTkcpIHtcbiAgICAgICAgdGhpcy5fcmVtYWluaW5nLS07XG5cbiAgICAgICAgaWYgKHRoaXMuX2Fib3J0T25SZWplY3QgJiYgc3RhdGUgPT09IGxpYiRyc3ZwJCRpbnRlcm5hbCQkUkVKRUNURUQpIHtcbiAgICAgICAgICBsaWIkcnN2cCQkaW50ZXJuYWwkJHJlamVjdChwcm9taXNlLCB2YWx1ZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5fcmVzdWx0W2ldID0gdGhpcy5fbWFrZVJlc3VsdChzdGF0ZSwgaSwgdmFsdWUpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLl9yZW1haW5pbmcgPT09IDApIHtcbiAgICAgICAgbGliJHJzdnAkJGludGVybmFsJCRmdWxmaWxsKHByb21pc2UsIHRoaXMuX3Jlc3VsdCk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIGxpYiRyc3ZwJGVudW1lcmF0b3IkJEVudW1lcmF0b3IucHJvdG90eXBlLl9tYWtlUmVzdWx0ID0gZnVuY3Rpb24oc3RhdGUsIGksIHZhbHVlKSB7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfTtcblxuICAgIGxpYiRyc3ZwJGVudW1lcmF0b3IkJEVudW1lcmF0b3IucHJvdG90eXBlLl93aWxsU2V0dGxlQXQgPSBmdW5jdGlvbihwcm9taXNlLCBpKSB7XG4gICAgICB2YXIgZW51bWVyYXRvciA9IHRoaXM7XG5cbiAgICAgIGxpYiRyc3ZwJCRpbnRlcm5hbCQkc3Vic2NyaWJlKHByb21pc2UsIHVuZGVmaW5lZCwgZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgICAgZW51bWVyYXRvci5fc2V0dGxlZEF0KGxpYiRyc3ZwJCRpbnRlcm5hbCQkRlVMRklMTEVELCBpLCB2YWx1ZSk7XG4gICAgICB9LCBmdW5jdGlvbihyZWFzb24pIHtcbiAgICAgICAgZW51bWVyYXRvci5fc2V0dGxlZEF0KGxpYiRyc3ZwJCRpbnRlcm5hbCQkUkVKRUNURUQsIGksIHJlYXNvbik7XG4gICAgICB9KTtcbiAgICB9O1xuICAgIGZ1bmN0aW9uIGxpYiRyc3ZwJHByb21pc2UkYWxsJCRhbGwoZW50cmllcywgbGFiZWwpIHtcbiAgICAgIHJldHVybiBuZXcgbGliJHJzdnAkZW51bWVyYXRvciQkZGVmYXVsdCh0aGlzLCBlbnRyaWVzLCB0cnVlIC8qIGFib3J0IG9uIHJlamVjdCAqLywgbGFiZWwpLnByb21pc2U7XG4gICAgfVxuICAgIHZhciBsaWIkcnN2cCRwcm9taXNlJGFsbCQkZGVmYXVsdCA9IGxpYiRyc3ZwJHByb21pc2UkYWxsJCRhbGw7XG4gICAgZnVuY3Rpb24gbGliJHJzdnAkcHJvbWlzZSRyYWNlJCRyYWNlKGVudHJpZXMsIGxhYmVsKSB7XG4gICAgICAvKmpzaGludCB2YWxpZHRoaXM6dHJ1ZSAqL1xuICAgICAgdmFyIENvbnN0cnVjdG9yID0gdGhpcztcblxuICAgICAgdmFyIHByb21pc2UgPSBuZXcgQ29uc3RydWN0b3IobGliJHJzdnAkJGludGVybmFsJCRub29wLCBsYWJlbCk7XG5cbiAgICAgIGlmICghbGliJHJzdnAkdXRpbHMkJGlzQXJyYXkoZW50cmllcykpIHtcbiAgICAgICAgbGliJHJzdnAkJGludGVybmFsJCRyZWplY3QocHJvbWlzZSwgbmV3IFR5cGVFcnJvcignWW91IG11c3QgcGFzcyBhbiBhcnJheSB0byByYWNlLicpKTtcbiAgICAgICAgcmV0dXJuIHByb21pc2U7XG4gICAgICB9XG5cbiAgICAgIHZhciBsZW5ndGggPSBlbnRyaWVzLmxlbmd0aDtcblxuICAgICAgZnVuY3Rpb24gb25GdWxmaWxsbWVudCh2YWx1ZSkge1xuICAgICAgICBsaWIkcnN2cCQkaW50ZXJuYWwkJHJlc29sdmUocHJvbWlzZSwgdmFsdWUpO1xuICAgICAgfVxuXG4gICAgICBmdW5jdGlvbiBvblJlamVjdGlvbihyZWFzb24pIHtcbiAgICAgICAgbGliJHJzdnAkJGludGVybmFsJCRyZWplY3QocHJvbWlzZSwgcmVhc29uKTtcbiAgICAgIH1cblxuICAgICAgZm9yICh2YXIgaSA9IDA7IHByb21pc2UuX3N0YXRlID09PSBsaWIkcnN2cCQkaW50ZXJuYWwkJFBFTkRJTkcgJiYgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGxpYiRyc3ZwJCRpbnRlcm5hbCQkc3Vic2NyaWJlKENvbnN0cnVjdG9yLnJlc29sdmUoZW50cmllc1tpXSksIHVuZGVmaW5lZCwgb25GdWxmaWxsbWVudCwgb25SZWplY3Rpb24pO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcHJvbWlzZTtcbiAgICB9XG4gICAgdmFyIGxpYiRyc3ZwJHByb21pc2UkcmFjZSQkZGVmYXVsdCA9IGxpYiRyc3ZwJHByb21pc2UkcmFjZSQkcmFjZTtcbiAgICBmdW5jdGlvbiBsaWIkcnN2cCRwcm9taXNlJHJlamVjdCQkcmVqZWN0KHJlYXNvbiwgbGFiZWwpIHtcbiAgICAgIC8qanNoaW50IHZhbGlkdGhpczp0cnVlICovXG4gICAgICB2YXIgQ29uc3RydWN0b3IgPSB0aGlzO1xuICAgICAgdmFyIHByb21pc2UgPSBuZXcgQ29uc3RydWN0b3IobGliJHJzdnAkJGludGVybmFsJCRub29wLCBsYWJlbCk7XG4gICAgICBsaWIkcnN2cCQkaW50ZXJuYWwkJHJlamVjdChwcm9taXNlLCByZWFzb24pO1xuICAgICAgcmV0dXJuIHByb21pc2U7XG4gICAgfVxuICAgIHZhciBsaWIkcnN2cCRwcm9taXNlJHJlamVjdCQkZGVmYXVsdCA9IGxpYiRyc3ZwJHByb21pc2UkcmVqZWN0JCRyZWplY3Q7XG5cbiAgICB2YXIgbGliJHJzdnAkcHJvbWlzZSQkZ3VpZEtleSA9ICdyc3ZwXycgKyBsaWIkcnN2cCR1dGlscyQkbm93KCkgKyAnLSc7XG4gICAgdmFyIGxpYiRyc3ZwJHByb21pc2UkJGNvdW50ZXIgPSAwO1xuXG4gICAgZnVuY3Rpb24gbGliJHJzdnAkcHJvbWlzZSQkbmVlZHNSZXNvbHZlcigpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1lvdSBtdXN0IHBhc3MgYSByZXNvbHZlciBmdW5jdGlvbiBhcyB0aGUgZmlyc3QgYXJndW1lbnQgdG8gdGhlIHByb21pc2UgY29uc3RydWN0b3InKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBsaWIkcnN2cCRwcm9taXNlJCRuZWVkc05ldygpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJGYWlsZWQgdG8gY29uc3RydWN0ICdQcm9taXNlJzogUGxlYXNlIHVzZSB0aGUgJ25ldycgb3BlcmF0b3IsIHRoaXMgb2JqZWN0IGNvbnN0cnVjdG9yIGNhbm5vdCBiZSBjYWxsZWQgYXMgYSBmdW5jdGlvbi5cIik7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbGliJHJzdnAkcHJvbWlzZSQkUHJvbWlzZShyZXNvbHZlciwgbGFiZWwpIHtcbiAgICAgIHRoaXMuX2lkID0gbGliJHJzdnAkcHJvbWlzZSQkY291bnRlcisrO1xuICAgICAgdGhpcy5fbGFiZWwgPSBsYWJlbDtcbiAgICAgIHRoaXMuX3N0YXRlID0gdW5kZWZpbmVkO1xuICAgICAgdGhpcy5fcmVzdWx0ID0gdW5kZWZpbmVkO1xuICAgICAgdGhpcy5fc3Vic2NyaWJlcnMgPSBbXTtcblxuICAgICAgbGliJHJzdnAkY29uZmlnJCRjb25maWcuaW5zdHJ1bWVudCAmJiBsaWIkcnN2cCRpbnN0cnVtZW50JCRkZWZhdWx0KCdjcmVhdGVkJywgdGhpcyk7XG5cbiAgICAgIGlmIChsaWIkcnN2cCQkaW50ZXJuYWwkJG5vb3AgIT09IHJlc29sdmVyKSB7XG4gICAgICAgIHR5cGVvZiByZXNvbHZlciAhPT0gJ2Z1bmN0aW9uJyAmJiBsaWIkcnN2cCRwcm9taXNlJCRuZWVkc1Jlc29sdmVyKCk7XG4gICAgICAgIHRoaXMgaW5zdGFuY2VvZiBsaWIkcnN2cCRwcm9taXNlJCRQcm9taXNlID8gbGliJHJzdnAkJGludGVybmFsJCRpbml0aWFsaXplUHJvbWlzZSh0aGlzLCByZXNvbHZlcikgOiBsaWIkcnN2cCRwcm9taXNlJCRuZWVkc05ldygpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHZhciBsaWIkcnN2cCRwcm9taXNlJCRkZWZhdWx0ID0gbGliJHJzdnAkcHJvbWlzZSQkUHJvbWlzZTtcblxuICAgIC8vIGRlcHJlY2F0ZWRcbiAgICBsaWIkcnN2cCRwcm9taXNlJCRQcm9taXNlLmNhc3QgPSBsaWIkcnN2cCRwcm9taXNlJHJlc29sdmUkJGRlZmF1bHQ7XG4gICAgbGliJHJzdnAkcHJvbWlzZSQkUHJvbWlzZS5hbGwgPSBsaWIkcnN2cCRwcm9taXNlJGFsbCQkZGVmYXVsdDtcbiAgICBsaWIkcnN2cCRwcm9taXNlJCRQcm9taXNlLnJhY2UgPSBsaWIkcnN2cCRwcm9taXNlJHJhY2UkJGRlZmF1bHQ7XG4gICAgbGliJHJzdnAkcHJvbWlzZSQkUHJvbWlzZS5yZXNvbHZlID0gbGliJHJzdnAkcHJvbWlzZSRyZXNvbHZlJCRkZWZhdWx0O1xuICAgIGxpYiRyc3ZwJHByb21pc2UkJFByb21pc2UucmVqZWN0ID0gbGliJHJzdnAkcHJvbWlzZSRyZWplY3QkJGRlZmF1bHQ7XG5cbiAgICBsaWIkcnN2cCRwcm9taXNlJCRQcm9taXNlLnByb3RvdHlwZSA9IHtcbiAgICAgIGNvbnN0cnVjdG9yOiBsaWIkcnN2cCRwcm9taXNlJCRQcm9taXNlLFxuXG4gICAgICBfZ3VpZEtleTogbGliJHJzdnAkcHJvbWlzZSQkZ3VpZEtleSxcblxuICAgICAgX29uRXJyb3I6IGZ1bmN0aW9uIChyZWFzb24pIHtcbiAgICAgICAgdmFyIHByb21pc2UgPSB0aGlzO1xuICAgICAgICBsaWIkcnN2cCRjb25maWckJGNvbmZpZy5hZnRlcihmdW5jdGlvbigpIHtcbiAgICAgICAgICBpZiAocHJvbWlzZS5fb25FcnJvcikge1xuICAgICAgICAgICAgbGliJHJzdnAkY29uZmlnJCRjb25maWdbJ3RyaWdnZXInXSgnZXJyb3InLCByZWFzb24sIHByb21pc2UuX2xhYmVsKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSxcblxuICAgIC8qKlxuICAgICAgVGhlIHByaW1hcnkgd2F5IG9mIGludGVyYWN0aW5nIHdpdGggYSBwcm9taXNlIGlzIHRocm91Z2ggaXRzIGB0aGVuYCBtZXRob2QsXG4gICAgICB3aGljaCByZWdpc3RlcnMgY2FsbGJhY2tzIHRvIHJlY2VpdmUgZWl0aGVyIGEgcHJvbWlzZSdzIGV2ZW50dWFsIHZhbHVlIG9yIHRoZVxuICAgICAgcmVhc29uIHdoeSB0aGUgcHJvbWlzZSBjYW5ub3QgYmUgZnVsZmlsbGVkLlxuXG4gICAgICBgYGBqc1xuICAgICAgZmluZFVzZXIoKS50aGVuKGZ1bmN0aW9uKHVzZXIpe1xuICAgICAgICAvLyB1c2VyIGlzIGF2YWlsYWJsZVxuICAgICAgfSwgZnVuY3Rpb24ocmVhc29uKXtcbiAgICAgICAgLy8gdXNlciBpcyB1bmF2YWlsYWJsZSwgYW5kIHlvdSBhcmUgZ2l2ZW4gdGhlIHJlYXNvbiB3aHlcbiAgICAgIH0pO1xuICAgICAgYGBgXG5cbiAgICAgIENoYWluaW5nXG4gICAgICAtLS0tLS0tLVxuXG4gICAgICBUaGUgcmV0dXJuIHZhbHVlIG9mIGB0aGVuYCBpcyBpdHNlbGYgYSBwcm9taXNlLiAgVGhpcyBzZWNvbmQsICdkb3duc3RyZWFtJ1xuICAgICAgcHJvbWlzZSBpcyByZXNvbHZlZCB3aXRoIHRoZSByZXR1cm4gdmFsdWUgb2YgdGhlIGZpcnN0IHByb21pc2UncyBmdWxmaWxsbWVudFxuICAgICAgb3IgcmVqZWN0aW9uIGhhbmRsZXIsIG9yIHJlamVjdGVkIGlmIHRoZSBoYW5kbGVyIHRocm93cyBhbiBleGNlcHRpb24uXG5cbiAgICAgIGBgYGpzXG4gICAgICBmaW5kVXNlcigpLnRoZW4oZnVuY3Rpb24gKHVzZXIpIHtcbiAgICAgICAgcmV0dXJuIHVzZXIubmFtZTtcbiAgICAgIH0sIGZ1bmN0aW9uIChyZWFzb24pIHtcbiAgICAgICAgcmV0dXJuICdkZWZhdWx0IG5hbWUnO1xuICAgICAgfSkudGhlbihmdW5jdGlvbiAodXNlck5hbWUpIHtcbiAgICAgICAgLy8gSWYgYGZpbmRVc2VyYCBmdWxmaWxsZWQsIGB1c2VyTmFtZWAgd2lsbCBiZSB0aGUgdXNlcidzIG5hbWUsIG90aGVyd2lzZSBpdFxuICAgICAgICAvLyB3aWxsIGJlIGAnZGVmYXVsdCBuYW1lJ2BcbiAgICAgIH0pO1xuXG4gICAgICBmaW5kVXNlcigpLnRoZW4oZnVuY3Rpb24gKHVzZXIpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdGb3VuZCB1c2VyLCBidXQgc3RpbGwgdW5oYXBweScpO1xuICAgICAgfSwgZnVuY3Rpb24gKHJlYXNvbikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2BmaW5kVXNlcmAgcmVqZWN0ZWQgYW5kIHdlJ3JlIHVuaGFwcHknKTtcbiAgICAgIH0pLnRoZW4oZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIC8vIG5ldmVyIHJlYWNoZWRcbiAgICAgIH0sIGZ1bmN0aW9uIChyZWFzb24pIHtcbiAgICAgICAgLy8gaWYgYGZpbmRVc2VyYCBmdWxmaWxsZWQsIGByZWFzb25gIHdpbGwgYmUgJ0ZvdW5kIHVzZXIsIGJ1dCBzdGlsbCB1bmhhcHB5Jy5cbiAgICAgICAgLy8gSWYgYGZpbmRVc2VyYCByZWplY3RlZCwgYHJlYXNvbmAgd2lsbCBiZSAnYGZpbmRVc2VyYCByZWplY3RlZCBhbmQgd2UncmUgdW5oYXBweScuXG4gICAgICB9KTtcbiAgICAgIGBgYFxuICAgICAgSWYgdGhlIGRvd25zdHJlYW0gcHJvbWlzZSBkb2VzIG5vdCBzcGVjaWZ5IGEgcmVqZWN0aW9uIGhhbmRsZXIsIHJlamVjdGlvbiByZWFzb25zIHdpbGwgYmUgcHJvcGFnYXRlZCBmdXJ0aGVyIGRvd25zdHJlYW0uXG5cbiAgICAgIGBgYGpzXG4gICAgICBmaW5kVXNlcigpLnRoZW4oZnVuY3Rpb24gKHVzZXIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBlZGFnb2dpY2FsRXhjZXB0aW9uKCdVcHN0cmVhbSBlcnJvcicpO1xuICAgICAgfSkudGhlbihmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgLy8gbmV2ZXIgcmVhY2hlZFxuICAgICAgfSkudGhlbihmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgLy8gbmV2ZXIgcmVhY2hlZFxuICAgICAgfSwgZnVuY3Rpb24gKHJlYXNvbikge1xuICAgICAgICAvLyBUaGUgYFBlZGdhZ29jaWFsRXhjZXB0aW9uYCBpcyBwcm9wYWdhdGVkIGFsbCB0aGUgd2F5IGRvd24gdG8gaGVyZVxuICAgICAgfSk7XG4gICAgICBgYGBcblxuICAgICAgQXNzaW1pbGF0aW9uXG4gICAgICAtLS0tLS0tLS0tLS1cblxuICAgICAgU29tZXRpbWVzIHRoZSB2YWx1ZSB5b3Ugd2FudCB0byBwcm9wYWdhdGUgdG8gYSBkb3duc3RyZWFtIHByb21pc2UgY2FuIG9ubHkgYmVcbiAgICAgIHJldHJpZXZlZCBhc3luY2hyb25vdXNseS4gVGhpcyBjYW4gYmUgYWNoaWV2ZWQgYnkgcmV0dXJuaW5nIGEgcHJvbWlzZSBpbiB0aGVcbiAgICAgIGZ1bGZpbGxtZW50IG9yIHJlamVjdGlvbiBoYW5kbGVyLiBUaGUgZG93bnN0cmVhbSBwcm9taXNlIHdpbGwgdGhlbiBiZSBwZW5kaW5nXG4gICAgICB1bnRpbCB0aGUgcmV0dXJuZWQgcHJvbWlzZSBpcyBzZXR0bGVkLiBUaGlzIGlzIGNhbGxlZCAqYXNzaW1pbGF0aW9uKi5cblxuICAgICAgYGBganNcbiAgICAgIGZpbmRVc2VyKCkudGhlbihmdW5jdGlvbiAodXNlcikge1xuICAgICAgICByZXR1cm4gZmluZENvbW1lbnRzQnlBdXRob3IodXNlcik7XG4gICAgICB9KS50aGVuKGZ1bmN0aW9uIChjb21tZW50cykge1xuICAgICAgICAvLyBUaGUgdXNlcidzIGNvbW1lbnRzIGFyZSBub3cgYXZhaWxhYmxlXG4gICAgICB9KTtcbiAgICAgIGBgYFxuXG4gICAgICBJZiB0aGUgYXNzaW1saWF0ZWQgcHJvbWlzZSByZWplY3RzLCB0aGVuIHRoZSBkb3duc3RyZWFtIHByb21pc2Ugd2lsbCBhbHNvIHJlamVjdC5cblxuICAgICAgYGBganNcbiAgICAgIGZpbmRVc2VyKCkudGhlbihmdW5jdGlvbiAodXNlcikge1xuICAgICAgICByZXR1cm4gZmluZENvbW1lbnRzQnlBdXRob3IodXNlcik7XG4gICAgICB9KS50aGVuKGZ1bmN0aW9uIChjb21tZW50cykge1xuICAgICAgICAvLyBJZiBgZmluZENvbW1lbnRzQnlBdXRob3JgIGZ1bGZpbGxzLCB3ZSdsbCBoYXZlIHRoZSB2YWx1ZSBoZXJlXG4gICAgICB9LCBmdW5jdGlvbiAocmVhc29uKSB7XG4gICAgICAgIC8vIElmIGBmaW5kQ29tbWVudHNCeUF1dGhvcmAgcmVqZWN0cywgd2UnbGwgaGF2ZSB0aGUgcmVhc29uIGhlcmVcbiAgICAgIH0pO1xuICAgICAgYGBgXG5cbiAgICAgIFNpbXBsZSBFeGFtcGxlXG4gICAgICAtLS0tLS0tLS0tLS0tLVxuXG4gICAgICBTeW5jaHJvbm91cyBFeGFtcGxlXG5cbiAgICAgIGBgYGphdmFzY3JpcHRcbiAgICAgIHZhciByZXN1bHQ7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIHJlc3VsdCA9IGZpbmRSZXN1bHQoKTtcbiAgICAgICAgLy8gc3VjY2Vzc1xuICAgICAgfSBjYXRjaChyZWFzb24pIHtcbiAgICAgICAgLy8gZmFpbHVyZVxuICAgICAgfVxuICAgICAgYGBgXG5cbiAgICAgIEVycmJhY2sgRXhhbXBsZVxuXG4gICAgICBgYGBqc1xuICAgICAgZmluZFJlc3VsdChmdW5jdGlvbihyZXN1bHQsIGVycil7XG4gICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAvLyBmYWlsdXJlXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gc3VjY2Vzc1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIGBgYFxuXG4gICAgICBQcm9taXNlIEV4YW1wbGU7XG5cbiAgICAgIGBgYGphdmFzY3JpcHRcbiAgICAgIGZpbmRSZXN1bHQoKS50aGVuKGZ1bmN0aW9uKHJlc3VsdCl7XG4gICAgICAgIC8vIHN1Y2Nlc3NcbiAgICAgIH0sIGZ1bmN0aW9uKHJlYXNvbil7XG4gICAgICAgIC8vIGZhaWx1cmVcbiAgICAgIH0pO1xuICAgICAgYGBgXG5cbiAgICAgIEFkdmFuY2VkIEV4YW1wbGVcbiAgICAgIC0tLS0tLS0tLS0tLS0tXG5cbiAgICAgIFN5bmNocm9ub3VzIEV4YW1wbGVcblxuICAgICAgYGBgamF2YXNjcmlwdFxuICAgICAgdmFyIGF1dGhvciwgYm9va3M7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGF1dGhvciA9IGZpbmRBdXRob3IoKTtcbiAgICAgICAgYm9va3MgID0gZmluZEJvb2tzQnlBdXRob3IoYXV0aG9yKTtcbiAgICAgICAgLy8gc3VjY2Vzc1xuICAgICAgfSBjYXRjaChyZWFzb24pIHtcbiAgICAgICAgLy8gZmFpbHVyZVxuICAgICAgfVxuICAgICAgYGBgXG5cbiAgICAgIEVycmJhY2sgRXhhbXBsZVxuXG4gICAgICBgYGBqc1xuXG4gICAgICBmdW5jdGlvbiBmb3VuZEJvb2tzKGJvb2tzKSB7XG5cbiAgICAgIH1cblxuICAgICAgZnVuY3Rpb24gZmFpbHVyZShyZWFzb24pIHtcblxuICAgICAgfVxuXG4gICAgICBmaW5kQXV0aG9yKGZ1bmN0aW9uKGF1dGhvciwgZXJyKXtcbiAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgIGZhaWx1cmUoZXJyKTtcbiAgICAgICAgICAvLyBmYWlsdXJlXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGZpbmRCb29va3NCeUF1dGhvcihhdXRob3IsIGZ1bmN0aW9uKGJvb2tzLCBlcnIpIHtcbiAgICAgICAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgICAgIGZhaWx1cmUoZXJyKTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgZm91bmRCb29rcyhib29rcyk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaChyZWFzb24pIHtcbiAgICAgICAgICAgICAgICAgIGZhaWx1cmUocmVhc29uKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0gY2F0Y2goZXJyb3IpIHtcbiAgICAgICAgICAgIGZhaWx1cmUoZXJyKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gc3VjY2Vzc1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIGBgYFxuXG4gICAgICBQcm9taXNlIEV4YW1wbGU7XG5cbiAgICAgIGBgYGphdmFzY3JpcHRcbiAgICAgIGZpbmRBdXRob3IoKS5cbiAgICAgICAgdGhlbihmaW5kQm9va3NCeUF1dGhvcikuXG4gICAgICAgIHRoZW4oZnVuY3Rpb24oYm9va3Mpe1xuICAgICAgICAgIC8vIGZvdW5kIGJvb2tzXG4gICAgICB9KS5jYXRjaChmdW5jdGlvbihyZWFzb24pe1xuICAgICAgICAvLyBzb21ldGhpbmcgd2VudCB3cm9uZ1xuICAgICAgfSk7XG4gICAgICBgYGBcblxuICAgICAgQG1ldGhvZCB0aGVuXG4gICAgICBAcGFyYW0ge0Z1bmN0aW9ufSBvbkZ1bGZpbGxtZW50XG4gICAgICBAcGFyYW0ge0Z1bmN0aW9ufSBvblJlamVjdGlvblxuICAgICAgQHBhcmFtIHtTdHJpbmd9IGxhYmVsIG9wdGlvbmFsIHN0cmluZyBmb3IgbGFiZWxpbmcgdGhlIHByb21pc2UuXG4gICAgICBVc2VmdWwgZm9yIHRvb2xpbmcuXG4gICAgICBAcmV0dXJuIHtQcm9taXNlfVxuICAgICovXG4gICAgICB0aGVuOiBsaWIkcnN2cCR0aGVuJCRkZWZhdWx0LFxuXG4gICAgLyoqXG4gICAgICBgY2F0Y2hgIGlzIHNpbXBseSBzdWdhciBmb3IgYHRoZW4odW5kZWZpbmVkLCBvblJlamVjdGlvbilgIHdoaWNoIG1ha2VzIGl0IHRoZSBzYW1lXG4gICAgICBhcyB0aGUgY2F0Y2ggYmxvY2sgb2YgYSB0cnkvY2F0Y2ggc3RhdGVtZW50LlxuXG4gICAgICBgYGBqc1xuICAgICAgZnVuY3Rpb24gZmluZEF1dGhvcigpe1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2NvdWxkbid0IGZpbmQgdGhhdCBhdXRob3InKTtcbiAgICAgIH1cblxuICAgICAgLy8gc3luY2hyb25vdXNcbiAgICAgIHRyeSB7XG4gICAgICAgIGZpbmRBdXRob3IoKTtcbiAgICAgIH0gY2F0Y2gocmVhc29uKSB7XG4gICAgICAgIC8vIHNvbWV0aGluZyB3ZW50IHdyb25nXG4gICAgICB9XG5cbiAgICAgIC8vIGFzeW5jIHdpdGggcHJvbWlzZXNcbiAgICAgIGZpbmRBdXRob3IoKS5jYXRjaChmdW5jdGlvbihyZWFzb24pe1xuICAgICAgICAvLyBzb21ldGhpbmcgd2VudCB3cm9uZ1xuICAgICAgfSk7XG4gICAgICBgYGBcblxuICAgICAgQG1ldGhvZCBjYXRjaFxuICAgICAgQHBhcmFtIHtGdW5jdGlvbn0gb25SZWplY3Rpb25cbiAgICAgIEBwYXJhbSB7U3RyaW5nfSBsYWJlbCBvcHRpb25hbCBzdHJpbmcgZm9yIGxhYmVsaW5nIHRoZSBwcm9taXNlLlxuICAgICAgVXNlZnVsIGZvciB0b29saW5nLlxuICAgICAgQHJldHVybiB7UHJvbWlzZX1cbiAgICAqL1xuICAgICAgJ2NhdGNoJzogZnVuY3Rpb24ob25SZWplY3Rpb24sIGxhYmVsKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnRoZW4odW5kZWZpbmVkLCBvblJlamVjdGlvbiwgbGFiZWwpO1xuICAgICAgfSxcblxuICAgIC8qKlxuICAgICAgYGZpbmFsbHlgIHdpbGwgYmUgaW52b2tlZCByZWdhcmRsZXNzIG9mIHRoZSBwcm9taXNlJ3MgZmF0ZSBqdXN0IGFzIG5hdGl2ZVxuICAgICAgdHJ5L2NhdGNoL2ZpbmFsbHkgYmVoYXZlc1xuXG4gICAgICBTeW5jaHJvbm91cyBleGFtcGxlOlxuXG4gICAgICBgYGBqc1xuICAgICAgZmluZEF1dGhvcigpIHtcbiAgICAgICAgaWYgKE1hdGgucmFuZG9tKCkgPiAwLjUpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IEF1dGhvcigpO1xuICAgICAgfVxuXG4gICAgICB0cnkge1xuICAgICAgICByZXR1cm4gZmluZEF1dGhvcigpOyAvLyBzdWNjZWVkIG9yIGZhaWxcbiAgICAgIH0gY2F0Y2goZXJyb3IpIHtcbiAgICAgICAgcmV0dXJuIGZpbmRPdGhlckF1dGhlcigpO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgLy8gYWx3YXlzIHJ1bnNcbiAgICAgICAgLy8gZG9lc24ndCBhZmZlY3QgdGhlIHJldHVybiB2YWx1ZVxuICAgICAgfVxuICAgICAgYGBgXG5cbiAgICAgIEFzeW5jaHJvbm91cyBleGFtcGxlOlxuXG4gICAgICBgYGBqc1xuICAgICAgZmluZEF1dGhvcigpLmNhdGNoKGZ1bmN0aW9uKHJlYXNvbil7XG4gICAgICAgIHJldHVybiBmaW5kT3RoZXJBdXRoZXIoKTtcbiAgICAgIH0pLmZpbmFsbHkoZnVuY3Rpb24oKXtcbiAgICAgICAgLy8gYXV0aG9yIHdhcyBlaXRoZXIgZm91bmQsIG9yIG5vdFxuICAgICAgfSk7XG4gICAgICBgYGBcblxuICAgICAgQG1ldGhvZCBmaW5hbGx5XG4gICAgICBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgICAgQHBhcmFtIHtTdHJpbmd9IGxhYmVsIG9wdGlvbmFsIHN0cmluZyBmb3IgbGFiZWxpbmcgdGhlIHByb21pc2UuXG4gICAgICBVc2VmdWwgZm9yIHRvb2xpbmcuXG4gICAgICBAcmV0dXJuIHtQcm9taXNlfVxuICAgICovXG4gICAgICAnZmluYWxseSc6IGZ1bmN0aW9uKGNhbGxiYWNrLCBsYWJlbCkge1xuICAgICAgICB2YXIgcHJvbWlzZSA9IHRoaXM7XG4gICAgICAgIHZhciBjb25zdHJ1Y3RvciA9IHByb21pc2UuY29uc3RydWN0b3I7XG5cbiAgICAgICAgcmV0dXJuIHByb21pc2UudGhlbihmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgICAgIHJldHVybiBjb25zdHJ1Y3Rvci5yZXNvbHZlKGNhbGxiYWNrKCkpLnRoZW4oZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0sIGZ1bmN0aW9uKHJlYXNvbikge1xuICAgICAgICAgIHJldHVybiBjb25zdHJ1Y3Rvci5yZXNvbHZlKGNhbGxiYWNrKCkpLnRoZW4oZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICByZXR1cm4gY29uc3RydWN0b3IucmVqZWN0KHJlYXNvbik7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0sIGxhYmVsKTtcbiAgICAgIH1cbiAgICB9O1xuICAgIGZ1bmN0aW9uICBsaWIkcnN2cCQkaW50ZXJuYWwkJHdpdGhPd25Qcm9taXNlKCkge1xuICAgICAgcmV0dXJuIG5ldyBUeXBlRXJyb3IoJ0EgcHJvbWlzZXMgY2FsbGJhY2sgY2Fubm90IHJldHVybiB0aGF0IHNhbWUgcHJvbWlzZS4nKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBsaWIkcnN2cCQkaW50ZXJuYWwkJG5vb3AoKSB7fVxuXG4gICAgdmFyIGxpYiRyc3ZwJCRpbnRlcm5hbCQkUEVORElORyAgID0gdm9pZCAwO1xuICAgIHZhciBsaWIkcnN2cCQkaW50ZXJuYWwkJEZVTEZJTExFRCA9IDE7XG4gICAgdmFyIGxpYiRyc3ZwJCRpbnRlcm5hbCQkUkVKRUNURUQgID0gMjtcblxuICAgIHZhciBsaWIkcnN2cCQkaW50ZXJuYWwkJEdFVF9USEVOX0VSUk9SID0gbmV3IGxpYiRyc3ZwJCRpbnRlcm5hbCQkRXJyb3JPYmplY3QoKTtcblxuICAgIGZ1bmN0aW9uIGxpYiRyc3ZwJCRpbnRlcm5hbCQkZ2V0VGhlbihwcm9taXNlKSB7XG4gICAgICB0cnkge1xuICAgICAgICByZXR1cm4gcHJvbWlzZS50aGVuO1xuICAgICAgfSBjYXRjaChlcnJvcikge1xuICAgICAgICBsaWIkcnN2cCQkaW50ZXJuYWwkJEdFVF9USEVOX0VSUk9SLmVycm9yID0gZXJyb3I7XG4gICAgICAgIHJldHVybiBsaWIkcnN2cCQkaW50ZXJuYWwkJEdFVF9USEVOX0VSUk9SO1xuICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGxpYiRyc3ZwJCRpbnRlcm5hbCQkdHJ5VGhlbih0aGVuLCB2YWx1ZSwgZnVsZmlsbG1lbnRIYW5kbGVyLCByZWplY3Rpb25IYW5kbGVyKSB7XG4gICAgICB0cnkge1xuICAgICAgICB0aGVuLmNhbGwodmFsdWUsIGZ1bGZpbGxtZW50SGFuZGxlciwgcmVqZWN0aW9uSGFuZGxlcik7XG4gICAgICB9IGNhdGNoKGUpIHtcbiAgICAgICAgcmV0dXJuIGU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbGliJHJzdnAkJGludGVybmFsJCRoYW5kbGVGb3JlaWduVGhlbmFibGUocHJvbWlzZSwgdGhlbmFibGUsIHRoZW4pIHtcbiAgICAgIGxpYiRyc3ZwJGNvbmZpZyQkY29uZmlnLmFzeW5jKGZ1bmN0aW9uKHByb21pc2UpIHtcbiAgICAgICAgdmFyIHNlYWxlZCA9IGZhbHNlO1xuICAgICAgICB2YXIgZXJyb3IgPSBsaWIkcnN2cCQkaW50ZXJuYWwkJHRyeVRoZW4odGhlbiwgdGhlbmFibGUsIGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICAgICAgaWYgKHNlYWxlZCkgeyByZXR1cm47IH1cbiAgICAgICAgICBzZWFsZWQgPSB0cnVlO1xuICAgICAgICAgIGlmICh0aGVuYWJsZSAhPT0gdmFsdWUpIHtcbiAgICAgICAgICAgIGxpYiRyc3ZwJCRpbnRlcm5hbCQkcmVzb2x2ZShwcm9taXNlLCB2YWx1ZSwgdW5kZWZpbmVkKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbGliJHJzdnAkJGludGVybmFsJCRmdWxmaWxsKHByb21pc2UsIHZhbHVlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sIGZ1bmN0aW9uKHJlYXNvbikge1xuICAgICAgICAgIGlmIChzZWFsZWQpIHsgcmV0dXJuOyB9XG4gICAgICAgICAgc2VhbGVkID0gdHJ1ZTtcblxuICAgICAgICAgIGxpYiRyc3ZwJCRpbnRlcm5hbCQkcmVqZWN0KHByb21pc2UsIHJlYXNvbik7XG4gICAgICAgIH0sICdTZXR0bGU6ICcgKyAocHJvbWlzZS5fbGFiZWwgfHwgJyB1bmtub3duIHByb21pc2UnKSk7XG5cbiAgICAgICAgaWYgKCFzZWFsZWQgJiYgZXJyb3IpIHtcbiAgICAgICAgICBzZWFsZWQgPSB0cnVlO1xuICAgICAgICAgIGxpYiRyc3ZwJCRpbnRlcm5hbCQkcmVqZWN0KHByb21pc2UsIGVycm9yKTtcbiAgICAgICAgfVxuICAgICAgfSwgcHJvbWlzZSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbGliJHJzdnAkJGludGVybmFsJCRoYW5kbGVPd25UaGVuYWJsZShwcm9taXNlLCB0aGVuYWJsZSkge1xuICAgICAgaWYgKHRoZW5hYmxlLl9zdGF0ZSA9PT0gbGliJHJzdnAkJGludGVybmFsJCRGVUxGSUxMRUQpIHtcbiAgICAgICAgbGliJHJzdnAkJGludGVybmFsJCRmdWxmaWxsKHByb21pc2UsIHRoZW5hYmxlLl9yZXN1bHQpO1xuICAgICAgfSBlbHNlIGlmICh0aGVuYWJsZS5fc3RhdGUgPT09IGxpYiRyc3ZwJCRpbnRlcm5hbCQkUkVKRUNURUQpIHtcbiAgICAgICAgdGhlbmFibGUuX29uRXJyb3IgPSBudWxsO1xuICAgICAgICBsaWIkcnN2cCQkaW50ZXJuYWwkJHJlamVjdChwcm9taXNlLCB0aGVuYWJsZS5fcmVzdWx0KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxpYiRyc3ZwJCRpbnRlcm5hbCQkc3Vic2NyaWJlKHRoZW5hYmxlLCB1bmRlZmluZWQsIGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICAgICAgaWYgKHRoZW5hYmxlICE9PSB2YWx1ZSkge1xuICAgICAgICAgICAgbGliJHJzdnAkJGludGVybmFsJCRyZXNvbHZlKHByb21pc2UsIHZhbHVlLCB1bmRlZmluZWQpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBsaWIkcnN2cCQkaW50ZXJuYWwkJGZ1bGZpbGwocHJvbWlzZSwgdmFsdWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSwgZnVuY3Rpb24ocmVhc29uKSB7XG4gICAgICAgICAgbGliJHJzdnAkJGludGVybmFsJCRyZWplY3QocHJvbWlzZSwgcmVhc29uKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbGliJHJzdnAkJGludGVybmFsJCRoYW5kbGVNYXliZVRoZW5hYmxlKHByb21pc2UsIG1heWJlVGhlbmFibGUsIHRoZW4pIHtcbiAgICAgIGlmIChtYXliZVRoZW5hYmxlLmNvbnN0cnVjdG9yID09PSBwcm9taXNlLmNvbnN0cnVjdG9yICYmXG4gICAgICAgICAgdGhlbiA9PT0gbGliJHJzdnAkdGhlbiQkZGVmYXVsdCAmJlxuICAgICAgICAgIGNvbnN0cnVjdG9yLnJlc29sdmUgPT09IGxpYiRyc3ZwJHByb21pc2UkcmVzb2x2ZSQkZGVmYXVsdCkge1xuICAgICAgICBsaWIkcnN2cCQkaW50ZXJuYWwkJGhhbmRsZU93blRoZW5hYmxlKHByb21pc2UsIG1heWJlVGhlbmFibGUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKHRoZW4gPT09IGxpYiRyc3ZwJCRpbnRlcm5hbCQkR0VUX1RIRU5fRVJST1IpIHtcbiAgICAgICAgICBsaWIkcnN2cCQkaW50ZXJuYWwkJHJlamVjdChwcm9taXNlLCBsaWIkcnN2cCQkaW50ZXJuYWwkJEdFVF9USEVOX0VSUk9SLmVycm9yKTtcbiAgICAgICAgfSBlbHNlIGlmICh0aGVuID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBsaWIkcnN2cCQkaW50ZXJuYWwkJGZ1bGZpbGwocHJvbWlzZSwgbWF5YmVUaGVuYWJsZSk7XG4gICAgICAgIH0gZWxzZSBpZiAobGliJHJzdnAkdXRpbHMkJGlzRnVuY3Rpb24odGhlbikpIHtcbiAgICAgICAgICBsaWIkcnN2cCQkaW50ZXJuYWwkJGhhbmRsZUZvcmVpZ25UaGVuYWJsZShwcm9taXNlLCBtYXliZVRoZW5hYmxlLCB0aGVuKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBsaWIkcnN2cCQkaW50ZXJuYWwkJGZ1bGZpbGwocHJvbWlzZSwgbWF5YmVUaGVuYWJsZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBsaWIkcnN2cCQkaW50ZXJuYWwkJHJlc29sdmUocHJvbWlzZSwgdmFsdWUpIHtcbiAgICAgIGlmIChwcm9taXNlID09PSB2YWx1ZSkge1xuICAgICAgICBsaWIkcnN2cCQkaW50ZXJuYWwkJGZ1bGZpbGwocHJvbWlzZSwgdmFsdWUpO1xuICAgICAgfSBlbHNlIGlmIChsaWIkcnN2cCR1dGlscyQkb2JqZWN0T3JGdW5jdGlvbih2YWx1ZSkpIHtcbiAgICAgICAgbGliJHJzdnAkJGludGVybmFsJCRoYW5kbGVNYXliZVRoZW5hYmxlKHByb21pc2UsIHZhbHVlLCBsaWIkcnN2cCQkaW50ZXJuYWwkJGdldFRoZW4odmFsdWUpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxpYiRyc3ZwJCRpbnRlcm5hbCQkZnVsZmlsbChwcm9taXNlLCB2YWx1ZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbGliJHJzdnAkJGludGVybmFsJCRwdWJsaXNoUmVqZWN0aW9uKHByb21pc2UpIHtcbiAgICAgIGlmIChwcm9taXNlLl9vbkVycm9yKSB7XG4gICAgICAgIHByb21pc2UuX29uRXJyb3IocHJvbWlzZS5fcmVzdWx0KTtcbiAgICAgIH1cblxuICAgICAgbGliJHJzdnAkJGludGVybmFsJCRwdWJsaXNoKHByb21pc2UpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGxpYiRyc3ZwJCRpbnRlcm5hbCQkZnVsZmlsbChwcm9taXNlLCB2YWx1ZSkge1xuICAgICAgaWYgKHByb21pc2UuX3N0YXRlICE9PSBsaWIkcnN2cCQkaW50ZXJuYWwkJFBFTkRJTkcpIHsgcmV0dXJuOyB9XG5cbiAgICAgIHByb21pc2UuX3Jlc3VsdCA9IHZhbHVlO1xuICAgICAgcHJvbWlzZS5fc3RhdGUgPSBsaWIkcnN2cCQkaW50ZXJuYWwkJEZVTEZJTExFRDtcblxuICAgICAgaWYgKHByb21pc2UuX3N1YnNjcmliZXJzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICBpZiAobGliJHJzdnAkY29uZmlnJCRjb25maWcuaW5zdHJ1bWVudCkge1xuICAgICAgICAgIGxpYiRyc3ZwJGluc3RydW1lbnQkJGRlZmF1bHQoJ2Z1bGZpbGxlZCcsIHByb21pc2UpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsaWIkcnN2cCRjb25maWckJGNvbmZpZy5hc3luYyhsaWIkcnN2cCQkaW50ZXJuYWwkJHB1Ymxpc2gsIHByb21pc2UpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGxpYiRyc3ZwJCRpbnRlcm5hbCQkcmVqZWN0KHByb21pc2UsIHJlYXNvbikge1xuICAgICAgaWYgKHByb21pc2UuX3N0YXRlICE9PSBsaWIkcnN2cCQkaW50ZXJuYWwkJFBFTkRJTkcpIHsgcmV0dXJuOyB9XG4gICAgICBwcm9taXNlLl9zdGF0ZSA9IGxpYiRyc3ZwJCRpbnRlcm5hbCQkUkVKRUNURUQ7XG4gICAgICBwcm9taXNlLl9yZXN1bHQgPSByZWFzb247XG4gICAgICBsaWIkcnN2cCRjb25maWckJGNvbmZpZy5hc3luYyhsaWIkcnN2cCQkaW50ZXJuYWwkJHB1Ymxpc2hSZWplY3Rpb24sIHByb21pc2UpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGxpYiRyc3ZwJCRpbnRlcm5hbCQkc3Vic2NyaWJlKHBhcmVudCwgY2hpbGQsIG9uRnVsZmlsbG1lbnQsIG9uUmVqZWN0aW9uKSB7XG4gICAgICB2YXIgc3Vic2NyaWJlcnMgPSBwYXJlbnQuX3N1YnNjcmliZXJzO1xuICAgICAgdmFyIGxlbmd0aCA9IHN1YnNjcmliZXJzLmxlbmd0aDtcblxuICAgICAgcGFyZW50Ll9vbkVycm9yID0gbnVsbDtcblxuICAgICAgc3Vic2NyaWJlcnNbbGVuZ3RoXSA9IGNoaWxkO1xuICAgICAgc3Vic2NyaWJlcnNbbGVuZ3RoICsgbGliJHJzdnAkJGludGVybmFsJCRGVUxGSUxMRURdID0gb25GdWxmaWxsbWVudDtcbiAgICAgIHN1YnNjcmliZXJzW2xlbmd0aCArIGxpYiRyc3ZwJCRpbnRlcm5hbCQkUkVKRUNURURdICA9IG9uUmVqZWN0aW9uO1xuXG4gICAgICBpZiAobGVuZ3RoID09PSAwICYmIHBhcmVudC5fc3RhdGUpIHtcbiAgICAgICAgbGliJHJzdnAkY29uZmlnJCRjb25maWcuYXN5bmMobGliJHJzdnAkJGludGVybmFsJCRwdWJsaXNoLCBwYXJlbnQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGxpYiRyc3ZwJCRpbnRlcm5hbCQkcHVibGlzaChwcm9taXNlKSB7XG4gICAgICB2YXIgc3Vic2NyaWJlcnMgPSBwcm9taXNlLl9zdWJzY3JpYmVycztcbiAgICAgIHZhciBzZXR0bGVkID0gcHJvbWlzZS5fc3RhdGU7XG5cbiAgICAgIGlmIChsaWIkcnN2cCRjb25maWckJGNvbmZpZy5pbnN0cnVtZW50KSB7XG4gICAgICAgIGxpYiRyc3ZwJGluc3RydW1lbnQkJGRlZmF1bHQoc2V0dGxlZCA9PT0gbGliJHJzdnAkJGludGVybmFsJCRGVUxGSUxMRUQgPyAnZnVsZmlsbGVkJyA6ICdyZWplY3RlZCcsIHByb21pc2UpO1xuICAgICAgfVxuXG4gICAgICBpZiAoc3Vic2NyaWJlcnMubGVuZ3RoID09PSAwKSB7IHJldHVybjsgfVxuXG4gICAgICB2YXIgY2hpbGQsIGNhbGxiYWNrLCBkZXRhaWwgPSBwcm9taXNlLl9yZXN1bHQ7XG5cbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc3Vic2NyaWJlcnMubGVuZ3RoOyBpICs9IDMpIHtcbiAgICAgICAgY2hpbGQgPSBzdWJzY3JpYmVyc1tpXTtcbiAgICAgICAgY2FsbGJhY2sgPSBzdWJzY3JpYmVyc1tpICsgc2V0dGxlZF07XG5cbiAgICAgICAgaWYgKGNoaWxkKSB7XG4gICAgICAgICAgbGliJHJzdnAkJGludGVybmFsJCRpbnZva2VDYWxsYmFjayhzZXR0bGVkLCBjaGlsZCwgY2FsbGJhY2ssIGRldGFpbCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY2FsbGJhY2soZGV0YWlsKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBwcm9taXNlLl9zdWJzY3JpYmVycy5sZW5ndGggPSAwO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGxpYiRyc3ZwJCRpbnRlcm5hbCQkRXJyb3JPYmplY3QoKSB7XG4gICAgICB0aGlzLmVycm9yID0gbnVsbDtcbiAgICB9XG5cbiAgICB2YXIgbGliJHJzdnAkJGludGVybmFsJCRUUllfQ0FUQ0hfRVJST1IgPSBuZXcgbGliJHJzdnAkJGludGVybmFsJCRFcnJvck9iamVjdCgpO1xuXG4gICAgZnVuY3Rpb24gbGliJHJzdnAkJGludGVybmFsJCR0cnlDYXRjaChjYWxsYmFjaywgZGV0YWlsKSB7XG4gICAgICB0cnkge1xuICAgICAgICByZXR1cm4gY2FsbGJhY2soZGV0YWlsKTtcbiAgICAgIH0gY2F0Y2goZSkge1xuICAgICAgICBsaWIkcnN2cCQkaW50ZXJuYWwkJFRSWV9DQVRDSF9FUlJPUi5lcnJvciA9IGU7XG4gICAgICAgIHJldHVybiBsaWIkcnN2cCQkaW50ZXJuYWwkJFRSWV9DQVRDSF9FUlJPUjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBsaWIkcnN2cCQkaW50ZXJuYWwkJGludm9rZUNhbGxiYWNrKHNldHRsZWQsIHByb21pc2UsIGNhbGxiYWNrLCBkZXRhaWwpIHtcbiAgICAgIHZhciBoYXNDYWxsYmFjayA9IGxpYiRyc3ZwJHV0aWxzJCRpc0Z1bmN0aW9uKGNhbGxiYWNrKSxcbiAgICAgICAgICB2YWx1ZSwgZXJyb3IsIHN1Y2NlZWRlZCwgZmFpbGVkO1xuXG4gICAgICBpZiAoaGFzQ2FsbGJhY2spIHtcbiAgICAgICAgdmFsdWUgPSBsaWIkcnN2cCQkaW50ZXJuYWwkJHRyeUNhdGNoKGNhbGxiYWNrLCBkZXRhaWwpO1xuXG4gICAgICAgIGlmICh2YWx1ZSA9PT0gbGliJHJzdnAkJGludGVybmFsJCRUUllfQ0FUQ0hfRVJST1IpIHtcbiAgICAgICAgICBmYWlsZWQgPSB0cnVlO1xuICAgICAgICAgIGVycm9yID0gdmFsdWUuZXJyb3I7XG4gICAgICAgICAgdmFsdWUgPSBudWxsO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHN1Y2NlZWRlZCA9IHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocHJvbWlzZSA9PT0gdmFsdWUpIHtcbiAgICAgICAgICBsaWIkcnN2cCQkaW50ZXJuYWwkJHJlamVjdChwcm9taXNlLCBsaWIkcnN2cCQkaW50ZXJuYWwkJHdpdGhPd25Qcm9taXNlKCkpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YWx1ZSA9IGRldGFpbDtcbiAgICAgICAgc3VjY2VlZGVkID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKHByb21pc2UuX3N0YXRlICE9PSBsaWIkcnN2cCQkaW50ZXJuYWwkJFBFTkRJTkcpIHtcbiAgICAgICAgLy8gbm9vcFxuICAgICAgfSBlbHNlIGlmIChoYXNDYWxsYmFjayAmJiBzdWNjZWVkZWQpIHtcbiAgICAgICAgbGliJHJzdnAkJGludGVybmFsJCRyZXNvbHZlKHByb21pc2UsIHZhbHVlKTtcbiAgICAgIH0gZWxzZSBpZiAoZmFpbGVkKSB7XG4gICAgICAgIGxpYiRyc3ZwJCRpbnRlcm5hbCQkcmVqZWN0KHByb21pc2UsIGVycm9yKTtcbiAgICAgIH0gZWxzZSBpZiAoc2V0dGxlZCA9PT0gbGliJHJzdnAkJGludGVybmFsJCRGVUxGSUxMRUQpIHtcbiAgICAgICAgbGliJHJzdnAkJGludGVybmFsJCRmdWxmaWxsKHByb21pc2UsIHZhbHVlKTtcbiAgICAgIH0gZWxzZSBpZiAoc2V0dGxlZCA9PT0gbGliJHJzdnAkJGludGVybmFsJCRSRUpFQ1RFRCkge1xuICAgICAgICBsaWIkcnN2cCQkaW50ZXJuYWwkJHJlamVjdChwcm9taXNlLCB2YWx1ZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbGliJHJzdnAkJGludGVybmFsJCRpbml0aWFsaXplUHJvbWlzZShwcm9taXNlLCByZXNvbHZlcikge1xuICAgICAgdmFyIHJlc29sdmVkID0gZmFsc2U7XG4gICAgICB0cnkge1xuICAgICAgICByZXNvbHZlcihmdW5jdGlvbiByZXNvbHZlUHJvbWlzZSh2YWx1ZSl7XG4gICAgICAgICAgaWYgKHJlc29sdmVkKSB7IHJldHVybjsgfVxuICAgICAgICAgIHJlc29sdmVkID0gdHJ1ZTtcbiAgICAgICAgICBsaWIkcnN2cCQkaW50ZXJuYWwkJHJlc29sdmUocHJvbWlzZSwgdmFsdWUpO1xuICAgICAgICB9LCBmdW5jdGlvbiByZWplY3RQcm9taXNlKHJlYXNvbikge1xuICAgICAgICAgIGlmIChyZXNvbHZlZCkgeyByZXR1cm47IH1cbiAgICAgICAgICByZXNvbHZlZCA9IHRydWU7XG4gICAgICAgICAgbGliJHJzdnAkJGludGVybmFsJCRyZWplY3QocHJvbWlzZSwgcmVhc29uKTtcbiAgICAgICAgfSk7XG4gICAgICB9IGNhdGNoKGUpIHtcbiAgICAgICAgbGliJHJzdnAkJGludGVybmFsJCRyZWplY3QocHJvbWlzZSwgZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbGliJHJzdnAkYWxsJHNldHRsZWQkJEFsbFNldHRsZWQoQ29uc3RydWN0b3IsIGVudHJpZXMsIGxhYmVsKSB7XG4gICAgICB0aGlzLl9zdXBlckNvbnN0cnVjdG9yKENvbnN0cnVjdG9yLCBlbnRyaWVzLCBmYWxzZSAvKiBkb24ndCBhYm9ydCBvbiByZWplY3QgKi8sIGxhYmVsKTtcbiAgICB9XG5cbiAgICBsaWIkcnN2cCRhbGwkc2V0dGxlZCQkQWxsU2V0dGxlZC5wcm90b3R5cGUgPSBsaWIkcnN2cCR1dGlscyQkb19jcmVhdGUobGliJHJzdnAkZW51bWVyYXRvciQkZGVmYXVsdC5wcm90b3R5cGUpO1xuICAgIGxpYiRyc3ZwJGFsbCRzZXR0bGVkJCRBbGxTZXR0bGVkLnByb3RvdHlwZS5fc3VwZXJDb25zdHJ1Y3RvciA9IGxpYiRyc3ZwJGVudW1lcmF0b3IkJGRlZmF1bHQ7XG4gICAgbGliJHJzdnAkYWxsJHNldHRsZWQkJEFsbFNldHRsZWQucHJvdG90eXBlLl9tYWtlUmVzdWx0ID0gbGliJHJzdnAkZW51bWVyYXRvciQkbWFrZVNldHRsZWRSZXN1bHQ7XG4gICAgbGliJHJzdnAkYWxsJHNldHRsZWQkJEFsbFNldHRsZWQucHJvdG90eXBlLl92YWxpZGF0aW9uRXJyb3IgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBuZXcgRXJyb3IoJ2FsbFNldHRsZWQgbXVzdCBiZSBjYWxsZWQgd2l0aCBhbiBhcnJheScpO1xuICAgIH07XG5cbiAgICBmdW5jdGlvbiBsaWIkcnN2cCRhbGwkc2V0dGxlZCQkYWxsU2V0dGxlZChlbnRyaWVzLCBsYWJlbCkge1xuICAgICAgcmV0dXJuIG5ldyBsaWIkcnN2cCRhbGwkc2V0dGxlZCQkQWxsU2V0dGxlZChsaWIkcnN2cCRwcm9taXNlJCRkZWZhdWx0LCBlbnRyaWVzLCBsYWJlbCkucHJvbWlzZTtcbiAgICB9XG4gICAgdmFyIGxpYiRyc3ZwJGFsbCRzZXR0bGVkJCRkZWZhdWx0ID0gbGliJHJzdnAkYWxsJHNldHRsZWQkJGFsbFNldHRsZWQ7XG4gICAgZnVuY3Rpb24gbGliJHJzdnAkYWxsJCRhbGwoYXJyYXksIGxhYmVsKSB7XG4gICAgICByZXR1cm4gbGliJHJzdnAkcHJvbWlzZSQkZGVmYXVsdC5hbGwoYXJyYXksIGxhYmVsKTtcbiAgICB9XG4gICAgdmFyIGxpYiRyc3ZwJGFsbCQkZGVmYXVsdCA9IGxpYiRyc3ZwJGFsbCQkYWxsO1xuICAgIHZhciBsaWIkcnN2cCRhc2FwJCRsZW4gPSAwO1xuICAgIHZhciBsaWIkcnN2cCRhc2FwJCR0b1N0cmluZyA9IHt9LnRvU3RyaW5nO1xuICAgIHZhciBsaWIkcnN2cCRhc2FwJCR2ZXJ0eE5leHQ7XG4gICAgZnVuY3Rpb24gbGliJHJzdnAkYXNhcCQkYXNhcChjYWxsYmFjaywgYXJnKSB7XG4gICAgICBsaWIkcnN2cCRhc2FwJCRxdWV1ZVtsaWIkcnN2cCRhc2FwJCRsZW5dID0gY2FsbGJhY2s7XG4gICAgICBsaWIkcnN2cCRhc2FwJCRxdWV1ZVtsaWIkcnN2cCRhc2FwJCRsZW4gKyAxXSA9IGFyZztcbiAgICAgIGxpYiRyc3ZwJGFzYXAkJGxlbiArPSAyO1xuICAgICAgaWYgKGxpYiRyc3ZwJGFzYXAkJGxlbiA9PT0gMikge1xuICAgICAgICAvLyBJZiBsZW4gaXMgMSwgdGhhdCBtZWFucyB0aGF0IHdlIG5lZWQgdG8gc2NoZWR1bGUgYW4gYXN5bmMgZmx1c2guXG4gICAgICAgIC8vIElmIGFkZGl0aW9uYWwgY2FsbGJhY2tzIGFyZSBxdWV1ZWQgYmVmb3JlIHRoZSBxdWV1ZSBpcyBmbHVzaGVkLCB0aGV5XG4gICAgICAgIC8vIHdpbGwgYmUgcHJvY2Vzc2VkIGJ5IHRoaXMgZmx1c2ggdGhhdCB3ZSBhcmUgc2NoZWR1bGluZy5cbiAgICAgICAgbGliJHJzdnAkYXNhcCQkc2NoZWR1bGVGbHVzaCgpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHZhciBsaWIkcnN2cCRhc2FwJCRkZWZhdWx0ID0gbGliJHJzdnAkYXNhcCQkYXNhcDtcblxuICAgIHZhciBsaWIkcnN2cCRhc2FwJCRicm93c2VyV2luZG93ID0gKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnKSA/IHdpbmRvdyA6IHVuZGVmaW5lZDtcbiAgICB2YXIgbGliJHJzdnAkYXNhcCQkYnJvd3Nlckdsb2JhbCA9IGxpYiRyc3ZwJGFzYXAkJGJyb3dzZXJXaW5kb3cgfHwge307XG4gICAgdmFyIGxpYiRyc3ZwJGFzYXAkJEJyb3dzZXJNdXRhdGlvbk9ic2VydmVyID0gbGliJHJzdnAkYXNhcCQkYnJvd3Nlckdsb2JhbC5NdXRhdGlvbk9ic2VydmVyIHx8IGxpYiRyc3ZwJGFzYXAkJGJyb3dzZXJHbG9iYWwuV2ViS2l0TXV0YXRpb25PYnNlcnZlcjtcbiAgICB2YXIgbGliJHJzdnAkYXNhcCQkaXNOb2RlID0gdHlwZW9mIHNlbGYgPT09ICd1bmRlZmluZWQnICYmXG4gICAgICB0eXBlb2YgcHJvY2VzcyAhPT0gJ3VuZGVmaW5lZCcgJiYge30udG9TdHJpbmcuY2FsbChwcm9jZXNzKSA9PT0gJ1tvYmplY3QgcHJvY2Vzc10nO1xuXG4gICAgLy8gdGVzdCBmb3Igd2ViIHdvcmtlciBidXQgbm90IGluIElFMTBcbiAgICB2YXIgbGliJHJzdnAkYXNhcCQkaXNXb3JrZXIgPSB0eXBlb2YgVWludDhDbGFtcGVkQXJyYXkgIT09ICd1bmRlZmluZWQnICYmXG4gICAgICB0eXBlb2YgaW1wb3J0U2NyaXB0cyAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgICAgIHR5cGVvZiBNZXNzYWdlQ2hhbm5lbCAhPT0gJ3VuZGVmaW5lZCc7XG5cbiAgICAvLyBub2RlXG4gICAgZnVuY3Rpb24gbGliJHJzdnAkYXNhcCQkdXNlTmV4dFRpY2soKSB7XG4gICAgICB2YXIgbmV4dFRpY2sgPSBwcm9jZXNzLm5leHRUaWNrO1xuICAgICAgLy8gbm9kZSB2ZXJzaW9uIDAuMTAueCBkaXNwbGF5cyBhIGRlcHJlY2F0aW9uIHdhcm5pbmcgd2hlbiBuZXh0VGljayBpcyB1c2VkIHJlY3Vyc2l2ZWx5XG4gICAgICAvLyBzZXRJbW1lZGlhdGUgc2hvdWxkIGJlIHVzZWQgaW5zdGVhZCBpbnN0ZWFkXG4gICAgICB2YXIgdmVyc2lvbiA9IHByb2Nlc3MudmVyc2lvbnMubm9kZS5tYXRjaCgvXig/OihcXGQrKVxcLik/KD86KFxcZCspXFwuKT8oXFwqfFxcZCspJC8pO1xuICAgICAgaWYgKEFycmF5LmlzQXJyYXkodmVyc2lvbikgJiYgdmVyc2lvblsxXSA9PT0gJzAnICYmIHZlcnNpb25bMl0gPT09ICcxMCcpIHtcbiAgICAgICAgbmV4dFRpY2sgPSBzZXRJbW1lZGlhdGU7XG4gICAgICB9XG4gICAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgIG5leHRUaWNrKGxpYiRyc3ZwJGFzYXAkJGZsdXNoKTtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLy8gdmVydHhcbiAgICBmdW5jdGlvbiBsaWIkcnN2cCRhc2FwJCR1c2VWZXJ0eFRpbWVyKCkge1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICBsaWIkcnN2cCRhc2FwJCR2ZXJ0eE5leHQobGliJHJzdnAkYXNhcCQkZmx1c2gpO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBsaWIkcnN2cCRhc2FwJCR1c2VNdXRhdGlvbk9ic2VydmVyKCkge1xuICAgICAgdmFyIGl0ZXJhdGlvbnMgPSAwO1xuICAgICAgdmFyIG9ic2VydmVyID0gbmV3IGxpYiRyc3ZwJGFzYXAkJEJyb3dzZXJNdXRhdGlvbk9ic2VydmVyKGxpYiRyc3ZwJGFzYXAkJGZsdXNoKTtcbiAgICAgIHZhciBub2RlID0gZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoJycpO1xuICAgICAgb2JzZXJ2ZXIub2JzZXJ2ZShub2RlLCB7IGNoYXJhY3RlckRhdGE6IHRydWUgfSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgbm9kZS5kYXRhID0gKGl0ZXJhdGlvbnMgPSArK2l0ZXJhdGlvbnMgJSAyKTtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLy8gd2ViIHdvcmtlclxuICAgIGZ1bmN0aW9uIGxpYiRyc3ZwJGFzYXAkJHVzZU1lc3NhZ2VDaGFubmVsKCkge1xuICAgICAgdmFyIGNoYW5uZWwgPSBuZXcgTWVzc2FnZUNoYW5uZWwoKTtcbiAgICAgIGNoYW5uZWwucG9ydDEub25tZXNzYWdlID0gbGliJHJzdnAkYXNhcCQkZmx1c2g7XG4gICAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICBjaGFubmVsLnBvcnQyLnBvc3RNZXNzYWdlKDApO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBsaWIkcnN2cCRhc2FwJCR1c2VTZXRUaW1lb3V0KCkge1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICBzZXRUaW1lb3V0KGxpYiRyc3ZwJGFzYXAkJGZsdXNoLCAxKTtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgdmFyIGxpYiRyc3ZwJGFzYXAkJHF1ZXVlID0gbmV3IEFycmF5KDEwMDApO1xuICAgIGZ1bmN0aW9uIGxpYiRyc3ZwJGFzYXAkJGZsdXNoKCkge1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsaWIkcnN2cCRhc2FwJCRsZW47IGkrPTIpIHtcbiAgICAgICAgdmFyIGNhbGxiYWNrID0gbGliJHJzdnAkYXNhcCQkcXVldWVbaV07XG4gICAgICAgIHZhciBhcmcgPSBsaWIkcnN2cCRhc2FwJCRxdWV1ZVtpKzFdO1xuXG4gICAgICAgIGNhbGxiYWNrKGFyZyk7XG5cbiAgICAgICAgbGliJHJzdnAkYXNhcCQkcXVldWVbaV0gPSB1bmRlZmluZWQ7XG4gICAgICAgIGxpYiRyc3ZwJGFzYXAkJHF1ZXVlW2krMV0gPSB1bmRlZmluZWQ7XG4gICAgICB9XG5cbiAgICAgIGxpYiRyc3ZwJGFzYXAkJGxlbiA9IDA7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbGliJHJzdnAkYXNhcCQkYXR0ZW1wdFZlcnRleCgpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHZhciByID0gcmVxdWlyZTtcbiAgICAgICAgdmFyIHZlcnR4ID0gcigndmVydHgnKTtcbiAgICAgICAgbGliJHJzdnAkYXNhcCQkdmVydHhOZXh0ID0gdmVydHgucnVuT25Mb29wIHx8IHZlcnR4LnJ1bk9uQ29udGV4dDtcbiAgICAgICAgcmV0dXJuIGxpYiRyc3ZwJGFzYXAkJHVzZVZlcnR4VGltZXIoKTtcbiAgICAgIH0gY2F0Y2goZSkge1xuICAgICAgICByZXR1cm4gbGliJHJzdnAkYXNhcCQkdXNlU2V0VGltZW91dCgpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHZhciBsaWIkcnN2cCRhc2FwJCRzY2hlZHVsZUZsdXNoO1xuICAgIC8vIERlY2lkZSB3aGF0IGFzeW5jIG1ldGhvZCB0byB1c2UgdG8gdHJpZ2dlcmluZyBwcm9jZXNzaW5nIG9mIHF1ZXVlZCBjYWxsYmFja3M6XG4gICAgaWYgKGxpYiRyc3ZwJGFzYXAkJGlzTm9kZSkge1xuICAgICAgbGliJHJzdnAkYXNhcCQkc2NoZWR1bGVGbHVzaCA9IGxpYiRyc3ZwJGFzYXAkJHVzZU5leHRUaWNrKCk7XG4gICAgfSBlbHNlIGlmIChsaWIkcnN2cCRhc2FwJCRCcm93c2VyTXV0YXRpb25PYnNlcnZlcikge1xuICAgICAgbGliJHJzdnAkYXNhcCQkc2NoZWR1bGVGbHVzaCA9IGxpYiRyc3ZwJGFzYXAkJHVzZU11dGF0aW9uT2JzZXJ2ZXIoKTtcbiAgICB9IGVsc2UgaWYgKGxpYiRyc3ZwJGFzYXAkJGlzV29ya2VyKSB7XG4gICAgICBsaWIkcnN2cCRhc2FwJCRzY2hlZHVsZUZsdXNoID0gbGliJHJzdnAkYXNhcCQkdXNlTWVzc2FnZUNoYW5uZWwoKTtcbiAgICB9IGVsc2UgaWYgKGxpYiRyc3ZwJGFzYXAkJGJyb3dzZXJXaW5kb3cgPT09IHVuZGVmaW5lZCAmJiB0eXBlb2YgcmVxdWlyZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgbGliJHJzdnAkYXNhcCQkc2NoZWR1bGVGbHVzaCA9IGxpYiRyc3ZwJGFzYXAkJGF0dGVtcHRWZXJ0ZXgoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbGliJHJzdnAkYXNhcCQkc2NoZWR1bGVGbHVzaCA9IGxpYiRyc3ZwJGFzYXAkJHVzZVNldFRpbWVvdXQoKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gbGliJHJzdnAkZGVmZXIkJGRlZmVyKGxhYmVsKSB7XG4gICAgICB2YXIgZGVmZXJyZWQgPSB7fTtcblxuICAgICAgZGVmZXJyZWRbJ3Byb21pc2UnXSA9IG5ldyBsaWIkcnN2cCRwcm9taXNlJCRkZWZhdWx0KGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICBkZWZlcnJlZFsncmVzb2x2ZSddID0gcmVzb2x2ZTtcbiAgICAgICAgZGVmZXJyZWRbJ3JlamVjdCddID0gcmVqZWN0O1xuICAgICAgfSwgbGFiZWwpO1xuXG4gICAgICByZXR1cm4gZGVmZXJyZWQ7XG4gICAgfVxuICAgIHZhciBsaWIkcnN2cCRkZWZlciQkZGVmYXVsdCA9IGxpYiRyc3ZwJGRlZmVyJCRkZWZlcjtcbiAgICBmdW5jdGlvbiBsaWIkcnN2cCRmaWx0ZXIkJGZpbHRlcihwcm9taXNlcywgZmlsdGVyRm4sIGxhYmVsKSB7XG4gICAgICByZXR1cm4gbGliJHJzdnAkcHJvbWlzZSQkZGVmYXVsdC5hbGwocHJvbWlzZXMsIGxhYmVsKS50aGVuKGZ1bmN0aW9uKHZhbHVlcykge1xuICAgICAgICBpZiAoIWxpYiRyc3ZwJHV0aWxzJCRpc0Z1bmN0aW9uKGZpbHRlckZuKSkge1xuICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJZb3UgbXVzdCBwYXNzIGEgZnVuY3Rpb24gYXMgZmlsdGVyJ3Mgc2Vjb25kIGFyZ3VtZW50LlwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBsZW5ndGggPSB2YWx1ZXMubGVuZ3RoO1xuICAgICAgICB2YXIgZmlsdGVyZWQgPSBuZXcgQXJyYXkobGVuZ3RoKTtcblxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgZmlsdGVyZWRbaV0gPSBmaWx0ZXJGbih2YWx1ZXNbaV0pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGxpYiRyc3ZwJHByb21pc2UkJGRlZmF1bHQuYWxsKGZpbHRlcmVkLCBsYWJlbCkudGhlbihmdW5jdGlvbihmaWx0ZXJlZCkge1xuICAgICAgICAgIHZhciByZXN1bHRzID0gbmV3IEFycmF5KGxlbmd0aCk7XG4gICAgICAgICAgdmFyIG5ld0xlbmd0aCA9IDA7XG5cbiAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAoZmlsdGVyZWRbaV0pIHtcbiAgICAgICAgICAgICAgcmVzdWx0c1tuZXdMZW5ndGhdID0gdmFsdWVzW2ldO1xuICAgICAgICAgICAgICBuZXdMZW5ndGgrKztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXN1bHRzLmxlbmd0aCA9IG5ld0xlbmd0aDtcblxuICAgICAgICAgIHJldHVybiByZXN1bHRzO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICB2YXIgbGliJHJzdnAkZmlsdGVyJCRkZWZhdWx0ID0gbGliJHJzdnAkZmlsdGVyJCRmaWx0ZXI7XG5cbiAgICBmdW5jdGlvbiBsaWIkcnN2cCRwcm9taXNlJGhhc2gkJFByb21pc2VIYXNoKENvbnN0cnVjdG9yLCBvYmplY3QsIGxhYmVsKSB7XG4gICAgICB0aGlzLl9zdXBlckNvbnN0cnVjdG9yKENvbnN0cnVjdG9yLCBvYmplY3QsIHRydWUsIGxhYmVsKTtcbiAgICB9XG5cbiAgICB2YXIgbGliJHJzdnAkcHJvbWlzZSRoYXNoJCRkZWZhdWx0ID0gbGliJHJzdnAkcHJvbWlzZSRoYXNoJCRQcm9taXNlSGFzaDtcblxuICAgIGxpYiRyc3ZwJHByb21pc2UkaGFzaCQkUHJvbWlzZUhhc2gucHJvdG90eXBlID0gbGliJHJzdnAkdXRpbHMkJG9fY3JlYXRlKGxpYiRyc3ZwJGVudW1lcmF0b3IkJGRlZmF1bHQucHJvdG90eXBlKTtcbiAgICBsaWIkcnN2cCRwcm9taXNlJGhhc2gkJFByb21pc2VIYXNoLnByb3RvdHlwZS5fc3VwZXJDb25zdHJ1Y3RvciA9IGxpYiRyc3ZwJGVudW1lcmF0b3IkJGRlZmF1bHQ7XG4gICAgbGliJHJzdnAkcHJvbWlzZSRoYXNoJCRQcm9taXNlSGFzaC5wcm90b3R5cGUuX2luaXQgPSBmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMuX3Jlc3VsdCA9IHt9O1xuICAgIH07XG5cbiAgICBsaWIkcnN2cCRwcm9taXNlJGhhc2gkJFByb21pc2VIYXNoLnByb3RvdHlwZS5fdmFsaWRhdGVJbnB1dCA9IGZ1bmN0aW9uKGlucHV0KSB7XG4gICAgICByZXR1cm4gaW5wdXQgJiYgdHlwZW9mIGlucHV0ID09PSAnb2JqZWN0JztcbiAgICB9O1xuXG4gICAgbGliJHJzdnAkcHJvbWlzZSRoYXNoJCRQcm9taXNlSGFzaC5wcm90b3R5cGUuX3ZhbGlkYXRpb25FcnJvciA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIG5ldyBFcnJvcignUHJvbWlzZS5oYXNoIG11c3QgYmUgY2FsbGVkIHdpdGggYW4gb2JqZWN0Jyk7XG4gICAgfTtcblxuICAgIGxpYiRyc3ZwJHByb21pc2UkaGFzaCQkUHJvbWlzZUhhc2gucHJvdG90eXBlLl9lbnVtZXJhdGUgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBlbnVtZXJhdG9yID0gdGhpcztcbiAgICAgIHZhciBwcm9taXNlICAgID0gZW51bWVyYXRvci5wcm9taXNlO1xuICAgICAgdmFyIGlucHV0ICAgICAgPSBlbnVtZXJhdG9yLl9pbnB1dDtcbiAgICAgIHZhciByZXN1bHRzICAgID0gW107XG5cbiAgICAgIGZvciAodmFyIGtleSBpbiBpbnB1dCkge1xuICAgICAgICBpZiAocHJvbWlzZS5fc3RhdGUgPT09IGxpYiRyc3ZwJCRpbnRlcm5hbCQkUEVORElORyAmJiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoaW5wdXQsIGtleSkpIHtcbiAgICAgICAgICByZXN1bHRzLnB1c2goe1xuICAgICAgICAgICAgcG9zaXRpb246IGtleSxcbiAgICAgICAgICAgIGVudHJ5OiBpbnB1dFtrZXldXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgdmFyIGxlbmd0aCA9IHJlc3VsdHMubGVuZ3RoO1xuICAgICAgZW51bWVyYXRvci5fcmVtYWluaW5nID0gbGVuZ3RoO1xuICAgICAgdmFyIHJlc3VsdDtcblxuICAgICAgZm9yICh2YXIgaSA9IDA7IHByb21pc2UuX3N0YXRlID09PSBsaWIkcnN2cCQkaW50ZXJuYWwkJFBFTkRJTkcgJiYgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHJlc3VsdCA9IHJlc3VsdHNbaV07XG4gICAgICAgIGVudW1lcmF0b3IuX2VhY2hFbnRyeShyZXN1bHQuZW50cnksIHJlc3VsdC5wb3NpdGlvbik7XG4gICAgICB9XG4gICAgfTtcblxuICAgIGZ1bmN0aW9uIGxpYiRyc3ZwJGhhc2gkc2V0dGxlZCQkSGFzaFNldHRsZWQoQ29uc3RydWN0b3IsIG9iamVjdCwgbGFiZWwpIHtcbiAgICAgIHRoaXMuX3N1cGVyQ29uc3RydWN0b3IoQ29uc3RydWN0b3IsIG9iamVjdCwgZmFsc2UsIGxhYmVsKTtcbiAgICB9XG5cbiAgICBsaWIkcnN2cCRoYXNoJHNldHRsZWQkJEhhc2hTZXR0bGVkLnByb3RvdHlwZSA9IGxpYiRyc3ZwJHV0aWxzJCRvX2NyZWF0ZShsaWIkcnN2cCRwcm9taXNlJGhhc2gkJGRlZmF1bHQucHJvdG90eXBlKTtcbiAgICBsaWIkcnN2cCRoYXNoJHNldHRsZWQkJEhhc2hTZXR0bGVkLnByb3RvdHlwZS5fc3VwZXJDb25zdHJ1Y3RvciA9IGxpYiRyc3ZwJGVudW1lcmF0b3IkJGRlZmF1bHQ7XG4gICAgbGliJHJzdnAkaGFzaCRzZXR0bGVkJCRIYXNoU2V0dGxlZC5wcm90b3R5cGUuX21ha2VSZXN1bHQgPSBsaWIkcnN2cCRlbnVtZXJhdG9yJCRtYWtlU2V0dGxlZFJlc3VsdDtcblxuICAgIGxpYiRyc3ZwJGhhc2gkc2V0dGxlZCQkSGFzaFNldHRsZWQucHJvdG90eXBlLl92YWxpZGF0aW9uRXJyb3IgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBuZXcgRXJyb3IoJ2hhc2hTZXR0bGVkIG11c3QgYmUgY2FsbGVkIHdpdGggYW4gb2JqZWN0Jyk7XG4gICAgfTtcblxuICAgIGZ1bmN0aW9uIGxpYiRyc3ZwJGhhc2gkc2V0dGxlZCQkaGFzaFNldHRsZWQob2JqZWN0LCBsYWJlbCkge1xuICAgICAgcmV0dXJuIG5ldyBsaWIkcnN2cCRoYXNoJHNldHRsZWQkJEhhc2hTZXR0bGVkKGxpYiRyc3ZwJHByb21pc2UkJGRlZmF1bHQsIG9iamVjdCwgbGFiZWwpLnByb21pc2U7XG4gICAgfVxuICAgIHZhciBsaWIkcnN2cCRoYXNoJHNldHRsZWQkJGRlZmF1bHQgPSBsaWIkcnN2cCRoYXNoJHNldHRsZWQkJGhhc2hTZXR0bGVkO1xuICAgIGZ1bmN0aW9uIGxpYiRyc3ZwJGhhc2gkJGhhc2gob2JqZWN0LCBsYWJlbCkge1xuICAgICAgcmV0dXJuIG5ldyBsaWIkcnN2cCRwcm9taXNlJGhhc2gkJGRlZmF1bHQobGliJHJzdnAkcHJvbWlzZSQkZGVmYXVsdCwgb2JqZWN0LCBsYWJlbCkucHJvbWlzZTtcbiAgICB9XG4gICAgdmFyIGxpYiRyc3ZwJGhhc2gkJGRlZmF1bHQgPSBsaWIkcnN2cCRoYXNoJCRoYXNoO1xuICAgIGZ1bmN0aW9uIGxpYiRyc3ZwJG1hcCQkbWFwKHByb21pc2VzLCBtYXBGbiwgbGFiZWwpIHtcbiAgICAgIHJldHVybiBsaWIkcnN2cCRwcm9taXNlJCRkZWZhdWx0LmFsbChwcm9taXNlcywgbGFiZWwpLnRoZW4oZnVuY3Rpb24odmFsdWVzKSB7XG4gICAgICAgIGlmICghbGliJHJzdnAkdXRpbHMkJGlzRnVuY3Rpb24obWFwRm4pKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIllvdSBtdXN0IHBhc3MgYSBmdW5jdGlvbiBhcyBtYXAncyBzZWNvbmQgYXJndW1lbnQuXCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGxlbmd0aCA9IHZhbHVlcy5sZW5ndGg7XG4gICAgICAgIHZhciByZXN1bHRzID0gbmV3IEFycmF5KGxlbmd0aCk7XG5cbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgICAgIHJlc3VsdHNbaV0gPSBtYXBGbih2YWx1ZXNbaV0pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGxpYiRyc3ZwJHByb21pc2UkJGRlZmF1bHQuYWxsKHJlc3VsdHMsIGxhYmVsKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICB2YXIgbGliJHJzdnAkbWFwJCRkZWZhdWx0ID0gbGliJHJzdnAkbWFwJCRtYXA7XG5cbiAgICBmdW5jdGlvbiBsaWIkcnN2cCRub2RlJCRSZXN1bHQoKSB7XG4gICAgICB0aGlzLnZhbHVlID0gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIHZhciBsaWIkcnN2cCRub2RlJCRFUlJPUiA9IG5ldyBsaWIkcnN2cCRub2RlJCRSZXN1bHQoKTtcbiAgICB2YXIgbGliJHJzdnAkbm9kZSQkR0VUX1RIRU5fRVJST1IgPSBuZXcgbGliJHJzdnAkbm9kZSQkUmVzdWx0KCk7XG5cbiAgICBmdW5jdGlvbiBsaWIkcnN2cCRub2RlJCRnZXRUaGVuKG9iaikge1xuICAgICAgdHJ5IHtcbiAgICAgICByZXR1cm4gb2JqLnRoZW47XG4gICAgICB9IGNhdGNoKGVycm9yKSB7XG4gICAgICAgIGxpYiRyc3ZwJG5vZGUkJEVSUk9SLnZhbHVlPSBlcnJvcjtcbiAgICAgICAgcmV0dXJuIGxpYiRyc3ZwJG5vZGUkJEVSUk9SO1xuICAgICAgfVxuICAgIH1cblxuXG4gICAgZnVuY3Rpb24gbGliJHJzdnAkbm9kZSQkdHJ5QXBwbHkoZiwgcywgYSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgZi5hcHBseShzLCBhKTtcbiAgICAgIH0gY2F0Y2goZXJyb3IpIHtcbiAgICAgICAgbGliJHJzdnAkbm9kZSQkRVJST1IudmFsdWUgPSBlcnJvcjtcbiAgICAgICAgcmV0dXJuIGxpYiRyc3ZwJG5vZGUkJEVSUk9SO1xuICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGxpYiRyc3ZwJG5vZGUkJG1ha2VPYmplY3QoXywgYXJndW1lbnROYW1lcykge1xuICAgICAgdmFyIG9iaiA9IHt9O1xuICAgICAgdmFyIG5hbWU7XG4gICAgICB2YXIgaTtcbiAgICAgIHZhciBsZW5ndGggPSBfLmxlbmd0aDtcbiAgICAgIHZhciBhcmdzID0gbmV3IEFycmF5KGxlbmd0aCk7XG5cbiAgICAgIGZvciAodmFyIHggPSAwOyB4IDwgbGVuZ3RoOyB4KyspIHtcbiAgICAgICAgYXJnc1t4XSA9IF9beF07XG4gICAgICB9XG5cbiAgICAgIGZvciAoaSA9IDA7IGkgPCBhcmd1bWVudE5hbWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIG5hbWUgPSBhcmd1bWVudE5hbWVzW2ldO1xuICAgICAgICBvYmpbbmFtZV0gPSBhcmdzW2kgKyAxXTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG9iajtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBsaWIkcnN2cCRub2RlJCRhcnJheVJlc3VsdChfKSB7XG4gICAgICB2YXIgbGVuZ3RoID0gXy5sZW5ndGg7XG4gICAgICB2YXIgYXJncyA9IG5ldyBBcnJheShsZW5ndGggLSAxKTtcblxuICAgICAgZm9yICh2YXIgaSA9IDE7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgICBhcmdzW2kgLSAxXSA9IF9baV07XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBhcmdzO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGxpYiRyc3ZwJG5vZGUkJHdyYXBUaGVuYWJsZSh0aGVuLCBwcm9taXNlKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0aGVuOiBmdW5jdGlvbihvbkZ1bEZpbGxtZW50LCBvblJlamVjdGlvbikge1xuICAgICAgICAgIHJldHVybiB0aGVuLmNhbGwocHJvbWlzZSwgb25GdWxGaWxsbWVudCwgb25SZWplY3Rpb24pO1xuICAgICAgICB9XG4gICAgICB9O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGxpYiRyc3ZwJG5vZGUkJGRlbm9kZWlmeShub2RlRnVuYywgb3B0aW9ucykge1xuICAgICAgdmFyIGZuID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAgICAgdmFyIGwgPSBhcmd1bWVudHMubGVuZ3RoO1xuICAgICAgICB2YXIgYXJncyA9IG5ldyBBcnJheShsICsgMSk7XG4gICAgICAgIHZhciBhcmc7XG4gICAgICAgIHZhciBwcm9taXNlSW5wdXQgPSBmYWxzZTtcblxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGw7ICsraSkge1xuICAgICAgICAgIGFyZyA9IGFyZ3VtZW50c1tpXTtcblxuICAgICAgICAgIGlmICghcHJvbWlzZUlucHV0KSB7XG4gICAgICAgICAgICAvLyBUT0RPOiBjbGVhbiB0aGlzIHVwXG4gICAgICAgICAgICBwcm9taXNlSW5wdXQgPSBsaWIkcnN2cCRub2RlJCRuZWVkc1Byb21pc2VJbnB1dChhcmcpO1xuICAgICAgICAgICAgaWYgKHByb21pc2VJbnB1dCA9PT0gbGliJHJzdnAkbm9kZSQkR0VUX1RIRU5fRVJST1IpIHtcbiAgICAgICAgICAgICAgdmFyIHAgPSBuZXcgbGliJHJzdnAkcHJvbWlzZSQkZGVmYXVsdChsaWIkcnN2cCQkaW50ZXJuYWwkJG5vb3ApO1xuICAgICAgICAgICAgICBsaWIkcnN2cCQkaW50ZXJuYWwkJHJlamVjdChwLCBsaWIkcnN2cCRub2RlJCRHRVRfVEhFTl9FUlJPUi52YWx1ZSk7XG4gICAgICAgICAgICAgIHJldHVybiBwO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChwcm9taXNlSW5wdXQgJiYgcHJvbWlzZUlucHV0ICE9PSB0cnVlKSB7XG4gICAgICAgICAgICAgIGFyZyA9IGxpYiRyc3ZwJG5vZGUkJHdyYXBUaGVuYWJsZShwcm9taXNlSW5wdXQsIGFyZyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGFyZ3NbaV0gPSBhcmc7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgcHJvbWlzZSA9IG5ldyBsaWIkcnN2cCRwcm9taXNlJCRkZWZhdWx0KGxpYiRyc3ZwJCRpbnRlcm5hbCQkbm9vcCk7XG5cbiAgICAgICAgYXJnc1tsXSA9IGZ1bmN0aW9uKGVyciwgdmFsKSB7XG4gICAgICAgICAgaWYgKGVycilcbiAgICAgICAgICAgIGxpYiRyc3ZwJCRpbnRlcm5hbCQkcmVqZWN0KHByb21pc2UsIGVycik7XG4gICAgICAgICAgZWxzZSBpZiAob3B0aW9ucyA9PT0gdW5kZWZpbmVkKVxuICAgICAgICAgICAgbGliJHJzdnAkJGludGVybmFsJCRyZXNvbHZlKHByb21pc2UsIHZhbCk7XG4gICAgICAgICAgZWxzZSBpZiAob3B0aW9ucyA9PT0gdHJ1ZSlcbiAgICAgICAgICAgIGxpYiRyc3ZwJCRpbnRlcm5hbCQkcmVzb2x2ZShwcm9taXNlLCBsaWIkcnN2cCRub2RlJCRhcnJheVJlc3VsdChhcmd1bWVudHMpKTtcbiAgICAgICAgICBlbHNlIGlmIChsaWIkcnN2cCR1dGlscyQkaXNBcnJheShvcHRpb25zKSlcbiAgICAgICAgICAgIGxpYiRyc3ZwJCRpbnRlcm5hbCQkcmVzb2x2ZShwcm9taXNlLCBsaWIkcnN2cCRub2RlJCRtYWtlT2JqZWN0KGFyZ3VtZW50cywgb3B0aW9ucykpO1xuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIGxpYiRyc3ZwJCRpbnRlcm5hbCQkcmVzb2x2ZShwcm9taXNlLCB2YWwpO1xuICAgICAgICB9O1xuXG4gICAgICAgIGlmIChwcm9taXNlSW5wdXQpIHtcbiAgICAgICAgICByZXR1cm4gbGliJHJzdnAkbm9kZSQkaGFuZGxlUHJvbWlzZUlucHV0KHByb21pc2UsIGFyZ3MsIG5vZGVGdW5jLCBzZWxmKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gbGliJHJzdnAkbm9kZSQkaGFuZGxlVmFsdWVJbnB1dChwcm9taXNlLCBhcmdzLCBub2RlRnVuYywgc2VsZik7XG4gICAgICAgIH1cbiAgICAgIH07XG5cbiAgICAgIGZuLl9fcHJvdG9fXyA9IG5vZGVGdW5jO1xuXG4gICAgICByZXR1cm4gZm47XG4gICAgfVxuXG4gICAgdmFyIGxpYiRyc3ZwJG5vZGUkJGRlZmF1bHQgPSBsaWIkcnN2cCRub2RlJCRkZW5vZGVpZnk7XG5cbiAgICBmdW5jdGlvbiBsaWIkcnN2cCRub2RlJCRoYW5kbGVWYWx1ZUlucHV0KHByb21pc2UsIGFyZ3MsIG5vZGVGdW5jLCBzZWxmKSB7XG4gICAgICB2YXIgcmVzdWx0ID0gbGliJHJzdnAkbm9kZSQkdHJ5QXBwbHkobm9kZUZ1bmMsIHNlbGYsIGFyZ3MpO1xuICAgICAgaWYgKHJlc3VsdCA9PT0gbGliJHJzdnAkbm9kZSQkRVJST1IpIHtcbiAgICAgICAgbGliJHJzdnAkJGludGVybmFsJCRyZWplY3QocHJvbWlzZSwgcmVzdWx0LnZhbHVlKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBwcm9taXNlO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGxpYiRyc3ZwJG5vZGUkJGhhbmRsZVByb21pc2VJbnB1dChwcm9taXNlLCBhcmdzLCBub2RlRnVuYywgc2VsZil7XG4gICAgICByZXR1cm4gbGliJHJzdnAkcHJvbWlzZSQkZGVmYXVsdC5hbGwoYXJncykudGhlbihmdW5jdGlvbihhcmdzKXtcbiAgICAgICAgdmFyIHJlc3VsdCA9IGxpYiRyc3ZwJG5vZGUkJHRyeUFwcGx5KG5vZGVGdW5jLCBzZWxmLCBhcmdzKTtcbiAgICAgICAgaWYgKHJlc3VsdCA9PT0gbGliJHJzdnAkbm9kZSQkRVJST1IpIHtcbiAgICAgICAgICBsaWIkcnN2cCQkaW50ZXJuYWwkJHJlamVjdChwcm9taXNlLCByZXN1bHQudmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBwcm9taXNlO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbGliJHJzdnAkbm9kZSQkbmVlZHNQcm9taXNlSW5wdXQoYXJnKSB7XG4gICAgICBpZiAoYXJnICYmIHR5cGVvZiBhcmcgPT09ICdvYmplY3QnKSB7XG4gICAgICAgIGlmIChhcmcuY29uc3RydWN0b3IgPT09IGxpYiRyc3ZwJHByb21pc2UkJGRlZmF1bHQpIHtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gbGliJHJzdnAkbm9kZSQkZ2V0VGhlbihhcmcpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuICAgIHZhciBsaWIkcnN2cCRwbGF0Zm9ybSQkcGxhdGZvcm07XG5cbiAgICAvKiBnbG9iYWwgc2VsZiAqL1xuICAgIGlmICh0eXBlb2Ygc2VsZiA9PT0gJ29iamVjdCcpIHtcbiAgICAgIGxpYiRyc3ZwJHBsYXRmb3JtJCRwbGF0Zm9ybSA9IHNlbGY7XG5cbiAgICAvKiBnbG9iYWwgZ2xvYmFsICovXG4gICAgfSBlbHNlIGlmICh0eXBlb2YgZ2xvYmFsID09PSAnb2JqZWN0Jykge1xuICAgICAgbGliJHJzdnAkcGxhdGZvcm0kJHBsYXRmb3JtID0gZ2xvYmFsO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ25vIGdsb2JhbDogYHNlbGZgIG9yIGBnbG9iYWxgIGZvdW5kJyk7XG4gICAgfVxuXG4gICAgdmFyIGxpYiRyc3ZwJHBsYXRmb3JtJCRkZWZhdWx0ID0gbGliJHJzdnAkcGxhdGZvcm0kJHBsYXRmb3JtO1xuICAgIGZ1bmN0aW9uIGxpYiRyc3ZwJHJhY2UkJHJhY2UoYXJyYXksIGxhYmVsKSB7XG4gICAgICByZXR1cm4gbGliJHJzdnAkcHJvbWlzZSQkZGVmYXVsdC5yYWNlKGFycmF5LCBsYWJlbCk7XG4gICAgfVxuICAgIHZhciBsaWIkcnN2cCRyYWNlJCRkZWZhdWx0ID0gbGliJHJzdnAkcmFjZSQkcmFjZTtcbiAgICBmdW5jdGlvbiBsaWIkcnN2cCRyZWplY3QkJHJlamVjdChyZWFzb24sIGxhYmVsKSB7XG4gICAgICByZXR1cm4gbGliJHJzdnAkcHJvbWlzZSQkZGVmYXVsdC5yZWplY3QocmVhc29uLCBsYWJlbCk7XG4gICAgfVxuICAgIHZhciBsaWIkcnN2cCRyZWplY3QkJGRlZmF1bHQgPSBsaWIkcnN2cCRyZWplY3QkJHJlamVjdDtcbiAgICBmdW5jdGlvbiBsaWIkcnN2cCRyZXNvbHZlJCRyZXNvbHZlKHZhbHVlLCBsYWJlbCkge1xuICAgICAgcmV0dXJuIGxpYiRyc3ZwJHByb21pc2UkJGRlZmF1bHQucmVzb2x2ZSh2YWx1ZSwgbGFiZWwpO1xuICAgIH1cbiAgICB2YXIgbGliJHJzdnAkcmVzb2x2ZSQkZGVmYXVsdCA9IGxpYiRyc3ZwJHJlc29sdmUkJHJlc29sdmU7XG4gICAgZnVuY3Rpb24gbGliJHJzdnAkcmV0aHJvdyQkcmV0aHJvdyhyZWFzb24pIHtcbiAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gICAgICAgIHRocm93IHJlYXNvbjtcbiAgICAgIH0pO1xuICAgICAgdGhyb3cgcmVhc29uO1xuICAgIH1cbiAgICB2YXIgbGliJHJzdnAkcmV0aHJvdyQkZGVmYXVsdCA9IGxpYiRyc3ZwJHJldGhyb3ckJHJldGhyb3c7XG5cbiAgICAvLyBkZWZhdWx0c1xuICAgIGxpYiRyc3ZwJGNvbmZpZyQkY29uZmlnLmFzeW5jID0gbGliJHJzdnAkYXNhcCQkZGVmYXVsdDtcbiAgICBsaWIkcnN2cCRjb25maWckJGNvbmZpZy5hZnRlciA9IGZ1bmN0aW9uKGNiKSB7XG4gICAgICBzZXRUaW1lb3V0KGNiLCAwKTtcbiAgICB9O1xuICAgIHZhciBsaWIkcnN2cCQkY2FzdCA9IGxpYiRyc3ZwJHJlc29sdmUkJGRlZmF1bHQ7XG4gICAgZnVuY3Rpb24gbGliJHJzdnAkJGFzeW5jKGNhbGxiYWNrLCBhcmcpIHtcbiAgICAgIGxpYiRyc3ZwJGNvbmZpZyQkY29uZmlnLmFzeW5jKGNhbGxiYWNrLCBhcmcpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGxpYiRyc3ZwJCRvbigpIHtcbiAgICAgIGxpYiRyc3ZwJGNvbmZpZyQkY29uZmlnWydvbiddLmFwcGx5KGxpYiRyc3ZwJGNvbmZpZyQkY29uZmlnLCBhcmd1bWVudHMpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGxpYiRyc3ZwJCRvZmYoKSB7XG4gICAgICBsaWIkcnN2cCRjb25maWckJGNvbmZpZ1snb2ZmJ10uYXBwbHkobGliJHJzdnAkY29uZmlnJCRjb25maWcsIGFyZ3VtZW50cyk7XG4gICAgfVxuXG4gICAgLy8gU2V0IHVwIGluc3RydW1lbnRhdGlvbiB0aHJvdWdoIGB3aW5kb3cuX19QUk9NSVNFX0lOVFJVTUVOVEFUSU9OX19gXG4gICAgaWYgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnICYmIHR5cGVvZiB3aW5kb3dbJ19fUFJPTUlTRV9JTlNUUlVNRU5UQVRJT05fXyddID09PSAnb2JqZWN0Jykge1xuICAgICAgdmFyIGxpYiRyc3ZwJCRjYWxsYmFja3MgPSB3aW5kb3dbJ19fUFJPTUlTRV9JTlNUUlVNRU5UQVRJT05fXyddO1xuICAgICAgbGliJHJzdnAkY29uZmlnJCRjb25maWd1cmUoJ2luc3RydW1lbnQnLCB0cnVlKTtcbiAgICAgIGZvciAodmFyIGxpYiRyc3ZwJCRldmVudE5hbWUgaW4gbGliJHJzdnAkJGNhbGxiYWNrcykge1xuICAgICAgICBpZiAobGliJHJzdnAkJGNhbGxiYWNrcy5oYXNPd25Qcm9wZXJ0eShsaWIkcnN2cCQkZXZlbnROYW1lKSkge1xuICAgICAgICAgIGxpYiRyc3ZwJCRvbihsaWIkcnN2cCQkZXZlbnROYW1lLCBsaWIkcnN2cCQkY2FsbGJhY2tzW2xpYiRyc3ZwJCRldmVudE5hbWVdKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHZhciBsaWIkcnN2cCR1bWQkJFJTVlAgPSB7XG4gICAgICAncmFjZSc6IGxpYiRyc3ZwJHJhY2UkJGRlZmF1bHQsXG4gICAgICAnUHJvbWlzZSc6IGxpYiRyc3ZwJHByb21pc2UkJGRlZmF1bHQsXG4gICAgICAnYWxsU2V0dGxlZCc6IGxpYiRyc3ZwJGFsbCRzZXR0bGVkJCRkZWZhdWx0LFxuICAgICAgJ2hhc2gnOiBsaWIkcnN2cCRoYXNoJCRkZWZhdWx0LFxuICAgICAgJ2hhc2hTZXR0bGVkJzogbGliJHJzdnAkaGFzaCRzZXR0bGVkJCRkZWZhdWx0LFxuICAgICAgJ2Rlbm9kZWlmeSc6IGxpYiRyc3ZwJG5vZGUkJGRlZmF1bHQsXG4gICAgICAnb24nOiBsaWIkcnN2cCQkb24sXG4gICAgICAnb2ZmJzogbGliJHJzdnAkJG9mZixcbiAgICAgICdtYXAnOiBsaWIkcnN2cCRtYXAkJGRlZmF1bHQsXG4gICAgICAnZmlsdGVyJzogbGliJHJzdnAkZmlsdGVyJCRkZWZhdWx0LFxuICAgICAgJ3Jlc29sdmUnOiBsaWIkcnN2cCRyZXNvbHZlJCRkZWZhdWx0LFxuICAgICAgJ3JlamVjdCc6IGxpYiRyc3ZwJHJlamVjdCQkZGVmYXVsdCxcbiAgICAgICdhbGwnOiBsaWIkcnN2cCRhbGwkJGRlZmF1bHQsXG4gICAgICAncmV0aHJvdyc6IGxpYiRyc3ZwJHJldGhyb3ckJGRlZmF1bHQsXG4gICAgICAnZGVmZXInOiBsaWIkcnN2cCRkZWZlciQkZGVmYXVsdCxcbiAgICAgICdFdmVudFRhcmdldCc6IGxpYiRyc3ZwJGV2ZW50cyQkZGVmYXVsdCxcbiAgICAgICdjb25maWd1cmUnOiBsaWIkcnN2cCRjb25maWckJGNvbmZpZ3VyZSxcbiAgICAgICdhc3luYyc6IGxpYiRyc3ZwJCRhc3luY1xuICAgIH07XG5cbiAgICAvKiBnbG9iYWwgZGVmaW5lOnRydWUgbW9kdWxlOnRydWUgd2luZG93OiB0cnVlICovXG4gICAgaWYgKHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lWydhbWQnXSkge1xuICAgICAgZGVmaW5lKGZ1bmN0aW9uKCkgeyByZXR1cm4gbGliJHJzdnAkdW1kJCRSU1ZQOyB9KTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnICYmIG1vZHVsZVsnZXhwb3J0cyddKSB7XG4gICAgICBtb2R1bGVbJ2V4cG9ydHMnXSA9IGxpYiRyc3ZwJHVtZCQkUlNWUDtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBsaWIkcnN2cCRwbGF0Zm9ybSQkZGVmYXVsdCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIGxpYiRyc3ZwJHBsYXRmb3JtJCRkZWZhdWx0WydSU1ZQJ10gPSBsaWIkcnN2cCR1bWQkJFJTVlA7XG4gICAgfVxufSkuY2FsbCh0aGlzKTtcblxuIl19\n"],"file":"algorithm_visualizer.js","sourceRoot":"/source/"}