diff --git a/dist/.gitkeep b/dist/.gitkeep
new file mode 100644
index 0000000..d7be189
--- /dev/null
+++ b/dist/.gitkeep
@@ -0,0 +1 @@
+# this is here to help keep the directory
\ No newline at end of file
diff --git a/dist/assets/_dist/Ships/large_purple_01.png b/dist/assets/_dist/Ships/large_purple_01.png
deleted file mode 100644
index 4740265..0000000
Binary files a/dist/assets/_dist/Ships/large_purple_01.png and /dev/null differ
diff --git a/dist/assets/_dist/Ships/metalic_01.png b/dist/assets/_dist/Ships/metalic_01.png
deleted file mode 100644
index 2ad6de9..0000000
Binary files a/dist/assets/_dist/Ships/metalic_01.png and /dev/null differ
diff --git a/dist/assets/_dist/Ships/metalic_02.png b/dist/assets/_dist/Ships/metalic_02.png
deleted file mode 100644
index d5a4f68..0000000
Binary files a/dist/assets/_dist/Ships/metalic_02.png and /dev/null differ
diff --git a/dist/assets/_dist/Ships/metalic_03.png b/dist/assets/_dist/Ships/metalic_03.png
deleted file mode 100644
index d694151..0000000
Binary files a/dist/assets/_dist/Ships/metalic_03.png and /dev/null differ
diff --git a/dist/assets/_dist/Ships/metalic_04.png b/dist/assets/_dist/Ships/metalic_04.png
deleted file mode 100644
index 8cd0d73..0000000
Binary files a/dist/assets/_dist/Ships/metalic_04.png and /dev/null differ
diff --git a/dist/assets/_dist/Ships/metalic_05.png b/dist/assets/_dist/Ships/metalic_05.png
deleted file mode 100644
index ff5532c..0000000
Binary files a/dist/assets/_dist/Ships/metalic_05.png and /dev/null differ
diff --git a/dist/assets/_dist/Ships/metalic_06.png b/dist/assets/_dist/Ships/metalic_06.png
deleted file mode 100644
index 47b86b3..0000000
Binary files a/dist/assets/_dist/Ships/metalic_06.png and /dev/null differ
diff --git a/dist/assets/_dist/Ships/orange_01.png b/dist/assets/_dist/Ships/orange_01.png
deleted file mode 100644
index cfeb138..0000000
Binary files a/dist/assets/_dist/Ships/orange_01.png and /dev/null differ
diff --git a/dist/assets/_dist/Ships/orange_02.png b/dist/assets/_dist/Ships/orange_02.png
deleted file mode 100644
index e23af41..0000000
Binary files a/dist/assets/_dist/Ships/orange_02.png and /dev/null differ
diff --git a/dist/assets/_dist/Ships/orange_03.png b/dist/assets/_dist/Ships/orange_03.png
deleted file mode 100644
index 71ee69a..0000000
Binary files a/dist/assets/_dist/Ships/orange_03.png and /dev/null differ
diff --git a/dist/assets/_dist/Ships/orange_04.png b/dist/assets/_dist/Ships/orange_04.png
deleted file mode 100644
index bac4116..0000000
Binary files a/dist/assets/_dist/Ships/orange_04.png and /dev/null differ
diff --git a/dist/assets/_dist/Ships/orange_05.png b/dist/assets/_dist/Ships/orange_05.png
deleted file mode 100644
index 5078ed0..0000000
Binary files a/dist/assets/_dist/Ships/orange_05.png and /dev/null differ
diff --git a/dist/assets/_dist/Ships/orange_06.png b/dist/assets/_dist/Ships/orange_06.png
deleted file mode 100644
index b578d59..0000000
Binary files a/dist/assets/_dist/Ships/orange_06.png and /dev/null differ
diff --git a/dist/assets/_dist/Tiles/bg_starfield - Copy.png b/dist/assets/_dist/Tiles/bg_starfield - Copy.png
deleted file mode 100644
index 966d69f..0000000
Binary files a/dist/assets/_dist/Tiles/bg_starfield - Copy.png and /dev/null differ
diff --git a/dist/assets/_dist/Tiles/bg_starfield.png b/dist/assets/_dist/Tiles/bg_starfield.png
deleted file mode 100644
index 966d69f..0000000
Binary files a/dist/assets/_dist/Tiles/bg_starfield.png and /dev/null differ
diff --git a/dist/assets/_dist/Tiles/grass.png b/dist/assets/_dist/Tiles/grass.png
deleted file mode 100644
index bb9a2e3..0000000
Binary files a/dist/assets/_dist/Tiles/grass.png and /dev/null differ
diff --git a/dist/assets/_dist/Tiles/ground/dirt.png b/dist/assets/_dist/Tiles/ground/dirt.png
deleted file mode 100644
index 8a77048..0000000
Binary files a/dist/assets/_dist/Tiles/ground/dirt.png and /dev/null differ
diff --git a/dist/assets/_dist/Tiles/ground/dirt_with_grass_middle.png b/dist/assets/_dist/Tiles/ground/dirt_with_grass_middle.png
deleted file mode 100644
index 26c6cfe..0000000
Binary files a/dist/assets/_dist/Tiles/ground/dirt_with_grass_middle.png and /dev/null differ
diff --git a/dist/assets/_dist/Tiles/ground/grass.png b/dist/assets/_dist/Tiles/ground/grass.png
deleted file mode 100644
index a4761de..0000000
Binary files a/dist/assets/_dist/Tiles/ground/grass.png and /dev/null differ
diff --git a/dist/assets/_dist/Tiles/ground/grass_with_dirt_bottom.png b/dist/assets/_dist/Tiles/ground/grass_with_dirt_bottom.png
deleted file mode 100644
index 364e02f..0000000
Binary files a/dist/assets/_dist/Tiles/ground/grass_with_dirt_bottom.png and /dev/null differ
diff --git a/dist/assets/_dist/Tiles/ground/grass_with_dirt_left.png b/dist/assets/_dist/Tiles/ground/grass_with_dirt_left.png
deleted file mode 100644
index 62d5b57..0000000
Binary files a/dist/assets/_dist/Tiles/ground/grass_with_dirt_left.png and /dev/null differ
diff --git a/dist/assets/_dist/Tiles/ground/grass_with_dirt_middle.png b/dist/assets/_dist/Tiles/ground/grass_with_dirt_middle.png
deleted file mode 100644
index 9acf3a8..0000000
Binary files a/dist/assets/_dist/Tiles/ground/grass_with_dirt_middle.png and /dev/null differ
diff --git a/dist/assets/_dist/Tiles/ground/grass_with_dirt_right.png b/dist/assets/_dist/Tiles/ground/grass_with_dirt_right.png
deleted file mode 100644
index 995cf93..0000000
Binary files a/dist/assets/_dist/Tiles/ground/grass_with_dirt_right.png and /dev/null differ
diff --git a/dist/assets/_dist/Tiles/ground/grass_with_dirt_top.png b/dist/assets/_dist/Tiles/ground/grass_with_dirt_top.png
deleted file mode 100644
index d3d8eb9..0000000
Binary files a/dist/assets/_dist/Tiles/ground/grass_with_dirt_top.png and /dev/null differ
diff --git a/dist/assets/_dist/Tiles/ground/sand.png b/dist/assets/_dist/Tiles/ground/sand.png
deleted file mode 100644
index b129990..0000000
Binary files a/dist/assets/_dist/Tiles/ground/sand.png and /dev/null differ
diff --git a/dist/assets/_dist/Tiles/ground/sand_grass_bottom.png b/dist/assets/_dist/Tiles/ground/sand_grass_bottom.png
deleted file mode 100644
index d7b7d17..0000000
Binary files a/dist/assets/_dist/Tiles/ground/sand_grass_bottom.png and /dev/null differ
diff --git a/dist/assets/_dist/Tiles/ground/sand_grass_left.png b/dist/assets/_dist/Tiles/ground/sand_grass_left.png
deleted file mode 100644
index ab5a3fd..0000000
Binary files a/dist/assets/_dist/Tiles/ground/sand_grass_left.png and /dev/null differ
diff --git a/dist/assets/_dist/Tiles/ground/sand_grass_right.png b/dist/assets/_dist/Tiles/ground/sand_grass_right.png
deleted file mode 100644
index 4946c30..0000000
Binary files a/dist/assets/_dist/Tiles/ground/sand_grass_right.png and /dev/null differ
diff --git a/dist/assets/_dist/Tiles/ground/sand_grass_top.png b/dist/assets/_dist/Tiles/ground/sand_grass_top.png
deleted file mode 100644
index d556e28..0000000
Binary files a/dist/assets/_dist/Tiles/ground/sand_grass_top.png and /dev/null differ
diff --git a/dist/assets/_dist/Tiles/ground/shallow_water.png b/dist/assets/_dist/Tiles/ground/shallow_water.png
deleted file mode 100644
index 91c3492..0000000
Binary files a/dist/assets/_dist/Tiles/ground/shallow_water.png and /dev/null differ
diff --git a/dist/assets/_dist/Tiles/ground/shallow_water_sand_bottom.png b/dist/assets/_dist/Tiles/ground/shallow_water_sand_bottom.png
deleted file mode 100644
index 9ef03e3..0000000
Binary files a/dist/assets/_dist/Tiles/ground/shallow_water_sand_bottom.png and /dev/null differ
diff --git a/dist/assets/_dist/Tiles/ground/shallow_water_sand_left.png b/dist/assets/_dist/Tiles/ground/shallow_water_sand_left.png
deleted file mode 100644
index ab19dda..0000000
Binary files a/dist/assets/_dist/Tiles/ground/shallow_water_sand_left.png and /dev/null differ
diff --git a/dist/assets/_dist/Tiles/ground/shallow_water_sand_right.png b/dist/assets/_dist/Tiles/ground/shallow_water_sand_right.png
deleted file mode 100644
index bdf9527..0000000
Binary files a/dist/assets/_dist/Tiles/ground/shallow_water_sand_right.png and /dev/null differ
diff --git a/dist/assets/_dist/Tiles/ground/shallow_water_sand_top.png b/dist/assets/_dist/Tiles/ground/shallow_water_sand_top.png
deleted file mode 100644
index 1005654..0000000
Binary files a/dist/assets/_dist/Tiles/ground/shallow_water_sand_top.png and /dev/null differ
diff --git a/dist/assets/_dist/Tiles/ground/stone.png b/dist/assets/_dist/Tiles/ground/stone.png
deleted file mode 100644
index 8cbcb99..0000000
Binary files a/dist/assets/_dist/Tiles/ground/stone.png and /dev/null differ
diff --git a/dist/assets/_dist/Tiles/space_tile - Copy.png b/dist/assets/_dist/Tiles/space_tile - Copy.png
deleted file mode 100644
index 9600fa3..0000000
Binary files a/dist/assets/_dist/Tiles/space_tile - Copy.png and /dev/null differ
diff --git a/dist/assets/_dist/Tiles/space_tile.png b/dist/assets/_dist/Tiles/space_tile.png
deleted file mode 100644
index 9600fa3..0000000
Binary files a/dist/assets/_dist/Tiles/space_tile.png and /dev/null differ
diff --git a/dist/assets/_dist/Tiles/space_tile2.png b/dist/assets/_dist/Tiles/space_tile2.png
deleted file mode 100644
index 6b4fb90..0000000
Binary files a/dist/assets/_dist/Tiles/space_tile2.png and /dev/null differ
diff --git a/dist/assets/_dist/Worlds/worlds.json b/dist/assets/_dist/Worlds/worlds.json
deleted file mode 100644
index 2be956e..0000000
--- a/dist/assets/_dist/Worlds/worlds.json
+++ /dev/null
@@ -1,72 +0,0 @@
-[
- {
- "worldId": 2,
- "start": {
- "x": 0,
- "y": 0
- },
- "tiles": [
- [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
- [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
- [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
- [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
- [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
- [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
- [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
- [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
- [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
- [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
- [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
- [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
- [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
- [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
- [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]
-
- ]
- },
- {
- "worldId": 1,
- "start": {
- "x": 0,
- "y": 0
- },
- "tiles":
- [
- [ 9, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 9 ],
- [ 2, 3, 2, 6, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 9 ],
- [ 2, 2, 5, 9, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 9 ],
- [ 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 9 ],
- [ 2, 12, 12, 12, 12, 12, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 9 ],
- [ 2, 17, 17, 17, 17, 17, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 9 ],
- [ 20, 16, 16, 16, 16, 16, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 9 ],
- [ 20, 16, 16, 16, 16, 16, 2, 2, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 2, 2, 2, 2, 2, 2, 2, 2, 2, 9 ],
- [ 16, 16, 16, 16, 16, 16, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 9 ],
- [ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 9 ],
- [ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 9 ],
- [ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 9 ],
- [ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 9 ],
- [ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 9 ],
- [ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 9 ],
- [ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 9 ],
- [ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 9 ],
- [ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 9 ],
- [ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 9 ],
- [ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 9 ],
- [ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 9 ],
- [ 9 , 14, 14, 14, 14, 14, 14, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 9 ]
- ]
-
- },
- {
- "worldId": 0,
- "start": {
- "x": 0,
- "y": 0
- },
- "tiles": [
- [0, 0, 0, 0],
- [0, 0, 0, 0],
- [0, 0, 0, 0]
- ]
- }
-]
\ No newline at end of file
diff --git a/dist/bundle.js b/dist/bundle.js
deleted file mode 100644
index 48fb265..0000000
--- a/dist/bundle.js
+++ /dev/null
@@ -1,3376 +0,0 @@
-/******/ (function(modules) { // webpackBootstrap
-/******/ // The module cache
-/******/ var installedModules = {};
-/******/
-/******/ // The require function
-/******/ function __webpack_require__(moduleId) {
-/******/
-/******/ // Check if module is in cache
-/******/ if(installedModules[moduleId]) {
-/******/ return installedModules[moduleId].exports;
-/******/ }
-/******/ // Create a new module (and put it into the cache)
-/******/ var module = installedModules[moduleId] = {
-/******/ i: moduleId,
-/******/ l: false,
-/******/ exports: {}
-/******/ };
-/******/
-/******/ // Execute the module function
-/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
-/******/
-/******/ // Flag the module as loaded
-/******/ module.l = true;
-/******/
-/******/ // Return the exports of the module
-/******/ return module.exports;
-/******/ }
-/******/
-/******/
-/******/ // expose the modules object (__webpack_modules__)
-/******/ __webpack_require__.m = modules;
-/******/
-/******/ // expose the module cache
-/******/ __webpack_require__.c = installedModules;
-/******/
-/******/ // define getter function for harmony exports
-/******/ __webpack_require__.d = function(exports, name, getter) {
-/******/ if(!__webpack_require__.o(exports, name)) {
-/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
-/******/ }
-/******/ };
-/******/
-/******/ // define __esModule on exports
-/******/ __webpack_require__.r = function(exports) {
-/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
-/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
-/******/ }
-/******/ Object.defineProperty(exports, '__esModule', { value: true });
-/******/ };
-/******/
-/******/ // create a fake namespace object
-/******/ // mode & 1: value is a module id, require it
-/******/ // mode & 2: merge all properties of value into the ns
-/******/ // mode & 4: return value when already ns object
-/******/ // mode & 8|1: behave like require
-/******/ __webpack_require__.t = function(value, mode) {
-/******/ if(mode & 1) value = __webpack_require__(value);
-/******/ if(mode & 8) return value;
-/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
-/******/ var ns = Object.create(null);
-/******/ __webpack_require__.r(ns);
-/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
-/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
-/******/ return ns;
-/******/ };
-/******/
-/******/ // getDefaultExport function for compatibility with non-harmony modules
-/******/ __webpack_require__.n = function(module) {
-/******/ var getter = module && module.__esModule ?
-/******/ function getDefault() { return module['default']; } :
-/******/ function getModuleExports() { return module; };
-/******/ __webpack_require__.d(getter, 'a', getter);
-/******/ return getter;
-/******/ };
-/******/
-/******/ // Object.prototype.hasOwnProperty.call
-/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
-/******/
-/******/ // __webpack_public_path__
-/******/ __webpack_require__.p = "";
-/******/
-/******/
-/******/ // Load entry module and return exports
-/******/ return __webpack_require__(__webpack_require__.s = 0);
-/******/ })
-/************************************************************************/
-/******/ ({
-
-/***/ "./src/application/Core/timer.service.ts":
-/*!***********************************************!*\
- !*** ./src/application/Core/timer.service.ts ***!
- \***********************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", { value: true });
-class TimerService {
- constructor(targetFps = 60) {
- this.fps = targetFps;
- this.timePerTick = 1000 / this.fps;
- this.delta = 0;
- this.now = 0;
- this.lastTime = performance.now();
- this.timer = 0;
- this.ticks = 0;
- this.lastTimeTook = 0;
- }
- CheckShouldRunLoop() {
- this.now = performance.now();
- this.delta += (this.now - this.lastTime) / this.timePerTick;
- this.timer += this.now - this.lastTime;
- this.lastTimeTook = this.now - this.lastTime;
- this.lastTime = this.now;
- if (this.delta >= 1) {
- return true;
- }
- console.warn(`RUNNING SLOWLY. did not render. Delta [${this.delta}]`);
- return false;
- }
- UpdateTicksAndRenderAfterLoop() {
- this.delta--;
- this.ticks++;
- }
- /**
- * returns true if it's a good time to print to
- * the console
- *
- * @returns {boolean}
- * @memberof FpsService
- */
- ShouldPrintDebugData() {
- return this.timer > 1000;
- }
- /**
- * prints debug data from this class
- * to the console
- *
- * @memberof FpsService
- */
- PrintCurrentFpsToConsole() {
- return `
- ticks and frames: ${this.ticks.toFixed(2)}
- lastDelta: ${this.delta.toFixed(2)}
- timer: ${this.timer.toFixed(2)}
- lastTime Took: ${this.lastTimeTook.toFixed(2)}`;
- }
- ResetTimers() {
- if (this.timer > 1000) {
- this.ticks = 0;
- this.timer = 0;
- }
- }
- GetLastUpdateTimeTook() {
- return this.lastTimeTook / 1000;
- }
-}
-exports.TimerService = TimerService;
-
-
-/***/ }),
-
-/***/ "./src/application/Entities/Creatures/baddy.ts":
-/*!*****************************************************!*\
- !*** ./src/application/Entities/Creatures/baddy.ts ***!
- \*****************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", { value: true });
-const creature_1 = __webpack_require__(/*! ./creature */ "./src/application/Entities/Creatures/creature.ts");
-const Vector2_model_1 = __webpack_require__(/*! ../../../numerics/models/Vector2.model */ "./src/numerics/models/Vector2.model.ts");
-const degrees_helper_1 = __webpack_require__(/*! ../../../numerics/helpers/degrees.helper */ "./src/numerics/helpers/degrees.helper.ts");
-const number_helper_1 = __webpack_require__(/*! ../../../numerics/helpers/number.helper */ "./src/numerics/helpers/number.helper.ts");
-class Baddy extends creature_1.Creature {
- constructor(position, size, name, texturePath, graphicsService, colour, playerService) {
- super(position, size, name, texturePath, graphicsService);
- this.playerService = playerService;
- this.colour = colour;
- this.maxSpeed = new Vector2_model_1.Vector2(10, 10);
- this.acceleration = new Vector2_model_1.Vector2(.55, .6);
- // const friction = 0.85; // RandomNumberGenerator.GetRandomNumber(100, 200) / 1000;
- // this.friction = new Vector2(friction,
- // friction);
- this.direction = new Vector2_model_1.Vector2(0, 0);
- // this.velocity = RandomNumberGenerator.GetRandomVector2(-10, 10, -10, 10);
- this.rotationDegrees = 0; // RandomNumberGenerator.GetRandomNumber(0, 359);
- this.turnSpeed = .0515;
- this.thrust = 1;
- }
- Tick(lastDelta) {
- this.UpdateAABB();
- const playerAABB = this.playerService.GetPlayer().getAABB();
- this.MoveToPlayer(playerAABB);
- this.Move(lastDelta);
- }
- Render() {
- // super.Draw(this.colour);
- }
- collideWithObject(entity) {
- console.log('colliding with object');
- }
- turnToPlayer(playerAABB) {
- let dx = playerAABB.GetCenter().getValueX() - this.getAABB().GetCenter().getValueX();
- let dy = playerAABB.GetCenter().getValueY() - this.getAABB().GetCenter().getValueY();
- const len = Math.sqrt(dx * dy + dy * dy);
- dx /= len ? len : 0.1;
- dy /= len ? len : 0.1;
- let dirX = Math.cos(degrees_helper_1.Radians(this.rotationDegrees));
- let dirY = Math.sin(degrees_helper_1.Radians(this.rotationDegrees));
- dirX += (dx - dirX) * 1;
- dirY += (dy - dirY) * 1;
- const rotateTo = Math.atan2(dirY, dirX);
- // this.rotationDegrees = Degrees(rotateTo) + (90);
- this.rotationDegrees = number_helper_1.Lerp(this.rotationDegrees, degrees_helper_1.Degrees(rotateTo) + (-this.angleAdjust), .5);
- }
- MoveToPlayer(playerAABB) {
- this.turnToPlayer(playerAABB);
- const rotationAsRadians = degrees_helper_1.Radians(this.rotationDegrees - this.angleAdjust);
- const rotSin = Math.sin(rotationAsRadians);
- const rotCos = Math.cos(rotationAsRadians);
- this.velocity.x -= (rotCos * this.thrust);
- this.velocity.y -= (rotSin * this.thrust);
- // const rotationAsRadians = this.rotationDegrees / Math.PI * 180;
- // const rotCos = Math.sin(rotationAsRadians);
- // const rotSin = Math.cos(rotationAsRadians);
- // this.velocity.x = (rotSin * thrust);
- // this.velocity.y = (rotCos * thrust);
- // console.log(`baddy:
- // rotation: ${this.rotationDegrees}
- // CosRotation: ${rotCos}
- // SinRotation: ${rotSin}
- // velocity: ${this.velocity.concat()}`);
- // if (IntersectionHelper.AabbVsAabb(
- // this.getAABB(), playerAABB) === false) {
- // if (this.getAABB().IsAbove(playerAABB)) {
- // this.setDirectionDown();
- // this.velocity.y += this.acceleration.y;
- // // console.log('entity is above player')
- // } else if (this.getAABB().IsBelow(playerAABB)) {
- // this.setDirectionUp();
- // // console.log('entity is above player')
- // this.velocity.y -= this.acceleration.y; // console.log('entity is below player')
- // }
- // if (this.getAABB().IsRight(playerAABB)) {
- // this.setDirectionLeft();
- // // console.log('entity is right of the player');
- // this.velocity.x += this.acceleration.x;
- // } else if (this.getAABB().IsLeft(playerAABB)) {
- // this.setDirectionRigth();
- // // console.log('entity is left of the player')
- // this.velocity.x -= this.acceleration.x;
- // }
- // }
- // this.velocity.x -= (this.getDirectionHorizontal() * this.acceleration.x) / 4;
- // this.velocity.y += (this.getDirectionVertical() * this.acceleration.y) / 4;
- }
- setDirectionRigth() {
- this.direction.setValueX(1);
- }
- setDirectionLeft() {
- this.direction.setValueX(-1);
- }
- setDirectionUp() {
- this.direction.setValueY(-1);
- }
- setDirectionDown() {
- this.direction.setValueY(1);
- }
- getDirectionHorizontal() {
- return this.direction.getValueX();
- }
- getDirectionVertical() {
- return this.direction.getValueY();
- }
-}
-exports.Baddy = Baddy;
-
-
-/***/ }),
-
-/***/ "./src/application/Entities/Creatures/creature.default.settings.ts":
-/*!*************************************************************************!*\
- !*** ./src/application/Entities/Creatures/creature.default.settings.ts ***!
- \*************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", { value: true });
-const Vector2_model_1 = __webpack_require__(/*! ../../../numerics/models/Vector2.model */ "./src/numerics/models/Vector2.model.ts");
-class CreatureDefaultSettings {
-}
-CreatureDefaultSettings.DEFAULT_HEALTH = 100;
-CreatureDefaultSettings.DEFAULT_MOVEMENT_SPEED = new Vector2_model_1.Vector2(3.0, 3.0);
-CreatureDefaultSettings.DEFAULT_MOVEMENT_SPEED_MAX = new Vector2_model_1.Vector2(11.0, 11.0);
-CreatureDefaultSettings.DEFAULT_MOVEMENT_ACCELERATION = new Vector2_model_1.Vector2(3.0, 3.0);
-CreatureDefaultSettings.DEFAULT_MOVEMENT_VELOCITY = new Vector2_model_1.Vector2(3, 3);
-CreatureDefaultSettings.DEFAULT_SIZE = new Vector2_model_1.Vector2(20, 20);
-CreatureDefaultSettings.DEFAULT_FRICTION = new Vector2_model_1.Vector2(0.95, 0.95);
-exports.CreatureDefaultSettings = CreatureDefaultSettings;
-
-
-/***/ }),
-
-/***/ "./src/application/Entities/Creatures/creature.ts":
-/*!********************************************************!*\
- !*** ./src/application/Entities/Creatures/creature.ts ***!
- \********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", { value: true });
-const _base_entity_1 = __webpack_require__(/*! ../_base-entity */ "./src/application/Entities/_base-entity.ts");
-const Vector2_model_1 = __webpack_require__(/*! ../../../numerics/models/Vector2.model */ "./src/numerics/models/Vector2.model.ts");
-const creature_default_settings_1 = __webpack_require__(/*! ./creature.default.settings */ "./src/application/Entities/Creatures/creature.default.settings.ts");
-const vector2_helper_1 = __webpack_require__(/*! ../../../numerics/helpers/vector2.helper */ "./src/numerics/helpers/vector2.helper.ts");
-const number_helper_1 = __webpack_require__(/*! ../../../numerics/helpers/number.helper */ "./src/numerics/helpers/number.helper.ts");
-class Creature extends _base_entity_1.Entity {
- // protected canvasId: string;
- // protected texture: Texture2D;
- constructor(position, size, name, texturePath, graphicsService) {
- super(position, size, name, '1', 'no_text_yet');
- this.turnSpeed = 1;
- this.angleAdjust = -90;
- console.error('passing incorrect texture ID and canvasId, and canvas to super');
- this.graphicsService = graphicsService;
- this.health = creature_default_settings_1.CreatureDefaultSettings.DEFAULT_HEALTH;
- this.speed = creature_default_settings_1.CreatureDefaultSettings.DEFAULT_MOVEMENT_SPEED;
- this.velocity = new Vector2_model_1.Vector2(0, 0);
- this.maxSpeed = creature_default_settings_1.CreatureDefaultSettings.DEFAULT_MOVEMENT_SPEED_MAX;
- this.acceleration = creature_default_settings_1.CreatureDefaultSettings.DEFAULT_MOVEMENT_ACCELERATION;
- this.deceleration = vector2_helper_1.Vector2Helpers.DivideByScale(creature_default_settings_1.CreatureDefaultSettings.DEFAULT_MOVEMENT_ACCELERATION, 1);
- this.friction = creature_default_settings_1.CreatureDefaultSettings.DEFAULT_FRICTION;
- this.setCanvasId(this.graphicsService.RegisterDrawableEntity());
- if (texturePath !== undefined && texturePath !== null && texturePath.length) {
- const textureId = this.graphicsService.GetTextureService().RegisterNewTexture(texturePath);
- this.SetTextureId(textureId);
- }
- else {
- console.error(new Error(`creature [${name}] did not have a texture`));
- }
- }
- Move(lastDelta) {
- this.CapMovementSpeed();
- this.CapRotation();
- this.UpdatePosition(lastDelta);
- this.ReduceSpeed();
- this.UpdateAABB();
- }
- ReduceSpeed() {
- this.velocity.y *= this.friction.y;
- this.velocity.x *= this.friction.x;
- // if (this.velocity.y > 0) {
- // this.velocity.y -= this.friction.y;
- // if (this.velocity.y < 0) {
- // this.velocity.y = 0;
- // }
- // } else if (this.velocity.y < 0) {
- // this.velocity.y += this.friction.y;
- // if (this.velocity.y > 0) {
- // this.velocity.y = 0;
- // }
- // }
- // if (this.velocity.x > 0) {
- // this.velocity.x -= this.friction.x;
- // if (this.velocity.x < 0) {
- // this.velocity.x = 0;
- // }
- // } else if (this.velocity.x < 0) {
- // this.velocity.x += this.friction.x;
- // if (this.velocity.x > 0) {
- // this.velocity.x = 0;
- // }
- // }
- }
- /**
- * updates the creature's position
- *
- * @private
- * @memberof Creature
- */
- UpdatePosition(lastDelta) {
- // this.position.x += (this.velocity.x * (lastDelta) * 50);
- // this.position.y += (this.velocity.y * (lastDelta) * 50);
- this.position.x = number_helper_1.Lerp(this.position.x, this.position.x + (this.velocity.x * (lastDelta) * 50), .8);
- this.position.y = number_helper_1.Lerp(this.position.y, this.position.y + (this.velocity.y * (lastDelta) * 50), .8);
- }
- /**
- * caps the creature's movement speed at
- * this.maxSpeed
- *
- * @private
- * @memberof Creature
- */
- CapMovementSpeed() {
- if (this.velocity.x > this.maxSpeed.x) {
- this.velocity.x = this.maxSpeed.x;
- }
- else if (this.velocity.x < -this.maxSpeed.x) {
- this.velocity.x = -this.maxSpeed.x;
- }
- if (this.velocity.y > this.maxSpeed.y) {
- this.velocity.y = this.maxSpeed.y;
- }
- else if (this.velocity.y < -this.maxSpeed.y) {
- this.velocity.y = -this.maxSpeed.y;
- }
- if (this.velocity.x < 0.1 && this.velocity.x > -0.1) {
- this.velocity.x = 0;
- }
- if (this.velocity.y < 0.1 && this.velocity.y > -0.1) {
- this.velocity.y = 0;
- }
- }
- CapRotation() {
- // if (this.rotationDegrees < 0) {
- // this.rotationDegrees = 360 - (-this.rotationDegrees);
- // }
- // if (this.rotationDegrees < 0) {
- // this.rotationDegrees = 359;
- // } if (this.rotationDegrees > 360) {
- // this.rotationDegrees = 0;
- // }
- }
- getHealth() {
- return this.health;
- }
- setHealth(health) {
- this.health = health;
- }
- getSpeed() {
- return this.speed;
- }
- setSpeed(speed) {
- this.speed = speed;
- }
- getMove() {
- return this.velocity;
- }
- setMove(move) {
- this.velocity = move;
- }
-}
-exports.Creature = Creature;
-
-
-/***/ }),
-
-/***/ "./src/application/Entities/Creatures/player.ts":
-/*!******************************************************!*\
- !*** ./src/application/Entities/Creatures/player.ts ***!
- \******************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", { value: true });
-const creature_1 = __webpack_require__(/*! ./creature */ "./src/application/Entities/Creatures/creature.ts");
-const Vector2_model_1 = __webpack_require__(/*! ../../../numerics/models/Vector2.model */ "./src/numerics/models/Vector2.model.ts");
-const degrees_helper_1 = __webpack_require__(/*! ../../../numerics/helpers/degrees.helper */ "./src/numerics/helpers/degrees.helper.ts");
-class Player extends creature_1.Creature {
- constructor(position, size, name, texturePath, inputManager, graphicsService) {
- super(position, size, name, texturePath, graphicsService);
- this.rotationSpeed = 5;
- this.strafeThrust = 1.5;
- this.startingFriction = this.friction;
- this.inputManager = inputManager;
- this.health = 100;
- this.detailsDiv = document.getElementById('details_div');
- this.colour = '#fff';
- this.thrust = 1;
- }
- Tick(lastDelta) {
- this.GetInput();
- this.Move(lastDelta);
- this.graphicsService.getGameCameraService().LookAt(this.position, this.size);
- }
- GetInput() {
- // this.setMove(new Vector2(0, 0));
- this.UpdatePlayerSpeedFromInput();
- this.UpdatePlayerRotationFromInput();
- this.UpdatePlayerStrafeFromInput();
- // if (this.inputManager.IsKeyPressed('direction_left')) {
- // this.AddToRotation(-(this.rotationSpeed * this.inputManager.GetForceValue('direction_left')));
- // // this.AddToRotation(-this.rotationSpeed);
- // // this.velocity.x -= this.acceleration.x;
- // }
- // if (this.inputManager.IsKeyPressed('direction_right')) {
- // this.AddToRotation(this.rotationSpeed * this.inputManager.GetForceValue('direction_right'));
- // // this.velocity.x += this.acceleration.x;
- // }
- if (this.inputManager.IsKeyPressed(''))
- if (this.inputManager.IsKeyPressed('action_a')) {
- console.log('space pressed');
- }
- // console.log(`this.movement.x = ${this.movement.x}`)
- }
- UpdatePlayerRotationFromInput() {
- if (this.inputManager.IsKeyPressed('axes_pad_left_horizontal')) {
- this.AddToRotation(this.rotationSpeed *
- this.inputManager.GetForceValue('axes_pad_left_horizontal'));
- }
- else {
- if (this.inputManager.IsKeyPressed('direction_right')) {
- this.AddToRotation(this.rotationSpeed *
- this.inputManager.GetForceValue('direction_right'));
- }
- if (this.inputManager.IsKeyPressed('direction_left')) {
- this.AddToRotation(-(this.rotationSpeed *
- this.inputManager.GetForceValue('direction_left')));
- }
- }
- }
- UpdatePlayerSpeedFromInput() {
- const rotationAsRadians = degrees_helper_1.Radians(this.rotationDegrees - this.angleAdjust);
- const rotSin = Math.sin(rotationAsRadians);
- const rotCos = Math.cos(rotationAsRadians);
- if (this.inputManager.IsKeyPressed('trigger_two_right') ||
- this.inputManager.IsKeyPressed('direction_up')) {
- const triggerTwoRightForce = Math.max(this.inputManager.GetForceValue('direction_up'), (this.inputManager.GetForceValue('trigger_two_right')));
- this.velocity.x -= (rotCos * (this.thrust * triggerTwoRightForce));
- this.velocity.y -= (rotSin * (this.thrust * triggerTwoRightForce));
- }
- if (this.inputManager.IsKeyPressed('trigger_two_left') ||
- this.inputManager.IsKeyPressed('direction_down')) {
- const triggerTwoLeftForce = Math.max(this.inputManager.GetForceValue('trigger_two_left'), (this.inputManager.GetForceValue('direction_down')));
- // this.velocity.x += (rotCos * (this.thrust * triggerTwoLeftForce));
- // this.velocity.y += (rotSin * (this.thrust * triggerTwoLeftForce));
- this.friction.x = 0.85;
- this.friction.y = 0.85;
- }
- else {
- this.friction = new Vector2_model_1.Vector2(this.startingFriction.getValueX(), this.startingFriction.getValueY());
- }
- if (this.inputManager.IsKeyPressed('trigger_one_right')) {
- const triggerOneRightForce = this.inputManager.GetForceValue('trigger_one_right');
- this.velocity.x += (rotSin * triggerOneRightForce) * this.strafeThrust;
- this.velocity.y -= (rotCos * triggerOneRightForce) * this.strafeThrust;
- }
- if (this.inputManager.IsKeyPressed('trigger_one_left')) {
- const triggerOneLeftForce = this.inputManager.GetForceValue('trigger_one_right');
- this.velocity.x -= rotSin * triggerOneLeftForce;
- this.velocity.y += rotCos * triggerOneLeftForce;
- }
- this.detailsDiv.innerHTML = `
- player:
- ve: ${this.velocity.concat(3)}
- ro: ${this.rotationDegrees.toFixed(3)}DEG
- ro: ${rotationAsRadians.toFixed(3)}RAD
- th: ${this.thrust.toFixed(3)}
- rS: ${rotSin.toFixed(3)}
- rC: ${rotCos.toFixed(3)}
-
- `;
- }
- UpdatePlayerStrafeFromInput() {
- // if (this.inputManager.IsKeyPressed('trigger_one_right')) {
- // this.velocity.x -= (this.inputManager.GetForceValue('trigger_one_right') * this.acceleration.y) ;
- // }
- // if (this.inputManager.IsKeyPressed('trigger_one_left')) {
- // this.velocity.x += (this.inputManager.GetForceValue('trigger_one_left') * this.acceleration.y) ;
- // }
- }
-}
-exports.Player = Player;
-
-
-/***/ }),
-
-/***/ "./src/application/Entities/_base-entity.ts":
-/*!**************************************************!*\
- !*** ./src/application/Entities/_base-entity.ts ***!
- \**************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", { value: true });
-const random_guid_generator_1 = __webpack_require__(/*! ../Tools/random_generators/random_guid.generator */ "./src/application/Tools/random_generators/random_guid.generator.ts");
-const AABB_model_1 = __webpack_require__(/*! ../../numerics/models/AABB.model */ "./src/numerics/models/AABB.model.ts");
-const drawable_1 = __webpack_require__(/*! ../Graphics/Draw/drawable */ "./src/application/Graphics/Draw/drawable.ts");
-// export interface IEntity {
-// position: Vector2;
-// size: Vector2;
-// name: string;
-// id: string;
-// }
-class Entity extends drawable_1.Drawable {
- // constructor(position: Vector2, size: Vector2, name: string, canvasId: string, texture: Texture2D, textureId: string) {
- constructor(position, size, name, canvasId, textureId) {
- super(position, size, canvasId, textureId);
- this.id = random_guid_generator_1.GuidGenerator.NewGuid();
- this.name = name;
- }
- getName() {
- return this.name;
- }
- getId() {
- return this.name;
- }
- getPosition() {
- return this.position;
- }
- setPosition(newPosition) {
- this.position = newPosition;
- return this.getPosition();
- }
- setPositionX(newPositionX) {
- this.position.x = newPositionX;
- return this.getPosition();
- }
- setPositionY(newPositionY) {
- this.position.y = newPositionY;
- return this.getPosition();
- }
- getSize() {
- return this.size;
- }
- setSize(newSize) {
- this.size = newSize;
- return this.getSize();
- }
- // getAABB(): AABB {
- // if (this.AABB === undefined) {
- // this.UpdateAABB();
- // }
- // return this.AABB;
- // }
- SetAABB(AABB) {
- this.setAABB(AABB);
- }
- UpdateAABB() {
- this.setAABB(new AABB_model_1.AABB(this.position, this.size));
- }
-}
-exports.Entity = Entity;
-
-
-/***/ }),
-
-/***/ "./src/application/Entities/entity.service.ts":
-/*!****************************************************!*\
- !*** ./src/application/Entities/entity.service.ts ***!
- \****************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", { value: true });
-class EntityService {
- constructor(
- // drawingService: DrawingService
- ) {
- this.gameEntities = new Array();
- }
- TickAllEntities(lastDelta) {
- for (let i = 0; i < this.gameEntities.length; i++) {
- this.gameEntities[i].Tick(lastDelta);
- }
- }
- RenderAllEntities(graphicsService) {
- for (let i = 0; i < this.gameEntities.length; i++) {
- graphicsService.getDrawingService().Draw(this.gameEntities[i]);
- }
- }
- RegisterEntity(entity) {
- console.log('registering an entity');
- this.gameEntities.push(entity);
- }
-}
-exports.EntityService = EntityService;
-
-
-/***/ }),
-
-/***/ "./src/application/Entities/player.service.ts":
-/*!****************************************************!*\
- !*** ./src/application/Entities/player.service.ts ***!
- \****************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", { value: true });
-class PlayerService {
- constructor() {
- }
- SetPlayer(player) {
- if (this.player !== undefined) {
- console.error(`playerService.SetPlayer would overwrite the existing player`);
- }
- else {
- console.warn('setting player');
- this.player = player;
- }
- }
- GetPlayer() {
- return this.player;
- }
-}
-exports.PlayerService = PlayerService;
-
-
-/***/ }),
-
-/***/ "./src/application/Graphics/Camera/game-camera.service.ts":
-/*!****************************************************************!*\
- !*** ./src/application/Graphics/Camera/game-camera.service.ts ***!
- \****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", { value: true });
-const Vector2_model_1 = __webpack_require__(/*! ../../../numerics/models/Vector2.model */ "./src/numerics/models/Vector2.model.ts");
-const Viewport_Helper_1 = __webpack_require__(/*! ../Viewport/Viewport.Helper */ "./src/application/Graphics/Viewport/Viewport.Helper.ts");
-const intersection_helper_1 = __webpack_require__(/*! ../../../numerics/helpers/intersection.helper */ "./src/numerics/helpers/intersection.helper.ts");
-const AABB_model_1 = __webpack_require__(/*! ../../../numerics/models/AABB.model */ "./src/numerics/models/AABB.model.ts");
-class GameCameraService {
- /**
- *Creates an instance of GameCameraService.
-
- applyWorldBounding tells the camera if it should continue
- moving right or left if it reaches the edge of the level
- * @param {number} xOffset
- * @param {number} yOffset
- * @param {boolean} applyWorldBounding
- * @memberof GameCameraService
- */
- constructor(xOffset, yOffset, applyWorldBounding) {
- this.offset = new Vector2_model_1.Vector2(xOffset, yOffset);
- this.applyWorldBounding = applyWorldBounding;
- this.displayableSize = Viewport_Helper_1.ViewportHelper.GetWindowInAspectRatio();
- this.UpdatePositionAndSize();
- }
- SetLevelAABB(levelAABB) {
- this.levelAABB = levelAABB;
- }
- GetDebugInfo() {
- return [`
- offset: ${this.offset.concat(2)}
- size: ${this.displayableSize.concat(2)}`];
- }
- /**
- * checks if two objects intersect
- *
- * @param {Vector2} position
- * @param {Vector2} size
- * @returns {boolean}
- * @memberof GameCameraService
- */
- IsObectOnScreen(position, size) {
- const objectAABB = new AABB_model_1.AABB(position, size);
- return this.IsObjectOnScreenAABB(objectAABB);
- }
- IsObjectOnScreenAABB(AABB) {
- if (intersection_helper_1.IntersectionHelper.AabbVsAabb(this.cameraAABB, AABB)) {
- return true;
- }
- else {
- return false;
- }
- }
- MoveCamera(xAmount, yAmount) {
- console.error('don\'t use MoveCamera');
- this.offset.x += xAmount;
- this.offset.y += yAmount;
- }
- /**
- * sets the camera to points at (looks at) a specific entity
- *
- * @param {Vector2} entityPosition
- * @param {Vector2} entitySize
- * @memberof GameCameraService
- */
- LookAt(entityPosition, entitySize) {
- const vieportWidth = Viewport_Helper_1.ViewportHelper.GetWindowInAspectRatio().getValueX();
- const vieportHeight = Viewport_Helper_1.ViewportHelper.GetWindowInAspectRatio().getValueY();
- const centerX = entityPosition.getValueX() - (vieportWidth / 2) + (entitySize.getValueX() / 2);
- const centerY = entityPosition.getValueY() - (vieportHeight / 2) + (entitySize.getValueY() / 2);
- this.SetOffset(new Vector2_model_1.Vector2(centerX, centerY));
- }
- SetOffset(positionVector) {
- this.offset = positionVector;
- if (this.applyWorldBounding) {
- if (this.offset.getValueX() < this.levelAABB.GetLeft()) {
- this.offset.setValueX(this.levelAABB.GetLeft());
- }
- if (this.offset.getValueX() > this.levelAABB.GetRight()) {
- this.offset.setValueX(this.levelAABB.GetRight());
- }
- if (this.offset.getValueY() < this.levelAABB.GetTop()) {
- this.offset.setValueY(this.levelAABB.GetTop());
- }
- if (this.offset.getValueY() > this.levelAABB.GetBottom()) {
- this.offset.setValueY(this.levelAABB.GetBottom());
- }
- }
- this.UpdatePositionAndSize();
- }
- UpdatePositionAndSize() {
- this.cameraAABB = new AABB_model_1.AABB(this.offset, this.displayableSize);
- }
- GetOffsetX() {
- return this.offset.getValueX();
- }
- GetOffsetY() {
- return this.offset.getValueY();
- }
- GetOffsetVector() {
- return this.offset;
- }
-}
-exports.GameCameraService = GameCameraService;
-
-
-/***/ }),
-
-/***/ "./src/application/Graphics/Canvas/graphics.canvas.service.ts":
-/*!********************************************************************!*\
- !*** ./src/application/Graphics/Canvas/graphics.canvas.service.ts ***!
- \********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", { value: true });
-const graphics_drawable_canvas_1 = __webpack_require__(/*! ../Models/graphics.drawable-canvas */ "./src/application/Graphics/Models/graphics.drawable-canvas.ts");
-const Viewport_Helper_1 = __webpack_require__(/*! ../Viewport/Viewport.Helper */ "./src/application/Graphics/Viewport/Viewport.Helper.ts");
-const random_guid_generator_1 = __webpack_require__(/*! ../../Tools/random_generators/random_guid.generator */ "./src/application/Tools/random_generators/random_guid.generator.ts");
-class CanvasService {
- constructor(htmlService) {
- console.log('creating a canvas service');
- this.htmlService = htmlService;
- }
- Init() {
- const viewportSize = Viewport_Helper_1.ViewportHelper.GetWindowInAspectRatioForCanvas();
- this.viewportHeight = viewportSize.y;
- this.viewportWidth = viewportSize.x;
- this.mainCanvas = this.htmlService.createCanvas('main_canvas', this.htmlService.GetMainDiv().id, this.viewportWidth, this.viewportHeight, ['parent']);
- this.mainCanvasCtx = this.mainCanvas.getContext('2d');
- this.drawableAreas = new Array();
- }
- RegisterNewCanvas(id = null) {
- console.log(`registering a new canvas with id ${id}`);
- if (id === null) {
- id = random_guid_generator_1.GuidGenerator.NewGuid();
- }
- const canvas = this.htmlService.createCanvas(id, this.mainCanvas.id, this.viewportWidth, this.viewportHeight);
- this.drawableAreas.push(new graphics_drawable_canvas_1.DrawableCanvas(canvas, id, this.viewportWidth, this.viewportHeight));
- return id;
- }
- GetMainCanvas() {
- return this.mainCanvas;
- }
- GetCanvas(id) {
- for (let i = 0; i < this.drawableAreas.length; i++) {
- if (this.drawableAreas[i].id === id) {
- return this.drawableAreas[i];
- }
- }
- console.error(`failed to get a canvas of id ${id}`);
- }
-}
-exports.CanvasService = CanvasService;
-
-
-/***/ }),
-
-/***/ "./src/application/Graphics/Draw/drawable.ts":
-/*!***************************************************!*\
- !*** ./src/application/Graphics/Draw/drawable.ts ***!
- \***************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", { value: true });
-const AABB_model_1 = __webpack_require__(/*! ../../../numerics/models/AABB.model */ "./src/numerics/models/AABB.model.ts");
-class Drawable {
- constructor(position, size, canvasId, textureId) {
- console.log(`drawable constructor`);
- this.position = position;
- this.size = size;
- this.AABB = new AABB_model_1.AABB(this.position, this.size);
- this.canvasId = canvasId;
- this.rotationDegrees = 0;
- this.textureId = textureId;
- }
- getCanvasId() {
- return this.canvasId;
- }
- setCanvasId(canvasId) {
- this.canvasId = canvasId;
- }
- GetTextureId() {
- return this.textureId;
- }
- SetTextureId(textureId) {
- this.textureId = textureId;
- }
- getAABB() {
- if (this.AABB === undefined) {
- this.UpdateAABB();
- }
- return this.AABB;
- }
- setAABB(AABB) {
- this.AABB = AABB;
- }
- UpdateAABB() {
- this.setAABB(new AABB_model_1.AABB(this.position, this.size));
- }
- GetPositionX() {
- return this.position.x;
- }
- GetPositionY() {
- return this.position.y;
- }
- GetSizeX() {
- return this.size.x;
- }
- GetSizeY() {
- return this.size.y;
- }
- GetColour() {
- if (this.colour) {
- return this.colour;
- }
- else {
- return '#f00';
- }
- }
- GetRotation() {
- return this.rotationDegrees;
- }
- AddToRotation(val) {
- this.rotationDegrees += val;
- if (this.rotationDegrees > 359) {
- this.rotationDegrees = 0;
- }
- else if (this.rotationDegrees < 0) {
- this.rotationDegrees = 359;
- }
- }
-}
-exports.Drawable = Drawable;
-
-
-/***/ }),
-
-/***/ "./src/application/Graphics/Draw/drawing.service.ts":
-/*!**********************************************************!*\
- !*** ./src/application/Graphics/Draw/drawing.service.ts ***!
- \**********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", { value: true });
-class DrawingService {
- constructor(cameraService, canvasService, textureService) {
- this.allowTextureDrawing = true;
- this.drawAsStroke = true;
- this.textureService = textureService;
- this.canvasService = canvasService;
- this.cameraService = cameraService;
- console.log('constructing drawing service');
- }
- Draw(drawable, skipCanvasClear = false) {
- const deg = drawable.GetRotation();
- if (this.cameraService.IsObjectOnScreenAABB(drawable.getAABB())) {
- const canv = this.canvasService.GetCanvas(drawable.getCanvasId());
- var rad = deg * (Math.PI / 180);
- if (!skipCanvasClear) {
- canv.ClearCanvas();
- }
- canv.ctx.save();
- // canv.ctx.scale(0.5, 0.5);
- const translateX = drawable.GetSizeX() + (drawable.GetPositionX() - (drawable.GetSizeX() / 2) - this.cameraService.GetOffsetX()); // + (drawable.GetSizeX() / 2));// + this.cameraService.GetOffsetY();
- const translateY = drawable.GetSizeX() + (drawable.GetPositionY() - (drawable.GetSizeX() / 2) - this.cameraService.GetOffsetY()); // + (drawable.GetSizeY() / 2));// + this.cameraService.GetOffsetY();
- canv.ctx.translate(translateX, translateY);
- canv.ctx.rotate(rad);
- const drawLocationX = -drawable.GetSizeX() / 2; // / 2;// ;
- const drawLocationY = -drawable.GetSizeY() / 2; // / 2;// - this.cameraService.GetOffsetY();
- const drawSizeX = drawable.GetSizeX();
- const drawSizeY = drawable.GetSizeY();
- const texture = this.textureService.GetTexture(drawable.GetTextureId());
- if (this.allowTextureDrawing && texture && texture.GetCanRender()) {
- this.DrawAsTexture(texture, canv, drawLocationX, drawLocationY, drawSizeX, drawSizeY);
- }
- else if (false) {}
- else {
- // if (drawable.GetTextureId()) {
- // console.log(`
- // text: ${texture.GetId()}
- // rend: ${texture.GetCanRender()}`);
- // }
- this.DrawAsRect(drawable, canv, drawLocationX, drawLocationY, drawSizeX, drawSizeY);
- }
- // detranslates the canvas
- canv.ctx.translate(-(translateX), -(translateY));
- canv.ctx.restore();
- }
- }
- // private rotate(ctx) {
- // //Convert degrees to radian
- // var rad = deg * Math.PI / 180;
- // //Set the origin to the center of the image
- // ctx.translate(x + width / 2, y + height / 2);
- // //Rotate the canvas around the origin
- // ctx.rotate(rad);
- // //draw the image
- // ctx.drawImage(img, width / 2 * (-1), height / 2 * (-1), width, height);
- // //reset the canvas
- // ctx.rotate(rad * (-1));
- // ctx.translate((x + width / 2) * (-1), (y + height / 2) * (-1));
- // }
- DrawAsTexture(texture, canv, drawLocationX, drawLocationY, drawSizeX, drawSizeY) {
- canv.ctx.strokeStyle = '#fff';
- canv.ctx.strokeRect(drawLocationX, drawLocationY, drawSizeX, drawSizeY);
- canv.ctx.drawImage(texture.GetImage(), drawLocationX, drawLocationY, drawSizeX, drawSizeY);
- }
- DrawAsRect(drawable, canv, drawLocationX, drawLocationY, drawSizeX, drawSizeY) {
- if (this.drawAsStroke) {
- canv.ctx.strokeStyle = drawable.GetColour();
- canv.ctx.strokeRect(drawLocationX, drawLocationY, drawSizeX, drawSizeY);
- }
- else {
- canv.ctx.fillStyle = drawable.GetColour();
- canv.ctx.fillRect(drawLocationX, drawLocationY, drawSizeX, drawSizeY);
- }
- }
-}
-exports.DrawingService = DrawingService;
-
-
-/***/ }),
-
-/***/ "./src/application/Graphics/Html/graphics.html.service.ts":
-/*!****************************************************************!*\
- !*** ./src/application/Graphics/Html/graphics.html.service.ts ***!
- \****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", { value: true });
-class HtmlService {
- constructor() {
- console.log('creating Html Helper Service in Graphics');
- }
- Init() {
- this.createMainDiv('main_div');
- }
- GetMainDiv() {
- return this.mainDiv;
- }
- createMainDiv(id = 'main_div') {
- this.mainDiv = document.createElement('div');
- this.mainDiv.id = id;
- document.body.appendChild(this.mainDiv);
- return this.mainDiv.id;
- }
- createCanvas(id, attatchTo, width, height, classList = null) {
- const canvas = document.createElement('canvas');
- canvas.id = id;
- canvas.width = width;
- canvas.height = height;
- if (classList != null) {
- for (let i = 0; i < classList.length; i++) {
- canvas.classList.add(classList[i]);
- }
- }
- document.getElementById(attatchTo).appendChild(canvas);
- return canvas;
- }
-}
-exports.HtmlService = HtmlService;
-
-
-/***/ }),
-
-/***/ "./src/application/Graphics/Images/ImageHelper.ts":
-/*!********************************************************!*\
- !*** ./src/application/Graphics/Images/ImageHelper.ts ***!
- \********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", { value: true });
-class ImageHelper {
- static NewImage(path) {
- const image = new Image(128, 128);
- image.src = this.assetBasePath + path;
- image.onerror = ((event) => this.onError(event));
- return image;
- }
- static onError(error) {
- console.log('error loading image', error);
- return;
- }
-}
-ImageHelper.assetBasePath = './assets/_dist/';
-exports.ImageHelper = ImageHelper;
-
-
-/***/ }),
-
-/***/ "./src/application/Graphics/Models/graphics.drawable-canvas.ts":
-/*!*********************************************************************!*\
- !*** ./src/application/Graphics/Models/graphics.drawable-canvas.ts ***!
- \*********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", { value: true });
-const Vector2_model_1 = __webpack_require__(/*! ../../../numerics/models/Vector2.model */ "./src/numerics/models/Vector2.model.ts");
-class DrawableCanvas extends Vector2_model_1.Vector2 {
- constructor(canvas, id, width, height) {
- super(width, height);
- this.id = id;
- this.canvas = canvas;
- this.ctx = this.canvas.getContext('2d');
- }
- GetWidth() {
- return this.getValueX();
- }
- GetHeight() {
- return this.getValueY();
- }
- ClearCanvas() {
- this.ctx.clearRect(0, 0, this.getValueX(), this.getValueY());
- }
- PaintImmediately() {
- this.ctx.drawImage(this.canvas, 0, 0);
- }
-}
-exports.DrawableCanvas = DrawableCanvas;
-
-
-/***/ }),
-
-/***/ "./src/application/Graphics/Textures/Texture2d.ts":
-/*!********************************************************!*\
- !*** ./src/application/Graphics/Textures/Texture2d.ts ***!
- \********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", { value: true });
-const random_guid_generator_1 = __webpack_require__(/*! ../../Tools/random_generators/random_guid.generator */ "./src/application/Tools/random_generators/random_guid.generator.ts");
-const ImageHelper_1 = __webpack_require__(/*! ../Images/ImageHelper */ "./src/application/Graphics/Images/ImageHelper.ts");
-class Texture2D {
- constructor(path) {
- this.path = path;
- this.url = path;
- this.id = random_guid_generator_1.GuidGenerator.NewGuid();
- this.image = ImageHelper_1.ImageHelper.NewImage(this.url);
- this.image.onload = (() => {
- this.imageCanRender = true;
- });
- this.image.onerror = (() => {
- this.imageCanRender = false;
- console.error('text2d: image could not render');
- });
- }
- GetPath() {
- return this.path;
- }
- /**
- * GetId
- */
- GetId() {
- return this.id;
- }
- /**
- * GetUrl
- */
- GetImage() {
- return this.image;
- }
- /**
- * returns imageCanRender. If the image is successfully loaded,
- * this returns true. Otherwise returns false
- *
- * @returns
- * @memberof Texture2D
- */
- GetCanRender() {
- return this.imageCanRender;
- }
-}
-exports.Texture2D = Texture2D;
-
-
-/***/ }),
-
-/***/ "./src/application/Graphics/Textures/texture.service.ts":
-/*!**************************************************************!*\
- !*** ./src/application/Graphics/Textures/texture.service.ts ***!
- \**************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", { value: true });
-const Texture2d_1 = __webpack_require__(/*! ./Texture2d */ "./src/application/Graphics/Textures/Texture2d.ts");
-class TextureService {
- constructor() {
- console.log('constructing texture service');
- this.textures = new Array();
- }
- GetTexture(textureId) {
- for (let i = 0; i < this.textures.length; i++) {
- if (textureId === this.textures[i].GetId()) {
- return this.textures[i];
- }
- }
- }
- /**
- * registers a new texture in the service. If the texture already
- * exists, throws an error and returns the existing one
- *
- * @param {string} texturePath
- * @returns {string}
- * @memberof TextureService
- */
- RegisterNewTexture(texturePath) {
- for (let i = 0; i < this.textures.length; i++) {
- const thisTextPath = this.textures[i].GetPath();
- if (thisTextPath === texturePath) {
- console.error('attempted to create a texture a second time');
- return this.textures[i].GetId();
- }
- }
- const newTexture = new Texture2d_1.Texture2D(texturePath);
- this.textures.push(newTexture);
- console.warn(`texture stack is now [${this.textures.length}] long`);
- return newTexture.GetId();
- }
-}
-exports.TextureService = TextureService;
-
-
-/***/ }),
-
-/***/ "./src/application/Graphics/Tiles/TileTypes/GroundTileTypes/dirt.tiletype.ts":
-/*!***********************************************************************************!*\
- !*** ./src/application/Graphics/Tiles/TileTypes/GroundTileTypes/dirt.tiletype.ts ***!
- \***********************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", { value: true });
-const _base_tiletype_1 = __webpack_require__(/*! ../_base-tiletype */ "./src/application/Graphics/Tiles/TileTypes/_base-tiletype.ts");
-class DirtTileType extends _base_tiletype_1.TileType {
- constructor(id, textId) {
- super(id, '#916D49', textId);
- }
-}
-DirtTileType.texturePath = '/Tiles/ground/dirt.png';
-exports.DirtTileType = DirtTileType;
-
-
-/***/ }),
-
-/***/ "./src/application/Graphics/Tiles/TileTypes/GroundTileTypes/grass.tiletype.ts":
-/*!************************************************************************************!*\
- !*** ./src/application/Graphics/Tiles/TileTypes/GroundTileTypes/grass.tiletype.ts ***!
- \************************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", { value: true });
-const _base_tiletype_1 = __webpack_require__(/*! ../_base-tiletype */ "./src/application/Graphics/Tiles/TileTypes/_base-tiletype.ts");
-class GrassTileType extends _base_tiletype_1.TileType {
- constructor(id, textId) {
- super(id, '#438337', textId);
- }
-}
-GrassTileType.texturePath = '/Tiles/ground/grass.png';
-exports.GrassTileType = GrassTileType;
-class GrassTileTypeDirt extends _base_tiletype_1.TileType {
- constructor(id, textId) {
- super(id, '#87CC6F', textId);
- }
-}
-GrassTileTypeDirt.texturePath = '/Tiles/ground/grass_with_dirt_middle.png';
-exports.GrassTileTypeDirt = GrassTileTypeDirt;
-class GrassTileTypeDirtTop extends _base_tiletype_1.TileType {
- constructor(id, textId) {
- super(id, '#438337', textId);
- }
-}
-GrassTileTypeDirtTop.texturePath = '/Tiles/ground/grass_with_dirt_top.png';
-exports.GrassTileTypeDirtTop = GrassTileTypeDirtTop;
-class GrassTileTypeDirtRight extends _base_tiletype_1.TileType {
- constructor(id, textId) {
- super(id, '#438337', textId);
- }
-}
-GrassTileTypeDirtRight.texturePath = '/Tiles/ground/grass_with_dirt_right.png';
-exports.GrassTileTypeDirtRight = GrassTileTypeDirtRight;
-class GrassTileTypeDirtBottom extends _base_tiletype_1.TileType {
- constructor(id, textId) {
- super(id, '#438337', textId);
- }
-}
-GrassTileTypeDirtBottom.texturePath = '/Tiles/ground/grass_with_dirt_bottom.png';
-exports.GrassTileTypeDirtBottom = GrassTileTypeDirtBottom;
-class GrassTileTypeDirtLeft extends _base_tiletype_1.TileType {
- constructor(id, textId) {
- super(id, '#438337', textId);
- }
-}
-GrassTileTypeDirtLeft.texturePath = '/Tiles/ground/grass_with_dirt_left.png';
-exports.GrassTileTypeDirtLeft = GrassTileTypeDirtLeft;
-class GrassTileTypeDirtMiddle extends _base_tiletype_1.TileType {
- constructor(id, textId) {
- super(id, '#438337', textId);
- }
-}
-GrassTileTypeDirtMiddle.texturePath = '/Tiles/ground/grass_with_dirt_middle.png';
-exports.GrassTileTypeDirtMiddle = GrassTileTypeDirtMiddle;
-
-
-/***/ }),
-
-/***/ "./src/application/Graphics/Tiles/TileTypes/GroundTileTypes/sand.tiletype.ts":
-/*!***********************************************************************************!*\
- !*** ./src/application/Graphics/Tiles/TileTypes/GroundTileTypes/sand.tiletype.ts ***!
- \***********************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", { value: true });
-const _base_tiletype_1 = __webpack_require__(/*! ../_base-tiletype */ "./src/application/Graphics/Tiles/TileTypes/_base-tiletype.ts");
-class SandTileType extends _base_tiletype_1.TileType {
- constructor(id, textId) {
- super(id, '#C1C128', textId);
- }
-}
-SandTileType.texturePath = '/Tiles/ground/sand.png';
-exports.SandTileType = SandTileType;
-class SandTileTypeGrassTop extends _base_tiletype_1.TileType {
- constructor(id, textId) {
- super(id, '#C1C128', textId);
- }
-}
-SandTileTypeGrassTop.texturePath = '/Tiles/ground/sand_grass_top.png';
-exports.SandTileTypeGrassTop = SandTileTypeGrassTop;
-class SandTileTypeGrassRight extends _base_tiletype_1.TileType {
- constructor(id, textId) {
- super(id, '#C1C128', textId);
- }
-}
-SandTileTypeGrassRight.texturePath = '/Tiles/ground/sand_grass_right.png';
-exports.SandTileTypeGrassRight = SandTileTypeGrassRight;
-class SandTileTypeGrassBottom extends _base_tiletype_1.TileType {
- constructor(id, textId) {
- super(id, '#C1C128', textId);
- }
-}
-SandTileTypeGrassBottom.texturePath = '/Tiles/ground/sand_grass_bottom.png';
-exports.SandTileTypeGrassBottom = SandTileTypeGrassBottom;
-class SandTileTypeGrassLeft extends _base_tiletype_1.TileType {
- constructor(id, textId) {
- super(id, '#C1C128', textId);
- }
-}
-SandTileTypeGrassLeft.texturePath = '/Tiles/ground/sand_grass_left.png';
-exports.SandTileTypeGrassLeft = SandTileTypeGrassLeft;
-
-
-/***/ }),
-
-/***/ "./src/application/Graphics/Tiles/TileTypes/GroundTileTypes/shallow-water.tiletype.ts":
-/*!********************************************************************************************!*\
- !*** ./src/application/Graphics/Tiles/TileTypes/GroundTileTypes/shallow-water.tiletype.ts ***!
- \********************************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", { value: true });
-const _base_tiletype_1 = __webpack_require__(/*! ../_base-tiletype */ "./src/application/Graphics/Tiles/TileTypes/_base-tiletype.ts");
-class ShallowWaterTileType extends _base_tiletype_1.TileType {
- constructor(id, textId) {
- super(id, '#4380E4', textId);
- }
-}
-ShallowWaterTileType.texturePath = '/Tiles/ground/shallow_water.png';
-exports.ShallowWaterTileType = ShallowWaterTileType;
-class ShallowWaterTileTypeSandTop extends _base_tiletype_1.TileType {
- constructor(id, textId) {
- super(id, '#4380E4', textId);
- }
-}
-ShallowWaterTileTypeSandTop.texturePath = '/Tiles/ground/shallow_water_sand_top.png';
-exports.ShallowWaterTileTypeSandTop = ShallowWaterTileTypeSandTop;
-class ShallowWaterTileTypeSandRight extends _base_tiletype_1.TileType {
- constructor(id, textId) {
- super(id, '#4380E4', textId);
- }
-}
-ShallowWaterTileTypeSandRight.texturePath = '/Tiles/ground/shallow_water_sand_right.png';
-exports.ShallowWaterTileTypeSandRight = ShallowWaterTileTypeSandRight;
-class ShallowWaterTileTypeSandBottom extends _base_tiletype_1.TileType {
- constructor(id, textId) {
- super(id, '#4380E4', textId);
- }
-}
-ShallowWaterTileTypeSandBottom.texturePath = '/Tiles/ground/shallow_water_sand_bottom.png';
-exports.ShallowWaterTileTypeSandBottom = ShallowWaterTileTypeSandBottom;
-class ShallowWaterTileTypeSandLeft extends _base_tiletype_1.TileType {
- constructor(id, textId) {
- super(id, '#4380E4', textId);
- }
-}
-ShallowWaterTileTypeSandLeft.texturePath = '/Tiles/ground/shallow_water_sand_left.png';
-exports.ShallowWaterTileTypeSandLeft = ShallowWaterTileTypeSandLeft;
-
-
-/***/ }),
-
-/***/ "./src/application/Graphics/Tiles/TileTypes/GroundTileTypes/stone.tiletype.ts":
-/*!************************************************************************************!*\
- !*** ./src/application/Graphics/Tiles/TileTypes/GroundTileTypes/stone.tiletype.ts ***!
- \************************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", { value: true });
-const _base_tiletype_1 = __webpack_require__(/*! ../_base-tiletype */ "./src/application/Graphics/Tiles/TileTypes/_base-tiletype.ts");
-class StoneTileType extends _base_tiletype_1.TileType {
- constructor(id, textId) {
- super(id, '#52504F', textId);
- }
-}
-StoneTileType.texturePath = '/Tiles/ground/stone.png';
-exports.StoneTileType = StoneTileType;
-
-
-/***/ }),
-
-/***/ "./src/application/Graphics/Tiles/TileTypes/SpaceTileTypes/space.tiletype.ts":
-/*!***********************************************************************************!*\
- !*** ./src/application/Graphics/Tiles/TileTypes/SpaceTileTypes/space.tiletype.ts ***!
- \***********************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", { value: true });
-const _base_tiletype_1 = __webpack_require__(/*! ../_base-tiletype */ "./src/application/Graphics/Tiles/TileTypes/_base-tiletype.ts");
-class SpaceTileType extends _base_tiletype_1.TileType {
- constructor(id, textId) {
- super(id, '#1C1C1B', textId);
- }
-}
-SpaceTileType.texturePath = '/Tiles/space_tile.png';
-exports.SpaceTileType = SpaceTileType;
-
-
-/***/ }),
-
-/***/ "./src/application/Graphics/Tiles/TileTypes/SpaceTileTypes/star.tiletype.ts":
-/*!**********************************************************************************!*\
- !*** ./src/application/Graphics/Tiles/TileTypes/SpaceTileTypes/star.tiletype.ts ***!
- \**********************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", { value: true });
-const _base_tiletype_1 = __webpack_require__(/*! ../_base-tiletype */ "./src/application/Graphics/Tiles/TileTypes/_base-tiletype.ts");
-class StarTileType extends _base_tiletype_1.TileType {
- constructor(id, textId) {
- super(id, '#060948', textId);
- }
-}
-StarTileType.texturePath = '/Tiles/space_tile2.png';
-exports.StarTileType = StarTileType;
-
-
-/***/ }),
-
-/***/ "./src/application/Graphics/Tiles/TileTypes/_base-tiletype.ts":
-/*!********************************************************************!*\
- !*** ./src/application/Graphics/Tiles/TileTypes/_base-tiletype.ts ***!
- \********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", { value: true });
-class TileType {
- constructor(id, fallbackOutlineColour, textureId) {
- this.textureId = textureId;
- this.id = id;
- this.fallbackOutlineColour = fallbackOutlineColour;
- }
- Tick() {
- }
- GetTextureId() {
- return this.textureId;
- }
- GetId() {
- return this.id;
- }
- GetFallbackColour() {
- return this.fallbackOutlineColour;
- }
-}
-exports.TileType = TileType;
-
-
-/***/ }),
-
-/***/ "./src/application/Graphics/Tiles/drawable-tile.ts":
-/*!*********************************************************!*\
- !*** ./src/application/Graphics/Tiles/drawable-tile.ts ***!
- \*********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", { value: true });
-const drawable_1 = __webpack_require__(/*! ../Draw/drawable */ "./src/application/Graphics/Draw/drawable.ts");
-class DrawableTile extends drawable_1.Drawable {
- constructor(tileTypeId, position, size, fallbackOutlineColour, canvasId, textureId) {
- super(position, size, canvasId, textureId);
- this.tileTypeId = tileTypeId;
- this.colour = fallbackOutlineColour;
- }
- getTileTypeId() {
- return this.tileTypeId;
- }
- getPosition() {
- return this.position;
- }
- getSize() {
- return this.size;
- }
-}
-exports.DrawableTile = DrawableTile;
-
-
-/***/ }),
-
-/***/ "./src/application/Graphics/Tiles/tile.default.settings.ts":
-/*!*****************************************************************!*\
- !*** ./src/application/Graphics/Tiles/tile.default.settings.ts ***!
- \*****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", { value: true });
-const Vector2_model_1 = __webpack_require__(/*! ../../../numerics/models/Vector2.model */ "./src/numerics/models/Vector2.model.ts");
-class TileDefaultSettings {
-}
-TileDefaultSettings.DEFAULT_SIZE = new Vector2_model_1.Vector2(64, 64);
-exports.TileDefaultSettings = TileDefaultSettings;
-
-
-/***/ }),
-
-/***/ "./src/application/Graphics/Tiles/tile.service.ts":
-/*!********************************************************!*\
- !*** ./src/application/Graphics/Tiles/tile.service.ts ***!
- \********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", { value: true });
-const space_tiletype_1 = __webpack_require__(/*! ./TileTypes/SpaceTileTypes/space.tiletype */ "./src/application/Graphics/Tiles/TileTypes/SpaceTileTypes/space.tiletype.ts");
-const Vector2_model_1 = __webpack_require__(/*! ../../../numerics/models/Vector2.model */ "./src/numerics/models/Vector2.model.ts");
-const tile_default_settings_1 = __webpack_require__(/*! ./tile.default.settings */ "./src/application/Graphics/Tiles/tile.default.settings.ts");
-const drawable_tile_1 = __webpack_require__(/*! ./drawable-tile */ "./src/application/Graphics/Tiles/drawable-tile.ts");
-const grass_tiletype_1 = __webpack_require__(/*! ./TileTypes/GroundTileTypes/grass.tiletype */ "./src/application/Graphics/Tiles/TileTypes/GroundTileTypes/grass.tiletype.ts");
-const star_tiletype_1 = __webpack_require__(/*! ./TileTypes/SpaceTileTypes/star.tiletype */ "./src/application/Graphics/Tiles/TileTypes/SpaceTileTypes/star.tiletype.ts");
-const dirt_tiletype_1 = __webpack_require__(/*! ./TileTypes/GroundTileTypes/dirt.tiletype */ "./src/application/Graphics/Tiles/TileTypes/GroundTileTypes/dirt.tiletype.ts");
-const sand_tiletype_1 = __webpack_require__(/*! ./TileTypes/GroundTileTypes/sand.tiletype */ "./src/application/Graphics/Tiles/TileTypes/GroundTileTypes/sand.tiletype.ts");
-const shallow_water_tiletype_1 = __webpack_require__(/*! ./TileTypes/GroundTileTypes/shallow-water.tiletype */ "./src/application/Graphics/Tiles/TileTypes/GroundTileTypes/shallow-water.tiletype.ts");
-const stone_tiletype_1 = __webpack_require__(/*! ./TileTypes/GroundTileTypes/stone.tiletype */ "./src/application/Graphics/Tiles/TileTypes/GroundTileTypes/stone.tiletype.ts");
-class TileService {
- constructor(canvasService, graphicsService) {
- this.tileSize = tile_default_settings_1.TileDefaultSettings.DEFAULT_SIZE;
- this.tileTypes = new Array(256);
- this.tiles = new Array();
- this.graphicsService = graphicsService;
- this.canvasService = canvasService;
- }
- Init() {
- this.tileCanvasId = this.canvasService.RegisterNewCanvas();
- this.spaceTileType = new space_tiletype_1.SpaceTileType(0, this.graphicsService.GetTextureService().RegisterNewTexture(space_tiletype_1.SpaceTileType.texturePath));
- this.starTileType = new star_tiletype_1.StarTileType(1, this.graphicsService.GetTextureService().RegisterNewTexture(star_tiletype_1.StarTileType.texturePath));
- this.grassTileType = new grass_tiletype_1.GrassTileType(2, this.graphicsService.GetTextureService().RegisterNewTexture(grass_tiletype_1.GrassTileType.texturePath));
- this.grassTileTypeDirt = new grass_tiletype_1.GrassTileTypeDirt(3, this.graphicsService.GetTextureService().RegisterNewTexture(grass_tiletype_1.GrassTileTypeDirt.texturePath));
- this.grassTileTypeDirtTop = new grass_tiletype_1.GrassTileTypeDirtTop(4, this.graphicsService.GetTextureService().RegisterNewTexture(grass_tiletype_1.GrassTileTypeDirtTop.texturePath));
- this.grassTileTypeDirtRight = new grass_tiletype_1.GrassTileTypeDirtRight(5, this.graphicsService.GetTextureService().RegisterNewTexture(grass_tiletype_1.GrassTileTypeDirtRight.texturePath));
- this.grassTileTypeBottom = new grass_tiletype_1.GrassTileTypeDirtBottom(6, this.graphicsService.GetTextureService().RegisterNewTexture(grass_tiletype_1.GrassTileTypeDirtBottom.texturePath));
- this.grassTileTypeLeft = new grass_tiletype_1.GrassTileTypeDirtLeft(7, this.graphicsService.GetTextureService().RegisterNewTexture(grass_tiletype_1.GrassTileTypeDirtLeft.texturePath));
- this.grassTileTypeMiddle = new grass_tiletype_1.GrassTileTypeDirtMiddle(8, this.graphicsService.GetTextureService().RegisterNewTexture(grass_tiletype_1.GrassTileTypeDirtMiddle.texturePath));
- this.dirtTileType = new dirt_tiletype_1.DirtTileType(9, this.graphicsService.GetTextureService().RegisterNewTexture(dirt_tiletype_1.DirtTileType.texturePath));
- this.stoneTileType = new stone_tiletype_1.StoneTileType(10, this.graphicsService.GetTextureService().RegisterNewTexture(stone_tiletype_1.StoneTileType.texturePath));
- this.sandTileType = new sand_tiletype_1.SandTileType(11, this.graphicsService.GetTextureService().RegisterNewTexture(sand_tiletype_1.SandTileType.texturePath));
- this.sandTileTypeDirtTop = new sand_tiletype_1.SandTileTypeGrassTop(12, this.graphicsService.GetTextureService().RegisterNewTexture(sand_tiletype_1.SandTileTypeGrassTop.texturePath));
- this.sandTileTypeDirtRight = new sand_tiletype_1.SandTileTypeGrassRight(13, this.graphicsService.GetTextureService().RegisterNewTexture(sand_tiletype_1.SandTileTypeGrassRight.texturePath));
- this.sandTileTypeBottom = new sand_tiletype_1.SandTileTypeGrassBottom(14, this.graphicsService.GetTextureService().RegisterNewTexture(sand_tiletype_1.SandTileTypeGrassBottom.texturePath));
- this.sandTileTypeLeft = new sand_tiletype_1.SandTileTypeGrassLeft(15, this.graphicsService.GetTextureService().RegisterNewTexture(sand_tiletype_1.SandTileTypeGrassLeft.texturePath));
- this.shallowWaterTileType = new shallow_water_tiletype_1.ShallowWaterTileType(16, this.graphicsService.GetTextureService().RegisterNewTexture(shallow_water_tiletype_1.ShallowWaterTileType.texturePath));
- this.shallowWaterTileTypeDirtTop = new shallow_water_tiletype_1.ShallowWaterTileTypeSandTop(17, this.graphicsService.GetTextureService().RegisterNewTexture(shallow_water_tiletype_1.ShallowWaterTileTypeSandTop.texturePath));
- this.shallowWaterTileTypeDirtRight = new shallow_water_tiletype_1.ShallowWaterTileTypeSandRight(18, this.graphicsService.GetTextureService().RegisterNewTexture(shallow_water_tiletype_1.ShallowWaterTileTypeSandRight.texturePath));
- this.shallowWaterTileTypeBottom = new shallow_water_tiletype_1.ShallowWaterTileTypeSandBottom(19, this.graphicsService.GetTextureService().RegisterNewTexture(shallow_water_tiletype_1.ShallowWaterTileTypeSandBottom.texturePath));
- this.shallowWaterTileTypeLeft = new shallow_water_tiletype_1.ShallowWaterTileTypeSandLeft(20, this.graphicsService.GetTextureService().RegisterNewTexture(shallow_water_tiletype_1.ShallowWaterTileTypeSandLeft.texturePath));
- this.setupTileTypes();
- // this.setupTiles();
- }
- setupTileTypes() {
- this.tileTypes[this.spaceTileType.GetId()] = this.spaceTileType;
- this.tileTypes[this.starTileType.GetId()] = this.starTileType;
- this.tileTypes[this.grassTileType.GetId()] = this.grassTileType;
- this.tileTypes[this.grassTileTypeDirt.GetId()] = this.grassTileTypeDirt;
- this.tileTypes[this.grassTileTypeDirtTop.GetId()] = this.grassTileTypeDirtTop;
- this.tileTypes[this.grassTileTypeDirtRight.GetId()] = this.grassTileTypeDirtRight;
- this.tileTypes[this.grassTileTypeBottom.GetId()] = this.grassTileTypeBottom;
- this.tileTypes[this.grassTileTypeLeft.GetId()] = this.grassTileTypeLeft;
- this.tileTypes[this.grassTileTypeMiddle.GetId()] = this.grassTileTypeMiddle;
- this.tileTypes[this.dirtTileType.GetId()] = this.dirtTileType;
- this.tileTypes[this.stoneTileType.GetId()] = this.stoneTileType;
- this.tileTypes[this.sandTileType.GetId()] = this.sandTileType;
- this.tileTypes[this.sandTileTypeDirtTop.GetId()] = this.sandTileTypeDirtTop;
- this.tileTypes[this.sandTileTypeDirtRight.GetId()] = this.sandTileTypeDirtRight;
- this.tileTypes[this.sandTileTypeBottom.GetId()] = this.sandTileTypeBottom;
- this.tileTypes[this.sandTileTypeLeft.GetId()] = this.sandTileTypeLeft;
- this.tileTypes[this.shallowWaterTileType.GetId()] = this.shallowWaterTileType;
- this.tileTypes[this.shallowWaterTileTypeDirtTop.GetId()] = this.shallowWaterTileTypeDirtTop;
- this.tileTypes[this.shallowWaterTileTypeDirtRight.GetId()] = this.shallowWaterTileTypeDirtRight;
- this.tileTypes[this.shallowWaterTileTypeBottom.GetId()] = this.shallowWaterTileTypeBottom;
- this.tileTypes[this.shallowWaterTileTypeLeft.GetId()] = this.shallowWaterTileTypeLeft;
- }
- /**
- * returns a Vector 2 containing a size
- *
- * @param {number[][]} tiles
- * @returns {Vector2}
- * @memberof TileService
- */
- setupTilesFromArray(tiles) {
- const size = new Vector2_model_1.Vector2(0, 0);
- // const canvId = `${this.graphicsService.RegisterDrawableEntity('texts')}`;
- for (let x = 0; x < tiles.length; x++) {
- for (let y = 0; y < tiles[x].length; y++) {
- this.tiles.push(new drawable_tile_1.DrawableTile(tiles[x][y], new Vector2_model_1.Vector2(y * this.GetTileSize().getValueX(), x * this.GetTileSize().getValueY()), tile_default_settings_1.TileDefaultSettings.DEFAULT_SIZE, this.tileTypes[tiles[x][y]].GetFallbackColour(), this.tileCanvasId, this.tileTypes[tiles[x][y]].GetTextureId()));
- }
- }
- return size;
- }
- PreClearCanvas() {
- const canv = this.graphicsService.GetCanvas(this.tileCanvasId);
- canv.ClearCanvas();
- }
- Redner() {
- this.PreClearCanvas();
- for (let i = 0; i < this.tiles.length; i++) {
- this.graphicsService.getDrawingService().Draw(this.tiles[i], true);
- }
- }
- GetTileSize() {
- return this.tileSize;
- }
-}
-exports.TileService = TileService;
-
-
-/***/ }),
-
-/***/ "./src/application/Graphics/Viewport/Viewport.Helper.ts":
-/*!**************************************************************!*\
- !*** ./src/application/Graphics/Viewport/Viewport.Helper.ts ***!
- \**************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", { value: true });
-const Vector2_model_1 = __webpack_require__(/*! ../../../numerics/models/Vector2.model */ "./src/numerics/models/Vector2.model.ts");
-class ViewportHelper {
- static GetSquareInBrowser() {
- const h = this.GetBrowserHeight() - 5;
- const w = this.GetBrowserWidth() - 5;
- if (h < w) {
- return new Vector2_model_1.Vector2(h, h);
- }
- else {
- return new Vector2_model_1.Vector2(w, w);
- }
- }
- static GetWindowInAspectRatio(aspectRatioWidth = 16, aspectRatioHeight = 9, widthPercent = 1, heightPercent = 1) {
- const aspectRatio = aspectRatioWidth / aspectRatioHeight;
- const adjustedWindowHeight = this.GetBrowserHeight() * heightPercent;
- const adjustedWindowWidth = this.GetBrowserWidth() * widthPercent;
- const displayWidth = Math.min(adjustedWindowWidth, (adjustedWindowHeight * aspectRatio));
- const displayHeight = Math.min(adjustedWindowHeight, (adjustedWindowWidth / aspectRatio));
- return new Vector2_model_1.Vector2(displayWidth, displayHeight);
- }
- /**
- * Gets a window in a given aspect ratio.
- *
- * @static
- * @param {number} [aspectRatioWidth=16]
- * @param {number} [aspectRatioHeight=9]
- * @param {number} [widthPercent=1] between 0 & 1. Should usually be the same as heightPercent
- * @param {number} [heightPercent=1] between 0 & 1. Shoudl usually be the same as widthPercent
- * @param {string} elementId An element to put this canvas into. Can be null (will use the full window)
- * @returns {Vector2}
- * @memberof ViewportHelper
- * @returns {Vector2}
- * @memberof ViewportHelper
- */
- static GetWindowInAspectRatioForCanvas(aspectRatioWidth = 16, aspectRatioHeight = 9, widthPercent = 1, heightPercent = 1, canvasableElement = null) {
- if (!canvasableElement) {
- console.warn(`setup with no canvasable element. Will use the entire window`);
- }
- else {
- console.warn(`setup with id of ${canvasableElement.id}`);
- }
- const aspectRatio = aspectRatioWidth / aspectRatioHeight;
- if (heightPercent !== widthPercent) {
- console.warn('window height and width percentages to not match. This will result in an abnormal screen size');
- }
- if (aspectRatioHeight > aspectRatioWidth) {
- console.log(`starting in portrait mode (${aspectRatioWidth}:${aspectRatioHeight})`);
- }
- else {
- console.info(`starting in landscape mode (${aspectRatioWidth}:${aspectRatioHeight})`);
- }
- const adjustedWindowHeight = this.GetBrowserHeight(canvasableElement) * heightPercent;
- const adjustedWindowWidth = this.GetBrowserWidth(canvasableElement) * widthPercent;
- const displayWidth = Math.min(adjustedWindowWidth, (adjustedWindowHeight * aspectRatio));
- const displayHeight = Math.min(adjustedWindowHeight, (adjustedWindowWidth / aspectRatio));
- return new Vector2_model_1.Vector2(displayWidth, displayHeight);
- }
- static GetBrowserWidth(element = null) {
- if (!element) {
- return window.innerWidth;
- }
- else {
- return element.clientWidth;
- }
- }
- static GetBrowserHeight(element = null) {
- if (!element) {
- return window.innerHeight;
- }
- else {
- return element.clientHeight;
- }
- }
-}
-exports.ViewportHelper = ViewportHelper;
-
-
-/***/ }),
-
-/***/ "./src/application/Graphics/Viewport/viewport.service.ts":
-/*!***************************************************************!*\
- !*** ./src/application/Graphics/Viewport/viewport.service.ts ***!
- \***************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", { value: true });
-const Vector2_model_1 = __webpack_require__(/*! ../../../numerics/models/Vector2.model */ "./src/numerics/models/Vector2.model.ts");
-class ViewportService {
- constructor(aspectRatio = new Vector2_model_1.Vector2(16, 9), sizePercent = new Vector2_model_1.Vector2(1, 1)) {
- this.listeningForBrowserChanges = false;
- this.aspectRatio = aspectRatio;
- this.aspectRatioCalculated = (this.aspectRatio.getValueX() / this.aspectRatio.getValueY());
- this.sizePercent = sizePercent;
- this.setupListner();
- }
- setupListner() {
- console.log('setting up browser listner');
- this.listner = window.addEventListener('resize', () => {
- this.listeningForBrowserChanges = true;
- setTimeout(() => {
- this.listeningForBrowserChanges = false;
- }, 5000);
- });
- }
- /**
- *Gets a window in a the game's aspect ratio
- *
- * @param {HTMLElement} [canvasableElement=null]
- * @returns {Vector2}
- * @memberof ViewportService
- */
- GetWindowInAspectRatioForCanvas(canvasableElement = null) {
- if (!canvasableElement) {
- console.warn(`setup with no canvasable element. Will use the entire window`);
- }
- else {
- console.warn(`setup with id of ${canvasableElement.id}`);
- }
- if (this.sizePercent.getValueX() !== this.sizePercent.getValueY()) {
- console.warn('window height and width percentages to not match. This will result in an abnormal screen size');
- }
- if (this.aspectRatio.getValueX() > this.aspectRatio.getValueY()) {
- console.log(`starting in portrait mode (${this.aspectRatio.getValueX()}:${this.aspectRatio.getValueY()})`);
- }
- else {
- console.info(`starting in landscape mode (${this.aspectRatio.getValueX()}:${this.aspectRatio.getValueY()})`);
- }
- const adjustedWindowHeight = this.GetBrowserHeight(canvasableElement) * this.sizePercent.getValueX();
- const adjustedWindowWidth = this.GetBrowserWidth(canvasableElement) * this.sizePercent.getValueY();
- const displayWidth = Math.min(adjustedWindowWidth, (adjustedWindowHeight * this.aspectRatioCalculated));
- const displayHeight = Math.min(adjustedWindowHeight, (adjustedWindowWidth / this.aspectRatioCalculated));
- return new Vector2_model_1.Vector2(displayWidth, displayHeight);
- }
- GetSquareInBrowser() {
- const h = this.GetBrowserHeight() - 5;
- const w = this.GetBrowserWidth() - 5;
- if (h < w) {
- return new Vector2_model_1.Vector2(h, h);
- }
- else {
- return new Vector2_model_1.Vector2(w, w);
- }
- }
- GetWindowInAspectRatio() {
- const adjustedWindowHeight = this.GetBrowserHeight() * this.sizePercent.getValueX();
- const adjustedWindowWidth = this.GetBrowserWidth() * this.sizePercent.getValueY();
- const displayWidth = Math.min(adjustedWindowWidth, (adjustedWindowHeight * this.aspectRatioCalculated));
- const displayHeight = Math.min(adjustedWindowHeight, (adjustedWindowWidth / this.aspectRatioCalculated));
- return new Vector2_model_1.Vector2(displayWidth, displayHeight);
- }
- GetBrowserWidth(element = null) {
- if (!element) {
- return window.innerWidth;
- }
- else {
- return element.clientWidth;
- }
- }
- GetBrowserHeight(element = null) {
- if (!element) {
- return window.innerHeight;
- }
- else {
- return element.clientHeight;
- }
- }
- getBrowserSize() {
- return this.browserSize;
- }
- setBrowserSize(browserSize) {
- this.browserSize = browserSize;
- }
- getViewportSize() {
- return this.viewportSize;
- }
- setViewportSize(viewportSize) {
- this.viewportSize = viewportSize;
- }
-}
-exports.ViewportService = ViewportService;
-
-
-/***/ }),
-
-/***/ "./src/application/Graphics/graphics.service.ts":
-/*!******************************************************!*\
- !*** ./src/application/Graphics/graphics.service.ts ***!
- \******************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", { value: true });
-const graphics_html_service_1 = __webpack_require__(/*! ./Html/graphics.html.service */ "./src/application/Graphics/Html/graphics.html.service.ts");
-const graphics_canvas_service_1 = __webpack_require__(/*! ./Canvas/graphics.canvas.service */ "./src/application/Graphics/Canvas/graphics.canvas.service.ts");
-const tile_service_1 = __webpack_require__(/*! ./Tiles/tile.service */ "./src/application/Graphics/Tiles/tile.service.ts");
-const game_camera_service_1 = __webpack_require__(/*! ./Camera/game-camera.service */ "./src/application/Graphics/Camera/game-camera.service.ts");
-const drawing_service_1 = __webpack_require__(/*! ./Draw/drawing.service */ "./src/application/Graphics/Draw/drawing.service.ts");
-const texture_service_1 = __webpack_require__(/*! ./Textures/texture.service */ "./src/application/Graphics/Textures/texture.service.ts");
-class GraphicsService {
- constructor() {
- console.log('starting graphics service');
- this.htmlService = new graphics_html_service_1.HtmlService();
- this.canvasService = new graphics_canvas_service_1.CanvasService(this.htmlService);
- this.tileService = new tile_service_1.TileService(this.canvasService, this);
- this.textureService = new texture_service_1.TextureService();
- const applyCameraWorldBounding = false;
- this.gameCameraService = new game_camera_service_1.GameCameraService(0, 0, applyCameraWorldBounding);
- this.drawingService = new drawing_service_1.DrawingService(this.gameCameraService, this.canvasService, this.textureService);
- }
- InitGraphicsService() {
- this.htmlService.Init();
- this.canvasService.Init();
- this.tileService.Init();
- }
- GetTextureService() {
- return this.textureService;
- }
- GetTileService() {
- return this.tileService;
- }
- getGameCameraService() {
- return this.gameCameraService;
- }
- getDrawingService() {
- return this.drawingService;
- }
- RegisterDrawableEntity(id = null) {
- return this.canvasService.RegisterNewCanvas(id);
- }
- GetCanvas(id) {
- return this.canvasService.GetCanvas(id);
- }
- Render() {
- // console.log('rendering in graphics service');
- this.canvasService.mainCanvasCtx.clearRect(0, 0, this.canvasService.mainCanvas.width, this.canvasService.mainCanvas.height);
- for (let i = 0; i < this.canvasService.drawableAreas.length; i++) {
- this.canvasService.mainCanvasCtx.drawImage(this.canvasService.drawableAreas[i].canvas, 0, 0);
- }
- }
-}
-exports.GraphicsService = GraphicsService;
-
-
-/***/ }),
-
-/***/ "./src/application/Input/InputManager.ts":
-/*!***********************************************!*\
- !*** ./src/application/Input/InputManager.ts ***!
- \***********************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", { value: true });
-const input_state_1 = __webpack_require__(/*! ./input-state */ "./src/application/Input/input-state.ts");
-class InputManager {
- constructor() {
- this.gamePads = Array();
- this.inputState = new input_state_1.InputState();
- this.currentInputs = new Array();
- this.gamePads = new Array();
- }
- /**
- * sets up the input manager
- *
- * @memberof InputManager
- */
- InitInputManager() {
- this.inputState.Init();
- // return;
- }
- /**
- * checks for new inputs. Should be called in a loop
- *
- * @memberof InputManager
- */
- NewInputLoopCheck() {
- this.inputState.UpdateInputs();
- // throw new Error("Method not implemented.");
- }
- // private RegisterGamePad(pad: Gamepad) {
- // console.warn('gamepad registered');
- // console.warn("Gamepad: connected at index %d: %s. %d buttons, %d axes.",
- // pad.index, pad.id,
- // pad.buttons.length, pad.axes.length);
- // this.gamePads = navigator.getGamepads();
- // // this.gamePads.push(pad); // = navigator.getGamepads ? navigator.getGamepads() : (navigator.getGamepads ? navigator.getGamepads : []);
- // for (let i = 0; i < this.gamePads.length; i++) {
- // const thisGp = this.gamePads[i];
- // if (thisGp) {
- // this.detailsDiv.innerHTML = "Gamepad connected at index " + thisGp.index + ": " + thisGp.id +
- // ". It has " + thisGp.buttons.length + " buttons and " + thisGp.axes.length + " axes.";
- // }
- // }
- // }
- // private DeRegisterGamePad(pad: Gamepad) {
- // console.warn('deregistering gamepad');
- // delete this.gamePads[pad.index];
- // this.ReportToHtml("gamepad DC");
- // }
- /**
- * public method to check if a key is pressed or not
- *
- * @param {string} key
- * @returns
- * @memberof InputManager
- */
- IsKeyPressed(inputDescription) {
- return this.inputState.IsInputPressed(inputDescription);
- }
- /**
- * gets the force value for a given input. If it's in
- * keyboard mode, then it just returns 0 or 1
- *
- * If it's in keyboard mode, then it returns a value of -1.0 to +1.0
- *
- * @param {string} inputDescription
- * @returns {number}
- * @memberof InputManager
- */
- GetForceValue(inputDescription) {
- return this.inputState.GetForceValue(inputDescription);
- }
-}
-InputManager.validInputs = ['w', 'a', 's', 'd', ' '];
-exports.InputManager = InputManager;
-
-
-/***/ }),
-
-/***/ "./src/application/Input/input-state.ts":
-/*!**********************************************!*\
- !*** ./src/application/Input/input-state.ts ***!
- \**********************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", { value: true });
-const input_model_1 = __webpack_require__(/*! ./input.model */ "./src/application/Input/input.model.ts");
-class InputState {
- constructor() {
- this.controllingWithPad = false;
- console.log('inputState: constructing input state');
- this.detailsDiv = document.getElementById('details_div');
- this.registeredGamePads = new Array();
- this.gamePads = new Array();
- }
- Init() {
- console.log('inputState: init inputstate');
- this.setupInputs();
- this.SetupGamePadRegistrationWatch();
- this.SetupKeyboardInputWatch();
- this.SetGamePadMode(false);
- }
- SetGamePadMode(controllingWithPad) {
- this.controllingWithPad = controllingWithPad;
- if (controllingWithPad) {
- this.detailsDiv.innerHTML = 'controlling with gamepad. Press >> k << to use keyboard mode';
- }
- else {
- this.detailsDiv.innerHTML = 'controlling with keyboard. Press >> select << to use gamepad mode';
- }
- }
- GetGamePadMode() {
- return this.controllingWithPad;
- }
- /**
- * // https://w3c.github.io/gamepad/#remapping
- *
- * @memberof InputState
- */
- setupInputs() {
- this.currentInputs = new Array();
- this.currentInputs.push(new input_model_1.Input('direction_left', 'a', 14, null), new input_model_1.Input('direction_right', 'd', 15, null), new input_model_1.Input('direction_up', 'w', 12, null), new input_model_1.Input('direction_down', 's', 13, null), new input_model_1.Input('axes_pad_left_horizontal', null, null, 0), new input_model_1.Input('axes_pad_left_vertical', null, null, 1), new input_model_1.Input('axes_pad_right_horizontal', null, null, 2), new input_model_1.Input('axes_pad_right_vertical', null, null, 3), new input_model_1.Input('trigger_one_left', 'q', 4, null), new input_model_1.Input('trigger_two_left', 'w', 6, null), new input_model_1.Input('trigger_one_right', 'e', 5, null), new input_model_1.Input('trigger_two_right', 's', 7, null),
- // 'action_{val}' where {val} is the
- // name of the button on an XBox360 controller
- new input_model_1.Input('action_a', ' ', 0, null), new input_model_1.Input('action_y', 'z', 3, null), new input_model_1.Input('action_x', 'x', 2, null), new input_model_1.Input('action_b', 'c', 1, null));
- }
- UpdateInputs() {
- // console.log('inputstate: updating inputs. There are ' + this.registeredGamePads.length + ' pads connected')
- this.UpdateGamePadInputs();
- }
- ResetInputsBeforeGamePadInput() {
- for (let input of this.currentInputs) {
- input.wasPressedPreviousCheck = input.pressed;
- input.pressed = false;
- }
- }
- UpdateGamePadInputs() {
- for (let i = 0; i < this.registeredGamePads.length; i++) {
- const padToCheck = this.GetGamePad(i);
- if (this.GetGamePadMode()) {
- this.ResetInputsBeforeGamePadInput();
- for (let btnIndex = 0; btnIndex < padToCheck.buttons.length; btnIndex++) {
- if (this.gamePadButtonPressed(padToCheck.buttons[btnIndex])) {
- this.pushToCurrentInputsFromGamePad(btnIndex, padToCheck.buttons[btnIndex].value);
- // console.log(`inputstate: btn ${btnIndex} is pressed`)
- }
- }
- for (let axesIndex = 0; axesIndex < padToCheck.axes.length; axesIndex++) {
- if (this.gamePadAxesPressed(padToCheck.axes[axesIndex])) {
- this.pushToCurrentInputsFromGamePadAxes(axesIndex, padToCheck.axes[axesIndex]);
- }
- }
- }
- else {
- if (this.gamePadButtonPressed(padToCheck.buttons[8])) {
- console.warn('inputstate: in gamepad mode');
- this.SetGamePadMode(true);
- }
- }
- }
- }
- IsInputPressed(inputDescription) {
- for (let input of this.currentInputs) {
- if (input.name === inputDescription) {
- return input.pressed;
- }
- }
- return false;
- }
- GetForceValue(inputDescription) {
- for (let input of this.currentInputs) {
- if (input.name === inputDescription) {
- return input.force;
- }
- }
- return 0;
- }
- /**
- * checks if this key is in the SYSTEM_KEYS array
- * (includes keys like F1 - F12)
- *
- * @private
- * @param {string} key
- * @returns
- * @memberof InputState
- */
- isSystemKey(key) {
- if (InputState.SYSTEM_KEYS.includes(key)) {
- return true;
- }
- return false;
- }
- SetupKeyboardInputWatch() {
- window.addEventListener('keydown', event => {
- if (!this.isSystemKey(event.key)) {
- event.preventDefault();
- this.pushToCurrentInputsFromKeyboard(event.key);
- }
- });
- window.addEventListener('keyup', event => {
- if (!this.isSystemKey(event.key)) {
- event.preventDefault();
- this.popFromCurrentInputsFromKeyboard(event.key);
- if (event.key === 'k') {
- console.warn(`inputstate: controlling by keyboard`);
- this.SetGamePadMode(false);
- }
- }
- });
- }
- pushToCurrentInputsFromKeyboard(key) {
- if (this.GetGamePadMode() === false) {
- for (let thisInput of this.currentInputs) {
- if (thisInput.keyboardId === key) {
- thisInput.pressed = true;
- thisInput.force = 1;
- // console.log(`inputstate marked ${thisInput.name} as pressed with force ${thisInput.force}`)
- return;
- }
- }
- }
- }
- popFromCurrentInputsFromKeyboard(key) {
- if (this.GetGamePadMode() === false) {
- for (let input of this.currentInputs) {
- if (input.keyboardId === key) {
- input.pressed = false;
- // console.log(`inputstate marked ${input.name} as pressed`)
- return;
- }
- }
- }
- }
- pushToCurrentInputsFromGamePad(btnId, pushForce) {
- for (let thisInput of this.currentInputs) {
- if (thisInput.gamepadId === btnId) {
- thisInput.pressed = true;
- thisInput.force = pushForce;
- // console.log(`inputstate marked ${thisInput.name} as pressed with force ${thisInput.force}`)
- return;
- }
- }
- }
- pushToCurrentInputsFromGamePadAxes(axesIndex, pushForce) {
- for (let thisInput of this.currentInputs) {
- if (thisInput.gamePadAxesId === axesIndex) {
- thisInput.pressed = true;
- thisInput.force = pushForce;
- // console.log(`inputstate marked ${thisInput.name} as pressed with force ${thisInput.force}`)
- return;
- }
- }
- }
- popFromCurrentInputsFromGamePad(btnId) {
- for (let input of this.currentInputs) {
- if (input.gamepadId === btnId) {
- input.pressed = false;
- // console.log(`inputstate marked ${input.name} as not`)
- return;
- }
- }
- }
- /* GamePad code */
- /**
- * watches for the game pad registration events
- *
- * @memberof InputState
- */
- SetupGamePadRegistrationWatch() {
- console.log('inputstate setting up registrations');
- window.addEventListener('gamepadconnected', (e) => {
- console.log('inputstate got gamepad');
- this.RegisterGamePad(e.gamepad);
- });
- window.addEventListener('gamepaddisconnected', (e) => {
- console.error('inputstate gamepad was disconnected');
- this.DeRegisterGamePad(e.gamepad);
- });
- }
- RegisterGamePad(gamePad) {
- console.warn("inputstate: Gamepad: connected at index %d: %s. %d buttons, %d axes.", gamePad.index, gamePad.id, gamePad.buttons.length, gamePad.axes.length);
- this.registeredGamePads[gamePad.index] = gamePad;
- this.detailsDiv.innerHTML = 'Gamepad has been connected';
- }
- DeRegisterGamePad(gamePad) {
- console.error("inputstate: Gamepad: connected at index %d: %s. %d buttons, %d axes.", gamePad.index, gamePad.id, gamePad.buttons.length, gamePad.axes.length);
- this.GetGamePads();
- this.detailsDiv.innerHTML = 'inputstate: Gamepad has been disconnected';
- }
- GetGamePads() {
- this.gamePads = navigator.getGamepads();
- }
- GetGamePad(index) {
- return navigator.getGamepads()[index];
- }
- gamePadAxesPressed(axes) {
- return (axes > InputState.DEFAULT_MIN_JOYSTICK_SENSITIVITY || axes < -InputState.DEFAULT_MIN_JOYSTICK_SENSITIVITY);
- }
- gamePadButtonPressed(btn) {
- // console.log(typeof(btn));
- if (typeof (btn) === 'object') {
- // firefox
- // console.log('gamepad: ff')
- if (btn.pressed) {
- // console.log('inputstate: button is pressed')
- }
- return btn.value;
- }
- else {
- // console.log('inputstate: gamepad: chrome')
- return btn === 1.0;
- }
- }
-}
-InputState.SYSTEM_KEYS = [
- 'F1',
- 'F2',
- 'F3',
- 'F4',
- 'F5',
- 'F6',
- 'F7',
- 'F8',
- 'F9',
- 'F10',
- 'F11',
- 'F12',
-];
-InputState.DEFAULT_MAX_INPUTS = 4;
-InputState.DEFAULT_MIN_JOYSTICK_SENSITIVITY = 0.1;
-exports.InputState = InputState;
-
-
-/***/ }),
-
-/***/ "./src/application/Input/input.model.ts":
-/*!**********************************************!*\
- !*** ./src/application/Input/input.model.ts ***!
- \**********************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", { value: true });
-class Input {
- constructor(name, keyboardId, gamepadId, gamePadAxesId) {
- this.pressed = false;
- this.force = 0;
- this.wasPressedPreviousCheck = false;
- this.name = name;
- this.keyboardId = keyboardId;
- this.gamepadId = gamepadId;
- this.gamePadAxesId = gamePadAxesId;
- }
-}
-exports.Input = Input;
-
-
-/***/ }),
-
-/***/ "./src/application/States/GameState.ts":
-/*!*********************************************!*\
- !*** ./src/application/States/GameState.ts ***!
- \*********************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", { value: true });
-const _BaseState_1 = __webpack_require__(/*! ./_BaseState */ "./src/application/States/_BaseState.ts");
-class GameState extends _BaseState_1.BaseState {
- constructor(graphicsService) {
- super();
- this.graphicsService = graphicsService;
- console.log('constructing GameState');
- }
- Tick() {
- // console.error("Method not implemented.");
- // this.graphicsService.getGameCameraService().MoveCamera(1, 0);
- }
- Render() {
- // console.error("Method not implemented.");
- }
-}
-exports.GameState = GameState;
-
-
-/***/ }),
-
-/***/ "./src/application/States/MenuState.ts":
-/*!*********************************************!*\
- !*** ./src/application/States/MenuState.ts ***!
- \*********************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", { value: true });
-const _BaseState_1 = __webpack_require__(/*! ./_BaseState */ "./src/application/States/_BaseState.ts");
-class MenuState extends _BaseState_1.BaseState {
- constructor() {
- super();
- console.log(`constructing MenuState`);
- }
- Tick() {
- console.error("Method not implemented.");
- }
- Render() {
- console.error("Method not implemented.");
- }
-}
-exports.MenuState = MenuState;
-
-
-/***/ }),
-
-/***/ "./src/application/States/SettingsState.ts":
-/*!*************************************************!*\
- !*** ./src/application/States/SettingsState.ts ***!
- \*************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", { value: true });
-const _BaseState_1 = __webpack_require__(/*! ./_BaseState */ "./src/application/States/_BaseState.ts");
-class SettingsState extends _BaseState_1.BaseState {
- constructor() {
- super();
- console.log(`constructing SettingsState`);
- }
- Tick() {
- console.error("Method not implemented.");
- }
- Render() {
- console.error("Method not implemented.");
- }
-}
-exports.SettingsState = SettingsState;
-
-
-/***/ }),
-
-/***/ "./src/application/States/_BaseState.ts":
-/*!**********************************************!*\
- !*** ./src/application/States/_BaseState.ts ***!
- \**********************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", { value: true });
-class BaseState {
-}
-exports.BaseState = BaseState;
-
-
-/***/ }),
-
-/***/ "./src/application/States/state.service.ts":
-/*!*************************************************!*\
- !*** ./src/application/States/state.service.ts ***!
- \*************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", { value: true });
-class StateService {
- constructor() {
- this.currentState = null;
- }
- setState(state) {
- this.currentState = state;
- }
- GetState() {
- return this.currentState;
- }
-}
-exports.StateService = StateService;
-
-
-/***/ }),
-
-/***/ "./src/application/Tools/random_generators/random_guid.generator.ts":
-/*!**************************************************************************!*\
- !*** ./src/application/Tools/random_generators/random_guid.generator.ts ***!
- \**************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", { value: true });
-class GuidGenerator {
- /**
- * returns a new guid
- *
- * https://stackoverflow.com/a/2117523
- *
- * @export
- * @returns a guid
- */
- static NewGuid() {
- return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
- var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
- return v.toString(16);
- });
- }
-}
-exports.GuidGenerator = GuidGenerator;
-
-
-/***/ }),
-
-/***/ "./src/application/Tools/random_generators/random_number.generators.ts":
-/*!*****************************************************************************!*\
- !*** ./src/application/Tools/random_generators/random_number.generators.ts ***!
- \*****************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", { value: true });
-const Vector2_model_1 = __webpack_require__(/*! ../../../numerics/models/Vector2.model */ "./src/numerics/models/Vector2.model.ts");
-class RandomNumberGenerator {
- /**
- * Generates a random number
- *
- * @static
- * @param {number} min
- * @param {number} max
- * @returns {number}
- * @memberof RandomNumberGenerator
- */
- static GetRandomNumber(min, max) {
- return Math.floor(Math.random() * (max - min + 1) + min);
- }
- /**
- * generates a random Vector 2
- *
- * @static
- * @param {number} minX
- * @param {number} maxX
- * @param {number} minY
- * @param {number} maxY
- * @returns {Vector2}
- * @memberof RandomNumberGenerator
- */
- static GetRandomVector2(minX, maxX, minY, maxY) {
- return new Vector2_model_1.Vector2(this.GetRandomNumber(minX, maxX), this.GetRandomNumber(minY, maxY));
- }
-}
-exports.RandomNumberGenerator = RandomNumberGenerator;
-
-
-/***/ }),
-
-/***/ "./src/application/Tools/random_generators/random_string.generator.ts":
-/*!****************************************************************************!*\
- !*** ./src/application/Tools/random_generators/random_string.generator.ts ***!
- \****************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", { value: true });
-class RandomStringGenerator {
- static GetRandomHexColour() {
- return '#' + (Math.random() * 0xFFFFFF << 0).toString(16);
- }
-}
-exports.RandomStringGenerator = RandomStringGenerator;
-
-
-/***/ }),
-
-/***/ "./src/application/World/world.jsonfiles.ts":
-/*!**************************************************!*\
- !*** ./src/application/World/world.jsonfiles.ts ***!
- \**************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-var __importStar = (this && this.__importStar) || function (mod) {
- if (mod && mod.__esModule) return mod;
- var result = {};
- if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
- result["default"] = mod;
- return result;
-};
-Object.defineProperty(exports, "__esModule", { value: true });
-const json = __importStar(__webpack_require__(/*! ../../assets/_dist/Worlds/worlds.json */ "./src/assets/_dist/Worlds/worlds.json"));
-const world_1 = __webpack_require__(/*! ./world */ "./src/application/World/world.ts");
-const Vector2_model_1 = __webpack_require__(/*! ../../numerics/models/Vector2.model */ "./src/numerics/models/Vector2.model.ts");
-/**
- * this is in a different file because adding .json files
- * causes VSCode to only want to load .js imports, and not
- * .ts imports
- *
- * @export
- * @class WorldJsonFileLoader
- */
-class WorldJsonFileLoader {
- constructor() {
- }
- static GetWorlds() {
- const worldArr = new Array();
- for (let i = 0; i < this.worldCount; i++) {
- const world = json[i];
- worldArr.push(new world_1.World(new Vector2_model_1.Vector2(world.tiles.length, world.tiles[0].length), new Vector2_model_1.Vector2(world.start.x, world.start.y), world.tiles, world.worldId));
- }
- return worldArr;
- }
-}
-WorldJsonFileLoader.worldCount = 2;
-exports.WorldJsonFileLoader = WorldJsonFileLoader;
-
-
-/***/ }),
-
-/***/ "./src/application/World/world.service.ts":
-/*!************************************************!*\
- !*** ./src/application/World/world.service.ts ***!
- \************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", { value: true });
-const Vector2_model_1 = __webpack_require__(/*! ../../numerics/models/Vector2.model */ "./src/numerics/models/Vector2.model.ts");
-const world_jsonfiles_1 = __webpack_require__(/*! ./world.jsonfiles */ "./src/application/World/world.jsonfiles.ts");
-const AABB_model_1 = __webpack_require__(/*! ../../numerics/models/AABB.model */ "./src/numerics/models/AABB.model.ts");
-const vector2_helper_1 = __webpack_require__(/*! ../../numerics/helpers/vector2.helper */ "./src/numerics/helpers/vector2.helper.ts");
-class WorldService {
- constructor(tileService) {
- this.currentWorldId = 0;
- this.worlds = new Array();
- this.tileService = tileService;
- }
- Init() {
- this.worlds = world_jsonfiles_1.WorldJsonFileLoader.GetWorlds();
- console.log(`this.worlds = ${JSON.stringify(this.worlds)} length is ${this.worlds.length}`);
- console.info('setting current world to index 0');
- this.SetWorld(2);
- }
- SetWorld(index) {
- this.DeRegisterWorld();
- this.tileService.setupTilesFromArray(this.GetWorld(index).GetTiles());
- }
- GetWorldSize() {
- const tileSize = this.tileService.GetTileSize();
- this.size = vector2_helper_1.Vector2Helpers.MultiplyByScale(tileSize, 2);
- console.log(`this.size: ${this.size}`);
- const worldPosition = new Vector2_model_1.Vector2(0, 0);
- return new AABB_model_1.AABB(worldPosition, this.size);
- }
- DeRegisterWorld() {
- console.error(" DeRegisterWorld: Method not implemented.");
- }
- GetStartingPosition(worldIndex) {
- return this.worlds[worldIndex].GetStartingPosition();
- }
- GetWorld(index) {
- if (index > this.worlds.length) {
- throw new Error(`index [${index}] out of range of world array (length: ${this.worlds.length})`);
- }
- return this.worlds[0];
- }
-}
-exports.WorldService = WorldService;
-
-
-/***/ }),
-
-/***/ "./src/application/World/world.ts":
-/*!****************************************!*\
- !*** ./src/application/World/world.ts ***!
- \****************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", { value: true });
-const Vector2_model_1 = __webpack_require__(/*! ../../numerics/models/Vector2.model */ "./src/numerics/models/Vector2.model.ts");
-class World {
- constructor(area, spawn, tiles, id) {
- this.area = new Vector2_model_1.Vector2(20, 20);
- this.area = area;
- this.spawn = spawn;
- this.tiles = tiles;
- this.id = id;
- }
- GetTiles() {
- return this.tiles;
- }
- GetStartingPosition() {
- return this.spawn;
- }
- GetId() {
- return this.id;
- }
-}
-exports.World = World;
-
-
-/***/ }),
-
-/***/ "./src/application/_debug/debug.component.ts":
-/*!***************************************************!*\
- !*** ./src/application/_debug/debug.component.ts ***!
- \***************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", { value: true });
-class DebugComponent {
- constructor(debugService) {
- this.debugService = debugService;
- this._debugService = debugService;
- }
- InitDebugComponent(mainDivId) {
- this.createDebugDiv(mainDivId);
- this.tick();
- }
- createDebugDiv(parentElementId, id = 'el_debug_info') {
- if (this.debugService.IsInDebugMode()) {
- const mainDiv = document.getElementById(parentElementId);
- this.debugInfoElement = document.createElement('div');
- this.debugInfoElement.id = id;
- mainDiv.appendChild(this.debugInfoElement);
- for (let i = 0; i < 10; i++) {
- this.debugService.PushOrUpdateInDebugArray('Debug Info' + i, 'debug value');
- }
- // this.debugService.PopFromDebugArray('Debug Info')
- return this.debugInfoElement;
- }
- }
- tick() {
- // setTimeout(() => {
- // this.ticks++;
- // });
- requestAnimationFrame(() => {
- // console.log('updating debugger')
- this.Update();
- this.tick();
- });
- }
- Update() {
- // console.log(this.debugService.GetDebugInfo(), null, 2)
- let DebugsAsString = '';
- const debugInfoArray = this.debugService.GetDebugInfo();
- for (let i = 0; i < debugInfoArray.length; i++) {
- // DebugsAsString += this.GetTemplateForKvp(debugInfoArray[i]);
- }
- this.debugInfoElement.innerHTML = DebugsAsString;
- }
- GetTemplateForKvp(item) {
- throw new Error('not implemented');
- return `
-
-
- ${item.Key}
-
-
- ${JSON.stringify(item.Value)}
-
-
`;
- }
-}
-exports.DebugComponent = DebugComponent;
-
-
-/***/ }),
-
-/***/ "./src/application/_debug/debug.service.ts":
-/*!*************************************************!*\
- !*** ./src/application/_debug/debug.service.ts ***!
- \*************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", { value: true });
-const debuggable_items_model_1 = __webpack_require__(/*! ./debuggable-items.model */ "./src/application/_debug/debuggable-items.model.ts");
-class DebugService {
- constructor(inDebugMode = false) {
- console.warn(`starting debug service. inDebugMode [${inDebugMode}]`);
- this.inDebugMode = inDebugMode;
- this.DebugInfo = new debuggable_items_model_1.DebuggableItems();
- }
- IsInDebugMode() {
- return this.inDebugMode;
- }
- GetDebugInfo() {
- return this.DebugInfo.debugItems;
- }
- PushOrUpdateInDebugArray(key, value) {
- console.log(`adding item ${key} to debug array`);
- if (!this.checkForExisting(key)) {
- this.DebugInfo.debugItems.push(new debuggable_items_model_1.DebugKvp(key, value));
- return;
- }
- else {
- if (this.PopFromDebugArray(key)) {
- this.PushOrUpdateInDebugArray(key, value);
- console.info(`successfully updated [${key}] in debug KVP`);
- return;
- }
- }
- console.error(`attempted to push or update [${key}], but the item didn't exist in the KVP`);
- }
- PopFromDebugArray(key) {
- console.log(`removing item ${key} to debug array`);
- for (let i = 0; i < this.DebugInfo.debugItems.length; i++) {
- if (this.DebugInfo.debugItems[i].Key === key) {
- this.DebugInfo.debugItems.splice(i, 1);
- return;
- }
- }
- console.error(`attempted to remove [${key} from debug KVP, but it couldn't be found]`);
- return false;
- }
- checkForExisting(key) {
- return false;
- }
-}
-exports.DebugService = DebugService;
-
-
-/***/ }),
-
-/***/ "./src/application/_debug/debuggable-items.model.ts":
-/*!**********************************************************!*\
- !*** ./src/application/_debug/debuggable-items.model.ts ***!
- \**********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", { value: true });
-class DebuggableItems {
- constructor() {
- this.debugItems = new Array();
- }
-}
-exports.DebuggableItems = DebuggableItems;
-class DebugKvp {
- constructor(key, value) {
- this.Key = key;
- this.Value = value;
- }
-}
-exports.DebugKvp = DebugKvp;
-
-
-/***/ }),
-
-/***/ "./src/application/game.ts":
-/*!*********************************!*\
- !*** ./src/application/game.ts ***!
- \*********************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", { value: true });
-const InputManager_1 = __webpack_require__(/*! ./Input/InputManager */ "./src/application/Input/InputManager.ts");
-const debug_service_1 = __webpack_require__(/*! ./_debug/debug.service */ "./src/application/_debug/debug.service.ts");
-const debug_component_1 = __webpack_require__(/*! ./_debug/debug.component */ "./src/application/_debug/debug.component.ts");
-const Vector2_model_1 = __webpack_require__(/*! ../numerics/models/Vector2.model */ "./src/numerics/models/Vector2.model.ts");
-const GameState_1 = __webpack_require__(/*! ./States/GameState */ "./src/application/States/GameState.ts");
-const state_service_1 = __webpack_require__(/*! ./States/state.service */ "./src/application/States/state.service.ts");
-const MenuState_1 = __webpack_require__(/*! ./States/MenuState */ "./src/application/States/MenuState.ts");
-const SettingsState_1 = __webpack_require__(/*! ./States/SettingsState */ "./src/application/States/SettingsState.ts");
-const player_1 = __webpack_require__(/*! ./Entities/Creatures/player */ "./src/application/Entities/Creatures/player.ts");
-const graphics_service_1 = __webpack_require__(/*! ./Graphics/graphics.service */ "./src/application/Graphics/graphics.service.ts");
-const baddy_1 = __webpack_require__(/*! ./Entities/Creatures/baddy */ "./src/application/Entities/Creatures/baddy.ts");
-const random_string_generator_1 = __webpack_require__(/*! ./Tools/random_generators/random_string.generator */ "./src/application/Tools/random_generators/random_string.generator.ts");
-const random_number_generators_1 = __webpack_require__(/*! ./Tools/random_generators/random_number.generators */ "./src/application/Tools/random_generators/random_number.generators.ts");
-const world_service_1 = __webpack_require__(/*! ./World/world.service */ "./src/application/World/world.service.ts");
-const viewport_service_1 = __webpack_require__(/*! ./Graphics/Viewport/viewport.service */ "./src/application/Graphics/Viewport/viewport.service.ts");
-const player_service_1 = __webpack_require__(/*! ./Entities/player.service */ "./src/application/Entities/player.service.ts");
-const entity_service_1 = __webpack_require__(/*! ./Entities/entity.service */ "./src/application/Entities/entity.service.ts");
-const timer_service_1 = __webpack_require__(/*! ./Core/timer.service */ "./src/application/Core/timer.service.ts");
-class Game {
- constructor() {
- this.running = false;
- this.launchMessage = 'Start';
- this.performanceInfoDiv = document.getElementById('performance_div');
- this.performanceInfoDiv.innerHTML = `waiting for perf data`;
- this.viewportService = new viewport_service_1.ViewportService();
- const loadedInDebugMode = this.checkDebugModeFromQueryString();
- this.graphicsService = new graphics_service_1.GraphicsService();
- this.stateService = new state_service_1.StateService();
- this.debugService = new debug_service_1.DebugService(loadedInDebugMode);
- this.debugComponent = new debug_component_1.DebugComponent(this.debugService);
- this.inputManager = new InputManager_1.InputManager();
- this.timerService = new timer_service_1.TimerService(60);
- this.worldService = new world_service_1.WorldService(this.graphicsService.GetTileService());
- this.entityService = new entity_service_1.EntityService();
- this.playerService = new player_service_1.PlayerService();
- }
- Run() {
- console.log('Run called in game.ts');
- this.Init();
- this.running = true;
- this.Loop();
- }
- Init() {
- console.log(this.launchMessage + ' will now be posted to the document ');
- this.SetupStates();
- this.inputManager.InitInputManager();
- this.graphicsService.InitGraphicsService();
- this.worldService.Init();
- this.graphicsService.getGameCameraService().SetLevelAABB(this.worldService.GetWorldSize());
- this.registerEntities();
- // this.canvasManager.InitCanvasManager('main_div', this.gameEntities);
- if (this.debugService.IsInDebugMode()) {
- console.log('setting up with debug info');
- this.debugComponent.InitDebugComponent('main_div');
- }
- return this.launchMessage;
- }
- SetupStates() {
- this.gameState = new GameState_1.GameState(this.graphicsService);
- this.menuState = new MenuState_1.MenuState();
- this.settingsState = new SettingsState_1.SettingsState();
- this.stateService.setState(this.gameState);
- }
- /**
- * loops continuously whenever the browser is ready
- * for a new frame
- *
- * @memberof Game
- */
- Loop() {
- requestAnimationFrame(() => {
- if (this.running) {
- if (this.timerService.CheckShouldRunLoop()) {
- const lastDelta = this.timerService.GetLastUpdateTimeTook();
- this.Update(lastDelta);
- this.Render(lastDelta);
- this.timerService.UpdateTicksAndRenderAfterLoop();
- }
- this.PrintDebugInfoToConsole(false, true);
- this.timerService.ResetTimers();
- }
- this.Loop();
- });
- }
- /**
- * prints debug info from various places in the
- * application
- *
- * @private
- * @memberof Game
- */
- PrintDebugInfoToConsole(printToConsole = false, printToHtml = false) {
- if (this.timerService.ShouldPrintDebugData()) {
- // console.clear();
- let debugInformation = new Array();
- debugInformation.push('FPS Serv: ' + this.timerService.PrintCurrentFpsToConsole());
- debugInformation.push('Cam Serv: ' + this.graphicsService.getGameCameraService().GetDebugInfo());
- if (printToConsole) {
- for (let line of debugInformation) {
- if (line.length > 0) {
- console.log('%c ' + line + ' ', 'background: #000; color:white; ');
- }
- }
- }
- if (printToHtml) {
- this.performanceInfoDiv.innerHTML = `${debugInformation.join('\n')}`;
- }
- // debugInformation = Array(0);
- }
- }
- Update(lastDelta) {
- if (this.stateService.GetState() !== null) {
- this.inputManager.NewInputLoopCheck();
- this.stateService.GetState().Tick();
- this.entityService.TickAllEntities(lastDelta);
- // for (let i = 0; i < this.gameEntities.length; i++) {
- // this.gameEntities[i].Tick();
- // }
- }
- }
- Render(lastDelta) {
- if (this.stateService.GetState() !== null) {
- this.graphicsService.GetTileService().Redner();
- this.entityService.RenderAllEntities(this.graphicsService);
- this.stateService.GetState().Render();
- this.graphicsService.Render();
- }
- }
- checkDebugModeFromQueryString() {
- const urlParams = new URLSearchParams(window.location.search);
- const debugModeParam = urlParams.get('inDebugMode');
- return JSON.parse(debugModeParam);
- }
- registerEntities(baddyCount = 75) {
- const ships = [
- 'metalic_01.png',
- 'metalic_02.png',
- 'metalic_03.png',
- 'metalic_04.png',
- 'metalic_05.png',
- 'metalic_06.png',
- 'orange_01.png',
- 'orange_02.png',
- 'orange_03.png',
- 'orange_04.png',
- 'orange_05.png',
- 'orange_06.png'
- ];
- const entitySize = new Vector2_model_1.Vector2(30, 30);
- for (let i = 0; i < baddyCount; i++) {
- const imageLoc = random_number_generators_1.RandomNumberGenerator.GetRandomNumber(0, 6);
- console.log('image loc will be ' + imageLoc);
- const entity = new baddy_1.Baddy(
- // new Vector2(500, 300),
- random_number_generators_1.RandomNumberGenerator.GetRandomVector2(0, this.viewportService.GetBrowserWidth(), 0, this.viewportService.GetBrowserHeight()), entitySize, 'baddy' + i.toString(), '/Ships/' + ships[imageLoc], this.graphicsService, random_string_generator_1.RandomStringGenerator.GetRandomHexColour(), this.playerService);
- this.entityService.RegisterEntity(entity);
- }
- this.playerService.SetPlayer(new player_1.Player(new Vector2_model_1.Vector2(this.viewportService.GetBrowserWidth() / 2, this.viewportService.GetBrowserHeight() / 2),
- // new Vector2(0, 0),
- new Vector2_model_1.Vector2(50, 50), 'player', 'Ships/large_purple_01.png', this.inputManager, this.graphicsService));
- this.entityService.RegisterEntity(this.playerService.GetPlayer());
- // return entities;
- }
-}
-exports.Game = Game;
-
-
-/***/ }),
-
-/***/ "./src/assets/_dist/Worlds/worlds.json":
-/*!*********************************************!*\
- !*** ./src/assets/_dist/Worlds/worlds.json ***!
- \*********************************************/
-/*! exports provided: 0, 1, 2, default */
-/***/ (function(module) {
-
-module.exports = [{"worldId":2,"start":{"x":0,"y":0},"tiles":[[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]]},{"worldId":1,"start":{"x":0,"y":0},"tiles":[[9,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,9],[2,3,2,6,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,9],[2,2,5,9,7,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,9],[2,2,2,4,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,9],[2,12,12,12,12,12,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,9],[2,17,17,17,17,17,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,9],[20,16,16,16,16,16,2,2,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,2,2,2,2,2,2,2,2,2,9],[20,16,16,16,16,16,2,2,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,2,2,2,2,2,2,2,2,2,9],[16,16,16,16,16,16,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,9],[2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,9],[2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,9],[2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,9],[2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,9],[2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,9],[2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,9],[2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,9],[2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,9],[2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,9],[2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,9],[2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,9],[2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,9],[9,14,14,14,14,14,14,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,9]]},{"worldId":0,"start":{"x":0,"y":0},"tiles":[[0,0,0,0],[0,0,0,0],[0,0,0,0]]}];
-
-/***/ }),
-
-/***/ "./src/index.ts":
-/*!**********************!*\
- !*** ./src/index.ts ***!
- \**********************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", { value: true });
-const game_1 = __webpack_require__(/*! ./application/game */ "./src/application/game.ts");
-class App {
- start() {
- const game = new game_1.Game();
- game.Run();
- }
-}
-exports.App = App;
-const application = new App();
-application.start();
-
-
-/***/ }),
-
-/***/ "./src/numerics/helpers/degrees.helper.ts":
-/*!************************************************!*\
- !*** ./src/numerics/helpers/degrees.helper.ts ***!
- \************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", { value: true });
-class DegreesHelper {
-}
-exports.DegreesHelper = DegreesHelper;
-/**
- * converts degrees into radians
- *
- * @export
- * @param {number} degrees
- * @returns
- */
-function Radians(degrees) {
- return degrees * Math.PI / 180;
-}
-exports.Radians = Radians;
-/**
- * converts radians into degrees
- *
- * @export
- * @param {number} radians
- * @returns
- */
-function Degrees(radians) {
- return radians * 180 / Math.PI;
-}
-exports.Degrees = Degrees;
-function FartherRight(fromDegrees, toDegrees) {
- return true;
-}
-exports.FartherRight = FartherRight;
-
-
-/***/ }),
-
-/***/ "./src/numerics/helpers/intersection.helper.ts":
-/*!*****************************************************!*\
- !*** ./src/numerics/helpers/intersection.helper.ts ***!
- \*****************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", { value: true });
-class IntersectionHelper {
- // checks if two AABBs intersect (rectangle only)
- static AabbVsAabb(left, right) {
- if ((left.max.getValueX() < right.min.getValueX()) || (left.min.getValueX() > right.max.getValueX())) {
- return false;
- }
- if ((left.max.getValueY() < right.min.getValueY()) || (left.min.getValueY() > right.max.getValueY())) {
- return false;
- }
- return true;
- }
-}
-exports.IntersectionHelper = IntersectionHelper;
-
-
-/***/ }),
-
-/***/ "./src/numerics/helpers/number.helper.ts":
-/*!***********************************************!*\
- !*** ./src/numerics/helpers/number.helper.ts ***!
- \***********************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", { value: true });
-function Between(x, min, max) {
- return x >= min && x <= max;
-}
-exports.Between = Between;
-function Lerp(start, end, amt) {
- return (1 - amt) * start + amt * end;
-}
-exports.Lerp = Lerp;
-
-
-/***/ }),
-
-/***/ "./src/numerics/helpers/vector2.helper.ts":
-/*!************************************************!*\
- !*** ./src/numerics/helpers/vector2.helper.ts ***!
- \************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", { value: true });
-const Vector2_model_1 = __webpack_require__(/*! ../models/Vector2.model */ "./src/numerics/models/Vector2.model.ts");
-class Vector2Helpers {
- /*
- * adds two Vector2 together and returns a new Vector2
- * containing the results
- */
- static Add(left, right) {
- const vecX = left.getValueX() + right.getValueX();
- const vecY = left.getValueY() + right.getValueY();
- return new Vector2_model_1.Vector2(vecX, vecY);
- }
- /**
- * compares two Vector 2s for equality
- * If the vectors are identica, this returns true otherwise returns false
- *
- * @static
- * @param {Vector2} left
- * @param {Vector2} right
- * @returns {boolean}
- * @memberof Vector2Helpers
- */
- static CompareEquality(left, right) {
- return !(left.getValueX() !== right.getValueX() || left.getValueY() !== right.getValueY());
- }
- /*
- * divides the first vector by the second
- * this is not scalar division
- */
- static Divide(left, right) {
- const vecX = left.getValueX() / right.getValueX();
- const vecY = left.getValueY() / right.getValueY();
- return new Vector2_model_1.Vector2(vecX, vecY);
- }
- /*
- * divides a given source vector2 by a scale factor
- */
- static DivideByScale(source, scaleFactor) {
- const factor = 1 / scaleFactor;
- const vecX = source.getValueX() * factor;
- const vecY = source.getValueY() * factor;
- return new Vector2_model_1.Vector2(vecX, vecY);
- }
- /*
- * gets the dot product of two vectors,
- * returns as a number (float?)
- */
- static Dot(left, right) {
- const vecX = left.getValueX() * right.getValueX();
- const vecY = left.getValueY() * right.getValueY();
- return vecX + vecY;
- }
- static Subtract(left, right) {
- const vecX = left.getValueX() - right.getValueX();
- const vecY = left.getValueY() - right.getValueY();
- return new Vector2_model_1.Vector2(vecX, vecY);
- }
- static NegativeOf(source) {
- const vecX = -source.getValueX();
- const vecY = -source.getValueY();
- return new Vector2_model_1.Vector2(vecX, vecY);
- }
- static Multiply(left, right) {
- const vecX = left.getValueX() * right.getValueX();
- const vecY = left.getValueY() * right.getValueY();
- return new Vector2_model_1.Vector2(vecX, vecY);
- }
- static MultiplyByScale(source, scaleFactor) {
- const vecX = source.getValueX() * scaleFactor;
- const vecY = source.getValueY() * scaleFactor;
- return new Vector2_model_1.Vector2(vecX, vecY);
- }
-}
-exports.Vector2Helpers = Vector2Helpers;
-
-
-/***/ }),
-
-/***/ "./src/numerics/models/AABB.model.ts":
-/*!*******************************************!*\
- !*** ./src/numerics/models/AABB.model.ts ***!
- \*******************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", { value: true });
-const Vector2_model_1 = __webpack_require__(/*! ./Vector2.model */ "./src/numerics/models/Vector2.model.ts");
-class AABB {
- constructor(position, size) {
- this.min = new Vector2_model_1.Vector2(position.getValueX(), position.getValueY());
- this.max = new Vector2_model_1.Vector2(position.getValueX() + size.getValueX(), position.getValueY() + size.getValueY());
- }
- GetCenter() {
- const x = ((this.max.x - this.min.x) / 2) + this.min.x;
- const y = ((this.max.y - this.min.y) / 2) + this.min.y;
- return new Vector2_model_1.Vector2(x, y);
- }
- GetTop() {
- return this.min.getValueY();
- }
- GetBottom() {
- return this.max.getValueY();
- }
- GetLeft() {
- return this.min.getValueX();
- }
- GetRight() {
- return this.max.getValueX();
- }
- IsAbove(target) {
- if (this.GetBottom() < target.GetTop()) {
- return true;
- }
- return false;
- }
- IsBelow(target) {
- if (this.GetTop() > target.GetBottom()) {
- return true;
- }
- return false;
- }
- IsRight(target) {
- if (this.GetRight() < target.GetLeft()) {
- return true;
- }
- return false;
- }
- IsLeft(target) {
- if (this.GetLeft() > target.GetRight()) {
- return true;
- }
- return false;
- }
-}
-exports.AABB = AABB;
-
-
-/***/ }),
-
-/***/ "./src/numerics/models/Vector2.model.ts":
-/*!**********************************************!*\
- !*** ./src/numerics/models/Vector2.model.ts ***!
- \**********************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", { value: true });
-class Vector2 {
- constructor(x, y) {
- this.x = x;
- this.y = y;
- }
- concat(decimalPlaces = -1) {
- if (decimalPlaces > -1) {
- return `x:[${this.x.toFixed(decimalPlaces)}], y:[${this.y.toFixed(decimalPlaces)}]`;
- }
- return `x:[${this.x}], y:[${this.y}]`;
- }
- getValueX() {
- return this.x;
- }
- getValueY() {
- return this.y;
- }
- setValueX(x) {
- this.x = x;
- }
- setValueY(y) {
- this.y = y;
- }
- setValues(x, y) {
- this.x = x;
- this.y = y;
- }
-}
-exports.Vector2 = Vector2;
-
-
-/***/ }),
-
-/***/ 0:
-/*!****************************!*\
- !*** multi ./src/index.ts ***!
- \****************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-module.exports = __webpack_require__(/*! ./src/index.ts */"./src/index.ts");
-
-
-/***/ })
-
-/******/ });
-//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAiLCJ3ZWJwYWNrOi8vLy4vc3JjL2FwcGxpY2F0aW9uL0NvcmUvdGltZXIuc2VydmljZS50cyIsIndlYnBhY2s6Ly8vLi9zcmMvYXBwbGljYXRpb24vRW50aXRpZXMvQ3JlYXR1cmVzL2JhZGR5LnRzIiwid2VicGFjazovLy8uL3NyYy9hcHBsaWNhdGlvbi9FbnRpdGllcy9DcmVhdHVyZXMvY3JlYXR1cmUuZGVmYXVsdC5zZXR0aW5ncy50cyIsIndlYnBhY2s6Ly8vLi9zcmMvYXBwbGljYXRpb24vRW50aXRpZXMvQ3JlYXR1cmVzL2NyZWF0dXJlLnRzIiwid2VicGFjazovLy8uL3NyYy9hcHBsaWNhdGlvbi9FbnRpdGllcy9DcmVhdHVyZXMvcGxheWVyLnRzIiwid2VicGFjazovLy8uL3NyYy9hcHBsaWNhdGlvbi9FbnRpdGllcy9fYmFzZS1lbnRpdHkudHMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2FwcGxpY2F0aW9uL0VudGl0aWVzL2VudGl0eS5zZXJ2aWNlLnRzIiwid2VicGFjazovLy8uL3NyYy9hcHBsaWNhdGlvbi9FbnRpdGllcy9wbGF5ZXIuc2VydmljZS50cyIsIndlYnBhY2s6Ly8vLi9zcmMvYXBwbGljYXRpb24vR3JhcGhpY3MvQ2FtZXJhL2dhbWUtY2FtZXJhLnNlcnZpY2UudHMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2FwcGxpY2F0aW9uL0dyYXBoaWNzL0NhbnZhcy9ncmFwaGljcy5jYW52YXMuc2VydmljZS50cyIsIndlYnBhY2s6Ly8vLi9zcmMvYXBwbGljYXRpb24vR3JhcGhpY3MvRHJhdy9kcmF3YWJsZS50cyIsIndlYnBhY2s6Ly8vLi9zcmMvYXBwbGljYXRpb24vR3JhcGhpY3MvRHJhdy9kcmF3aW5nLnNlcnZpY2UudHMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2FwcGxpY2F0aW9uL0dyYXBoaWNzL0h0bWwvZ3JhcGhpY3MuaHRtbC5zZXJ2aWNlLnRzIiwid2VicGFjazovLy8uL3NyYy9hcHBsaWNhdGlvbi9HcmFwaGljcy9JbWFnZXMvSW1hZ2VIZWxwZXIudHMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2FwcGxpY2F0aW9uL0dyYXBoaWNzL01vZGVscy9ncmFwaGljcy5kcmF3YWJsZS1jYW52YXMudHMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2FwcGxpY2F0aW9uL0dyYXBoaWNzL1RleHR1cmVzL1RleHR1cmUyZC50cyIsIndlYnBhY2s6Ly8vLi9zcmMvYXBwbGljYXRpb24vR3JhcGhpY3MvVGV4dHVyZXMvdGV4dHVyZS5zZXJ2aWNlLnRzIiwid2VicGFjazovLy8uL3NyYy9hcHBsaWNhdGlvbi9HcmFwaGljcy9UaWxlcy9UaWxlVHlwZXMvR3JvdW5kVGlsZVR5cGVzL2RpcnQudGlsZXR5cGUudHMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2FwcGxpY2F0aW9uL0dyYXBoaWNzL1RpbGVzL1RpbGVUeXBlcy9Hcm91bmRUaWxlVHlwZXMvZ3Jhc3MudGlsZXR5cGUudHMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2FwcGxpY2F0aW9uL0dyYXBoaWNzL1RpbGVzL1RpbGVUeXBlcy9Hcm91bmRUaWxlVHlwZXMvc2FuZC50aWxldHlwZS50cyIsIndlYnBhY2s6Ly8vLi9zcmMvYXBwbGljYXRpb24vR3JhcGhpY3MvVGlsZXMvVGlsZVR5cGVzL0dyb3VuZFRpbGVUeXBlcy9zaGFsbG93LXdhdGVyLnRpbGV0eXBlLnRzIiwid2VicGFjazovLy8uL3NyYy9hcHBsaWNhdGlvbi9HcmFwaGljcy9UaWxlcy9UaWxlVHlwZXMvR3JvdW5kVGlsZVR5cGVzL3N0b25lLnRpbGV0eXBlLnRzIiwid2VicGFjazovLy8uL3NyYy9hcHBsaWNhdGlvbi9HcmFwaGljcy9UaWxlcy9UaWxlVHlwZXMvU3BhY2VUaWxlVHlwZXMvc3BhY2UudGlsZXR5cGUudHMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2FwcGxpY2F0aW9uL0dyYXBoaWNzL1RpbGVzL1RpbGVUeXBlcy9TcGFjZVRpbGVUeXBlcy9zdGFyLnRpbGV0eXBlLnRzIiwid2VicGFjazovLy8uL3NyYy9hcHBsaWNhdGlvbi9HcmFwaGljcy9UaWxlcy9UaWxlVHlwZXMvX2Jhc2UtdGlsZXR5cGUudHMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2FwcGxpY2F0aW9uL0dyYXBoaWNzL1RpbGVzL2RyYXdhYmxlLXRpbGUudHMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2FwcGxpY2F0aW9uL0dyYXBoaWNzL1RpbGVzL3RpbGUuZGVmYXVsdC5zZXR0aW5ncy50cyIsIndlYnBhY2s6Ly8vLi9zcmMvYXBwbGljYXRpb24vR3JhcGhpY3MvVGlsZXMvdGlsZS5zZXJ2aWNlLnRzIiwid2VicGFjazovLy8uL3NyYy9hcHBsaWNhdGlvbi9HcmFwaGljcy9WaWV3cG9ydC9WaWV3cG9ydC5IZWxwZXIudHMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2FwcGxpY2F0aW9uL0dyYXBoaWNzL1ZpZXdwb3J0L3ZpZXdwb3J0LnNlcnZpY2UudHMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2FwcGxpY2F0aW9uL0dyYXBoaWNzL2dyYXBoaWNzLnNlcnZpY2UudHMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2FwcGxpY2F0aW9uL0lucHV0L0lucHV0TWFuYWdlci50cyIsIndlYnBhY2s6Ly8vLi9zcmMvYXBwbGljYXRpb24vSW5wdXQvaW5wdXQtc3RhdGUudHMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2FwcGxpY2F0aW9uL0lucHV0L2lucHV0Lm1vZGVsLnRzIiwid2VicGFjazovLy8uL3NyYy9hcHBsaWNhdGlvbi9TdGF0ZXMvR2FtZVN0YXRlLnRzIiwid2VicGFjazovLy8uL3NyYy9hcHBsaWNhdGlvbi9TdGF0ZXMvTWVudVN0YXRlLnRzIiwid2VicGFjazovLy8uL3NyYy9hcHBsaWNhdGlvbi9TdGF0ZXMvU2V0dGluZ3NTdGF0ZS50cyIsIndlYnBhY2s6Ly8vLi9zcmMvYXBwbGljYXRpb24vU3RhdGVzL19CYXNlU3RhdGUudHMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2FwcGxpY2F0aW9uL1N0YXRlcy9zdGF0ZS5zZXJ2aWNlLnRzIiwid2VicGFjazovLy8uL3NyYy9hcHBsaWNhdGlvbi9Ub29scy9yYW5kb21fZ2VuZXJhdG9ycy9yYW5kb21fZ3VpZC5nZW5lcmF0b3IudHMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2FwcGxpY2F0aW9uL1Rvb2xzL3JhbmRvbV9nZW5lcmF0b3JzL3JhbmRvbV9udW1iZXIuZ2VuZXJhdG9ycy50cyIsIndlYnBhY2s6Ly8vLi9zcmMvYXBwbGljYXRpb24vVG9vbHMvcmFuZG9tX2dlbmVyYXRvcnMvcmFuZG9tX3N0cmluZy5nZW5lcmF0b3IudHMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2FwcGxpY2F0aW9uL1dvcmxkL3dvcmxkLmpzb25maWxlcy50cyIsIndlYnBhY2s6Ly8vLi9zcmMvYXBwbGljYXRpb24vV29ybGQvd29ybGQuc2VydmljZS50cyIsIndlYnBhY2s6Ly8vLi9zcmMvYXBwbGljYXRpb24vV29ybGQvd29ybGQudHMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2FwcGxpY2F0aW9uL19kZWJ1Zy9kZWJ1Zy5jb21wb25lbnQudHMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2FwcGxpY2F0aW9uL19kZWJ1Zy9kZWJ1Zy5zZXJ2aWNlLnRzIiwid2VicGFjazovLy8uL3NyYy9hcHBsaWNhdGlvbi9fZGVidWcvZGVidWdnYWJsZS1pdGVtcy5tb2RlbC50cyIsIndlYnBhY2s6Ly8vLi9zcmMvYXBwbGljYXRpb24vZ2FtZS50cyIsIndlYnBhY2s6Ly8vLi9zcmMvaW5kZXgudHMiLCJ3ZWJwYWNrOi8vLy4vc3JjL251bWVyaWNzL2hlbHBlcnMvZGVncmVlcy5oZWxwZXIudHMiLCJ3ZWJwYWNrOi8vLy4vc3JjL251bWVyaWNzL2hlbHBlcnMvaW50ZXJzZWN0aW9uLmhlbHBlci50cyIsIndlYnBhY2s6Ly8vLi9zcmMvbnVtZXJpY3MvaGVscGVycy9udW1iZXIuaGVscGVyLnRzIiwid2VicGFjazovLy8uL3NyYy9udW1lcmljcy9oZWxwZXJzL3ZlY3RvcjIuaGVscGVyLnRzIiwid2VicGFjazovLy8uL3NyYy9udW1lcmljcy9tb2RlbHMvQUFCQi5tb2RlbC50cyIsIndlYnBhY2s6Ly8vLi9zcmMvbnVtZXJp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SUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDZixDQUFDO0lBRUQsTUFBTSxDQUFDLGdCQUF3QixDQUFDLENBQUM7UUFDN0IsSUFBSSxhQUFhLEdBQUcsQ0FBQyxDQUFDLEVBQUU7WUFDcEIsT0FBTyxNQUFNLElBQUksQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBQyxTQUFTLElBQUksQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUM7U0FDdkY7UUFDRCxPQUFPLE1BQU0sSUFBSSxDQUFDLENBQUMsU0FBUyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUM7SUFDMUMsQ0FBQztJQUVELFNBQVM7UUFDTCxPQUFPLElBQUksQ0FBQyxDQUFDLENBQUM7SUFDbEIsQ0FBQztJQUNELFNBQVM7UUFDTCxPQUFPLElBQUksQ0FBQyxDQUFDLENBQUM7SUFDbEIsQ0FBQztJQUVELFNBQVMsQ0FBQyxDQUFTO1FBQ2YsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDZixDQUFDO0lBQ0QsU0FBUyxDQUFDLENBQVM7UUFDZixJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNmLENBQUM7SUFDRCxTQUFTLENBQUMsQ0FBUyxFQUFFLENBQVM7UUFDMUIsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDWCxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNmLENBQUM7Q0FFSjtBQWxDRCwwQkFrQ0MiLCJmaWxlIjoiYnVuZGxlLmpzIiwic291cmNlc0NvbnRlbnQiOlsiIFx0Ly8gVGhlIG1vZHVsZSBjYWNoZVxuIFx0dmFyIGluc3RhbGxlZE1vZHVsZXMgPSB7fTtcblxuIFx0Ly8gVGhlIHJlcXVpcmUgZnVuY3Rpb25cbiBcdGZ1bmN0aW9uIF9fd2VicGFja19yZXF1aXJlX18obW9kdWxlSWQpIHtcblxuIFx0XHQvLyBDaGVjayBpZiBtb2R1bGUgaXMgaW4gY2FjaGVcbiBcdFx0aWYoaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0pIHtcbiBcdFx0XHRyZXR1cm4gaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0uZXhwb3J0cztcbiBcdFx0fVxuIFx0XHQvLyBDcmVhdGUgYSBuZXcgbW9kdWxlIChhbmQgcHV0IGl0IGludG8gdGhlIGNhY2hlKVxuIFx0XHR2YXIgbW9kdWxlID0gaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0gPSB7XG4gXHRcdFx0aTogbW9kdWxlSWQsXG4gXHRcdFx0bDogZmFsc2UsXG4gXHRcdFx0ZXhwb3J0czoge31cbiBcdFx0fTtcblxuIFx0XHQvLyBFeGVjdXRlIHRoZSBtb2R1bGUgZnVuY3Rpb25cbiBcdFx0bW9kdWxlc1ttb2R1bGVJZF0uY2FsbChtb2R1bGUuZXhwb3J0cywgbW9kdWxlLCBtb2R1bGUuZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXyk7XG5cbiBcdFx0Ly8gRmxhZyB0aGUgbW9kdWxlIGFzIGxvYWRlZFxuIFx0XHRtb2R1bGUubCA9IHRydWU7XG5cbiBcdFx0Ly8gUmV0dXJuIHRoZSBleHBvcnRzIG9mIHRoZSBtb2R1bGVcbiBcdFx0cmV0dXJuIG1vZHVsZS5leHBvcnRzO1xuIFx0fVxuXG5cbiBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlcyBvYmplY3QgKF9fd2VicGFja19tb2R1bGVzX18pXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm0gPSBtb2R1bGVzO1xuXG4gXHQvLyBleHBvc2UgdGhlIG1vZHVsZSBjYWNoZVxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5jID0gaW5zdGFsbGVkTW9kdWxlcztcblxuIFx0Ly8gZGVmaW5lIGdldHRlciBmdW5jdGlvbiBmb3IgaGFybW9ueSBleHBvcnRzXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmQgPSBmdW5jdGlvbihleHBvcnRzLCBuYW1lLCBnZXR0ZXIpIHtcbiBcdFx0aWYoIV9fd2VicGFja19yZXF1aXJlX18ubyhleHBvcnRzLCBuYW1lKSkge1xuIFx0XHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBuYW1lLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZ2V0dGVyIH0pO1xuIFx0XHR9XG4gXHR9O1xuXG4gXHQvLyBkZWZpbmUgX19lc01vZHVsZSBvbiBleHBvcnRzXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLnIgPSBmdW5jdGlvbihleHBvcnRzKSB7XG4gXHRcdGlmKHR5cGVvZiBTeW1ib2wgIT09ICd1bmRlZmluZWQnICYmIFN5bWJvbC50b1N0cmluZ1RhZykge1xuIFx0XHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBTeW1ib2wudG9TdHJpbmdUYWcsIHsgdmFsdWU6ICdNb2R1bGUnIH0pO1xuIFx0XHR9XG4gXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnX19lc01vZHVsZScsIHsgdmFsdWU6IHRydWUgfSk7XG4gXHR9O1xuXG4gXHQvLyBjcmVhdGUgYSBmYWtlIG5hbWVzcGFjZSBvYmplY3RcbiBcdC8vIG1vZGUgJiAxOiB2YWx1ZSBpcyBhIG1vZHVsZSBpZCwgcmVxdWlyZSBpdFxuIFx0Ly8gbW9kZSAmIDI6IG1lcmdlIGFsbCBwcm9wZXJ0aWVzIG9mIHZhbHVlIGludG8gdGhlIG5zXG4gXHQvLyBtb2RlICYgNDogcmV0dXJuIHZhbHVlIHdoZW4gYWxyZWFkeSBucyBvYmplY3RcbiBcdC8vIG1vZGUgJiA4fDE6IGJlaGF2ZSBsaWtlIHJlcXVpcmVcbiBcdF9fd2VicGFja19yZXF1aXJlX18udCA9IGZ1bmN0aW9uKHZhbHVlLCBtb2RlKSB7XG4gXHRcdGlmKG1vZGUgJiAxKSB2YWx1ZSA9IF9fd2VicGFja19yZXF1aXJlX18odmFsdWUpO1xuIFx0XHRpZihtb2RlICYgOCkgcmV0dXJuIHZhbHVlO1xuIFx0XHRpZigobW9kZSAmIDQpICYmIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgdmFsdWUgJiYgdmFsdWUuX19lc01vZHVsZSkgcmV0dXJuIHZhbHVlO1xuIFx0XHR2YXIgbnMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuIFx0XHRfX3dlYnBhY2tfcmVxdWlyZV9fLnIobnMpO1xuIFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkobnMsICdkZWZhdWx0JywgeyBlbnVtZXJhYmxlOiB0cnVlLCB2YWx1ZTogdmFsdWUgfSk7XG4gXHRcdGlmKG1vZGUgJiAyICYmIHR5cGVvZiB2YWx1ZSAhPSAnc3RyaW5nJykgZm9yKHZhciBrZXkgaW4gdmFsdWUpIF9fd2VicGFja19yZXF1aXJlX18uZChucywga2V5LCBmdW5jdGlvbihrZXkpIHsgcmV0dXJuIHZhbHVlW2tleV07IH0uYmluZChudWxsLCBrZXkpKTtcbiBcdFx0cmV0dXJuIG5zO1xuIFx0fTtcblxuIFx0Ly8gZ2V0RGVmYXVsdEV4cG9ydCBmdW5jdGlvbiBmb3IgY29tcGF0aWJpbGl0eSB3aXRoIG5vbi1oYXJtb255IG1vZHVsZXNcbiBcdF9fd2VicGFja19yZXF1aXJlX18ubiA9IGZ1bmN0aW9uKG1vZHVsZSkge1xuIFx0XHR2YXIgZ2V0dGVyID0gbW9kdWxlICYmIG1vZHVsZS5fX2VzTW9kdWxlID9cbiBcdFx0XHRmdW5jdGlvbiBnZXREZWZhdWx0KCkgeyByZXR1cm4gbW9kdWxlWydkZWZhdWx0J107IH0gOlxuIFx0XHRcdGZ1bmN0aW9uIGdldE1vZHVsZUV4cG9ydHMoKSB7IHJldHVybiBtb2R1bGU7IH07XG4gXHRcdF9fd2VicGFja19yZXF1aXJlX18uZChnZXR0ZXIsICdhJywgZ2V0dGVyKTtcbiBcdFx0cmV0dXJuIGdldHRlcjtcbiBcdH07XG5cbiBcdC8vIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbFxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5vID0gZnVuY3Rpb24ob2JqZWN0LCBwcm9wZXJ0eSkgeyByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwgcHJvcGVydHkpOyB9O1xuXG4gXHQvLyBfX3dlYnBhY2tfcHVibGljX3BhdGhfX1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5wID0gXCJcIjtcblxuXG4gXHQvLyBMb2FkIGVudHJ5IG1vZHVsZSBhbmQgcmV0dXJuIGV4cG9ydHNcbiBcdHJldHVybiBfX3dlYnBhY2tfcmVxdWlyZV9fKF9fd2VicGFja19yZXF1aXJlX18ucyA9IDApO1xuIiwiZXhwb3J0IGNsYXNzIFRpbWVyU2VydmljZSB7XHJcbiAgICBwcml2YXRlIG5vdzogbnVtYmVyO1xyXG4gICAgcHJpdmF0ZSBkZWx0YTogbnVtYmVyO1xyXG4gICAgcHJpdmF0ZSB0aW1lcjogbnVtYmVyO1xyXG4gICAgcHJpdmF0ZSBsYXN0VGltZTogbnVtYmVyO1xyXG4gICAgcHJpdmF0ZSB0aWNrczogbnVtYmVyO1xyXG4gICAgcHJpdmF0ZSBsYXN0VGltZVRvb2s6IG51bWJlcjtcclxuXHJcbiAgICBwcml2YXRlIHRpbWVQZXJUaWNrOiBudW1iZXI7XHJcbiAgICBwcml2YXRlIGZwczogbnVtYmVyO1xyXG4gICAgY29uc3RydWN0b3IodGFyZ2V0RnBzOiBudW1iZXIgPSA2MCkge1xyXG4gICAgICAgIHRoaXMuZnBzID0gdGFyZ2V0RnBzO1xyXG4gICAgICAgIHRoaXMudGltZVBlclRpY2sgPSAxMDAwIC8gdGhpcy5mcHM7XHJcbiAgICAgICAgdGhpcy5kZWx0YSA9IDA7XHJcbiAgICAgICAgdGhpcy5ub3cgPSAwO1xyXG4gICAgICAgIHRoaXMubGFzdFRpbWUgPSBwZXJmb3JtYW5jZS5ub3coKTtcclxuICAgICAgICB0aGlzLnRpbWVyID0gMDtcclxuICAgICAgICB0aGlzLnRpY2tzID0gMDtcclxuICAgICAgICB0aGlzLmxhc3RUaW1lVG9vayA9IDA7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIENoZWNrU2hvdWxkUnVuTG9vcCgpOiBib29sZWFuIHtcclxuICAgICAgICB0aGlzLm5vdyA9IHBlcmZvcm1hbmNlLm5vdygpO1xyXG4gICAgICAgIHRoaXMuZGVsdGEgKz0gKHRoaXMubm93IC0gdGhpcy5sYXN0VGltZSkgLyB0aGlzLnRpbWVQZXJUaWNrO1xyXG4gICAgICAgIHRoaXMudGltZXIgKz0gdGhpcy5ub3cgLSB0aGlzLmxhc3RUaW1lO1xyXG4gICAgICAgIHRoaXMubGFzdFRpbWVUb29rID0gdGhpcy5ub3cgLSB0aGlzLmxhc3RUaW1lO1xyXG4gICAgICAgIHRoaXMubGFzdFRpbWUgPSB0aGlzLm5vdztcclxuXHJcbiAgICAgICAgaWYgKHRoaXMuZGVsdGEgPj0gMSkge1xyXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc29sZS53YXJuKGBSVU5OSU5HIFNMT1dMWS4gZGlkIG5vdCByZW5kZXIuIERlbHRhIFske3RoaXMuZGVsdGF9XWApXHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBVcGRhdGVUaWNrc0FuZFJlbmRlckFmdGVyTG9vcCgpIHtcclxuICAgICAgICB0aGlzLmRlbHRhLS07XHJcbiAgICAgICAgdGhpcy50aWNrcysrO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogcmV0dXJucyB0cnVlIGlmIGl0J3MgYSBnb29kIHRpbWUgdG8gcHJpbnQgdG8gXHJcbiAgICAgKiB0aGUgY29uc29sZVxyXG4gICAgICpcclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufVxyXG4gICAgICogQG1lbWJlcm9mIEZwc1NlcnZpY2VcclxuICAgICAqL1xyXG4gICAgcHVibGljIFNob3VsZFByaW50RGVidWdEYXRhKCk6IGJvb2xlYW4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnRpbWVyID4gMTAwMDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIHByaW50cyBkZWJ1ZyBkYXRhIGZyb20gdGhpcyBjbGFzc1xyXG4gICAgICogdG8gdGhlIGNvbnNvbGVcclxuICAgICAqXHJcbiAgICAgKiBAbWVtYmVyb2YgRnBzU2VydmljZVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgUHJpbnRDdXJyZW50RnBzVG9Db25zb2xlKCkge1xyXG4gICAgICAgIHJldHVybiBgXHJcbiAgICAgICAgdGlja3MgYW5kIGZyYW1lczogJHt0aGlzLnRpY2tzLnRvRml4ZWQoMil9XHJcbiAgICAgICAgbGFzdERlbHRhOiAke3RoaXMuZGVsdGEudG9GaXhlZCgyKX1cclxuICAgICAgICB0aW1lcjogJHt0aGlzLnRpbWVyLnRvRml4ZWQoMil9XHJcbiAgICAgICAgbGFzdFRpbWUgVG9vazogJHt0aGlzLmxhc3RUaW1lVG9vay50b0ZpeGVkKDIpfWA7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIFJlc2V0VGltZXJzKCkge1xyXG4gICAgICAgIGlmICh0aGlzLnRpbWVyID4gMTAwMCkge1xyXG4gICAgICAgICAgICB0aGlzLnRpY2tzID0gMDtcclxuICAgICAgICAgICAgdGhpcy50aW1lciA9IDA7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBHZXRMYXN0VXBkYXRlVGltZVRvb2soKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMubGFzdFRpbWVUb29rIC8gMTAwMDtcclxuICAgIH1cclxufSIsImltcG9ydCB7IENyZWF0dXJlIH0gZnJvbSBcIi4vY3JlYXR1cmVcIjtcclxuaW1wb3J0IHsgR3JhcGhpY3NTZXJ2aWNlIH0gZnJvbSBcIi4uLy4uL0dyYXBoaWNzL2dyYXBoaWNzLnNlcnZpY2VcIjtcclxuaW1wb3J0IHsgVmVjdG9yMiB9IGZyb20gXCIuLi8uLi8uLi9udW1lcmljcy9tb2RlbHMvVmVjdG9yMi5tb2RlbFwiO1xyXG5pbXBvcnQgeyBQbGF5ZXJTZXJ2aWNlIH0gZnJvbSBcIi4uL3BsYXllci5zZXJ2aWNlXCI7XHJcbmltcG9ydCB7IEFBQkIgfSBmcm9tIFwiLi4vLi4vLi4vbnVtZXJpY3MvbW9kZWxzL0FBQkIubW9kZWxcIjtcclxuaW1wb3J0IHsgSW50ZXJzZWN0aW9uSGVscGVyIH0gZnJvbSBcIi4uLy4uLy4uL251bWVyaWNzL2hlbHBlcnMvaW50ZXJzZWN0aW9uLmhlbHBlclwiO1xyXG5pbXBvcnQgeyBSYW5kb21OdW1iZXJHZW5lcmF0b3IgfSBmcm9tIFwiLi4vLi4vVG9vbHMvcmFuZG9tX2dlbmVyYXRvcnMvcmFuZG9tX251bWJlci5nZW5lcmF0b3JzXCI7XHJcbmltcG9ydCB7IFJhZGlhbnMsIERlZ3JlZXMsIEZhcnRoZXJSaWdodCB9IGZyb20gXCIuLi8uLi8uLi9udW1lcmljcy9oZWxwZXJzL2RlZ3JlZXMuaGVscGVyXCI7XHJcbmltcG9ydCB7IEJldHdlZW4sIExlcnAgfSBmcm9tIFwiLi4vLi4vLi4vbnVtZXJpY3MvaGVscGVycy9udW1iZXIuaGVscGVyXCI7XHJcbmltcG9ydCB7IEVudGl0eSB9IGZyb20gXCIuLi9fYmFzZS1lbnRpdHlcIjtcclxuXHJcbmV4cG9ydCBjbGFzcyBCYWRkeSBleHRlbmRzIENyZWF0dXJlIHtcclxuICAgIHByaXZhdGUgcGxheWVyU2VydmljZTogUGxheWVyU2VydmljZTtcclxuICAgIHByaXZhdGUgZGlyZWN0aW9uOiBWZWN0b3IyO1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKHBvc2l0aW9uOiBWZWN0b3IyLCBzaXplOiBWZWN0b3IyLCBuYW1lOiBzdHJpbmcsXHJcbiAgICAgICAgdGV4dHVyZVBhdGg6IHN0cmluZyxcclxuICAgICAgICBncmFwaGljc1NlcnZpY2U6IEdyYXBoaWNzU2VydmljZSwgY29sb3VyOiBzdHJpbmcsXHJcbiAgICAgICAgcGxheWVyU2VydmljZTogUGxheWVyU2VydmljZSkge1xyXG4gICAgICAgIHN1cGVyKHBvc2l0aW9uLCBzaXplLCBuYW1lLCB0ZXh0dXJlUGF0aCwgZ3JhcGhpY3NTZXJ2aWNlKTtcclxuICAgICAgICB0aGlzLnBsYXllclNlcnZpY2UgPSBwbGF5ZXJTZXJ2aWNlO1xyXG4gICAgICAgIHRoaXMuY29sb3VyID0gY29sb3VyO1xyXG4gICAgICAgIHRoaXMubWF4U3BlZWQgPSBuZXcgVmVjdG9yMigxMCwgMTApO1xyXG4gICAgICAgIHRoaXMuYWNjZWxlcmF0aW9uID0gbmV3IFZlY3RvcjIoLjU1LCAuNik7XHJcblxyXG4gICAgICAgIC8vIGNvbnN0IGZyaWN0aW9uID0gMC44NTsgLy8gUmFuZG9tTnVtYmVyR2VuZXJhdG9yLkdldFJhbmRvbU51bWJlcigxMDAsIDIwMCkgLyAxMDAwO1xyXG4gICAgICAgIC8vIHRoaXMuZnJpY3Rpb24gPSBuZXcgVmVjdG9yMihmcmljdGlvbixcclxuICAgICAgICAvLyAgICAgZnJpY3Rpb24pO1xyXG5cclxuICAgICAgICB0aGlzLmRpcmVjdGlvbiA9IG5ldyBWZWN0b3IyKDAsIDApO1xyXG5cclxuXHJcbiAgICAgICAgLy8gdGhpcy52ZWxvY2l0eSA9IFJhbmRvbU51bWJlckdlbmVyYXRvci5HZXRSYW5kb21WZWN0b3IyKC0xMCwgMTAsIC0xMCwgMTApO1xyXG4gICAgICAgIHRoaXMucm90YXRpb25EZWdyZWVzID0gMDsvLyBSYW5kb21OdW1iZXJHZW5lcmF0b3IuR2V0UmFuZG9tTnVtYmVyKDAsIDM1OSk7XHJcbiAgICAgICAgdGhpcy50dXJuU3BlZWQgPSAuMDUxNTtcclxuICAgICAgICB0aGlzLnRocnVzdCA9IDE7XHJcblxyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBUaWNrKGxhc3REZWx0YTogbnVtYmVyKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5VcGRhdGVBQUJCKCk7XHJcblxyXG4gICAgICAgIGNvbnN0IHBsYXllckFBQkIgPSB0aGlzLnBsYXllclNlcnZpY2UuR2V0UGxheWVyKCkuZ2V0QUFCQigpO1xyXG4gICAgICAgIHRoaXMuTW92ZVRvUGxheWVyKHBsYXllckFBQkIpO1xyXG5cclxuICAgICAgICB0aGlzLk1vdmUobGFzdERlbHRhKTtcclxuICAgIH1cclxuICAgIHB1YmxpYyBSZW5kZXIoKTogdm9pZCB7XHJcbiAgICAgICAgLy8gc3VwZXIuRHJhdyh0aGlzLmNvbG91cik7XHJcbiAgICB9XHJcblxyXG4gICAgY29sbGlkZVdpdGhPYmplY3QoZW50aXR5OiBFbnRpdHkpIHtcclxuICAgICAgICBjb25zb2xlLmxvZygnY29sbGlkaW5nIHdpdGggb2JqZWN0JylcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIHR1cm5Ub1BsYXllcihwbGF5ZXJBQUJCOiBBQUJCKSB7XHJcbiAgICAgICAgbGV0IGR4ID0gcGxheWVyQUFCQi5HZXRDZW50ZXIoKS5nZXRWYWx1ZVgoKSAtIHRoaXMuZ2V0QUFCQigpLkdldENlbnRlcigpLmdldFZhbHVlWCgpO1xyXG4gICAgICAgIGxldCBkeSA9IHBsYXllckFBQkIuR2V0Q2VudGVyKCkuZ2V0VmFsdWVZKCkgLSB0aGlzLmdldEFBQkIoKS5HZXRDZW50ZXIoKS5nZXRWYWx1ZVkoKTtcclxuICAgICAgICBjb25zdCBsZW4gPSBNYXRoLnNxcnQoZHggKiBkeSArIGR5ICogZHkpO1xyXG4gICAgICAgIGR4IC89IGxlbiA/IGxlbiA6IDAuMTtcclxuICAgICAgICBkeSAvPSBsZW4gPyBsZW4gOiAwLjE7XHJcblxyXG4gICAgICAgIGxldCBkaXJYID0gTWF0aC5jb3MoUmFkaWFucyh0aGlzLnJvdGF0aW9uRGVncmVlcykpO1xyXG4gICAgICAgIGxldCBkaXJZID0gTWF0aC5zaW4oUmFkaWFucyh0aGlzLnJvdGF0aW9uRGVncmVlcykpO1xyXG5cclxuICAgICAgICBkaXJYICs9IChkeCAtIGRpclgpICogMTtcclxuICAgICAgICBkaXJZICs9IChkeSAtIGRpclkpICogMTtcclxuXHJcbiAgICAgICAgY29uc3Qgcm90YXRlVG8gPSBNYXRoLmF0YW4yKGRpclksIGRpclgpO1xyXG5cclxuICAgICAgICAvLyB0aGlzLnJvdGF0aW9uRGVncmVlcyA9IERlZ3JlZXMocm90YXRlVG8pICsgKDkwKTtcclxuICAgICAgICB0aGlzLnJvdGF0aW9uRGVncmVlcyA9IExlcnAodGhpcy5yb3RhdGlvbkRlZ3JlZXMsIERlZ3JlZXMocm90YXRlVG8pICsgKC10aGlzLmFuZ2xlQWRqdXN0KSwgLjUpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgTW92ZVRvUGxheWVyKHBsYXllckFBQkI6IEFBQkIpIHtcclxuICAgICAgICB0aGlzLnR1cm5Ub1BsYXllcihwbGF5ZXJBQUJCKTtcclxuICAgICAgICBjb25zdCByb3RhdGlvbkFzUmFkaWFucyA9IFJhZGlhbnModGhpcy5yb3RhdGlvbkRlZ3JlZXMgLSB0aGlzLmFuZ2xlQWRqdXN0KTtcclxuICAgICAgICBjb25zdCByb3RTaW4gPSBNYXRoLnNpbihyb3RhdGlvbkFzUmFkaWFucyk7XHJcbiAgICAgICAgY29uc3Qgcm90Q29zID0gTWF0aC5jb3Mocm90YXRpb25Bc1JhZGlhbnMpO1xyXG5cclxuICAgICAgICB0aGlzLnZlbG9jaXR5LnggLT0gKHJvdENvcyAqIHRoaXMudGhydXN0KTtcclxuICAgICAgICB0aGlzLnZlbG9jaXR5LnkgLT0gKHJvdFNpbiAqIHRoaXMudGhydXN0KTtcclxuXHJcblxyXG4gICAgICAgIC8vIGNvbnN0IHJvdGF0aW9uQXNSYWRpYW5zID0gdGhpcy5yb3RhdGlvbkRlZ3JlZXMgLyBNYXRoLlBJICogMTgwO1xyXG4gICAgICAgIC8vIGNvbnN0IHJvdENvcyA9IE1hdGguc2luKHJvdGF0aW9uQXNSYWRpYW5zKTtcclxuICAgICAgICAvLyBjb25zdCByb3RTaW4gPSBNYXRoLmNvcyhyb3RhdGlvbkFzUmFkaWFucyk7XHJcblxyXG4gICAgICAgIC8vIHRoaXMudmVsb2NpdHkueCA9IChyb3RTaW4gKiB0aHJ1c3QpO1xyXG4gICAgICAgIC8vIHRoaXMudmVsb2NpdHkueSA9IChyb3RDb3MgKiB0aHJ1c3QpO1xyXG5cclxuICAgICAgICAvLyBjb25zb2xlLmxvZyhgYmFkZHk6IFxyXG4gICAgICAgIC8vICByb3RhdGlvbjogJHt0aGlzLnJvdGF0aW9uRGVncmVlc31cclxuICAgICAgICAvLyAgQ29zUm90YXRpb246ICR7cm90Q29zfVxyXG4gICAgICAgIC8vICBTaW5Sb3RhdGlvbjogJHtyb3RTaW59XHJcbiAgICAgICAgLy8gIHZlbG9jaXR5OiAke3RoaXMudmVsb2NpdHkuY29uY2F0KCl9YCk7XHJcblxyXG5cclxuXHJcbiAgICAgICAgLy8gaWYgKEludGVyc2VjdGlvbkhlbHBlci5BYWJiVnNBYWJiKFxyXG4gICAgICAgIC8vICAgICB0aGlzLmdldEFBQkIoKSwgcGxheWVyQUFCQikgPT09IGZhbHNlKSB7XHJcbiAgICAgICAgLy8gICAgIGlmICh0aGlzLmdldEFBQkIoKS5Jc0Fib3ZlKHBsYXllckFBQkIpKSB7XHJcbiAgICAgICAgLy8gICAgICAgICB0aGlzLnNldERpcmVjdGlvbkRvd24oKTtcclxuICAgICAgICAvLyAgICAgICAgIHRoaXMudmVsb2NpdHkueSArPSB0aGlzLmFjY2VsZXJhdGlvbi55O1xyXG4gICAgICAgIC8vICAgICAgICAgLy8gY29uc29sZS5sb2coJ2VudGl0eSBpcyBhYm92ZSBwbGF5ZXInKVxyXG4gICAgICAgIC8vICAgICB9IGVsc2UgaWYgKHRoaXMuZ2V0QUFCQigpLklzQmVsb3cocGxheWVyQUFCQikpIHtcclxuICAgICAgICAvLyAgICAgICAgIHRoaXMuc2V0RGlyZWN0aW9uVXAoKTtcclxuICAgICAgICAvLyAgICAgICAgIC8vIGNvbnNvbGUubG9nKCdlbnRpdHkgaXMgYWJvdmUgcGxheWVyJylcclxuICAgICAgICAvLyAgICAgICAgIHRoaXMudmVsb2NpdHkueSAtPSB0aGlzLmFjY2VsZXJhdGlvbi55OyAgICAgICAgICAgICAgICAvLyBjb25zb2xlLmxvZygnZW50aXR5IGlzIGJlbG93IHBsYXllcicpXHJcbiAgICAgICAgLy8gICAgIH1cclxuXHJcbiAgICAgICAgLy8gICAgIGlmICh0aGlzLmdldEFBQkIoKS5Jc1JpZ2h0KHBsYXllckFBQkIpKSB7XHJcbiAgICAgICAgLy8gICAgICAgICB0aGlzLnNldERpcmVjdGlvbkxlZnQoKTtcclxuICAgICAgICAvLyAgICAgICAgIC8vIGNvbnNvbGUubG9nKCdlbnRpdHkgaXMgcmlnaHQgb2YgdGhlIHBsYXllcicpO1xyXG4gICAgICAgIC8vICAgICAgICAgdGhpcy52ZWxvY2l0eS54ICs9IHRoaXMuYWNjZWxlcmF0aW9uLng7XHJcbiAgICAgICAgLy8gICAgIH0gZWxzZSBpZiAodGhpcy5nZXRBQUJCKCkuSXNMZWZ0KHBsYXllckFBQkIpKSB7XHJcbiAgICAgICAgLy8gICAgICAgICB0aGlzLnNldERpcmVjdGlvblJpZ3RoKCk7XHJcbiAgICAgICAgLy8gICAgICAgICAvLyBjb25zb2xlLmxvZygnZW50aXR5IGlzIGxlZnQgb2YgdGhlIHBsYXllcicpXHJcbiAgICAgICAgLy8gICAgICAgICB0aGlzLnZlbG9jaXR5LnggLT0gdGhpcy5hY2NlbGVyYXRpb24ueDtcclxuICAgICAgICAvLyAgICAgfVxyXG4gICAgICAgIC8vIH1cclxuXHJcbiAgICAgICAgLy8gdGhpcy52ZWxvY2l0eS54IC09ICh0aGlzLmdldERpcmVjdGlvbkhvcml6b250YWwoKSAqIHRoaXMuYWNjZWxlcmF0aW9uLngpIC8gNDtcclxuICAgICAgICAvLyB0aGlzLnZlbG9jaXR5LnkgKz0gKHRoaXMuZ2V0RGlyZWN0aW9uVmVydGljYWwoKSAqIHRoaXMuYWNjZWxlcmF0aW9uLnkpIC8gNDtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIHNldERpcmVjdGlvblJpZ3RoKCk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMuZGlyZWN0aW9uLnNldFZhbHVlWCgxKTtcclxuICAgIH1cclxuICAgIHByaXZhdGUgc2V0RGlyZWN0aW9uTGVmdCgpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLmRpcmVjdGlvbi5zZXRWYWx1ZVgoLTEpO1xyXG4gICAgfVxyXG4gICAgcHJpdmF0ZSBzZXREaXJlY3Rpb25VcCgpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLmRpcmVjdGlvbi5zZXRWYWx1ZVkoLTEpO1xyXG4gICAgfVxyXG4gICAgcHJpdmF0ZSBzZXREaXJlY3Rpb25Eb3duKCk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMuZGlyZWN0aW9uLnNldFZhbHVlWSgxKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGdldERpcmVjdGlvbkhvcml6b250YWwoKTogbnVtYmVyIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5kaXJlY3Rpb24uZ2V0VmFsdWVYKCk7XHJcbiAgICB9XHJcbiAgICBwcml2YXRlIGdldERpcmVjdGlvblZlcnRpY2FsKCk6IG51bWJlciB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZGlyZWN0aW9uLmdldFZhbHVlWSgpO1xyXG4gICAgfVxyXG59IiwiaW1wb3J0IHsgVmVjdG9yMiB9IGZyb20gXCIuLi8uLi8uLi9udW1lcmljcy9tb2RlbHMvVmVjdG9yMi5tb2RlbFwiO1xyXG5cclxuZXhwb3J0IGNsYXNzIENyZWF0dXJlRGVmYXVsdFNldHRpbmdzIHtcclxuICAgIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgREVGQVVMVF9IRUFMVEg6IG51bWJlciA9IDEwMDtcclxuICAgIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgREVGQVVMVF9NT1ZFTUVOVF9TUEVFRDogVmVjdG9yMiA9IG5ldyBWZWN0b3IyKDMuMCwgMy4wKTtcclxuICAgIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgREVGQVVMVF9NT1ZFTUVOVF9TUEVFRF9NQVg6IFZlY3RvcjIgPSBuZXcgVmVjdG9yMigxMS4wLCAxMS4wKTtcclxuICAgIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgREVGQVVMVF9NT1ZFTUVOVF9BQ0NFTEVSQVRJT046IFZlY3RvcjIgPSBuZXcgVmVjdG9yMigzLjAsIDMuMCk7XHJcbiAgICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IERFRkFVTFRfTU9WRU1FTlRfVkVMT0NJVFk6IFZlY3RvcjIgPSBuZXcgVmVjdG9yMigzLCAzKTtcclxuICAgIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgREVGQVVMVF9TSVpFOiBWZWN0b3IyID0gbmV3IFZlY3RvcjIoMjAsIDIwKTtcclxuICAgIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgREVGQVVMVF9GUklDVElPTjogVmVjdG9yMiA9IG5ldyBWZWN0b3IyKDAuOTUsIDAuOTUpO1xyXG59IiwiaW1wb3J0IHsgRW50aXR5IH0gZnJvbSBcIi4uL19iYXNlLWVudGl0eVwiO1xyXG5pbXBvcnQgeyBWZWN0b3IyIH0gZnJvbSBcIi4uLy4uLy4uL251bWVyaWNzL21vZGVscy9WZWN0b3IyLm1vZGVsXCI7XHJcbmltcG9ydCB7IEdyYXBoaWNzU2VydmljZSB9IGZyb20gXCIuLi8uLi9HcmFwaGljcy9ncmFwaGljcy5zZXJ2aWNlXCI7XHJcbmltcG9ydCB7IENyZWF0dXJlRGVmYXVsdFNldHRpbmdzIH0gZnJvbSBcIi4vY3JlYXR1cmUuZGVmYXVsdC5zZXR0aW5nc1wiO1xyXG5pbXBvcnQgeyBUZXh0dXJlMkQgfSBmcm9tIFwiLi4vLi4vR3JhcGhpY3MvVGV4dHVyZXMvVGV4dHVyZTJkXCI7XHJcbmltcG9ydCB7IERyYXdhYmxlQ2FudmFzIH0gZnJvbSBcIi4uLy4uL0dyYXBoaWNzL01vZGVscy9ncmFwaGljcy5kcmF3YWJsZS1jYW52YXNcIjtcclxuaW1wb3J0IHsgQUFCQiB9IGZyb20gXCIuLi8uLi8uLi9udW1lcmljcy9tb2RlbHMvQUFCQi5tb2RlbFwiO1xyXG5pbXBvcnQgeyBWZWN0b3IySGVscGVycyB9IGZyb20gXCIuLi8uLi8uLi9udW1lcmljcy9oZWxwZXJzL3ZlY3RvcjIuaGVscGVyXCI7XHJcbmltcG9ydCB7IExlcnAgfSBmcm9tIFwiLi4vLi4vLi4vbnVtZXJpY3MvaGVscGVycy9udW1iZXIuaGVscGVyXCI7XHJcblxyXG5cclxuXHJcbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBDcmVhdHVyZSBleHRlbmRzIEVudGl0eSB7XHJcbiAgICBncmFwaGljc1NlcnZpY2U6IEdyYXBoaWNzU2VydmljZTtcclxuXHJcbiAgICBwcm90ZWN0ZWQgaGVhbHRoOiBudW1iZXI7XHJcbiAgICBwcm90ZWN0ZWQgc3BlZWQ6IFZlY3RvcjI7XHJcbiAgICBwcm90ZWN0ZWQgbWF4U3BlZWQ6IFZlY3RvcjI7XHJcbiAgICBwcm90ZWN0ZWQgdmVsb2NpdHk6IFZlY3RvcjI7XHJcbiAgICBwcm90ZWN0ZWQgYWNjZWxlcmF0aW9uOiBWZWN0b3IyO1xyXG4gICAgcHJvdGVjdGVkIGRlY2VsZXJhdGlvbjogVmVjdG9yMjtcclxuICAgIHByb3RlY3RlZCBmcmljdGlvbjogVmVjdG9yMjtcclxuICAgIHByb3RlY3RlZCB0aHJ1c3Q6IG51bWJlcjtcclxuXHJcbiAgICBwcm90ZWN0ZWQgdHVyblNwZWVkOiBudW1iZXIgPSAxO1xyXG4gICAgcHJvdGVjdGVkIHJlYWRvbmx5IGFuZ2xlQWRqdXN0OiBudW1iZXIgPSAtOTA7XHJcblxyXG5cclxuICAgIC8vIHByb3RlY3RlZCBjYW52YXNJZDogc3RyaW5nO1xyXG5cclxuICAgIC8vIHByb3RlY3RlZCB0ZXh0dXJlOiBUZXh0dXJlMkQ7XHJcblxyXG5cclxuICAgIGNvbnN0cnVjdG9yKHBvc2l0aW9uOiBWZWN0b3IyLCBzaXplOiBWZWN0b3IyLCBuYW1lOiBzdHJpbmcsXHJcbiAgICAgICAgdGV4dHVyZVBhdGg6IHN0cmluZyxcclxuICAgICAgICBncmFwaGljc1NlcnZpY2U6IEdyYXBoaWNzU2VydmljZSkge1xyXG4gICAgICAgIHN1cGVyKHBvc2l0aW9uLCBzaXplLCBuYW1lLCAnMScsICdub190ZXh0X3lldCcpO1xyXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ3Bhc3NpbmcgaW5jb3JyZWN0IHRleHR1cmUgSUQgYW5kIGNhbnZhc0lkLCBhbmQgY2FudmFzIHRvIHN1cGVyJyk7XHJcblxyXG4gICAgICAgIHRoaXMuZ3JhcGhpY3NTZXJ2aWNlID0gZ3JhcGhpY3NTZXJ2aWNlO1xyXG5cclxuICAgICAgICB0aGlzLmhlYWx0aCA9IENyZWF0dXJlRGVmYXVsdFNldHRpbmdzLkRFRkFVTFRfSEVBTFRIO1xyXG4gICAgICAgIHRoaXMuc3BlZWQgPSBDcmVhdHVyZURlZmF1bHRTZXR0aW5ncy5ERUZBVUxUX01PVkVNRU5UX1NQRUVEO1xyXG4gICAgICAgIHRoaXMudmVsb2NpdHkgPSBuZXcgVmVjdG9yMigwLCAwKTtcclxuICAgICAgICB0aGlzLm1heFNwZWVkID0gQ3JlYXR1cmVEZWZhdWx0U2V0dGluZ3MuREVGQVVMVF9NT1ZFTUVOVF9TUEVFRF9NQVg7XHJcbiAgICAgICAgdGhpcy5hY2NlbGVyYXRpb24gPSBDcmVhdHVyZURlZmF1bHRTZXR0aW5ncy5ERUZBVUxUX01PVkVNRU5UX0FDQ0VMRVJBVElPTjtcclxuICAgICAgICB0aGlzLmRlY2VsZXJhdGlvbiA9IFZlY3RvcjJIZWxwZXJzLkRpdmlkZUJ5U2NhbGUoQ3JlYXR1cmVEZWZhdWx0U2V0dGluZ3MuREVGQVVMVF9NT1ZFTUVOVF9BQ0NFTEVSQVRJT04sIDEpO1xyXG4gICAgICAgIHRoaXMuZnJpY3Rpb24gPSBDcmVhdHVyZURlZmF1bHRTZXR0aW5ncy5ERUZBVUxUX0ZSSUNUSU9OO1xyXG4gICAgICAgIHRoaXMuc2V0Q2FudmFzSWQodGhpcy5ncmFwaGljc1NlcnZpY2UuUmVnaXN0ZXJEcmF3YWJsZUVudGl0eSgpKTtcclxuXHJcblxyXG4gICAgICAgIGlmICh0ZXh0dXJlUGF0aCAhPT0gdW5kZWZpbmVkICYmIHRleHR1cmVQYXRoICE9PSBudWxsICYmIHRleHR1cmVQYXRoLmxlbmd0aCkge1xyXG4gICAgICAgICAgICBjb25zdCB0ZXh0dXJlSWQgPSB0aGlzLmdyYXBoaWNzU2VydmljZS5HZXRUZXh0dXJlU2VydmljZSgpLlJlZ2lzdGVyTmV3VGV4dHVyZSh0ZXh0dXJlUGF0aCk7XHJcbiAgICAgICAgICAgIHRoaXMuU2V0VGV4dHVyZUlkKHRleHR1cmVJZCk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgY29uc29sZS5lcnJvcihuZXcgRXJyb3IoYGNyZWF0dXJlIFske25hbWV9XSBkaWQgbm90IGhhdmUgYSB0ZXh0dXJlYCkpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIE1vdmUobGFzdERlbHRhOiBudW1iZXIpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLkNhcE1vdmVtZW50U3BlZWQoKTtcclxuICAgICAgICB0aGlzLkNhcFJvdGF0aW9uKCk7XHJcbiAgICAgICAgdGhpcy5VcGRhdGVQb3NpdGlvbihsYXN0RGVsdGEpO1xyXG4gICAgICAgIHRoaXMuUmVkdWNlU3BlZWQoKTtcclxuICAgICAgICB0aGlzLlVwZGF0ZUFBQkIoKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIFJlZHVjZVNwZWVkKCkge1xyXG5cclxuICAgICAgICB0aGlzLnZlbG9jaXR5LnkgKj0gdGhpcy5mcmljdGlvbi55O1xyXG4gICAgICAgIHRoaXMudmVsb2NpdHkueCAqPSB0aGlzLmZyaWN0aW9uLng7XHJcblxyXG4gICAgICAgIC8vIGlmICh0aGlzLnZlbG9jaXR5LnkgPiAwKSB7XHJcbiAgICAgICAgLy8gICAgIHRoaXMudmVsb2NpdHkueSAtPSB0aGlzLmZyaWN0aW9uLnk7XHJcbiAgICAgICAgLy8gICAgIGlmICh0aGlzLnZlbG9jaXR5LnkgPCAwKSB7XHJcbiAgICAgICAgLy8gICAgICAgICB0aGlzLnZlbG9jaXR5LnkgPSAwO1xyXG4gICAgICAgIC8vICAgICB9XHJcbiAgICAgICAgLy8gfSBlbHNlIGlmICh0aGlzLnZlbG9jaXR5LnkgPCAwKSB7XHJcbiAgICAgICAgLy8gICAgIHRoaXMudmVsb2NpdHkueSArPSB0aGlzLmZyaWN0aW9uLnk7XHJcbiAgICAgICAgLy8gICAgIGlmICh0aGlzLnZlbG9jaXR5LnkgPiAwKSB7XHJcbiAgICAgICAgLy8gICAgICAgICB0aGlzLnZlbG9jaXR5LnkgPSAwO1xyXG4gICAgICAgIC8vICAgICB9XHJcbiAgICAgICAgLy8gfVxyXG5cclxuICAgICAgICAvLyBpZiAodGhpcy52ZWxvY2l0eS54ID4gMCkge1xyXG4gICAgICAgIC8vICAgICB0aGlzLnZlbG9jaXR5LnggLT0gdGhpcy5mcmljdGlvbi54O1xyXG4gICAgICAgIC8vICAgICBpZiAodGhpcy52ZWxvY2l0eS54IDwgMCkge1xyXG4gICAgICAgIC8vICAgICAgICAgdGhpcy52ZWxvY2l0eS54ID0gMDtcclxuICAgICAgICAvLyAgICAgfVxyXG4gICAgICAgIC8vIH0gZWxzZSBpZiAodGhpcy52ZWxvY2l0eS54IDwgMCkge1xyXG4gICAgICAgIC8vICAgICB0aGlzLnZlbG9jaXR5LnggKz0gdGhpcy5mcmljdGlvbi54O1xyXG4gICAgICAgIC8vICAgICBpZiAodGhpcy52ZWxvY2l0eS54ID4gMCkge1xyXG4gICAgICAgIC8vICAgICAgICAgdGhpcy52ZWxvY2l0eS54ID0gMDtcclxuICAgICAgICAvLyAgICAgfVxyXG4gICAgICAgIC8vIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIHVwZGF0ZXMgdGhlIGNyZWF0dXJlJ3MgcG9zaXRpb25cclxuICAgICAqXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICogQG1lbWJlcm9mIENyZWF0dXJlXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgVXBkYXRlUG9zaXRpb24obGFzdERlbHRhOiBudW1iZXIpIHtcclxuICAgICAgICAvLyB0aGlzLnBvc2l0aW9uLnggKz0gKHRoaXMudmVsb2NpdHkueCAqIChsYXN0RGVsdGEpICogNTApO1xyXG4gICAgICAgIC8vIHRoaXMucG9zaXRpb24ueSArPSAodGhpcy52ZWxvY2l0eS55ICogKGxhc3REZWx0YSkgKiA1MCk7XHJcblxyXG4gICAgICAgIHRoaXMucG9zaXRpb24ueCA9IExlcnAodGhpcy5wb3NpdGlvbi54LCB0aGlzLnBvc2l0aW9uLnggKyAodGhpcy52ZWxvY2l0eS54ICogKGxhc3REZWx0YSkgKiA1MCksIC44KTtcclxuICAgICAgICB0aGlzLnBvc2l0aW9uLnkgPSBMZXJwKHRoaXMucG9zaXRpb24ueSwgdGhpcy5wb3NpdGlvbi55ICsgKHRoaXMudmVsb2NpdHkueSAqIChsYXN0RGVsdGEpICogNTApLCAuOCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBjYXBzIHRoZSBjcmVhdHVyZSdzIG1vdmVtZW50IHNwZWVkIGF0XHJcbiAgICAgKiB0aGlzLm1heFNwZWVkXHJcbiAgICAgKlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqIEBtZW1iZXJvZiBDcmVhdHVyZVxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIENhcE1vdmVtZW50U3BlZWQoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMudmVsb2NpdHkueCA+IHRoaXMubWF4U3BlZWQueCkge1xyXG4gICAgICAgICAgICB0aGlzLnZlbG9jaXR5LnggPSB0aGlzLm1heFNwZWVkLng7XHJcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLnZlbG9jaXR5LnggPCAtdGhpcy5tYXhTcGVlZC54KSB7XHJcbiAgICAgICAgICAgIHRoaXMudmVsb2NpdHkueCA9IC10aGlzLm1heFNwZWVkLng7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0aGlzLnZlbG9jaXR5LnkgPiB0aGlzLm1heFNwZWVkLnkpIHtcclxuICAgICAgICAgICAgdGhpcy52ZWxvY2l0eS55ID0gdGhpcy5tYXhTcGVlZC55O1xyXG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy52ZWxvY2l0eS55IDwgLXRoaXMubWF4U3BlZWQueSkge1xyXG4gICAgICAgICAgICB0aGlzLnZlbG9jaXR5LnkgPSAtdGhpcy5tYXhTcGVlZC55O1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHRoaXMudmVsb2NpdHkueCA8IDAuMSAmJiB0aGlzLnZlbG9jaXR5LnggPiAtMC4xKSB7XHJcbiAgICAgICAgICAgIHRoaXMudmVsb2NpdHkueCA9IDA7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0aGlzLnZlbG9jaXR5LnkgPCAwLjEgJiYgdGhpcy52ZWxvY2l0eS55ID4gLTAuMSkge1xyXG4gICAgICAgICAgICB0aGlzLnZlbG9jaXR5LnkgPSAwO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIENhcFJvdGF0aW9uKCkge1xyXG4gICAgICAgIC8vIGlmICh0aGlzLnJvdGF0aW9uRGVncmVlcyA8IDApIHtcclxuICAgICAgICAvLyAgICAgdGhpcy5yb3RhdGlvbkRlZ3JlZXMgPSAzNjAgLSAoLXRoaXMucm90YXRpb25EZWdyZWVzKTtcclxuICAgICAgICAvLyB9XHJcbiAgICAgICAgLy8gaWYgKHRoaXMucm90YXRpb25EZWdyZWVzIDwgMCkge1xyXG4gICAgICAgIC8vICAgICB0aGlzLnJvdGF0aW9uRGVncmVlcyA9IDM1OTtcclxuICAgICAgICAvLyB9IGlmICh0aGlzLnJvdGF0aW9uRGVncmVlcyA+IDM2MCkge1xyXG4gICAgICAgIC8vICAgICB0aGlzLnJvdGF0aW9uRGVncmVlcyA9IDA7XHJcbiAgICAgICAgLy8gfVxyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBnZXRIZWFsdGgoKTogbnVtYmVyIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5oZWFsdGg7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIHNldEhlYWx0aChoZWFsdGg6IG51bWJlcik6IHZvaWQge1xyXG4gICAgICAgIHRoaXMuaGVhbHRoID0gaGVhbHRoO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBnZXRTcGVlZCgpOiBWZWN0b3IyIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5zcGVlZDtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgc2V0U3BlZWQoc3BlZWQ6IFZlY3RvcjIpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLnNwZWVkID0gc3BlZWQ7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGdldE1vdmUoKTogVmVjdG9yMiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMudmVsb2NpdHk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIHNldE1vdmUobW92ZTogVmVjdG9yMik6IHZvaWQge1xyXG4gICAgICAgIHRoaXMudmVsb2NpdHkgPSBtb3ZlO1xyXG4gICAgfVxyXG5cclxufSIsImltcG9ydCB7IENyZWF0dXJlIH0gZnJvbSBcIi4vY3JlYXR1cmVcIjtcclxuaW1wb3J0IHsgVmVjdG9yMiB9IGZyb20gXCIuLi8uLi8uLi9udW1lcmljcy9tb2RlbHMvVmVjdG9yMi5tb2RlbFwiO1xyXG5pbXBvcnQgeyBJbnB1dE1hbmFnZXIgfSBmcm9tIFwiLi4vLi4vSW5wdXQvSW5wdXRNYW5hZ2VyXCI7XHJcbmltcG9ydCB7IEdyYXBoaWNzU2VydmljZSB9IGZyb20gXCIuLi8uLi9HcmFwaGljcy9ncmFwaGljcy5zZXJ2aWNlXCI7XHJcbmltcG9ydCB7IFJhbmRvbVN0cmluZ0dlbmVyYXRvciB9IGZyb20gXCIuLi8uLi9Ub29scy9yYW5kb21fZ2VuZXJhdG9ycy9yYW5kb21fc3RyaW5nLmdlbmVyYXRvclwiO1xyXG5pbXBvcnQgeyBUZXh0dXJlMkQgfSBmcm9tIFwiLi4vLi4vR3JhcGhpY3MvVGV4dHVyZXMvVGV4dHVyZTJkXCI7XHJcbmltcG9ydCB7IERyYXdhYmxlQ2FudmFzIH0gZnJvbSBcIi4uLy4uL0dyYXBoaWNzL01vZGVscy9ncmFwaGljcy5kcmF3YWJsZS1jYW52YXNcIjtcclxuaW1wb3J0IHsgUmFkaWFucyB9IGZyb20gXCIuLi8uLi8uLi9udW1lcmljcy9oZWxwZXJzL2RlZ3JlZXMuaGVscGVyXCI7XHJcblxyXG5leHBvcnQgY2xhc3MgUGxheWVyIGV4dGVuZHMgQ3JlYXR1cmUge1xyXG4gICAgaW5wdXRNYW5hZ2VyOiBJbnB1dE1hbmFnZXI7XHJcblxyXG4gICAgcHJpdmF0ZSBkZXRhaWxzRGl2OiBIVE1MRWxlbWVudDtcclxuICAgIHByaXZhdGUgcm90YXRpb25TcGVlZDogbnVtYmVyID0gNTtcclxuXHJcbiAgICBwcml2YXRlIHN0cmFmZVRocnVzdCA9IDEuNTtcclxuICAgIHByaXZhdGUgcmVhZG9ubHkgc3RhcnRpbmdGcmljdGlvbjogVmVjdG9yMjtcclxuXHJcbiAgICBjb25zdHJ1Y3Rvcihwb3NpdGlvbjogVmVjdG9yMiwgc2l6ZTogVmVjdG9yMiwgbmFtZTogc3RyaW5nLFxyXG4gICAgICAgIHRleHR1cmVQYXRoOiBzdHJpbmcsIGlucHV0TWFuYWdlcjogSW5wdXRNYW5hZ2VyLCBncmFwaGljc1NlcnZpY2U6IEdyYXBoaWNzU2VydmljZSkge1xyXG4gICAgICAgIHN1cGVyKHBvc2l0aW9uLCBzaXplLCBuYW1lLCB0ZXh0dXJlUGF0aCwgZ3JhcGhpY3NTZXJ2aWNlKTtcclxuICAgICAgICB0aGlzLnN0YXJ0aW5nRnJpY3Rpb24gPSB0aGlzLmZyaWN0aW9uO1xyXG4gICAgICAgIHRoaXMuaW5wdXRNYW5hZ2VyID0gaW5wdXRNYW5hZ2VyO1xyXG4gICAgICAgIHRoaXMuaGVhbHRoID0gMTAwO1xyXG4gICAgICAgIHRoaXMuZGV0YWlsc0RpdiA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdkZXRhaWxzX2RpdicpO1xyXG4gICAgICAgIHRoaXMuY29sb3VyID0gJyNmZmYnO1xyXG4gICAgICAgIHRoaXMudGhydXN0ID0gMTtcclxuXHJcblxyXG5cclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgVGljayhsYXN0RGVsdGE6IG51bWJlcik6IHZvaWQge1xyXG4gICAgICAgIHRoaXMuR2V0SW5wdXQoKTtcclxuICAgICAgICB0aGlzLk1vdmUobGFzdERlbHRhKTtcclxuICAgICAgICB0aGlzLmdyYXBoaWNzU2VydmljZS5nZXRHYW1lQ2FtZXJhU2VydmljZSgpLkxvb2tBdCh0aGlzLnBvc2l0aW9uLCB0aGlzLnNpemUpO1xyXG4gICAgfVxyXG5cclxuXHJcbiAgICBwcml2YXRlIEdldElucHV0KCk6IHZvaWQge1xyXG4gICAgICAgIC8vIHRoaXMuc2V0TW92ZShuZXcgVmVjdG9yMigwLCAwKSk7XHJcblxyXG4gICAgICAgIHRoaXMuVXBkYXRlUGxheWVyU3BlZWRGcm9tSW5wdXQoKTtcclxuICAgICAgICB0aGlzLlVwZGF0ZVBsYXllclJvdGF0aW9uRnJvbUlucHV0KCk7XHJcbiAgICAgICAgdGhpcy5VcGRhdGVQbGF5ZXJTdHJhZmVGcm9tSW5wdXQoKTtcclxuXHJcbiAgICAgICAgLy8gaWYgKHRoaXMuaW5wdXRNYW5hZ2VyLklzS2V5UHJlc3NlZCgnZGlyZWN0aW9uX2xlZnQnKSkge1xyXG4gICAgICAgIC8vICAgICB0aGlzLkFkZFRvUm90YXRpb24oLSh0aGlzLnJvdGF0aW9uU3BlZWQgKiB0aGlzLmlucHV0TWFuYWdlci5HZXRGb3JjZVZhbHVlKCdkaXJlY3Rpb25fbGVmdCcpKSk7XHJcblxyXG4gICAgICAgIC8vICAgICAvLyB0aGlzLkFkZFRvUm90YXRpb24oLXRoaXMucm90YXRpb25TcGVlZCk7XHJcbiAgICAgICAgLy8gICAgIC8vIHRoaXMudmVsb2NpdHkueCAtPSB0aGlzLmFjY2VsZXJhdGlvbi54O1xyXG4gICAgICAgIC8vIH1cclxuICAgICAgICAvLyBpZiAodGhpcy5pbnB1dE1hbmFnZXIuSXNLZXlQcmVzc2VkKCdkaXJlY3Rpb25fcmlnaHQnKSkge1xyXG4gICAgICAgIC8vICAgICB0aGlzLkFkZFRvUm90YXRpb24odGhpcy5yb3RhdGlvblNwZWVkICogdGhpcy5pbnB1dE1hbmFnZXIuR2V0Rm9yY2VWYWx1ZSgnZGlyZWN0aW9uX3JpZ2h0JykpO1xyXG4gICAgICAgIC8vICAgICAvLyB0aGlzLnZlbG9jaXR5LnggKz0gdGhpcy5hY2NlbGVyYXRpb24ueDtcclxuICAgICAgICAvLyB9XHJcbiAgICAgICAgaWYgKHRoaXMuaW5wdXRNYW5hZ2VyLklzS2V5UHJlc3NlZCgnJykpXHJcblxyXG4gICAgICAgICAgICBpZiAodGhpcy5pbnB1dE1hbmFnZXIuSXNLZXlQcmVzc2VkKCdhY3Rpb25fYScpKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnc3BhY2UgcHJlc3NlZCcpXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAvLyBjb25zb2xlLmxvZyhgdGhpcy5tb3ZlbWVudC54ID0gJHt0aGlzLm1vdmVtZW50Lnh9YClcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIFVwZGF0ZVBsYXllclJvdGF0aW9uRnJvbUlucHV0KCkge1xyXG4gICAgICAgIGlmICh0aGlzLmlucHV0TWFuYWdlci5Jc0tleVByZXNzZWQoJ2F4ZXNfcGFkX2xlZnRfaG9yaXpvbnRhbCcpKSB7XHJcbiAgICAgICAgICAgIHRoaXMuQWRkVG9Sb3RhdGlvbih0aGlzLnJvdGF0aW9uU3BlZWQgKlxyXG4gICAgICAgICAgICAgICAgdGhpcy5pbnB1dE1hbmFnZXIuR2V0Rm9yY2VWYWx1ZSgnYXhlc19wYWRfbGVmdF9ob3Jpem9udGFsJykpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmlucHV0TWFuYWdlci5Jc0tleVByZXNzZWQoJ2RpcmVjdGlvbl9yaWdodCcpKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLkFkZFRvUm90YXRpb24odGhpcy5yb3RhdGlvblNwZWVkICpcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmlucHV0TWFuYWdlci5HZXRGb3JjZVZhbHVlKCdkaXJlY3Rpb25fcmlnaHQnKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHRoaXMuaW5wdXRNYW5hZ2VyLklzS2V5UHJlc3NlZCgnZGlyZWN0aW9uX2xlZnQnKSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5BZGRUb1JvdGF0aW9uKC0odGhpcy5yb3RhdGlvblNwZWVkICpcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmlucHV0TWFuYWdlci5HZXRGb3JjZVZhbHVlKCdkaXJlY3Rpb25fbGVmdCcpKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBVcGRhdGVQbGF5ZXJTcGVlZEZyb21JbnB1dCgpIHtcclxuICAgICAgICBjb25zdCByb3RhdGlvbkFzUmFkaWFucyA9IFJhZGlhbnModGhpcy5yb3RhdGlvbkRlZ3JlZXMgLSB0aGlzLmFuZ2xlQWRqdXN0KTtcclxuICAgICAgICBjb25zdCByb3RTaW4gPSBNYXRoLnNpbihyb3RhdGlvbkFzUmFkaWFucyk7XHJcbiAgICAgICAgY29uc3Qgcm90Q29zID0gTWF0aC5jb3Mocm90YXRpb25Bc1JhZGlhbnMpO1xyXG5cclxuXHJcbiAgICAgICAgaWYgKHRoaXMuaW5wdXRNYW5hZ2VyLklzS2V5UHJlc3NlZCgndHJpZ2dlcl90d29fcmlnaHQnKSB8fFxyXG4gICAgICAgICAgICB0aGlzLmlucHV0TWFuYWdlci5Jc0tleVByZXNzZWQoJ2RpcmVjdGlvbl91cCcpKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHRyaWdnZXJUd29SaWdodEZvcmNlID1cclxuICAgICAgICAgICAgICAgIE1hdGgubWF4KHRoaXMuaW5wdXRNYW5hZ2VyLkdldEZvcmNlVmFsdWUoJ2RpcmVjdGlvbl91cCcpLFxyXG4gICAgICAgICAgICAgICAgICAgICh0aGlzLmlucHV0TWFuYWdlci5HZXRGb3JjZVZhbHVlKCd0cmlnZ2VyX3R3b19yaWdodCcpKSk7XHJcbiAgICAgICAgICAgIHRoaXMudmVsb2NpdHkueCAtPSAocm90Q29zICogKHRoaXMudGhydXN0ICogdHJpZ2dlclR3b1JpZ2h0Rm9yY2UpKTtcclxuICAgICAgICAgICAgdGhpcy52ZWxvY2l0eS55IC09IChyb3RTaW4gKiAodGhpcy50aHJ1c3QgKiB0cmlnZ2VyVHdvUmlnaHRGb3JjZSkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodGhpcy5pbnB1dE1hbmFnZXIuSXNLZXlQcmVzc2VkKCd0cmlnZ2VyX3R3b19sZWZ0JykgfHxcclxuICAgICAgICAgICAgdGhpcy5pbnB1dE1hbmFnZXIuSXNLZXlQcmVzc2VkKCdkaXJlY3Rpb25fZG93bicpKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHRyaWdnZXJUd29MZWZ0Rm9yY2UgPSBNYXRoLm1heCh0aGlzLmlucHV0TWFuYWdlci5HZXRGb3JjZVZhbHVlKCd0cmlnZ2VyX3R3b19sZWZ0JyksXHJcbiAgICAgICAgICAgICAgICAodGhpcy5pbnB1dE1hbmFnZXIuR2V0Rm9yY2VWYWx1ZSgnZGlyZWN0aW9uX2Rvd24nKSkpO1xyXG4gICAgICAgICAgICAvLyB0aGlzLnZlbG9jaXR5LnggKz0gKHJvdENvcyAqICh0aGlzLnRocnVzdCAqIHRyaWdnZXJUd29MZWZ0Rm9yY2UpKTtcclxuICAgICAgICAgICAgLy8gdGhpcy52ZWxvY2l0eS55ICs9IChyb3RTaW4gKiAodGhpcy50aHJ1c3QgKiB0cmlnZ2VyVHdvTGVmdEZvcmNlKSk7XHJcbiAgICAgICAgICAgIHRoaXMuZnJpY3Rpb24ueCA9IDAuODU7XHJcbiAgICAgICAgICAgIHRoaXMuZnJpY3Rpb24ueSA9IDAuODU7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5mcmljdGlvbiA9IG5ldyBWZWN0b3IyKHRoaXMuc3RhcnRpbmdGcmljdGlvbi5nZXRWYWx1ZVgoKSwgdGhpcy5zdGFydGluZ0ZyaWN0aW9uLmdldFZhbHVlWSgpKTtcclxuICAgICAgICB9XHJcblxyXG5cclxuXHJcbiAgICAgICAgaWYgKHRoaXMuaW5wdXRNYW5hZ2VyLklzS2V5UHJlc3NlZCgndHJpZ2dlcl9vbmVfcmlnaHQnKSkge1xyXG4gICAgICAgICAgICBjb25zdCB0cmlnZ2VyT25lUmlnaHRGb3JjZSA9IHRoaXMuaW5wdXRNYW5hZ2VyLkdldEZvcmNlVmFsdWUoJ3RyaWdnZXJfb25lX3JpZ2h0Jyk7XHJcbiAgICAgICAgICAgIHRoaXMudmVsb2NpdHkueCArPSAocm90U2luICogdHJpZ2dlck9uZVJpZ2h0Rm9yY2UpICogdGhpcy5zdHJhZmVUaHJ1c3Q7XHJcbiAgICAgICAgICAgIHRoaXMudmVsb2NpdHkueSAtPSAocm90Q29zICogdHJpZ2dlck9uZVJpZ2h0Rm9yY2UpICogdGhpcy5zdHJhZmVUaHJ1c3Q7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0aGlzLmlucHV0TWFuYWdlci5Jc0tleVByZXNzZWQoJ3RyaWdnZXJfb25lX2xlZnQnKSkge1xyXG4gICAgICAgICAgICBjb25zdCB0cmlnZ2VyT25lTGVmdEZvcmNlID0gdGhpcy5pbnB1dE1hbmFnZXIuR2V0Rm9yY2VWYWx1ZSgndHJpZ2dlcl9vbmVfcmlnaHQnKTtcclxuICAgICAgICAgICAgdGhpcy52ZWxvY2l0eS54IC09IHJvdFNpbiAqIHRyaWdnZXJPbmVMZWZ0Rm9yY2U7XHJcbiAgICAgICAgICAgIHRoaXMudmVsb2NpdHkueSArPSByb3RDb3MgKiB0cmlnZ2VyT25lTGVmdEZvcmNlO1xyXG4gICAgICAgIH1cclxuXHJcblxyXG5cclxuXHJcblxyXG4gICAgICAgIHRoaXMuZGV0YWlsc0Rpdi5pbm5lckhUTUwgPSBgXHJcbiAgICAgICAgcGxheWVyOiA8YnIgLz5cclxuICAgICAgICB2ZTogJHt0aGlzLnZlbG9jaXR5LmNvbmNhdCgzKX08YnIgLz5cclxuICAgICAgICBybzogJHt0aGlzLnJvdGF0aW9uRGVncmVlcy50b0ZpeGVkKDMpfURFRzxiciAvPlxyXG4gICAgICAgIHJvOiAke3JvdGF0aW9uQXNSYWRpYW5zLnRvRml4ZWQoMyl9UkFEPGJyIC8+XHJcbiAgICAgICAgdGg6ICR7dGhpcy50aHJ1c3QudG9GaXhlZCgzKX08YnIgLz5cclxuICAgICAgICByUzogJHtyb3RTaW4udG9GaXhlZCgzKX08YnIgLz5cclxuICAgICAgICByQzogJHtyb3RDb3MudG9GaXhlZCgzKX08YnIgLz5cclxuXHJcbiAgICAgICAgYDtcclxuICAgIH1cclxuXHJcbiAgICBwcm90ZWN0ZWQgVXBkYXRlUGxheWVyU3RyYWZlRnJvbUlucHV0KCkge1xyXG4gICAgICAgIC8vICAgICBpZiAodGhpcy5pbnB1dE1hbmFnZXIuSXNLZXlQcmVzc2VkKCd0cmlnZ2VyX29uZV9yaWdodCcpKSB7XHJcbiAgICAgICAgLy8gICAgICAgICB0aGlzLnZlbG9jaXR5LnggLT0gKHRoaXMuaW5wdXRNYW5hZ2VyLkdldEZvcmNlVmFsdWUoJ3RyaWdnZXJfb25lX3JpZ2h0JykgKiB0aGlzLmFjY2VsZXJhdGlvbi55KSA7XHJcbiAgICAgICAgLy8gICAgIH1cclxuICAgICAgICAvLyAgICAgaWYgKHRoaXMuaW5wdXRNYW5hZ2VyLklzS2V5UHJlc3NlZCgndHJpZ2dlcl9vbmVfbGVmdCcpKSB7XHJcbiAgICAgICAgLy8gICAgICAgICB0aGlzLnZlbG9jaXR5LnggKz0gKHRoaXMuaW5wdXRNYW5hZ2VyLkdldEZvcmNlVmFsdWUoJ3RyaWdnZXJfb25lX2xlZnQnKSAqIHRoaXMuYWNjZWxlcmF0aW9uLnkpIDtcclxuICAgICAgICAvLyAgICAgfVxyXG4gICAgfVxyXG59XHJcbiIsImltcG9ydCB7IFZlY3RvcjIgfSBmcm9tIFwiLi4vLi4vbnVtZXJpY3MvbW9kZWxzL1ZlY3RvcjIubW9kZWxcIjtcclxuaW1wb3J0IHsgR3VpZEdlbmVyYXRvciB9IGZyb20gXCIuLi9Ub29scy9yYW5kb21fZ2VuZXJhdG9ycy9yYW5kb21fZ3VpZC5nZW5lcmF0b3JcIjtcclxuaW1wb3J0IHsgQUFCQiB9IGZyb20gXCIuLi8uLi9udW1lcmljcy9tb2RlbHMvQUFCQi5tb2RlbFwiO1xyXG5pbXBvcnQgeyBEcmF3YWJsZSB9IGZyb20gXCIuLi9HcmFwaGljcy9EcmF3L2RyYXdhYmxlXCI7XHJcbmltcG9ydCB7IERyYXdhYmxlQ2FudmFzIH0gZnJvbSBcIi4uL0dyYXBoaWNzL01vZGVscy9ncmFwaGljcy5kcmF3YWJsZS1jYW52YXNcIjtcclxuaW1wb3J0IHsgVGV4dHVyZTJEIH0gZnJvbSBcIi4uL0dyYXBoaWNzL1RleHR1cmVzL1RleHR1cmUyZFwiO1xyXG5cclxuLy8gZXhwb3J0IGludGVyZmFjZSBJRW50aXR5IHtcclxuLy8gICAgIHBvc2l0aW9uOiBWZWN0b3IyO1xyXG4vLyAgICAgc2l6ZTogVmVjdG9yMjtcclxuLy8gICAgIG5hbWU6IHN0cmluZztcclxuLy8gICAgIGlkOiBzdHJpbmc7XHJcbi8vIH1cclxuXHJcbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBFbnRpdHkgZXh0ZW5kcyBEcmF3YWJsZSB7XHJcbiAgICBwcm90ZWN0ZWQgcG9zaXRpb246IFZlY3RvcjI7XHJcbiAgICBwcm90ZWN0ZWQgc2l6ZTogVmVjdG9yMjtcclxuICAgIHByb3RlY3RlZCBuYW1lOiBzdHJpbmc7XHJcbiAgICBwcm90ZWN0ZWQgaWQ6IHN0cmluZztcclxuXHJcblxyXG4gICAgLy8gY29uc3RydWN0b3IocG9zaXRpb246IFZlY3RvcjIsIHNpemU6IFZlY3RvcjIsIG5hbWU6IHN0cmluZywgY2FudmFzSWQ6IHN0cmluZywgdGV4dHVyZTogVGV4dHVyZTJELCB0ZXh0dXJlSWQ6IHN0cmluZykge1xyXG4gICAgY29uc3RydWN0b3IocG9zaXRpb246IFZlY3RvcjIsIHNpemU6IFZlY3RvcjIsIG5hbWU6IHN0cmluZywgY2FudmFzSWQ6IHN0cmluZywgdGV4dHVyZUlkOiBzdHJpbmcpIHtcclxuICAgICAgICBzdXBlcihwb3NpdGlvbiwgc2l6ZSwgY2FudmFzSWQsIHRleHR1cmVJZCk7XHJcbiAgICAgICAgdGhpcy5pZCA9IEd1aWRHZW5lcmF0b3IuTmV3R3VpZCgpO1xyXG4gICAgICAgIHRoaXMubmFtZSA9IG5hbWU7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGFic3RyYWN0IFRpY2sobGFzdERlbHRhOiBudW1iZXIpOiB2b2lkO1xyXG5cclxuXHJcbiAgICBnZXROYW1lKCk6IHN0cmluZyB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMubmFtZTtcclxuICAgIH1cclxuXHJcbiAgICBnZXRJZCgpOiBzdHJpbmcge1xyXG4gICAgICAgIHJldHVybiB0aGlzLm5hbWU7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0UG9zaXRpb24oKTogVmVjdG9yMiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMucG9zaXRpb247XHJcbiAgICB9XHJcbiAgICBzZXRQb3NpdGlvbihuZXdQb3NpdGlvbjogVmVjdG9yMik6IFZlY3RvcjIge1xyXG4gICAgICAgIHRoaXMucG9zaXRpb24gPSBuZXdQb3NpdGlvbjtcclxuICAgICAgICByZXR1cm4gdGhpcy5nZXRQb3NpdGlvbigpO1xyXG4gICAgfVxyXG4gICAgc2V0UG9zaXRpb25YKG5ld1Bvc2l0aW9uWDogbnVtYmVyKTogVmVjdG9yMiB7XHJcbiAgICAgICAgdGhpcy5wb3NpdGlvbi54ID0gbmV3UG9zaXRpb25YO1xyXG4gICAgICAgIHJldHVybiB0aGlzLmdldFBvc2l0aW9uKCk7XHJcbiAgICB9XHJcbiAgICBzZXRQb3NpdGlvblkobmV3UG9zaXRpb25ZOiBudW1iZXIpOiBWZWN0b3IyIHtcclxuICAgICAgICB0aGlzLnBvc2l0aW9uLnkgPSBuZXdQb3NpdGlvblk7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UG9zaXRpb24oKTtcclxuICAgIH1cclxuXHJcblxyXG4gICAgZ2V0U2l6ZSgpOiBWZWN0b3IyIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5zaXplO1xyXG4gICAgfVxyXG4gICAgc2V0U2l6ZShuZXdTaXplOiBWZWN0b3IyKTogVmVjdG9yMiB7XHJcbiAgICAgICAgdGhpcy5zaXplID0gbmV3U2l6ZTtcclxuICAgICAgICByZXR1cm4gdGhpcy5nZXRTaXplKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gZ2V0QUFCQigpOiBBQUJCIHtcclxuICAgIC8vICAgICBpZiAodGhpcy5BQUJCID09PSB1bmRlZmluZWQpIHtcclxuICAgIC8vICAgICAgICAgdGhpcy5VcGRhdGVBQUJCKCk7XHJcbiAgICAvLyAgICAgfVxyXG4gICAgLy8gICAgIHJldHVybiB0aGlzLkFBQkI7XHJcbiAgICAvLyB9XHJcblxyXG4gICAgcHJvdGVjdGVkIFNldEFBQkIoQUFCQjogQUFCQik6IHZvaWQge1xyXG4gICAgICAgIHRoaXMuc2V0QUFCQihBQUJCKTtcclxuICAgIH1cclxuICAgIHByb3RlY3RlZCBVcGRhdGVBQUJCKCk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMuc2V0QUFCQihuZXcgQUFCQih0aGlzLnBvc2l0aW9uLCB0aGlzLnNpemUpKTtcclxuICAgIH1cclxuXHJcbn0iLCJpbXBvcnQgeyBFbnRpdHkgfSBmcm9tIFwiLi9fYmFzZS1lbnRpdHlcIjtcclxuaW1wb3J0IHsgRHJhd2luZ1NlcnZpY2UgfSBmcm9tIFwiLi4vR3JhcGhpY3MvRHJhdy9kcmF3aW5nLnNlcnZpY2VcIjtcclxuaW1wb3J0IHsgR3JhcGhpY3NTZXJ2aWNlIH0gZnJvbSBcIi4uL0dyYXBoaWNzL2dyYXBoaWNzLnNlcnZpY2VcIjtcclxuXHJcbmV4cG9ydCBjbGFzcyBFbnRpdHlTZXJ2aWNlIHtcclxuICAgIHByaXZhdGUgZ2FtZUVudGl0aWVzOiBFbnRpdHlbXTtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihcclxuICAgICAgICAgICAgLy8gZHJhd2luZ1NlcnZpY2U6IERyYXdpbmdTZXJ2aWNlXHJcbiAgICAgICAgKSB7XHJcbiAgICAgICAgdGhpcy5nYW1lRW50aXRpZXMgPSBuZXcgQXJyYXk8RW50aXR5PigpO1xyXG4gICAgfVxyXG5cclxuXHJcbiAgICBwdWJsaWMgVGlja0FsbEVudGl0aWVzKGxhc3REZWx0YTogbnVtYmVyKSB7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmdhbWVFbnRpdGllcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICB0aGlzLmdhbWVFbnRpdGllc1tpXS5UaWNrKGxhc3REZWx0YSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBSZW5kZXJBbGxFbnRpdGllcyhncmFwaGljc1NlcnZpY2U6IEdyYXBoaWNzU2VydmljZSkge1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5nYW1lRW50aXRpZXMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgZ3JhcGhpY3NTZXJ2aWNlLmdldERyYXdpbmdTZXJ2aWNlKCkuRHJhdyh0aGlzLmdhbWVFbnRpdGllc1tpXSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBSZWdpc3RlckVudGl0eShlbnRpdHk6IEVudGl0eSkge1xyXG4gICAgICAgIGNvbnNvbGUubG9nKCdyZWdpc3RlcmluZyBhbiBlbnRpdHknKVxyXG4gICAgICAgIHRoaXMuZ2FtZUVudGl0aWVzLnB1c2goZW50aXR5KTtcclxuICAgIH1cclxufSIsImltcG9ydCB7IFBsYXllciB9IGZyb20gXCIuL0NyZWF0dXJlcy9wbGF5ZXJcIjtcclxuaW1wb3J0IHsgQUFCQiB9IGZyb20gXCIuLi8uLi9udW1lcmljcy9tb2RlbHMvQUFCQi5tb2RlbFwiO1xyXG5cclxuZXhwb3J0IGNsYXNzIFBsYXllclNlcnZpY2Uge1xyXG4gICAgcHJpdmF0ZSBwbGF5ZXI6IFBsYXllcjtcclxuICAgIGNvbnN0cnVjdG9yKCkge1xyXG5cclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgU2V0UGxheWVyKHBsYXllcjogUGxheWVyKSB7XHJcbiAgICAgICAgaWYgKHRoaXMucGxheWVyICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgY29uc29sZS5lcnJvcihgcGxheWVyU2VydmljZS5TZXRQbGF5ZXIgd291bGQgb3ZlcndyaXRlIHRoZSBleGlzdGluZyBwbGF5ZXJgKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ3NldHRpbmcgcGxheWVyJyk7XHJcbiAgICAgICAgICAgIHRoaXMucGxheWVyID0gcGxheWVyO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICB9XHJcbiAgICBwdWJsaWMgR2V0UGxheWVyKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnBsYXllcjtcclxuICAgIH0gIFxyXG5cclxuICAgIFxyXG59IiwiaW1wb3J0IHsgVmVjdG9yMiB9IGZyb20gXCIuLi8uLi8uLi9udW1lcmljcy9tb2RlbHMvVmVjdG9yMi5tb2RlbFwiO1xyXG5pbXBvcnQgeyBFbnRpdHkgfSBmcm9tIFwiLi4vLi4vRW50aXRpZXMvX2Jhc2UtZW50aXR5XCI7XHJcbmltcG9ydCB7IFZpZXdwb3J0SGVscGVyIH0gZnJvbSBcIi4uL1ZpZXdwb3J0L1ZpZXdwb3J0LkhlbHBlclwiO1xyXG5pbXBvcnQgeyBWZWN0b3IySGVscGVycyB9IGZyb20gXCIuLi8uLi8uLi9udW1lcmljcy9oZWxwZXJzL3ZlY3RvcjIuaGVscGVyXCI7XHJcbmltcG9ydCB7IEludGVyc2VjdGlvbkhlbHBlciB9IGZyb20gXCIuLi8uLi8uLi9udW1lcmljcy9oZWxwZXJzL2ludGVyc2VjdGlvbi5oZWxwZXJcIjtcclxuaW1wb3J0IHsgQUFCQiB9IGZyb20gXCIuLi8uLi8uLi9udW1lcmljcy9tb2RlbHMvQUFCQi5tb2RlbFwiO1xyXG5cclxuZXhwb3J0IGNsYXNzIEdhbWVDYW1lcmFTZXJ2aWNlIHtcclxuICAgIHByaXZhdGUgb2Zmc2V0OiBWZWN0b3IyO1xyXG4gICAgcHJpdmF0ZSBkaXNwbGF5YWJsZVNpemU6IFZlY3RvcjI7XHJcbiAgICBwcml2YXRlIGFwcGx5V29ybGRCb3VuZGluZzogYm9vbGVhbjtcclxuXHJcbiAgICBwcml2YXRlIGNhbWVyYUFBQkI6IEFBQkI7XHJcbiAgICBwcml2YXRlIGxldmVsQUFCQjogQUFCQjtcclxuXHJcbiAgICAvKipcclxuICAgICAqQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBHYW1lQ2FtZXJhU2VydmljZS5cclxuXHJcbiAgICAgYXBwbHlXb3JsZEJvdW5kaW5nIHRlbGxzIHRoZSBjYW1lcmEgaWYgaXQgc2hvdWxkIGNvbnRpbnVlXHJcbiAgICAgbW92aW5nIHJpZ2h0IG9yIGxlZnQgaWYgaXQgcmVhY2hlcyB0aGUgZWRnZSBvZiB0aGUgbGV2ZWxcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB4T2Zmc2V0XHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0geU9mZnNldFxyXG4gICAgICogQHBhcmFtIHtib29sZWFufSBhcHBseVdvcmxkQm91bmRpbmdcclxuICAgICAqIEBtZW1iZXJvZiBHYW1lQ2FtZXJhU2VydmljZVxyXG4gICAgICovXHJcbiAgICBjb25zdHJ1Y3Rvcih4T2Zmc2V0OiBudW1iZXIsIHlPZmZzZXQ6IG51bWJlciwgYXBwbHlXb3JsZEJvdW5kaW5nOiBib29sZWFuKSB7XHJcbiAgICAgICAgdGhpcy5vZmZzZXQgPSBuZXcgVmVjdG9yMih4T2Zmc2V0LCB5T2Zmc2V0KTtcclxuICAgICAgICB0aGlzLmFwcGx5V29ybGRCb3VuZGluZyA9IGFwcGx5V29ybGRCb3VuZGluZztcclxuXHJcbiAgICAgICAgdGhpcy5kaXNwbGF5YWJsZVNpemUgPSBWaWV3cG9ydEhlbHBlci5HZXRXaW5kb3dJbkFzcGVjdFJhdGlvKCk7XHJcbiAgICAgICAgdGhpcy5VcGRhdGVQb3NpdGlvbkFuZFNpemUoKTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgU2V0TGV2ZWxBQUJCKGxldmVsQUFCQjogQUFCQikge1xyXG4gICAgICAgIHRoaXMubGV2ZWxBQUJCID0gbGV2ZWxBQUJCO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBHZXREZWJ1Z0luZm8oKTogc3RyaW5nW10ge1xyXG4gICAgICAgIHJldHVybiBbYFxyXG4gICAgICAgIG9mZnNldDogICAgICR7dGhpcy5vZmZzZXQuY29uY2F0KDIpfSBcclxuICAgICAgICBzaXplOiAgICAgICAke3RoaXMuZGlzcGxheWFibGVTaXplLmNvbmNhdCgyKX1gXTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIGNoZWNrcyBpZiB0d28gb2JqZWN0cyBpbnRlcnNlY3RcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge1ZlY3RvcjJ9IHBvc2l0aW9uXHJcbiAgICAgKiBAcGFyYW0ge1ZlY3RvcjJ9IHNpemVcclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufVxyXG4gICAgICogQG1lbWJlcm9mIEdhbWVDYW1lcmFTZXJ2aWNlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBJc09iZWN0T25TY3JlZW4ocG9zaXRpb246IFZlY3RvcjIsIHNpemU6IFZlY3RvcjIpOiBib29sZWFuIHtcclxuICAgICAgICBjb25zdCBvYmplY3RBQUJCOiBBQUJCID0gbmV3IEFBQkIocG9zaXRpb24sIHNpemUpO1xyXG4gICAgICAgIHJldHVybiB0aGlzLklzT2JqZWN0T25TY3JlZW5BQUJCKG9iamVjdEFBQkIpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBJc09iamVjdE9uU2NyZWVuQUFCQihBQUJCOiBBQUJCKSB7XHJcbiAgICAgICAgaWYgKEludGVyc2VjdGlvbkhlbHBlci5BYWJiVnNBYWJiKHRoaXMuY2FtZXJhQUFCQiwgQUFCQikpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgTW92ZUNhbWVyYSh4QW1vdW50OiBudW1iZXIsIHlBbW91bnQ6IG51bWJlcik6IHZvaWQge1xyXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ2RvblxcJ3QgdXNlIE1vdmVDYW1lcmEnKTtcclxuICAgICAgICB0aGlzLm9mZnNldC54ICs9IHhBbW91bnQ7XHJcbiAgICAgICAgdGhpcy5vZmZzZXQueSArPSB5QW1vdW50O1xyXG4gICAgfVxyXG5cclxuXHJcbiAgICAvKipcclxuICAgICAqIHNldHMgdGhlIGNhbWVyYSB0byBwb2ludHMgYXQgKGxvb2tzIGF0KSBhIHNwZWNpZmljIGVudGl0eSBcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge1ZlY3RvcjJ9IGVudGl0eVBvc2l0aW9uXHJcbiAgICAgKiBAcGFyYW0ge1ZlY3RvcjJ9IGVudGl0eVNpemVcclxuICAgICAqIEBtZW1iZXJvZiBHYW1lQ2FtZXJhU2VydmljZVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgTG9va0F0KGVudGl0eVBvc2l0aW9uOiBWZWN0b3IyLCBlbnRpdHlTaXplOiBWZWN0b3IyKTogdm9pZCB7XHJcblxyXG4gICAgICAgIGNvbnN0IHZpZXBvcnRXaWR0aCA9IFZpZXdwb3J0SGVscGVyLkdldFdpbmRvd0luQXNwZWN0UmF0aW8oKS5nZXRWYWx1ZVgoKTtcclxuICAgICAgICBjb25zdCB2aWVwb3J0SGVpZ2h0ID0gVmlld3BvcnRIZWxwZXIuR2V0V2luZG93SW5Bc3BlY3RSYXRpbygpLmdldFZhbHVlWSgpO1xyXG5cclxuICAgICAgICBjb25zdCBjZW50ZXJYID0gZW50aXR5UG9zaXRpb24uZ2V0VmFsdWVYKCkgLSAodmllcG9ydFdpZHRoIC8gMikgKyAoZW50aXR5U2l6ZS5nZXRWYWx1ZVgoKSAvIDIpO1xyXG4gICAgICAgIGNvbnN0IGNlbnRlclkgPSBlbnRpdHlQb3NpdGlvbi5nZXRWYWx1ZVkoKSAtICh2aWVwb3J0SGVpZ2h0IC8gMikgKyAoZW50aXR5U2l6ZS5nZXRWYWx1ZVkoKSAvIDIpO1xyXG5cclxuICAgICAgICB0aGlzLlNldE9mZnNldChuZXcgVmVjdG9yMihcclxuICAgICAgICAgICAgY2VudGVyWCxcclxuICAgICAgICAgICAgY2VudGVyWVxyXG4gICAgICAgICkpO1xyXG4gICAgfVxyXG4gICAgcHJpdmF0ZSBTZXRPZmZzZXQocG9zaXRpb25WZWN0b3I6IFZlY3RvcjIpIHtcclxuICAgICAgICB0aGlzLm9mZnNldCA9IHBvc2l0aW9uVmVjdG9yO1xyXG4gICAgICAgIGlmICh0aGlzLmFwcGx5V29ybGRCb3VuZGluZykge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5vZmZzZXQuZ2V0VmFsdWVYKCkgPCB0aGlzLmxldmVsQUFCQi5HZXRMZWZ0KCkpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMub2Zmc2V0LnNldFZhbHVlWCh0aGlzLmxldmVsQUFCQi5HZXRMZWZ0KCkpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAodGhpcy5vZmZzZXQuZ2V0VmFsdWVYKCkgPiB0aGlzLmxldmVsQUFCQi5HZXRSaWdodCgpKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLm9mZnNldC5zZXRWYWx1ZVgodGhpcy5sZXZlbEFBQkIuR2V0UmlnaHQoKSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcblxyXG4gICAgICAgICAgICBpZiAodGhpcy5vZmZzZXQuZ2V0VmFsdWVZKCkgPCB0aGlzLmxldmVsQUFCQi5HZXRUb3AoKSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5vZmZzZXQuc2V0VmFsdWVZKHRoaXMubGV2ZWxBQUJCLkdldFRvcCgpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAodGhpcy5vZmZzZXQuZ2V0VmFsdWVZKCkgPiB0aGlzLmxldmVsQUFCQi5HZXRCb3R0b20oKSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5vZmZzZXQuc2V0VmFsdWVZKHRoaXMubGV2ZWxBQUJCLkdldEJvdHRvbSgpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLlVwZGF0ZVBvc2l0aW9uQW5kU2l6ZSgpO1xyXG4gICAgfVxyXG4gICAgVXBkYXRlUG9zaXRpb25BbmRTaXplKCkge1xyXG4gICAgICAgIHRoaXMuY2FtZXJhQUFCQiA9IG5ldyBBQUJCKHRoaXMub2Zmc2V0LCB0aGlzLmRpc3BsYXlhYmxlU2l6ZSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIEdldE9mZnNldFgoKTogbnVtYmVyIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5vZmZzZXQuZ2V0VmFsdWVYKCk7XHJcbiAgICB9XHJcbiAgICBwdWJsaWMgR2V0T2Zmc2V0WSgpOiBudW1iZXIge1xyXG4gICAgICAgIHJldHVybiB0aGlzLm9mZnNldC5nZXRWYWx1ZVkoKTtcclxuICAgIH1cclxuICAgIHB1YmxpYyBHZXRPZmZzZXRWZWN0b3IoKTogVmVjdG9yMiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMub2Zmc2V0O1xyXG4gICAgfVxyXG59IiwiaW1wb3J0IHsgSHRtbFNlcnZpY2UgfSBmcm9tIFwiLi4vSHRtbC9ncmFwaGljcy5odG1sLnNlcnZpY2VcIjtcclxuaW1wb3J0IHsgRHJhd2FibGVDYW52YXMgfSBmcm9tIFwiLi4vTW9kZWxzL2dyYXBoaWNzLmRyYXdhYmxlLWNhbnZhc1wiO1xyXG5pbXBvcnQgeyBWaWV3cG9ydEhlbHBlciB9IGZyb20gXCIuLi9WaWV3cG9ydC9WaWV3cG9ydC5IZWxwZXJcIjtcclxuaW1wb3J0IHsgR3VpZEdlbmVyYXRvciB9IGZyb20gXCIuLi8uLi9Ub29scy9yYW5kb21fZ2VuZXJhdG9ycy9yYW5kb21fZ3VpZC5nZW5lcmF0b3JcIjtcclxuXHJcbmV4cG9ydCBjbGFzcyBDYW52YXNTZXJ2aWNlIHtcclxuICAgIHByaXZhdGUgaHRtbFNlcnZpY2U6IEh0bWxTZXJ2aWNlO1xyXG5cclxuICAgIHB1YmxpYyBtYWluQ2FudmFzOiBIVE1MQ2FudmFzRWxlbWVudDtcclxuICAgIHB1YmxpYyBtYWluQ2FudmFzQ3R4OiBDYW52YXNSZW5kZXJpbmdDb250ZXh0MkQ7XHJcbiAgICBwdWJsaWMgZHJhd2FibGVBcmVhczogQXJyYXk8RHJhd2FibGVDYW52YXM+O1xyXG5cclxuICAgIHZpZXdwb3J0V2lkdGg6IG51bWJlcjtcclxuICAgIHZpZXdwb3J0SGVpZ2h0OiBudW1iZXI7XHJcblxyXG4gICAgY29uc3RydWN0b3IoaHRtbFNlcnZpY2U6IEh0bWxTZXJ2aWNlKSB7XHJcbiAgICAgICAgY29uc29sZS5sb2coJ2NyZWF0aW5nIGEgY2FudmFzIHNlcnZpY2UnKTtcclxuICAgICAgICB0aGlzLmh0bWxTZXJ2aWNlID0gaHRtbFNlcnZpY2U7XHJcbiAgICB9XHJcblxyXG4gICAgSW5pdCgpIHtcclxuICAgICAgICBjb25zdCB2aWV3cG9ydFNpemUgPSBWaWV3cG9ydEhlbHBlci5HZXRXaW5kb3dJbkFzcGVjdFJhdGlvRm9yQ2FudmFzKCk7XHJcbiAgICAgICAgdGhpcy52aWV3cG9ydEhlaWdodCA9IHZpZXdwb3J0U2l6ZS55O1xyXG4gICAgICAgIHRoaXMudmlld3BvcnRXaWR0aCA9IHZpZXdwb3J0U2l6ZS54O1xyXG5cclxuICAgICAgICB0aGlzLm1haW5DYW52YXMgPSB0aGlzLmh0bWxTZXJ2aWNlLmNyZWF0ZUNhbnZhcygnbWFpbl9jYW52YXMnLCBcclxuICAgICAgICAgICAgdGhpcy5odG1sU2VydmljZS5HZXRNYWluRGl2KCkuaWQsXHJcbiAgICAgICAgICAgIHRoaXMudmlld3BvcnRXaWR0aCxcclxuICAgICAgICAgICAgdGhpcy52aWV3cG9ydEhlaWdodCxcclxuICAgICAgICAgICAgWydwYXJlbnQnXSk7XHJcbiAgICAgICAgdGhpcy5tYWluQ2FudmFzQ3R4ID0gdGhpcy5tYWluQ2FudmFzLmdldENvbnRleHQoJzJkJyk7XHJcbiAgICAgICAgdGhpcy5kcmF3YWJsZUFyZWFzID0gbmV3IEFycmF5PERyYXdhYmxlQ2FudmFzPigpO1xyXG4gICAgfVxyXG5cclxuICAgIFJlZ2lzdGVyTmV3Q2FudmFzKGlkOiBzdHJpbmcgPSBudWxsKTogc3RyaW5nIHtcclxuICAgICAgICBjb25zb2xlLmxvZyhgcmVnaXN0ZXJpbmcgYSBuZXcgY2FudmFzIHdpdGggaWQgJHtpZH1gKTtcclxuICAgICAgICBpZiAoaWQgPT09IG51bGwpIHtcclxuICAgICAgICAgICAgaWQgPSBHdWlkR2VuZXJhdG9yLk5ld0d1aWQoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3QgY2FudmFzID0gdGhpcy5odG1sU2VydmljZS5jcmVhdGVDYW52YXMoaWQsIHRoaXMubWFpbkNhbnZhcy5pZCwgXHJcbiAgICAgICAgICAgIHRoaXMudmlld3BvcnRXaWR0aCwgdGhpcy52aWV3cG9ydEhlaWdodCk7XHJcbiAgICAgICAgdGhpcy5kcmF3YWJsZUFyZWFzLnB1c2gobmV3IERyYXdhYmxlQ2FudmFzKGNhbnZhcywgaWQsIHRoaXMudmlld3BvcnRXaWR0aCwgdGhpcy52aWV3cG9ydEhlaWdodCkpO1xyXG4gICAgICAgIHJldHVybiBpZDtcclxuICAgIH1cclxuXHJcbiAgICBHZXRNYWluQ2FudmFzKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLm1haW5DYW52YXM7XHJcbiAgICB9XHJcblxyXG4gICAgR2V0Q2FudmFzKGlkOiBzdHJpbmcpIHtcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuZHJhd2FibGVBcmVhcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5kcmF3YWJsZUFyZWFzW2ldLmlkID09PSBpZCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZHJhd2FibGVBcmVhc1tpXTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zb2xlLmVycm9yKGBmYWlsZWQgdG8gZ2V0IGEgY2FudmFzIG9mIGlkICR7aWR9YCk7XHJcbiAgICB9XHJcbn1cclxuXHJcbiIsImltcG9ydCB7IEFBQkIgfSBmcm9tIFwiLi4vLi4vLi4vbnVtZXJpY3MvbW9kZWxzL0FBQkIubW9kZWxcIjtcclxuaW1wb3J0IHsgVmVjdG9yMiB9IGZyb20gXCIuLi8uLi8uLi9udW1lcmljcy9tb2RlbHMvVmVjdG9yMi5tb2RlbFwiO1xyXG5cclxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIERyYXdhYmxlIHtcclxuICAgIHByaXZhdGUgY2FudmFzSWQ6IHN0cmluZztcclxuICAgIHByaXZhdGUgQUFCQjogQUFCQjtcclxuICAgIHByb3RlY3RlZCBjb2xvdXI6IHN0cmluZztcclxuICAgIHByb3RlY3RlZCB0ZXh0dXJlSWQ6IHN0cmluZztcclxuXHJcbiAgICBwcm90ZWN0ZWQgcG9zaXRpb246IFZlY3RvcjI7XHJcbiAgICBwcm90ZWN0ZWQgc2l6ZTogVmVjdG9yMjtcclxuICAgIHByb3RlY3RlZCByb3RhdGlvbkRlZ3JlZXM6IG51bWJlcjtcclxuXHJcbiAgICBjb25zdHJ1Y3Rvcihwb3NpdGlvbjogVmVjdG9yMiwgc2l6ZTogVmVjdG9yMiwgY2FudmFzSWQ6IHN0cmluZywgdGV4dHVyZUlkOiBzdHJpbmcpIHtcclxuICAgICAgICBjb25zb2xlLmxvZyhgZHJhd2FibGUgY29uc3RydWN0b3JgKTtcclxuICAgICAgICB0aGlzLnBvc2l0aW9uID0gcG9zaXRpb247XHJcbiAgICAgICAgdGhpcy5zaXplID0gc2l6ZTtcclxuICAgICAgICB0aGlzLkFBQkIgPSBuZXcgQUFCQih0aGlzLnBvc2l0aW9uLCB0aGlzLnNpemUpO1xyXG4gICAgICAgIHRoaXMuY2FudmFzSWQgPSBjYW52YXNJZDtcclxuICAgICAgICB0aGlzLnJvdGF0aW9uRGVncmVlcyA9IDA7XHJcbiAgICAgICAgdGhpcy50ZXh0dXJlSWQgPSB0ZXh0dXJlSWQ7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGdldENhbnZhc0lkKCk6IHN0cmluZyB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuY2FudmFzSWQ7XHJcbiAgICB9XHJcblxyXG4gICAgcHJvdGVjdGVkIHNldENhbnZhc0lkKGNhbnZhc0lkOiBzdHJpbmcpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLmNhbnZhc0lkID0gY2FudmFzSWQ7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIEdldFRleHR1cmVJZCgpOiBzdHJpbmcge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnRleHR1cmVJZDtcclxuICAgIH1cclxuICAgIHB1YmxpYyBTZXRUZXh0dXJlSWQodGV4dHVyZUlkOiBzdHJpbmcpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLnRleHR1cmVJZCA9IHRleHR1cmVJZDtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgZ2V0QUFCQigpOiBBQUJCIHtcclxuICAgICAgICBpZiAodGhpcy5BQUJCID09PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgdGhpcy5VcGRhdGVBQUJCKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB0aGlzLkFBQkI7XHJcbiAgICB9XHJcblxyXG4gICAgcHJvdGVjdGVkIHNldEFBQkIoQUFCQjogQUFCQik6IHZvaWQge1xyXG4gICAgICAgIHRoaXMuQUFCQiA9IEFBQkI7XHJcbiAgICB9XHJcblxyXG4gICAgcHJvdGVjdGVkIFVwZGF0ZUFBQkIoKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5zZXRBQUJCKG5ldyBBQUJCKHRoaXMucG9zaXRpb24sIHRoaXMuc2l6ZSkpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBHZXRQb3NpdGlvblgoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMucG9zaXRpb24ueDtcclxuICAgIH1cclxuICAgIHB1YmxpYyBHZXRQb3NpdGlvblkoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMucG9zaXRpb24ueTtcclxuICAgIH1cclxuICAgIHB1YmxpYyBHZXRTaXplWCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5zaXplLng7XHJcbiAgICB9XHJcbiAgICBwdWJsaWMgR2V0U2l6ZVkoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuc2l6ZS55O1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBHZXRDb2xvdXIoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuY29sb3VyKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmNvbG91cjtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICByZXR1cm4gJyNmMDAnO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgR2V0Um90YXRpb24oKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMucm90YXRpb25EZWdyZWVzO1xyXG4gICAgfVxyXG4gICAgcHVibGljIEFkZFRvUm90YXRpb24odmFsOiBudW1iZXIpIHtcclxuICAgICAgICB0aGlzLnJvdGF0aW9uRGVncmVlcyArPSB2YWw7XHJcbiAgICAgICAgaWYgKHRoaXMucm90YXRpb25EZWdyZWVzID4gMzU5KSB7XHJcbiAgICAgICAgICAgIHRoaXMucm90YXRpb25EZWdyZWVzID0gMDtcclxuICAgICAgICB9IGVsc2UgaWYgKHRoaXMucm90YXRpb25EZWdyZWVzIDwgMCkge1xyXG4gICAgICAgICAgICB0aGlzLnJvdGF0aW9uRGVncmVlcyA9IDM1OTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuIiwiaW1wb3J0IHsgR3JhcGhpY3NTZXJ2aWNlIH0gZnJvbSBcIi4uL2dyYXBoaWNzLnNlcnZpY2VcIjtcclxuaW1wb3J0IHsgRHJhd2FibGVDYW52YXMgfSBmcm9tIFwiLi4vTW9kZWxzL2dyYXBoaWNzLmRyYXdhYmxlLWNhbnZhc1wiO1xyXG5pbXBvcnQgeyBBQUJCIH0gZnJvbSBcIi4uLy4uLy4uL251bWVyaWNzL21vZGVscy9BQUJCLm1vZGVsXCI7XHJcbmltcG9ydCB7IFRleHR1cmUyRCB9IGZyb20gXCIuLi9UZXh0dXJlcy9UZXh0dXJlMmRcIjtcclxuaW1wb3J0IHsgRHJhd2FibGUgfSBmcm9tIFwiLi9kcmF3YWJsZVwiO1xyXG5pbXBvcnQgeyBDYW52YXNTZXJ2aWNlIH0gZnJvbSBcIi4uL0NhbnZhcy9ncmFwaGljcy5jYW52YXMuc2VydmljZVwiO1xyXG5pbXBvcnQgeyBHYW1lQ2FtZXJhU2VydmljZSB9IGZyb20gXCIuLi9DYW1lcmEvZ2FtZS1jYW1lcmEuc2VydmljZVwiO1xyXG5pbXBvcnQgeyBEcmF3YWJsZVRpbGUgfSBmcm9tIFwiLi4vVGlsZXMvZHJhd2FibGUtdGlsZVwiO1xyXG5pbXBvcnQgeyBUZXh0dXJlU2VydmljZSB9IGZyb20gXCIuLi9UZXh0dXJlcy90ZXh0dXJlLnNlcnZpY2VcIjtcclxuXHJcbmV4cG9ydCBjbGFzcyBEcmF3aW5nU2VydmljZSB7XHJcbiAgICBwcml2YXRlIGNhbWVyYVNlcnZpY2U6IEdhbWVDYW1lcmFTZXJ2aWNlO1xyXG4gICAgcHJpdmF0ZSBjYW52YXNTZXJ2aWNlOiBDYW52YXNTZXJ2aWNlO1xyXG4gICAgcHJpdmF0ZSB0ZXh0dXJlU2VydmljZTogVGV4dHVyZVNlcnZpY2U7XHJcbiAgICBwcml2YXRlIGFsbG93VGV4dHVyZURyYXdpbmc6IGJvb2xlYW4gPSB0cnVlO1xyXG4gICAgcHJpdmF0ZSBkcmF3QXNTdHJva2UgPSB0cnVlO1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKFxyXG4gICAgICAgIGNhbWVyYVNlcnZpY2U6IEdhbWVDYW1lcmFTZXJ2aWNlLFxyXG4gICAgICAgIGNhbnZhc1NlcnZpY2U6IENhbnZhc1NlcnZpY2UsXHJcbiAgICAgICAgdGV4dHVyZVNlcnZpY2U6IFRleHR1cmVTZXJ2aWNlKSB7XHJcbiAgICAgICAgdGhpcy50ZXh0dXJlU2VydmljZSA9IHRleHR1cmVTZXJ2aWNlO1xyXG4gICAgICAgIHRoaXMuY2FudmFzU2VydmljZSA9IGNhbnZhc1NlcnZpY2U7XHJcbiAgICAgICAgdGhpcy5jYW1lcmFTZXJ2aWNlID0gY2FtZXJhU2VydmljZTtcclxuICAgICAgICBjb25zb2xlLmxvZygnY29uc3RydWN0aW5nIGRyYXdpbmcgc2VydmljZScpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBEcmF3KGRyYXdhYmxlOiBEcmF3YWJsZSwgc2tpcENhbnZhc0NsZWFyOiBib29sZWFuID0gZmFsc2UpIHtcclxuICAgICAgICBjb25zdCBkZWc6IG51bWJlciA9IGRyYXdhYmxlLkdldFJvdGF0aW9uKCk7XHJcbiAgICAgICAgaWYgKHRoaXMuY2FtZXJhU2VydmljZS5Jc09iamVjdE9uU2NyZWVuQUFCQihkcmF3YWJsZS5nZXRBQUJCKCkpKSB7XHJcblxyXG4gICAgICAgICAgICBjb25zdCBjYW52ID0gdGhpcy5jYW52YXNTZXJ2aWNlLkdldENhbnZhcyhkcmF3YWJsZS5nZXRDYW52YXNJZCgpKTtcclxuXHJcbiAgICAgICAgICAgIHZhciByYWQgPSBkZWcgKiAoTWF0aC5QSSAvIDE4MCk7XHJcblxyXG4gICAgICAgICAgICBpZiAoIXNraXBDYW52YXNDbGVhcikge1xyXG4gICAgICAgICAgICAgICAgY2Fudi5DbGVhckNhbnZhcygpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBjYW52LmN0eC5zYXZlKCk7XHJcbiAgICAgICAgICAgIC8vIGNhbnYuY3R4LnNjYWxlKDAuNSwgMC41KTtcclxuICAgICAgICAgICAgY29uc3QgdHJhbnNsYXRlWCA9IGRyYXdhYmxlLkdldFNpemVYKCkgKyAoZHJhd2FibGUuR2V0UG9zaXRpb25YKCkgLSAoZHJhd2FibGUuR2V0U2l6ZVgoKSAvIDIpIC0gdGhpcy5jYW1lcmFTZXJ2aWNlLkdldE9mZnNldFgoKSk7Ly8gICsgKGRyYXdhYmxlLkdldFNpemVYKCkgLyAyKSk7Ly8gICsgdGhpcy5jYW1lcmFTZXJ2aWNlLkdldE9mZnNldFkoKTtcclxuICAgICAgICAgICAgY29uc3QgdHJhbnNsYXRlWSA9IGRyYXdhYmxlLkdldFNpemVYKCkgKyAoZHJhd2FibGUuR2V0UG9zaXRpb25ZKCkgLSAoZHJhd2FibGUuR2V0U2l6ZVgoKSAvIDIpIC0gdGhpcy5jYW1lcmFTZXJ2aWNlLkdldE9mZnNldFkoKSk7Ly8gICsgKGRyYXdhYmxlLkdldFNpemVZKCkgLyAyKSk7Ly8gICsgdGhpcy5jYW1lcmFTZXJ2aWNlLkdldE9mZnNldFkoKTtcclxuICAgICAgICAgICAgY2Fudi5jdHgudHJhbnNsYXRlKFxyXG4gICAgICAgICAgICAgICAgdHJhbnNsYXRlWCxcclxuICAgICAgICAgICAgICAgIHRyYW5zbGF0ZVkpO1xyXG5cclxuICAgICAgICAgICAgY2Fudi5jdHgucm90YXRlKHJhZCk7XHJcblxyXG4gICAgICAgICAgICBjb25zdCBkcmF3TG9jYXRpb25YID0gLWRyYXdhYmxlLkdldFNpemVYKCkgLyAyOy8vICAvIDI7Ly8gIDtcclxuICAgICAgICAgICAgY29uc3QgZHJhd0xvY2F0aW9uWSA9IC1kcmF3YWJsZS5HZXRTaXplWSgpIC8gMjsvLyAgLyAyOy8vICAtIHRoaXMuY2FtZXJhU2VydmljZS5HZXRPZmZzZXRZKCk7XHJcbiAgICAgICAgICAgIGNvbnN0IGRyYXdTaXplWCA9IGRyYXdhYmxlLkdldFNpemVYKCk7XHJcbiAgICAgICAgICAgIGNvbnN0IGRyYXdTaXplWSA9IGRyYXdhYmxlLkdldFNpemVZKCk7XHJcblxyXG4gICAgICAgICAgICBjb25zdCB0ZXh0dXJlID0gdGhpcy50ZXh0dXJlU2VydmljZS5HZXRUZXh0dXJlKGRyYXdhYmxlLkdldFRleHR1cmVJZCgpKTtcclxuXHJcblxyXG4gICAgICAgICAgICBpZiAodGhpcy5hbGxvd1RleHR1cmVEcmF3aW5nICYmIHRleHR1cmUgJiYgdGV4dHVyZS5HZXRDYW5SZW5kZXIoKSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5EcmF3QXNUZXh0dXJlKHRleHR1cmUsIGNhbnYsIGRyYXdMb2NhdGlvblgsIGRyYXdMb2NhdGlvblksIGRyYXdTaXplWCwgZHJhd1NpemVZKTtcclxuICAgICAgICAgICAgfSBlbHNlIGlmIChmYWxzZSkge1xyXG4gICAgICAgICAgICAgICAgLy9UT0RPIHJlbW92ZSBvciBjaGFuZ2UgdGhpc1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgLy8gaWYgKGRyYXdhYmxlLkdldFRleHR1cmVJZCgpKSB7XHJcbiAgICAgICAgICAgICAgICAvLyAgICAgY29uc29sZS5sb2coYFxyXG4gICAgICAgICAgICAgICAgLy8gICAgICB0ZXh0OiAke3RleHR1cmUuR2V0SWQoKX1cclxuICAgICAgICAgICAgICAgIC8vICAgICAgcmVuZDogJHt0ZXh0dXJlLkdldENhblJlbmRlcigpfWApO1xyXG4gICAgICAgICAgICAgICAgLy8gfVxyXG4gICAgICAgICAgICAgICAgdGhpcy5EcmF3QXNSZWN0KGRyYXdhYmxlLCBjYW52LCBkcmF3TG9jYXRpb25YLCBkcmF3TG9jYXRpb25ZLCBkcmF3U2l6ZVgsIGRyYXdTaXplWSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIGRldHJhbnNsYXRlcyB0aGUgY2FudmFzXHJcbiAgICAgICAgICAgIGNhbnYuY3R4LnRyYW5zbGF0ZSgtKHRyYW5zbGF0ZVgpLCAtKHRyYW5zbGF0ZVkpKTtcclxuICAgICAgICAgICAgY2Fudi5jdHgucmVzdG9yZSgpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvLyBwcml2YXRlIHJvdGF0ZShjdHgpIHtcclxuICAgIC8vICAgICAvL0NvbnZlcnQgZGVncmVlcyB0byByYWRpYW4gXHJcbiAgICAvLyAgICAgdmFyIHJhZCA9IGRlZyAqIE1hdGguUEkgLyAxODA7XHJcblxyXG4gICAgLy8gICAgIC8vU2V0IHRoZSBvcmlnaW4gdG8gdGhlIGNlbnRlciBvZiB0aGUgaW1hZ2VcclxuICAgIC8vICAgICBjdHgudHJhbnNsYXRlKHggKyB3aWR0aCAvIDIsIHkgKyBoZWlnaHQgLyAyKTtcclxuXHJcbiAgICAvLyAgICAgLy9Sb3RhdGUgdGhlIGNhbnZhcyBhcm91bmQgdGhlIG9yaWdpblxyXG4gICAgLy8gICAgIGN0eC5yb3RhdGUocmFkKTtcclxuXHJcbiAgICAvLyAgICAgLy9kcmF3IHRoZSBpbWFnZSAgICBcclxuICAgIC8vICAgICBjdHguZHJhd0ltYWdlKGltZywgd2lkdGggLyAyICogKC0xKSwgaGVpZ2h0IC8gMiAqICgtMSksIHdpZHRoLCBoZWlnaHQpO1xyXG5cclxuICAgIC8vICAgICAvL3Jlc2V0IHRoZSBjYW52YXMgIFxyXG4gICAgLy8gICAgIGN0eC5yb3RhdGUocmFkICogKC0xKSk7XHJcbiAgICAvLyAgICAgY3R4LnRyYW5zbGF0ZSgoeCArIHdpZHRoIC8gMikgKiAoLTEpLCAoeSArIGhlaWdodCAvIDIpICogKC0xKSk7XHJcblxyXG4gICAgLy8gfVxyXG5cclxuICAgIERyYXdBc1RleHR1cmUodGV4dHVyZTogVGV4dHVyZTJELCBjYW52OiBEcmF3YWJsZUNhbnZhcyxcclxuICAgICAgICBkcmF3TG9jYXRpb25YOiBudW1iZXIsIGRyYXdMb2NhdGlvblk6IG51bWJlciwgZHJhd1NpemVYOiBudW1iZXIsIGRyYXdTaXplWTogbnVtYmVyKSB7XHJcblxyXG4gICAgICAgIGNhbnYuY3R4LnN0cm9rZVN0eWxlID0gJyNmZmYnO1xyXG4gICAgICAgIGNhbnYuY3R4LnN0cm9rZVJlY3QoXHJcbiAgICAgICAgICAgIGRyYXdMb2NhdGlvblgsXHJcbiAgICAgICAgICAgIGRyYXdMb2NhdGlvblksXHJcbiAgICAgICAgICAgIGRyYXdTaXplWCxcclxuICAgICAgICAgICAgZHJhd1NpemVZXHJcbiAgICAgICAgKTtcclxuXHJcblxyXG5cclxuICAgICAgICBjYW52LmN0eC5kcmF3SW1hZ2UodGV4dHVyZS5HZXRJbWFnZSgpLFxyXG4gICAgICAgICAgICBkcmF3TG9jYXRpb25YLFxyXG4gICAgICAgICAgICBkcmF3TG9jYXRpb25ZLFxyXG4gICAgICAgICAgICBkcmF3U2l6ZVgsXHJcbiAgICAgICAgICAgIGRyYXdTaXplWSk7XHJcblxyXG5cclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIERyYXdBc1JlY3QoZHJhd2FibGU6IERyYXdhYmxlLCBjYW52OiBEcmF3YWJsZUNhbnZhcyxcclxuICAgICAgICBkcmF3TG9jYXRpb25YOiBudW1iZXIsIGRyYXdMb2NhdGlvblk6IG51bWJlciwgZHJhd1NpemVYOiBudW1iZXIsIGRyYXdTaXplWTogbnVtYmVyKSB7XHJcblxyXG4gICAgICAgIGlmICh0aGlzLmRyYXdBc1N0cm9rZSkge1xyXG4gICAgICAgICAgICBjYW52LmN0eC5zdHJva2VTdHlsZSA9IGRyYXdhYmxlLkdldENvbG91cigpO1xyXG4gICAgICAgICAgICBjYW52LmN0eC5zdHJva2VSZWN0KFxyXG4gICAgICAgICAgICAgICAgZHJhd0xvY2F0aW9uWCxcclxuICAgICAgICAgICAgICAgIGRyYXdMb2NhdGlvblksXHJcbiAgICAgICAgICAgICAgICBkcmF3U2l6ZVgsXHJcbiAgICAgICAgICAgICAgICBkcmF3U2l6ZVlcclxuICAgICAgICAgICAgKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBjYW52LmN0eC5maWxsU3R5bGUgPSBkcmF3YWJsZS5HZXRDb2xvdXIoKTtcclxuICAgICAgICAgICAgY2Fudi5jdHguZmlsbFJlY3QoXHJcbiAgICAgICAgICAgICAgICBkcmF3TG9jYXRpb25YLFxyXG4gICAgICAgICAgICAgICAgZHJhd0xvY2F0aW9uWSxcclxuICAgICAgICAgICAgICAgIGRyYXdTaXplWCxcclxuICAgICAgICAgICAgICAgIGRyYXdTaXplWVxyXG4gICAgICAgICAgICApO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxyXG5cclxuIiwiZXhwb3J0IGNsYXNzIEh0bWxTZXJ2aWNlIHtcclxuICAgIHByaXZhdGUgbWFpbkRpdjogSFRNTERpdkVsZW1lbnQ7XHJcblxyXG4gICAgY29uc3RydWN0b3IoKSB7XHJcbiAgICAgICAgY29uc29sZS5sb2coJ2NyZWF0aW5nIEh0bWwgSGVscGVyIFNlcnZpY2UgaW4gR3JhcGhpY3MnKTtcclxuICAgIH1cclxuXHJcbiAgICBJbml0KCkge1xyXG4gICAgICAgIHRoaXMuY3JlYXRlTWFpbkRpdignbWFpbl9kaXYnKTtcclxuICAgIH1cclxuXHJcblxyXG4gICAgR2V0TWFpbkRpdigpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5tYWluRGl2O1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgY3JlYXRlTWFpbkRpdihpZDogc3RyaW5nID0gJ21haW5fZGl2Jyk6IHN0cmluZyB7XHJcbiAgICAgICAgdGhpcy5tYWluRGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XHJcbiAgICAgICAgdGhpcy5tYWluRGl2LmlkID0gaWQ7XHJcbiAgICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZCh0aGlzLm1haW5EaXYpO1xyXG4gICAgICAgIHJldHVybiB0aGlzLm1haW5EaXYuaWQ7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGNyZWF0ZUNhbnZhcyhpZDogc3RyaW5nLCBhdHRhdGNoVG86IHN0cmluZywgd2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIsIGNsYXNzTGlzdDogc3RyaW5nW10gPSBudWxsKTogSFRNTENhbnZhc0VsZW1lbnQge1xyXG4gICAgICAgIGNvbnN0IGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xyXG4gICAgICAgIGNhbnZhcy5pZCA9IGlkO1xyXG4gICAgICAgIGNhbnZhcy53aWR0aCA9IHdpZHRoO1xyXG4gICAgICAgIGNhbnZhcy5oZWlnaHQgPSBoZWlnaHQ7XHJcbiAgICAgICAgaWYgKGNsYXNzTGlzdCAhPSBudWxsKSB7XHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY2xhc3NMaXN0Lmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICBjYW52YXMuY2xhc3NMaXN0LmFkZChjbGFzc0xpc3RbaV0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGF0dGF0Y2hUbykuYXBwZW5kQ2hpbGQoY2FudmFzKTtcclxuICAgICAgICByZXR1cm4gY2FudmFzO1xyXG4gICAgfVxyXG59IiwiZXhwb3J0IGNsYXNzIEltYWdlSGVscGVye1xyXG4gICAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgYXNzZXRCYXNlUGF0aDogc3RyaW5nID0gJy4vYXNzZXRzL19kaXN0Lyc7XHJcbiAgICBzdGF0aWMgTmV3SW1hZ2UocGF0aDogc3RyaW5nKTogSFRNTEltYWdlRWxlbWVudCB7XHJcbiAgICAgICAgY29uc3QgaW1hZ2UgPSBuZXcgSW1hZ2UoMTI4LCAxMjgpO1xyXG4gICAgICAgIGltYWdlLnNyYyA9IHRoaXMuYXNzZXRCYXNlUGF0aCArIHBhdGg7XHJcbiAgICAgICAgaW1hZ2Uub25lcnJvciA9ICgoZXZlbnQpID0+IHRoaXMub25FcnJvcihldmVudCkpO1xyXG4gICAgICAgIHJldHVybiBpbWFnZTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIHN0YXRpYyBvbkVycm9yKGVycm9yOiBzdHJpbmcgfCBFdmVudCkge1xyXG4gICAgICAgIGNvbnNvbGUubG9nKCdlcnJvciBsb2FkaW5nIGltYWdlJywgZXJyb3IpO1xyXG4gICAgICAgIHJldHVybjtcclxuICAgIH0gICBcclxufSIsImltcG9ydCB7IFZlY3RvcjIgfSBmcm9tIFwiLi4vLi4vLi4vbnVtZXJpY3MvbW9kZWxzL1ZlY3RvcjIubW9kZWxcIjtcclxuXHJcbmV4cG9ydCBjbGFzcyBEcmF3YWJsZUNhbnZhcyBleHRlbmRzIFZlY3RvcjIge1xyXG4gICAgcHVibGljIGNhbnZhczogSFRNTENhbnZhc0VsZW1lbnQ7XHJcbiAgICBwdWJsaWMgY3R4OiBDYW52YXNSZW5kZXJpbmdDb250ZXh0MkQ7XHJcbiAgICBwdWJsaWMgaWQ6IHN0cmluZztcclxuICAgIGNvbnN0cnVjdG9yKGNhbnZhczogSFRNTENhbnZhc0VsZW1lbnQsIGlkOiBzdHJpbmcsXHJcbiAgICAgICAgd2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIpIHtcclxuICAgICAgICBzdXBlcih3aWR0aCwgaGVpZ2h0KTtcclxuICAgICAgICB0aGlzLmlkID0gaWQ7XHJcbiAgICAgICAgdGhpcy5jYW52YXMgPSBjYW52YXM7XHJcbiAgICAgICAgdGhpcy5jdHggPSB0aGlzLmNhbnZhcy5nZXRDb250ZXh0KCcyZCcpO1xyXG4gICAgfVxyXG5cclxuICAgIHByb3RlY3RlZCBHZXRXaWR0aCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5nZXRWYWx1ZVgoKTtcclxuICAgIH1cclxuICAgIHByb3RlY3RlZCBHZXRIZWlnaHQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0VmFsdWVZKCk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIENsZWFyQ2FudmFzKCkge1xyXG4gICAgICAgIHRoaXMuY3R4LmNsZWFyUmVjdCgwLCAwLCB0aGlzLmdldFZhbHVlWCgpLCB0aGlzLmdldFZhbHVlWSgpKTtcclxuXHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIFBhaW50SW1tZWRpYXRlbHkoKSB7XHJcbiAgICAgICAgdGhpcy5jdHguZHJhd0ltYWdlKHRoaXMuY2FudmFzLCAwLCAwKTtcclxuICAgIH1cclxuXHJcbn0iLCJpbXBvcnQgeyBHdWlkR2VuZXJhdG9yIH0gZnJvbSBcIi4uLy4uL1Rvb2xzL3JhbmRvbV9nZW5lcmF0b3JzL3JhbmRvbV9ndWlkLmdlbmVyYXRvclwiO1xyXG5pbXBvcnQgeyBJbWFnZUhlbHBlciB9IGZyb20gXCIuLi9JbWFnZXMvSW1hZ2VIZWxwZXJcIjtcclxuXHJcbmV4cG9ydCBjbGFzcyBUZXh0dXJlMkQge1xyXG4gICAgcHJpdmF0ZSBpZDogc3RyaW5nO1xyXG4gICAgcHJpdmF0ZSB1cmw6IHN0cmluZztcclxuICAgIHByaXZhdGUgaW1hZ2U6IEhUTUxJbWFnZUVsZW1lbnQ7XHJcbiAgICBwcml2YXRlIGltYWdlQ2FuUmVuZGVyOiBib29sZWFuO1xyXG4gICAgcHJpdmF0ZSBwYXRoOiBzdHJpbmc7XHJcblxyXG4gICAgY29uc3RydWN0b3IocGF0aDogc3RyaW5nKSB7XHJcbiAgICAgICAgdGhpcy5wYXRoID0gcGF0aDtcclxuICAgICAgICB0aGlzLnVybCA9IHBhdGg7XHJcbiAgICAgICAgdGhpcy5pZCA9IEd1aWRHZW5lcmF0b3IuTmV3R3VpZCgpO1xyXG4gICAgICAgIHRoaXMuaW1hZ2UgPSBJbWFnZUhlbHBlci5OZXdJbWFnZSh0aGlzLnVybCk7XHJcbiAgICAgICAgdGhpcy5pbWFnZS5vbmxvYWQgPSAoKCkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLmltYWdlQ2FuUmVuZGVyID0gdHJ1ZTtcclxuICAgICAgICB9KVxyXG4gICAgICAgIHRoaXMuaW1hZ2Uub25lcnJvciA9ICgoKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuaW1hZ2VDYW5SZW5kZXIgPSBmYWxzZTtcclxuICAgICAgICAgICAgY29uc29sZS5lcnJvcigndGV4dDJkOiBpbWFnZSBjb3VsZCBub3QgcmVuZGVyJylcclxuICAgICAgICB9KVxyXG5cclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgR2V0UGF0aCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5wYXRoO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0SWRcclxuICAgICAqL1xyXG4gICAgcHVibGljIEdldElkKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmlkO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0VXJsXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBHZXRJbWFnZSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5pbWFnZTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIHJldHVybnMgaW1hZ2VDYW5SZW5kZXIuIElmIHRoZSBpbWFnZSBpcyBzdWNjZXNzZnVsbHkgbG9hZGVkLCBcclxuICAgICAqIHRoaXMgcmV0dXJucyB0cnVlLiBPdGhlcndpc2UgcmV0dXJucyBmYWxzZVxyXG4gICAgICpcclxuICAgICAqIEByZXR1cm5zXHJcbiAgICAgKiBAbWVtYmVyb2YgVGV4dHVyZTJEXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBHZXRDYW5SZW5kZXIoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuaW1hZ2VDYW5SZW5kZXI7XHJcbiAgICB9XHJcbn0iLCJpbXBvcnQgeyBUZXh0dXJlMkQgfSBmcm9tIFwiLi9UZXh0dXJlMmRcIjtcclxuXHJcbmV4cG9ydCBjbGFzcyBUZXh0dXJlU2VydmljZSB7XHJcbiAgICB0ZXh0dXJlczogQXJyYXk8VGV4dHVyZTJEPjtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcigpIHtcclxuICAgICAgICBjb25zb2xlLmxvZygnY29uc3RydWN0aW5nIHRleHR1cmUgc2VydmljZScpO1xyXG4gICAgICAgIHRoaXMudGV4dHVyZXMgPSBuZXcgQXJyYXk8VGV4dHVyZTJEPigpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBHZXRUZXh0dXJlKHRleHR1cmVJZDogc3RyaW5nKTogVGV4dHVyZTJEIHtcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMudGV4dHVyZXMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgaWYgKHRleHR1cmVJZCA9PT0gdGhpcy50ZXh0dXJlc1tpXS5HZXRJZCgpKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy50ZXh0dXJlc1tpXTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiByZWdpc3RlcnMgYSBuZXcgdGV4dHVyZSBpbiB0aGUgc2VydmljZS4gSWYgdGhlIHRleHR1cmUgYWxyZWFkeVxyXG4gICAgICogZXhpc3RzLCB0aHJvd3MgYW4gZXJyb3IgYW5kIHJldHVybnMgdGhlIGV4aXN0aW5nIG9uZVxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0dXJlUGF0aFxyXG4gICAgICogQHJldHVybnMge3N0cmluZ31cclxuICAgICAqIEBtZW1iZXJvZiBUZXh0dXJlU2VydmljZVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgUmVnaXN0ZXJOZXdUZXh0dXJlKHRleHR1cmVQYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy50ZXh0dXJlcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBjb25zdCB0aGlzVGV4dFBhdGggPSB0aGlzLnRleHR1cmVzW2ldLkdldFBhdGgoKVxyXG4gICAgICAgICAgICBpZiAodGhpc1RleHRQYXRoID09PSB0ZXh0dXJlUGF0aCkge1xyXG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignYXR0ZW1wdGVkIHRvIGNyZWF0ZSBhIHRleHR1cmUgYSBzZWNvbmQgdGltZScpXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy50ZXh0dXJlc1tpXS5HZXRJZCgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IG5ld1RleHR1cmUgPSBuZXcgVGV4dHVyZTJEKHRleHR1cmVQYXRoKTtcclxuICAgICAgICB0aGlzLnRleHR1cmVzLnB1c2gobmV3VGV4dHVyZSk7XHJcbiAgICAgICAgY29uc29sZS53YXJuKGB0ZXh0dXJlIHN0YWNrIGlzIG5vdyBbJHt0aGlzLnRleHR1cmVzLmxlbmd0aH1dIGxvbmdgKVxyXG4gICAgICAgIHJldHVybiBuZXdUZXh0dXJlLkdldElkKCk7XHJcbiAgICB9XHJcbn0iLCJpbXBvcnQgeyBUaWxlVHlwZSB9IGZyb20gXCIuLi9fYmFzZS10aWxldHlwZVwiO1xyXG5cclxuZXhwb3J0IGNsYXNzIERpcnRUaWxlVHlwZSBleHRlbmRzIFRpbGVUeXBlIHtcclxuICAgIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgdGV4dHVyZVBhdGg6IHN0cmluZyA9ICcvVGlsZXMvZ3JvdW5kL2RpcnQucG5nJztcclxuICAgIGNvbnN0cnVjdG9yKGlkOiBudW1iZXIsIHRleHRJZDogc3RyaW5nKSB7XHJcbiAgICAgICAgc3VwZXIoaWQsICcjOTE2RDQ5JywgdGV4dElkKTtcclxuICAgIH1cclxufSIsImltcG9ydCB7IFRpbGVUeXBlIH0gZnJvbSBcIi4uL19iYXNlLXRpbGV0eXBlXCI7XHJcblxyXG5leHBvcnQgY2xhc3MgR3Jhc3NUaWxlVHlwZSBleHRlbmRzIFRpbGVUeXBlIHtcclxuICAgIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgdGV4dHVyZVBhdGg6IHN0cmluZyA9ICcvVGlsZXMvZ3JvdW5kL2dyYXNzLnBuZyc7XHJcbiAgICBjb25zdHJ1Y3RvcihpZDogbnVtYmVyLCB0ZXh0SWQ6IHN0cmluZykge1xyXG4gICAgICAgIHN1cGVyKGlkLCAnIzQzODMzNycsIHRleHRJZCk7XHJcbiAgICB9XHJcbn1cclxuXHJcbmV4cG9ydCBjbGFzcyBHcmFzc1RpbGVUeXBlRGlydCBleHRlbmRzIFRpbGVUeXBlIHtcclxuICAgIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgdGV4dHVyZVBhdGg6IHN0cmluZyA9ICcvVGlsZXMvZ3JvdW5kL2dyYXNzX3dpdGhfZGlydF9taWRkbGUucG5nJztcclxuICAgIGNvbnN0cnVjdG9yKGlkOiBudW1iZXIsIHRleHRJZDogc3RyaW5nKSB7XHJcbiAgICAgICAgc3VwZXIoaWQsICcjODdDQzZGJywgdGV4dElkKTtcclxuICAgIH1cclxufVxyXG5cclxuZXhwb3J0IGNsYXNzIEdyYXNzVGlsZVR5cGVEaXJ0VG9wIGV4dGVuZHMgVGlsZVR5cGUge1xyXG4gICAgcHVibGljIHN0YXRpYyByZWFkb25seSB0ZXh0dXJlUGF0aDogc3RyaW5nID0gJy9UaWxlcy9ncm91bmQvZ3Jhc3Nfd2l0aF9kaXJ0X3RvcC5wbmcnO1xyXG4gICAgY29uc3RydWN0b3IoaWQ6IG51bWJlciwgdGV4dElkOiBzdHJpbmcpIHtcclxuICAgICAgICBzdXBlcihpZCwgJyM0MzgzMzcnLCB0ZXh0SWQpO1xyXG4gICAgfVxyXG59XHJcblxyXG5leHBvcnQgY2xhc3MgR3Jhc3NUaWxlVHlwZURpcnRSaWdodCBleHRlbmRzIFRpbGVUeXBlIHtcclxuICAgIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgdGV4dHVyZVBhdGg6IHN0cmluZyA9ICcvVGlsZXMvZ3JvdW5kL2dyYXNzX3dpdGhfZGlydF9yaWdodC5wbmcnO1xyXG4gICAgY29uc3RydWN0b3IoaWQ6IG51bWJlciwgdGV4dElkOiBzdHJpbmcpIHtcclxuICAgICAgICBzdXBlcihpZCwgJyM0MzgzMzcnLCB0ZXh0SWQpO1xyXG4gICAgfVxyXG59XHJcblxyXG5leHBvcnQgY2xhc3MgR3Jhc3NUaWxlVHlwZURpcnRCb3R0b20gZXh0ZW5kcyBUaWxlVHlwZSB7XHJcbiAgICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IHRleHR1cmVQYXRoOiBzdHJpbmcgPSAnL1RpbGVzL2dyb3VuZC9ncmFzc193aXRoX2RpcnRfYm90dG9tLnBuZyc7XHJcbiAgICBjb25zdHJ1Y3RvcihpZDogbnVtYmVyLCB0ZXh0SWQ6IHN0cmluZykge1xyXG4gICAgICAgIHN1cGVyKGlkLCAnIzQzODMzNycsIHRleHRJZCk7XHJcbiAgICB9XHJcbn1cclxuXHJcbmV4cG9ydCBjbGFzcyBHcmFzc1RpbGVUeXBlRGlydExlZnQgZXh0ZW5kcyBUaWxlVHlwZSB7XHJcbiAgICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IHRleHR1cmVQYXRoOiBzdHJpbmcgPSAnL1RpbGVzL2dyb3VuZC9ncmFzc193aXRoX2RpcnRfbGVmdC5wbmcnO1xyXG4gICAgY29uc3RydWN0b3IoaWQ6IG51bWJlciwgdGV4dElkOiBzdHJpbmcpIHtcclxuICAgICAgICBzdXBlcihpZCwgJyM0MzgzMzcnLCB0ZXh0SWQpO1xyXG4gICAgfVxyXG59XHJcblxyXG5leHBvcnQgY2xhc3MgR3Jhc3NUaWxlVHlwZURpcnRNaWRkbGUgZXh0ZW5kcyBUaWxlVHlwZSB7XHJcbiAgICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IHRleHR1cmVQYXRoOiBzdHJpbmcgPSAnL1RpbGVzL2dyb3VuZC9ncmFzc193aXRoX2RpcnRfbWlkZGxlLnBuZyc7XHJcbiAgICBjb25zdHJ1Y3RvcihpZDogbnVtYmVyLCB0ZXh0SWQ6IHN0cmluZykge1xyXG4gICAgICAgIHN1cGVyKGlkLCAnIzQzODMzNycsIHRleHRJZCk7XHJcbiAgICB9XHJcbn1cclxuXHJcbiIsImltcG9ydCB7IFRpbGVUeXBlIH0gZnJvbSBcIi4uL19iYXNlLXRpbGV0eXBlXCI7XHJcblxyXG5leHBvcnQgY2xhc3MgU2FuZFRpbGVUeXBlIGV4dGVuZHMgVGlsZVR5cGUge1xyXG4gICAgcHVibGljIHN0YXRpYyByZWFkb25seSB0ZXh0dXJlUGF0aDogc3RyaW5nID0gJy9UaWxlcy9ncm91bmQvc2FuZC5wbmcnO1xyXG4gICAgY29uc3RydWN0b3IoaWQ6IG51bWJlciwgdGV4dElkOiBzdHJpbmcpIHtcclxuICAgICAgICBzdXBlcihpZCwgJyNDMUMxMjgnLCB0ZXh0SWQpO1xyXG4gICAgfVxyXG59XHJcblxyXG5leHBvcnQgY2xhc3MgU2FuZFRpbGVUeXBlR3Jhc3NUb3AgZXh0ZW5kcyBUaWxlVHlwZSB7XHJcbiAgICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IHRleHR1cmVQYXRoOiBzdHJpbmcgPSAnL1RpbGVzL2dyb3VuZC9zYW5kX2dyYXNzX3RvcC5wbmcnO1xyXG4gICAgY29uc3RydWN0b3IoaWQ6IG51bWJlciwgdGV4dElkOiBzdHJpbmcpIHtcclxuICAgICAgICBzdXBlcihpZCwgJyNDMUMxMjgnLCB0ZXh0SWQpO1xyXG4gICAgfVxyXG59XHJcblxyXG5leHBvcnQgY2xhc3MgU2FuZFRpbGVUeXBlR3Jhc3NSaWdodCBleHRlbmRzIFRpbGVUeXBlIHtcclxuICAgIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgdGV4dHVyZVBhdGg6IHN0cmluZyA9ICcvVGlsZXMvZ3JvdW5kL3NhbmRfZ3Jhc3NfcmlnaHQucG5nJztcclxuICAgIGNvbnN0cnVjdG9yKGlkOiBudW1iZXIsIHRleHRJZDogc3RyaW5nKSB7XHJcbiAgICAgICAgc3VwZXIoaWQsICcjQzFDMTI4JywgdGV4dElkKTtcclxuICAgIH1cclxufVxyXG5cclxuZXhwb3J0IGNsYXNzIFNhbmRUaWxlVHlwZUdyYXNzQm90dG9tIGV4dGVuZHMgVGlsZVR5cGUge1xyXG4gICAgcHVibGljIHN0YXRpYyByZWFkb25seSB0ZXh0dXJlUGF0aDogc3RyaW5nID0gJy9UaWxlcy9ncm91bmQvc2FuZF9ncmFzc19ib3R0b20ucG5nJztcclxuICAgIGNvbnN0cnVjdG9yKGlkOiBudW1iZXIsIHRleHRJZDogc3RyaW5nKSB7XHJcbiAgICAgICAgc3VwZXIoaWQsICcjQzFDMTI4JywgdGV4dElkKTtcclxuICAgIH1cclxufVxyXG5cclxuZXhwb3J0IGNsYXNzIFNhbmRUaWxlVHlwZUdyYXNzTGVmdCBleHRlbmRzIFRpbGVUeXBlIHtcclxuICAgIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgdGV4dHVyZVBhdGg6IHN0cmluZyA9ICcvVGlsZXMvZ3JvdW5kL3NhbmRfZ3Jhc3NfbGVmdC5wbmcnO1xyXG4gICAgY29uc3RydWN0b3IoaWQ6IG51bWJlciwgdGV4dElkOiBzdHJpbmcpIHtcclxuICAgICAgICBzdXBlcihpZCwgJyNDMUMxMjgnLCB0ZXh0SWQpO1xyXG4gICAgfVxyXG59IiwiaW1wb3J0IHsgVGlsZVR5cGUgfSBmcm9tIFwiLi4vX2Jhc2UtdGlsZXR5cGVcIjtcclxuXHJcbmV4cG9ydCBjbGFzcyBTaGFsbG93V2F0ZXJUaWxlVHlwZSBleHRlbmRzIFRpbGVUeXBlIHtcclxuICAgIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgdGV4dHVyZVBhdGg6IHN0cmluZyA9ICcvVGlsZXMvZ3JvdW5kL3NoYWxsb3dfd2F0ZXIucG5nJztcclxuICAgIGNvbnN0cnVjdG9yKGlkOiBudW1iZXIsIHRleHRJZDogc3RyaW5nKSB7XHJcbiAgICAgICAgc3VwZXIoaWQsICcjNDM4MEU0JywgdGV4dElkKTtcclxuICAgIH1cclxufVxyXG5cclxuZXhwb3J0IGNsYXNzIFNoYWxsb3dXYXRlclRpbGVUeXBlU2FuZFRvcCBleHRlbmRzIFRpbGVUeXBlIHtcclxuICAgIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgdGV4dHVyZVBhdGg6IHN0cmluZyA9ICcvVGlsZXMvZ3JvdW5kL3NoYWxsb3dfd2F0ZXJfc2FuZF90b3AucG5nJztcclxuICAgIGNvbnN0cnVjdG9yKGlkOiBudW1iZXIsIHRleHRJZDogc3RyaW5nKSB7XHJcbiAgICAgICAgc3VwZXIoaWQsICcjNDM4MEU0JywgdGV4dElkKTtcclxuICAgIH1cclxufVxyXG5cclxuZXhwb3J0IGNsYXNzIFNoYWxsb3dXYXRlclRpbGVUeXBlU2FuZFJpZ2h0IGV4dGVuZHMgVGlsZVR5cGUge1xyXG4gICAgcHVibGljIHN0YXRpYyByZWFkb25seSB0ZXh0dXJlUGF0aDogc3RyaW5nID0gJy9UaWxlcy9ncm91bmQvc2hhbGxvd193YXRlcl9zYW5kX3JpZ2h0LnBuZyc7XHJcbiAgICBjb25zdHJ1Y3RvcihpZDogbnVtYmVyLCB0ZXh0SWQ6IHN0cmluZykge1xyXG4gICAgICAgIHN1cGVyKGlkLCAnIzQzODBFNCcsIHRleHRJZCk7XHJcbiAgICB9XHJcbn1cclxuXHJcbmV4cG9ydCBjbGFzcyBTaGFsbG93V2F0ZXJUaWxlVHlwZVNhbmRCb3R0b20gZXh0ZW5kcyBUaWxlVHlwZSB7XHJcbiAgICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IHRleHR1cmVQYXRoOiBzdHJpbmcgPSAnL1RpbGVzL2dyb3VuZC9zaGFsbG93X3dhdGVyX3NhbmRfYm90dG9tLnBuZyc7XHJcbiAgICBjb25zdHJ1Y3RvcihpZDogbnVtYmVyLCB0ZXh0SWQ6IHN0cmluZykge1xyXG4gICAgICAgIHN1cGVyKGlkLCAnIzQzODBFNCcsIHRleHRJZCk7XHJcbiAgICB9XHJcbn1cclxuXHJcbmV4cG9ydCBjbGFzcyBTaGFsbG93V2F0ZXJUaWxlVHlwZVNhbmRMZWZ0IGV4dGVuZHMgVGlsZVR5cGUge1xyXG4gICAgcHVibGljIHN0YXRpYyByZWFkb25seSB0ZXh0dXJlUGF0aDogc3RyaW5nID0gJy9UaWxlcy9ncm91bmQvc2hhbGxvd193YXRlcl9zYW5kX2xlZnQucG5nJztcclxuICAgIGNvbnN0cnVjdG9yKGlkOiBudW1iZXIsIHRleHRJZDogc3RyaW5nKSB7XHJcbiAgICAgICAgc3VwZXIoaWQsICcjNDM4MEU0JywgdGV4dElkKTtcclxuICAgIH1cclxufSIsImltcG9ydCB7IFRpbGVUeXBlIH0gZnJvbSBcIi4uL19iYXNlLXRpbGV0eXBlXCI7XHJcblxyXG5leHBvcnQgY2xhc3MgU3RvbmVUaWxlVHlwZSBleHRlbmRzIFRpbGVUeXBlIHtcclxuICAgIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgdGV4dHVyZVBhdGg6IHN0cmluZyA9ICcvVGlsZXMvZ3JvdW5kL3N0b25lLnBuZyc7XHJcbiAgICBjb25zdHJ1Y3RvcihpZDogbnVtYmVyLCB0ZXh0SWQ6IHN0cmluZykge1xyXG4gICAgICAgIHN1cGVyKGlkLCAnIzUyNTA0RicsIHRleHRJZCk7XHJcbiAgICB9XHJcbn0iLCJpbXBvcnQgeyBUaWxlVHlwZSB9IGZyb20gXCIuLi9fYmFzZS10aWxldHlwZVwiO1xyXG5cclxuZXhwb3J0IGNsYXNzIFNwYWNlVGlsZVR5cGUgZXh0ZW5kcyBUaWxlVHlwZSB7XHJcbiAgICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IHRleHR1cmVQYXRoOiBzdHJpbmcgPSAnL1RpbGVzL3NwYWNlX3RpbGUucG5nJztcclxuICAgIGNvbnN0cnVjdG9yKGlkOiBudW1iZXIsIHRleHRJZDogc3RyaW5nKSB7XHJcbiAgICAgICAgc3VwZXIoaWQsICcjMUMxQzFCJywgdGV4dElkKTtcclxuICAgIH1cclxufVxyXG4iLCJpbXBvcnQgeyBUaWxlVHlwZSB9IGZyb20gXCIuLi9fYmFzZS10aWxldHlwZVwiO1xyXG5cclxuZXhwb3J0IGNsYXNzIFN0YXJUaWxlVHlwZSBleHRlbmRzIFRpbGVUeXBlIHtcclxuICAgIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgdGV4dHVyZVBhdGg6IHN0cmluZyA9ICcvVGlsZXMvc3BhY2VfdGlsZTIucG5nJztcclxuICAgIGNvbnN0cnVjdG9yKGlkOiBudW1iZXIsIHRleHRJZDogc3RyaW5nKSB7XHJcbiAgICAgICAgc3VwZXIoaWQsICcjMDYwOTQ4JywgdGV4dElkKTtcclxuICAgIH1cclxufSIsImV4cG9ydCBjbGFzcyBUaWxlVHlwZSB7XHJcblxyXG4gICAgcHJvdGVjdGVkIHJlYWRvbmx5IGlkOiBudW1iZXI7XHJcbiAgICBwcml2YXRlIHJlYWRvbmx5IHRleHR1cmVJZDogc3RyaW5nO1xyXG4gICAgcHJvdGVjdGVkIHJlYWRvbmx5IGZhbGxiYWNrT3V0bGluZUNvbG91cjogc3RyaW5nO1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKGlkOiBudW1iZXIsIGZhbGxiYWNrT3V0bGluZUNvbG91cjogc3RyaW5nLFxyXG4gICAgICAgIHRleHR1cmVJZDogc3RyaW5nKSB7XHJcbiAgICAgICAgdGhpcy50ZXh0dXJlSWQgPSB0ZXh0dXJlSWQ7XHJcbiAgICAgICAgdGhpcy5pZCA9IGlkO1xyXG4gICAgICAgIHRoaXMuZmFsbGJhY2tPdXRsaW5lQ29sb3VyID0gZmFsbGJhY2tPdXRsaW5lQ29sb3VyO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBUaWNrKCk6IHZvaWQge1xyXG5cclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgR2V0VGV4dHVyZUlkKCk6IHN0cmluZyB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMudGV4dHVyZUlkO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBHZXRJZCgpOiBudW1iZXIge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmlkO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBHZXRGYWxsYmFja0NvbG91cigpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5mYWxsYmFja091dGxpbmVDb2xvdXI7XHJcbiAgICB9XHJcbn1cclxuIiwiaW1wb3J0IHsgVmVjdG9yMiB9IGZyb20gXCIuLi8uLi8uLi9udW1lcmljcy9tb2RlbHMvVmVjdG9yMi5tb2RlbFwiO1xyXG5pbXBvcnQgeyBEcmF3YWJsZSB9IGZyb20gXCIuLi9EcmF3L2RyYXdhYmxlXCI7XHJcblxyXG5leHBvcnQgY2xhc3MgRHJhd2FibGVUaWxlIGV4dGVuZHMgRHJhd2FibGUge1xyXG4gICAgcHJpdmF0ZSByZWFkb25seSB0aWxlVHlwZUlkOiBudW1iZXI7XHJcblxyXG4gICAgY29uc3RydWN0b3IodGlsZVR5cGVJZDogbnVtYmVyLCBwb3NpdGlvbjogVmVjdG9yMiwgc2l6ZTogVmVjdG9yMiwgZmFsbGJhY2tPdXRsaW5lQ29sb3VyOiBzdHJpbmcsIGNhbnZhc0lkOiBzdHJpbmcsXHJcbiAgICAgICAgdGV4dHVyZUlkOiBzdHJpbmcpIHtcclxuICAgICAgICBzdXBlcihwb3NpdGlvbiwgc2l6ZSwgY2FudmFzSWQsIHRleHR1cmVJZCk7XHJcbiAgICAgICAgdGhpcy50aWxlVHlwZUlkID0gdGlsZVR5cGVJZDtcclxuICAgICAgICB0aGlzLmNvbG91ciA9IGZhbGxiYWNrT3V0bGluZUNvbG91cjtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgZ2V0VGlsZVR5cGVJZCgpOiBudW1iZXIge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnRpbGVUeXBlSWQ7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGdldFBvc2l0aW9uKCk6IFZlY3RvcjIge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnBvc2l0aW9uO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBnZXRTaXplKCk6IFZlY3RvcjIge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnNpemU7XHJcbiAgICB9XHJcbn0iLCJpbXBvcnQgeyBWZWN0b3IyIH0gZnJvbSBcIi4uLy4uLy4uL251bWVyaWNzL21vZGVscy9WZWN0b3IyLm1vZGVsXCI7XHJcblxyXG5leHBvcnQgY2xhc3MgVGlsZURlZmF1bHRTZXR0aW5ncyB7XHJcbiAgICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IERFRkFVTFRfU0laRTogVmVjdG9yMiA9IG5ldyBWZWN0b3IyKDY0LCA2NCk7XHJcbn0iLCJpbXBvcnQgeyBUaWxlVHlwZSB9IGZyb20gXCIuL1RpbGVUeXBlcy9fYmFzZS10aWxldHlwZVwiO1xyXG5pbXBvcnQgeyBDYW52YXNTZXJ2aWNlIH0gZnJvbSBcIi4uL0NhbnZhcy9ncmFwaGljcy5jYW52YXMuc2VydmljZVwiO1xyXG5pbXBvcnQgeyBTcGFjZVRpbGVUeXBlIH0gZnJvbSBcIi4vVGlsZVR5cGVzL1NwYWNlVGlsZVR5cGVzL3NwYWNlLnRpbGV0eXBlXCI7XHJcbmltcG9ydCB7IEdyYXBoaWNzU2VydmljZSB9IGZyb20gXCIuLi9ncmFwaGljcy5zZXJ2aWNlXCI7XHJcbmltcG9ydCB7IFZlY3RvcjIgfSBmcm9tIFwiLi4vLi4vLi4vbnVtZXJpY3MvbW9kZWxzL1ZlY3RvcjIubW9kZWxcIjtcclxuaW1wb3J0IHsgVGlsZURlZmF1bHRTZXR0aW5ncyB9IGZyb20gXCIuL3RpbGUuZGVmYXVsdC5zZXR0aW5nc1wiO1xyXG5pbXBvcnQgeyBEcmF3YWJsZVRpbGUgfSBmcm9tIFwiLi9kcmF3YWJsZS10aWxlXCI7XHJcbmltcG9ydCB7IEdyYXNzVGlsZVR5cGUsIEdyYXNzVGlsZVR5cGVEaXJ0LCBHcmFzc1RpbGVUeXBlRGlydFRvcCwgR3Jhc3NUaWxlVHlwZURpcnRSaWdodCwgR3Jhc3NUaWxlVHlwZURpcnRMZWZ0LCBHcmFzc1RpbGVUeXBlRGlydEJvdHRvbSwgR3Jhc3NUaWxlVHlwZURpcnRNaWRkbGUgfSBmcm9tIFwiLi9UaWxlVHlwZXMvR3JvdW5kVGlsZVR5cGVzL2dyYXNzLnRpbGV0eXBlXCI7XHJcbmltcG9ydCB7IERyYXdhYmxlQ2FudmFzIH0gZnJvbSBcIi4uL01vZGVscy9ncmFwaGljcy5kcmF3YWJsZS1jYW52YXNcIjtcclxuaW1wb3J0IHsgU3RhclRpbGVUeXBlIH0gZnJvbSBcIi4vVGlsZVR5cGVzL1NwYWNlVGlsZVR5cGVzL3N0YXIudGlsZXR5cGVcIjtcclxuaW1wb3J0IHsgRGlydFRpbGVUeXBlIH0gZnJvbSBcIi4vVGlsZVR5cGVzL0dyb3VuZFRpbGVUeXBlcy9kaXJ0LnRpbGV0eXBlXCI7XHJcbmltcG9ydCB7IFNhbmRUaWxlVHlwZUdyYXNzVG9wLCBTYW5kVGlsZVR5cGUsIFNhbmRUaWxlVHlwZUdyYXNzUmlnaHQsIFNhbmRUaWxlVHlwZUdyYXNzQm90dG9tLCBTYW5kVGlsZVR5cGVHcmFzc0xlZnQgfSBmcm9tIFwiLi9UaWxlVHlwZXMvR3JvdW5kVGlsZVR5cGVzL3NhbmQudGlsZXR5cGVcIjtcclxuaW1wb3J0IHsgU2hhbGxvd1dhdGVyVGlsZVR5cGUsIFNoYWxsb3dXYXRlclRpbGVUeXBlU2FuZFRvcCwgU2hhbGxvd1dhdGVyVGlsZVR5cGVTYW5kUmlnaHQsIFNoYWxsb3dXYXRlclRpbGVUeXBlU2FuZEJvdHRvbSwgU2hhbGxvd1dhdGVyVGlsZVR5cGVTYW5kTGVmdCB9IGZyb20gXCIuL1RpbGVUeXBlcy9Hcm91bmRUaWxlVHlwZXMvc2hhbGxvdy13YXRlci50aWxldHlwZVwiO1xyXG5pbXBvcnQgeyBTdG9uZVRpbGVUeXBlIH0gZnJvbSBcIi4vVGlsZVR5cGVzL0dyb3VuZFRpbGVUeXBlcy9zdG9uZS50aWxldHlwZVwiO1xyXG5pbXBvcnQgeyBUZXh0dXJlMkQgfSBmcm9tIFwiLi4vVGV4dHVyZXMvVGV4dHVyZTJkXCI7XHJcblxyXG5leHBvcnQgY2xhc3MgVGlsZVNlcnZpY2Uge1xyXG5cclxuICAgIHByaXZhdGUgdGlsZVNpemU6IFZlY3RvcjIgPSBUaWxlRGVmYXVsdFNldHRpbmdzLkRFRkFVTFRfU0laRTtcclxuXHJcbiAgICBwdWJsaWMgdGlsZVR5cGVzOiBUaWxlVHlwZVtdID0gbmV3IEFycmF5PFRpbGVUeXBlPigyNTYpO1xyXG4gICAgcHJpdmF0ZSBzcGFjZVRpbGVUeXBlOiBUaWxlVHlwZTtcclxuICAgIHByaXZhdGUgc3RhclRpbGVUeXBlOiBUaWxlVHlwZTtcclxuXHJcbiAgICBwcml2YXRlIGdyYXNzVGlsZVR5cGU6IFRpbGVUeXBlO1xyXG4gICAgcHJpdmF0ZSBncmFzc1RpbGVUeXBlRGlydDogR3Jhc3NUaWxlVHlwZURpcnQ7XHJcbiAgICBwcml2YXRlIGdyYXNzVGlsZVR5cGVEaXJ0VG9wOiBHcmFzc1RpbGVUeXBlRGlydFRvcDtcclxuICAgIHByaXZhdGUgZ3Jhc3NUaWxlVHlwZURpcnRSaWdodDogR3Jhc3NUaWxlVHlwZURpcnRSaWdodDtcclxuICAgIHByaXZhdGUgZ3Jhc3NUaWxlVHlwZUJvdHRvbTogR3Jhc3NUaWxlVHlwZURpcnRCb3R0b207XHJcbiAgICBwcml2YXRlIGdyYXNzVGlsZVR5cGVMZWZ0OiBHcmFzc1RpbGVUeXBlRGlydExlZnQ7XHJcbiAgICBwcml2YXRlIGdyYXNzVGlsZVR5cGVNaWRkbGU6IEdyYXNzVGlsZVR5cGVEaXJ0TWlkZGxlO1xyXG5cclxuICAgIHByaXZhdGUgZGlydFRpbGVUeXBlOiBEaXJ0VGlsZVR5cGU7XHJcbiAgICBwcml2YXRlIHN0b25lVGlsZVR5cGU6IFN0b25lVGlsZVR5cGU7XHJcblxyXG4gICAgcHJpdmF0ZSBzYW5kVGlsZVR5cGU6IFNhbmRUaWxlVHlwZTtcclxuICAgIHByaXZhdGUgc2FuZFRpbGVUeXBlRGlydFRvcDogU2FuZFRpbGVUeXBlR3Jhc3NUb3A7XHJcbiAgICBwcml2YXRlIHNhbmRUaWxlVHlwZURpcnRSaWdodDogU2FuZFRpbGVUeXBlR3Jhc3NSaWdodDtcclxuICAgIHByaXZhdGUgc2FuZFRpbGVUeXBlQm90dG9tOiBTYW5kVGlsZVR5cGVHcmFzc0JvdHRvbTtcclxuICAgIHByaXZhdGUgc2FuZFRpbGVUeXBlTGVmdDogU2FuZFRpbGVUeXBlR3Jhc3NMZWZ0O1xyXG5cclxuICAgIHByaXZhdGUgc2hhbGxvd1dhdGVyVGlsZVR5cGU6IFNoYWxsb3dXYXRlclRpbGVUeXBlO1xyXG4gICAgcHJpdmF0ZSBzaGFsbG93V2F0ZXJUaWxlVHlwZURpcnRUb3A6IFNoYWxsb3dXYXRlclRpbGVUeXBlU2FuZFRvcDtcclxuICAgIHByaXZhdGUgc2hhbGxvd1dhdGVyVGlsZVR5cGVEaXJ0UmlnaHQ6IFNoYWxsb3dXYXRlclRpbGVUeXBlU2FuZFJpZ2h0O1xyXG4gICAgcHJpdmF0ZSBzaGFsbG93V2F0ZXJUaWxlVHlwZUJvdHRvbTogU2hhbGxvd1dhdGVyVGlsZVR5cGVTYW5kQm90dG9tO1xyXG4gICAgcHJpdmF0ZSBzaGFsbG93V2F0ZXJUaWxlVHlwZUxlZnQ6IFNoYWxsb3dXYXRlclRpbGVUeXBlU2FuZExlZnQ7XHJcblxyXG5cclxuXHJcbiAgICBwcml2YXRlIHRpbGVzOiBBcnJheTxEcmF3YWJsZVRpbGU+ID0gbmV3IEFycmF5PERyYXdhYmxlVGlsZT4oKTtcclxuXHJcbiAgICBwcml2YXRlIGNhbnZhc1NlcnZpY2U6IENhbnZhc1NlcnZpY2U7XHJcbiAgICBwcml2YXRlIGdyYXBoaWNzU2VydmljZTogR3JhcGhpY3NTZXJ2aWNlO1xyXG5cclxuICAgIHByaXZhdGUgdGlsZUNhbnZhc0lkOiBzdHJpbmc7XHJcblxyXG4gICAgY29uc3RydWN0b3IoY2FudmFzU2VydmljZTogQ2FudmFzU2VydmljZSxcclxuICAgICAgICBncmFwaGljc1NlcnZpY2U6IEdyYXBoaWNzU2VydmljZSkge1xyXG4gICAgICAgIHRoaXMuZ3JhcGhpY3NTZXJ2aWNlID0gZ3JhcGhpY3NTZXJ2aWNlO1xyXG4gICAgICAgIHRoaXMuY2FudmFzU2VydmljZSA9IGNhbnZhc1NlcnZpY2U7XHJcbiAgICB9XHJcblxyXG4gICAgSW5pdCgpIHtcclxuICAgICAgICB0aGlzLnRpbGVDYW52YXNJZCA9IHRoaXMuY2FudmFzU2VydmljZS5SZWdpc3Rlck5ld0NhbnZhcygpO1xyXG4gICAgICAgIHRoaXMuc3BhY2VUaWxlVHlwZSA9IG5ldyBTcGFjZVRpbGVUeXBlKDAsIHRoaXMuZ3JhcGhpY3NTZXJ2aWNlLkdldFRleHR1cmVTZXJ2aWNlKCkuUmVnaXN0ZXJOZXdUZXh0dXJlKFNwYWNlVGlsZVR5cGUudGV4dHVyZVBhdGgpKTtcclxuICAgICAgICB0aGlzLnN0YXJUaWxlVHlwZSA9IG5ldyBTdGFyVGlsZVR5cGUoMSwgdGhpcy5ncmFwaGljc1NlcnZpY2UuR2V0VGV4dHVyZVNlcnZpY2UoKS5SZWdpc3Rlck5ld1RleHR1cmUoU3RhclRpbGVUeXBlLnRleHR1cmVQYXRoKSk7XHJcbiAgICAgICAgdGhpcy5ncmFzc1RpbGVUeXBlID0gbmV3IEdyYXNzVGlsZVR5cGUoMiwgdGhpcy5ncmFwaGljc1NlcnZpY2UuR2V0VGV4dHVyZVNlcnZpY2UoKS5SZWdpc3Rlck5ld1RleHR1cmUoR3Jhc3NUaWxlVHlwZS50ZXh0dXJlUGF0aCkpO1xyXG5cclxuICAgICAgICB0aGlzLmdyYXNzVGlsZVR5cGVEaXJ0ID0gbmV3IEdyYXNzVGlsZVR5cGVEaXJ0KDMsIHRoaXMuZ3JhcGhpY3NTZXJ2aWNlLkdldFRleHR1cmVTZXJ2aWNlKCkuUmVnaXN0ZXJOZXdUZXh0dXJlKEdyYXNzVGlsZVR5cGVEaXJ0LnRleHR1cmVQYXRoKSk7XHJcbiAgICAgICAgdGhpcy5ncmFzc1RpbGVUeXBlRGlydFRvcCA9IG5ldyBHcmFzc1RpbGVUeXBlRGlydFRvcCg0LCB0aGlzLmdyYXBoaWNzU2VydmljZS5HZXRUZXh0dXJlU2VydmljZSgpLlJlZ2lzdGVyTmV3VGV4dHVyZShHcmFzc1RpbGVUeXBlRGlydFRvcC50ZXh0dXJlUGF0aCkpO1xyXG4gICAgICAgIHRoaXMuZ3Jhc3NUaWxlVHlwZURpcnRSaWdodCA9IG5ldyBHcmFzc1RpbGVUeXBlRGlydFJpZ2h0KDUsIHRoaXMuZ3JhcGhpY3NTZXJ2aWNlLkdldFRleHR1cmVTZXJ2aWNlKCkuUmVnaXN0ZXJOZXdUZXh0dXJlKEdyYXNzVGlsZVR5cGVEaXJ0UmlnaHQudGV4dHVyZVBhdGgpKTtcclxuICAgICAgICB0aGlzLmdyYXNzVGlsZVR5cGVCb3R0b20gPSBuZXcgR3Jhc3NUaWxlVHlwZURpcnRCb3R0b20oNiwgdGhpcy5ncmFwaGljc1NlcnZpY2UuR2V0VGV4dHVyZVNlcnZpY2UoKS5SZWdpc3Rlck5ld1RleHR1cmUoR3Jhc3NUaWxlVHlwZURpcnRCb3R0b20udGV4dHVyZVBhdGgpKTtcclxuICAgICAgICB0aGlzLmdyYXNzVGlsZVR5cGVMZWZ0ID0gbmV3IEdyYXNzVGlsZVR5cGVEaXJ0TGVmdCg3LCB0aGlzLmdyYXBoaWNzU2VydmljZS5HZXRUZXh0dXJlU2VydmljZSgpLlJlZ2lzdGVyTmV3VGV4dHVyZShHcmFzc1RpbGVUeXBlRGlydExlZnQudGV4dHVyZVBhdGgpKTtcclxuICAgICAgICB0aGlzLmdyYXNzVGlsZVR5cGVNaWRkbGUgPSBuZXcgR3Jhc3NUaWxlVHlwZURpcnRNaWRkbGUoOCwgdGhpcy5ncmFwaGljc1NlcnZpY2UuR2V0VGV4dHVyZVNlcnZpY2UoKS5SZWdpc3Rlck5ld1RleHR1cmUoR3Jhc3NUaWxlVHlwZURpcnRNaWRkbGUudGV4dHVyZVBhdGgpKTtcclxuXHJcbiAgICAgICAgdGhpcy5kaXJ0VGlsZVR5cGUgPSBuZXcgRGlydFRpbGVUeXBlKDksIHRoaXMuZ3JhcGhpY3NTZXJ2aWNlLkdldFRleHR1cmVTZXJ2aWNlKCkuUmVnaXN0ZXJOZXdUZXh0dXJlKERpcnRUaWxlVHlwZS50ZXh0dXJlUGF0aCkpO1xyXG5cclxuICAgICAgICB0aGlzLnN0b25lVGlsZVR5cGUgPSBuZXcgU3RvbmVUaWxlVHlwZSgxMCwgdGhpcy5ncmFwaGljc1NlcnZpY2UuR2V0VGV4dHVyZVNlcnZpY2UoKS5SZWdpc3Rlck5ld1RleHR1cmUoU3RvbmVUaWxlVHlwZS50ZXh0dXJlUGF0aCkpO1xyXG5cclxuICAgICAgICB0aGlzLnNhbmRUaWxlVHlwZSA9IG5ldyBTYW5kVGlsZVR5cGUoMTEsIHRoaXMuZ3JhcGhpY3NTZXJ2aWNlLkdldFRleHR1cmVTZXJ2aWNlKCkuUmVnaXN0ZXJOZXdUZXh0dXJlKFNhbmRUaWxlVHlwZS50ZXh0dXJlUGF0aCkpO1xyXG4gICAgICAgIHRoaXMuc2FuZFRpbGVUeXBlRGlydFRvcCA9IG5ldyBTYW5kVGlsZVR5cGVHcmFzc1RvcCgxMiwgdGhpcy5ncmFwaGljc1NlcnZpY2UuR2V0VGV4dHVyZVNlcnZpY2UoKS5SZWdpc3Rlck5ld1RleHR1cmUoU2FuZFRpbGVUeXBlR3Jhc3NUb3AudGV4dHVyZVBhdGgpKTtcclxuICAgICAgICB0aGlzLnNhbmRUaWxlVHlwZURpcnRSaWdodCA9IG5ldyBTYW5kVGlsZVR5cGVHcmFzc1JpZ2h0KDEzLCB0aGlzLmdyYXBoaWNzU2VydmljZS5HZXRUZXh0dXJlU2VydmljZSgpLlJlZ2lzdGVyTmV3VGV4dHVyZShTYW5kVGlsZVR5cGVHcmFzc1JpZ2h0LnRleHR1cmVQYXRoKSk7XHJcbiAgICAgICAgdGhpcy5zYW5kVGlsZVR5cGVCb3R0b20gPSBuZXcgU2FuZFRpbGVUeXBlR3Jhc3NCb3R0b20oMTQsIHRoaXMuZ3JhcGhpY3NTZXJ2aWNlLkdldFRleHR1cmVTZXJ2aWNlKCkuUmVnaXN0ZXJOZXdUZXh0dXJlKFNhbmRUaWxlVHlwZUdyYXNzQm90dG9tLnRleHR1cmVQYXRoKSk7XHJcbiAgICAgICAgdGhpcy5zYW5kVGlsZVR5cGVMZWZ0ID0gbmV3IFNhbmRUaWxlVHlwZUdyYXNzTGVmdCgxNSwgdGhpcy5ncmFwaGljc1NlcnZpY2UuR2V0VGV4dHVyZVNlcnZpY2UoKS5SZWdpc3Rlck5ld1RleHR1cmUoU2FuZFRpbGVUeXBlR3Jhc3NMZWZ0LnRleHR1cmVQYXRoKSk7XHJcblxyXG4gICAgICAgIHRoaXMuc2hhbGxvd1dhdGVyVGlsZVR5cGUgPSBuZXcgU2hhbGxvd1dhdGVyVGlsZVR5cGUoMTYsIHRoaXMuZ3JhcGhpY3NTZXJ2aWNlLkdldFRleHR1cmVTZXJ2aWNlKCkuUmVnaXN0ZXJOZXdUZXh0dXJlKFNoYWxsb3dXYXRlclRpbGVUeXBlLnRleHR1cmVQYXRoKSk7XHJcbiAgICAgICAgdGhpcy5zaGFsbG93V2F0ZXJUaWxlVHlwZURpcnRUb3AgPSBuZXcgU2hhbGxvd1dhdGVyVGlsZVR5cGVTYW5kVG9wKDE3LCB0aGlzLmdyYXBoaWNzU2VydmljZS5HZXRUZXh0dXJlU2VydmljZSgpLlJlZ2lzdGVyTmV3VGV4dHVyZShTaGFsbG93V2F0ZXJUaWxlVHlwZVNhbmRUb3AudGV4dHVyZVBhdGgpKTtcclxuICAgICAgICB0aGlzLnNoYWxsb3dXYXRlclRpbGVUeXBlRGlydFJpZ2h0ID0gbmV3IFNoYWxsb3dXYXRlclRpbGVUeXBlU2FuZFJpZ2h0KDE4LCB0aGlzLmdyYXBoaWNzU2VydmljZS5HZXRUZXh0dXJlU2VydmljZSgpLlJlZ2lzdGVyTmV3VGV4dHVyZShTaGFsbG93V2F0ZXJUaWxlVHlwZVNhbmRSaWdodC50ZXh0dXJlUGF0aCkpO1xyXG4gICAgICAgIHRoaXMuc2hhbGxvd1dhdGVyVGlsZVR5cGVCb3R0b20gPSBuZXcgU2hhbGxvd1dhdGVyVGlsZVR5cGVTYW5kQm90dG9tKDE5LCB0aGlzLmdyYXBoaWNzU2VydmljZS5HZXRUZXh0dXJlU2VydmljZSgpLlJlZ2lzdGVyTmV3VGV4dHVyZShTaGFsbG93V2F0ZXJUaWxlVHlwZVNhbmRCb3R0b20udGV4dHVyZVBhdGgpKTtcclxuICAgICAgICB0aGlzLnNoYWxsb3dXYXRlclRpbGVUeXBlTGVmdCA9IG5ldyBTaGFsbG93V2F0ZXJUaWxlVHlwZVNhbmRMZWZ0KDIwLCB0aGlzLmdyYXBoaWNzU2VydmljZS5HZXRUZXh0dXJlU2VydmljZSgpLlJlZ2lzdGVyTmV3VGV4dHVyZShTaGFsbG93V2F0ZXJUaWxlVHlwZVNhbmRMZWZ0LnRleHR1cmVQYXRoKSk7XHJcblxyXG4gICAgICAgIHRoaXMuc2V0dXBUaWxlVHlwZXMoKTtcclxuICAgICAgICAvLyB0aGlzLnNldHVwVGlsZXMoKTtcclxuICAgIH1cclxuXHJcbiAgICBzZXR1cFRpbGVUeXBlcygpIHtcclxuICAgICAgICB0aGlzLnRpbGVUeXBlc1t0aGlzLnNwYWNlVGlsZVR5cGUuR2V0SWQoKV0gPSB0aGlzLnNwYWNlVGlsZVR5cGU7XHJcbiAgICAgICAgdGhpcy50aWxlVHlwZXNbdGhpcy5zdGFyVGlsZVR5cGUuR2V0SWQoKV0gPSB0aGlzLnN0YXJUaWxlVHlwZTtcclxuICAgICAgICB0aGlzLnRpbGVUeXBlc1t0aGlzLmdyYXNzVGlsZVR5cGUuR2V0SWQoKV0gPSB0aGlzLmdyYXNzVGlsZVR5cGU7XHJcbiAgICAgICAgdGhpcy50aWxlVHlwZXNbdGhpcy5ncmFzc1RpbGVUeXBlRGlydC5HZXRJZCgpXSA9IHRoaXMuZ3Jhc3NUaWxlVHlwZURpcnQ7XHJcblxyXG4gICAgICAgIHRoaXMudGlsZVR5cGVzW3RoaXMuZ3Jhc3NUaWxlVHlwZURpcnRUb3AuR2V0SWQoKV0gPSB0aGlzLmdyYXNzVGlsZVR5cGVEaXJ0VG9wO1xyXG4gICAgICAgIHRoaXMudGlsZVR5cGVzW3RoaXMuZ3Jhc3NUaWxlVHlwZURpcnRSaWdodC5HZXRJZCgpXSA9IHRoaXMuZ3Jhc3NUaWxlVHlwZURpcnRSaWdodDtcclxuICAgICAgICB0aGlzLnRpbGVUeXBlc1t0aGlzLmdyYXNzVGlsZVR5cGVCb3R0b20uR2V0SWQoKV0gPSB0aGlzLmdyYXNzVGlsZVR5cGVCb3R0b207XHJcbiAgICAgICAgdGhpcy50aWxlVHlwZXNbdGhpcy5ncmFzc1RpbGVUeXBlTGVmdC5HZXRJZCgpXSA9IHRoaXMuZ3Jhc3NUaWxlVHlwZUxlZnQ7XHJcbiAgICAgICAgdGhpcy50aWxlVHlwZXNbdGhpcy5ncmFzc1RpbGVUeXBlTWlkZGxlLkdldElkKCldID0gdGhpcy5ncmFzc1RpbGVUeXBlTWlkZGxlO1xyXG5cclxuICAgICAgICB0aGlzLnRpbGVUeXBlc1t0aGlzLmRpcnRUaWxlVHlwZS5HZXRJZCgpXSA9IHRoaXMuZGlydFRpbGVUeXBlO1xyXG5cclxuICAgICAgICB0aGlzLnRpbGVUeXBlc1t0aGlzLnN0b25lVGlsZVR5cGUuR2V0SWQoKV0gPSB0aGlzLnN0b25lVGlsZVR5cGU7XHJcblxyXG4gICAgICAgIHRoaXMudGlsZVR5cGVzW3RoaXMuc2FuZFRpbGVUeXBlLkdldElkKCldID0gdGhpcy5zYW5kVGlsZVR5cGU7XHJcbiAgICAgICAgdGhpcy50aWxlVHlwZXNbdGhpcy5zYW5kVGlsZVR5cGVEaXJ0VG9wLkdldElkKCldID0gdGhpcy5zYW5kVGlsZVR5cGVEaXJ0VG9wO1xyXG4gICAgICAgIHRoaXMudGlsZVR5cGVzW3RoaXMuc2FuZFRpbGVUeXBlRGlydFJpZ2h0LkdldElkKCldID0gdGhpcy5zYW5kVGlsZVR5cGVEaXJ0UmlnaHQ7XHJcbiAgICAgICAgdGhpcy50aWxlVHlwZXNbdGhpcy5zYW5kVGlsZVR5cGVCb3R0b20uR2V0SWQoKV0gPSB0aGlzLnNhbmRUaWxlVHlwZUJvdHRvbTtcclxuICAgICAgICB0aGlzLnRpbGVUeXBlc1t0aGlzLnNhbmRUaWxlVHlwZUxlZnQuR2V0SWQoKV0gPSB0aGlzLnNhbmRUaWxlVHlwZUxlZnQ7XHJcblxyXG4gICAgICAgIHRoaXMudGlsZVR5cGVzW3RoaXMuc2hhbGxvd1dhdGVyVGlsZVR5cGUuR2V0SWQoKV0gPSB0aGlzLnNoYWxsb3dXYXRlclRpbGVUeXBlO1xyXG4gICAgICAgIHRoaXMudGlsZVR5cGVzW3RoaXMuc2hhbGxvd1dhdGVyVGlsZVR5cGVEaXJ0VG9wLkdldElkKCldID0gdGhpcy5zaGFsbG93V2F0ZXJUaWxlVHlwZURpcnRUb3A7XHJcbiAgICAgICAgdGhpcy50aWxlVHlwZXNbdGhpcy5zaGFsbG93V2F0ZXJUaWxlVHlwZURpcnRSaWdodC5HZXRJZCgpXSA9IHRoaXMuc2hhbGxvd1dhdGVyVGlsZVR5cGVEaXJ0UmlnaHQ7XHJcbiAgICAgICAgdGhpcy50aWxlVHlwZXNbdGhpcy5zaGFsbG93V2F0ZXJUaWxlVHlwZUJvdHRvbS5HZXRJZCgpXSA9IHRoaXMuc2hhbGxvd1dhdGVyVGlsZVR5cGVCb3R0b207XHJcbiAgICAgICAgdGhpcy50aWxlVHlwZXNbdGhpcy5zaGFsbG93V2F0ZXJUaWxlVHlwZUxlZnQuR2V0SWQoKV0gPSB0aGlzLnNoYWxsb3dXYXRlclRpbGVUeXBlTGVmdDtcclxuXHJcblxyXG4gICAgfVxyXG5cclxuXHJcbiAgICAvKipcclxuICAgICAqIHJldHVybnMgYSBWZWN0b3IgMiBjb250YWluaW5nIGEgc2l6ZVxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyW11bXX0gdGlsZXNcclxuICAgICAqIEByZXR1cm5zIHtWZWN0b3IyfVxyXG4gICAgICogQG1lbWJlcm9mIFRpbGVTZXJ2aWNlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzZXR1cFRpbGVzRnJvbUFycmF5KHRpbGVzOiBudW1iZXJbXVtdKTogVmVjdG9yMiB7XHJcbiAgICAgICAgY29uc3Qgc2l6ZTogVmVjdG9yMiA9IG5ldyBWZWN0b3IyKDAsIDApO1xyXG4gICAgICAgIC8vIGNvbnN0IGNhbnZJZCA9IGAke3RoaXMuZ3JhcGhpY3NTZXJ2aWNlLlJlZ2lzdGVyRHJhd2FibGVFbnRpdHkoJ3RleHRzJyl9YDtcclxuICAgICAgICBmb3IgKGxldCB4ID0gMDsgeCA8IHRpbGVzLmxlbmd0aDsgeCsrKSB7XHJcbiAgICAgICAgICAgIGZvciAobGV0IHkgPSAwOyB5IDwgdGlsZXNbeF0ubGVuZ3RoOyB5KyspIHtcclxuICAgICAgICAgICAgICAgIHRoaXMudGlsZXMucHVzaChuZXcgRHJhd2FibGVUaWxlKHRpbGVzW3hdW3ldLFxyXG4gICAgICAgICAgICAgICAgICAgIG5ldyBWZWN0b3IyKFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB5ICogdGhpcy5HZXRUaWxlU2l6ZSgpLmdldFZhbHVlWCgpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB4ICogdGhpcy5HZXRUaWxlU2l6ZSgpLmdldFZhbHVlWSgpKSxcclxuICAgICAgICAgICAgICAgICAgICBUaWxlRGVmYXVsdFNldHRpbmdzLkRFRkFVTFRfU0laRSxcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnRpbGVUeXBlc1t0aWxlc1t4XVt5XV0uR2V0RmFsbGJhY2tDb2xvdXIoKSxcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnRpbGVDYW52YXNJZCxcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnRpbGVUeXBlc1t0aWxlc1t4XVt5XV0uR2V0VGV4dHVyZUlkKCkpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gc2l6ZTtcclxuICAgIH1cclxuXHJcblxyXG4gICAgcHJpdmF0ZSBQcmVDbGVhckNhbnZhcygpIHtcclxuICAgICAgICBjb25zdCBjYW52ID0gdGhpcy5ncmFwaGljc1NlcnZpY2UuR2V0Q2FudmFzKHRoaXMudGlsZUNhbnZhc0lkKTtcclxuICAgICAgICBjYW52LkNsZWFyQ2FudmFzKCk7XHJcbiAgICB9XHJcbiAgICBSZWRuZXIoKSB7XHJcbiAgICAgICAgdGhpcy5QcmVDbGVhckNhbnZhcygpO1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy50aWxlcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICB0aGlzLmdyYXBoaWNzU2VydmljZS5nZXREcmF3aW5nU2VydmljZSgpLkRyYXcoXHJcbiAgICAgICAgICAgICAgICB0aGlzLnRpbGVzW2ldLFxyXG4gICAgICAgICAgICAgICAgdHJ1ZSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuXHJcbiAgICBwdWJsaWMgR2V0VGlsZVNpemUoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMudGlsZVNpemU7XHJcbiAgICB9XHJcbn1cclxuXHJcbiIsImltcG9ydCB7IFZlY3RvcjIgfSBmcm9tIFwiLi4vLi4vLi4vbnVtZXJpY3MvbW9kZWxzL1ZlY3RvcjIubW9kZWxcIjtcclxuXHJcbmV4cG9ydCBjbGFzcyBWaWV3cG9ydEhlbHBlciB7XHJcblxyXG4gICAgcHVibGljIHN0YXRpYyBHZXRTcXVhcmVJbkJyb3dzZXIoKTogVmVjdG9yMiB7XHJcbiAgICAgICAgY29uc3QgaCA9IHRoaXMuR2V0QnJvd3NlckhlaWdodCgpIC0gNTtcclxuICAgICAgICBjb25zdCB3ID0gdGhpcy5HZXRCcm93c2VyV2lkdGgoKSAtIDU7XHJcbiAgICAgICAgaWYgKGggPCB3KSB7XHJcbiAgICAgICAgICAgIHJldHVybiBuZXcgVmVjdG9yMihoLCBoKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICByZXR1cm4gbmV3IFZlY3RvcjIodywgdyk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBzdGF0aWMgR2V0V2luZG93SW5Bc3BlY3RSYXRpbyhhc3BlY3RSYXRpb1dpZHRoOiBudW1iZXIgPSAxNiwgYXNwZWN0UmF0aW9IZWlnaHQ6IG51bWJlciA9IDksXHJcbiAgICAgICAgd2lkdGhQZXJjZW50OiBudW1iZXIgPSAxLCBoZWlnaHRQZXJjZW50OiBudW1iZXIgPSAxKSB7XHJcbiAgICAgICAgY29uc3QgYXNwZWN0UmF0aW8gPSBhc3BlY3RSYXRpb1dpZHRoIC8gYXNwZWN0UmF0aW9IZWlnaHQ7XHJcblxyXG4gICAgICAgIGNvbnN0IGFkanVzdGVkV2luZG93SGVpZ2h0ID0gdGhpcy5HZXRCcm93c2VySGVpZ2h0KCkgKiBoZWlnaHRQZXJjZW50O1xyXG4gICAgICAgIGNvbnN0IGFkanVzdGVkV2luZG93V2lkdGggPSB0aGlzLkdldEJyb3dzZXJXaWR0aCgpICogd2lkdGhQZXJjZW50O1xyXG5cclxuICAgICAgICBjb25zdCBkaXNwbGF5V2lkdGggPSBNYXRoLm1pbihhZGp1c3RlZFdpbmRvd1dpZHRoLCAoYWRqdXN0ZWRXaW5kb3dIZWlnaHQgKiBhc3BlY3RSYXRpbykpO1xyXG4gICAgICAgIGNvbnN0IGRpc3BsYXlIZWlnaHQgPSBNYXRoLm1pbihhZGp1c3RlZFdpbmRvd0hlaWdodCwgKGFkanVzdGVkV2luZG93V2lkdGggLyBhc3BlY3RSYXRpbykpO1xyXG4gICAgICAgIFxyXG4gICAgICAgIHJldHVybiBuZXcgVmVjdG9yMihkaXNwbGF5V2lkdGgsIGRpc3BsYXlIZWlnaHQpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyBhIHdpbmRvdyBpbiBhIGdpdmVuIGFzcGVjdCByYXRpby4gXHJcbiAgICAgKlxyXG4gICAgICogQHN0YXRpY1xyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFthc3BlY3RSYXRpb1dpZHRoPTE2XVxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFthc3BlY3RSYXRpb0hlaWdodD05XVxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFt3aWR0aFBlcmNlbnQ9MV0gYmV0d2VlbiAwICYgMS4gU2hvdWxkIHVzdWFsbHkgYmUgdGhlIHNhbWUgYXMgaGVpZ2h0UGVyY2VudFxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtoZWlnaHRQZXJjZW50PTFdIGJldHdlZW4gMCAmIDEuIFNob3VkbCB1c3VhbGx5IGJlIHRoZSBzYW1lIGFzIHdpZHRoUGVyY2VudFxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGVsZW1lbnRJZCBBbiBlbGVtZW50IHRvIHB1dCB0aGlzIGNhbnZhcyBpbnRvLiBDYW4gYmUgbnVsbCAod2lsbCB1c2UgdGhlIGZ1bGwgd2luZG93KVxyXG4gICAgICogQHJldHVybnMge1ZlY3RvcjJ9XHJcbiAgICAgKiBAbWVtYmVyb2YgVmlld3BvcnRIZWxwZXJcclxuICAgICAqIEByZXR1cm5zIHtWZWN0b3IyfVxyXG4gICAgICogQG1lbWJlcm9mIFZpZXdwb3J0SGVscGVyXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzdGF0aWMgR2V0V2luZG93SW5Bc3BlY3RSYXRpb0ZvckNhbnZhcyhhc3BlY3RSYXRpb1dpZHRoOiBudW1iZXIgPSAxNiwgYXNwZWN0UmF0aW9IZWlnaHQ6IG51bWJlciA9IDksXHJcbiAgICAgICAgd2lkdGhQZXJjZW50OiBudW1iZXIgPSAxLCBoZWlnaHRQZXJjZW50OiBudW1iZXIgPSAxLCBjYW52YXNhYmxlRWxlbWVudDogSFRNTEVsZW1lbnQgPSBudWxsKTogVmVjdG9yMiB7XHJcblxyXG4gICAgICAgIGlmICghY2FudmFzYWJsZUVsZW1lbnQpIHtcclxuICAgICAgICAgICAgY29uc29sZS53YXJuKGBzZXR1cCB3aXRoIG5vIGNhbnZhc2FibGUgZWxlbWVudC4gV2lsbCB1c2UgdGhlIGVudGlyZSB3aW5kb3dgKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBjb25zb2xlLndhcm4oYHNldHVwIHdpdGggaWQgb2YgJHtjYW52YXNhYmxlRWxlbWVudC5pZH1gKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3QgYXNwZWN0UmF0aW8gPSBhc3BlY3RSYXRpb1dpZHRoIC8gYXNwZWN0UmF0aW9IZWlnaHQ7XHJcblxyXG4gICAgICAgIGlmIChoZWlnaHRQZXJjZW50ICE9PSB3aWR0aFBlcmNlbnQpIHtcclxuICAgICAgICAgICAgY29uc29sZS53YXJuKCd3aW5kb3cgaGVpZ2h0IGFuZCB3aWR0aCBwZXJjZW50YWdlcyB0byBub3QgbWF0Y2guIFRoaXMgd2lsbCByZXN1bHQgaW4gYW4gYWJub3JtYWwgc2NyZWVuIHNpemUnKVxyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoYXNwZWN0UmF0aW9IZWlnaHQgPiBhc3BlY3RSYXRpb1dpZHRoKSB7XHJcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGBzdGFydGluZyBpbiBwb3J0cmFpdCBtb2RlICgke2FzcGVjdFJhdGlvV2lkdGh9OiR7YXNwZWN0UmF0aW9IZWlnaHR9KWApO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhgc3RhcnRpbmcgaW4gbGFuZHNjYXBlIG1vZGUgKCR7YXNwZWN0UmF0aW9XaWR0aH06JHthc3BlY3RSYXRpb0hlaWdodH0pYCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCBhZGp1c3RlZFdpbmRvd0hlaWdodCA9IHRoaXMuR2V0QnJvd3NlckhlaWdodChjYW52YXNhYmxlRWxlbWVudCkgKiBoZWlnaHRQZXJjZW50O1xyXG4gICAgICAgIGNvbnN0IGFkanVzdGVkV2luZG93V2lkdGggPSB0aGlzLkdldEJyb3dzZXJXaWR0aChjYW52YXNhYmxlRWxlbWVudCkgKiB3aWR0aFBlcmNlbnQ7XHJcblxyXG4gICAgICAgIGNvbnN0IGRpc3BsYXlXaWR0aCA9IE1hdGgubWluKGFkanVzdGVkV2luZG93V2lkdGgsIChhZGp1c3RlZFdpbmRvd0hlaWdodCAqIGFzcGVjdFJhdGlvKSk7XHJcbiAgICAgICAgY29uc3QgZGlzcGxheUhlaWdodCA9IE1hdGgubWluKGFkanVzdGVkV2luZG93SGVpZ2h0LCAoYWRqdXN0ZWRXaW5kb3dXaWR0aCAvIGFzcGVjdFJhdGlvKSk7XHJcblxyXG4gICAgICAgIHJldHVybiBuZXcgVmVjdG9yMihkaXNwbGF5V2lkdGgsIGRpc3BsYXlIZWlnaHQpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgc3RhdGljIEdldEJyb3dzZXJXaWR0aChlbGVtZW50OiBIVE1MRWxlbWVudCA9IG51bGwpIHtcclxuICAgICAgICBpZiAoIWVsZW1lbnQpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHdpbmRvdy5pbm5lcldpZHRoO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHJldHVybiBlbGVtZW50LmNsaWVudFdpZHRoO1xyXG5cclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBwcml2YXRlIHN0YXRpYyBHZXRCcm93c2VySGVpZ2h0KGVsZW1lbnQ6IEhUTUxFbGVtZW50ID0gbnVsbCkge1xyXG4gICAgICAgIGlmICghZWxlbWVudCkge1xyXG4gICAgICAgICAgICByZXR1cm4gd2luZG93LmlubmVySGVpZ2h0O1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHJldHVybiBlbGVtZW50LmNsaWVudEhlaWdodDtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn0iLCJpbXBvcnQgeyBWZWN0b3IyIH0gZnJvbSBcIi4uLy4uLy4uL251bWVyaWNzL21vZGVscy9WZWN0b3IyLm1vZGVsXCI7XHJcblxyXG5leHBvcnQgY2xhc3MgVmlld3BvcnRTZXJ2aWNlIHtcclxuXHJcbiAgICBwcml2YXRlIGJyb3dzZXJTaXplOiBWZWN0b3IyO1xyXG4gICAgcHJpdmF0ZSB2aWV3cG9ydFNpemU6IFZlY3RvcjI7XHJcblxyXG4gICAgcHJpdmF0ZSBhc3BlY3RSYXRpbzogVmVjdG9yMjtcclxuICAgIHByaXZhdGUgYXNwZWN0UmF0aW9DYWxjdWxhdGVkOiBudW1iZXI7XHJcbiAgICBwcml2YXRlIHNpemVQZXJjZW50OiBWZWN0b3IyO1xyXG5cclxuICAgIHByaXZhdGUgbGlzdG5lcjogYW55O1xyXG5cclxuICAgIHByaXZhdGUgbGlzdGVuaW5nRm9yQnJvd3NlckNoYW5nZXM6IGJvb2xlYW4gPSBmYWxzZTtcclxuICAgIGNvbnN0cnVjdG9yKFxyXG4gICAgICAgIGFzcGVjdFJhdGlvOiBWZWN0b3IyID0gbmV3IFZlY3RvcjIoMTYsIDkpLFxyXG4gICAgICAgIHNpemVQZXJjZW50OiBWZWN0b3IyID0gbmV3IFZlY3RvcjIoMSwgMSkpIHtcclxuICAgICAgICB0aGlzLmFzcGVjdFJhdGlvID0gYXNwZWN0UmF0aW87XHJcbiAgICAgICAgdGhpcy5hc3BlY3RSYXRpb0NhbGN1bGF0ZWQgPSAodGhpcy5hc3BlY3RSYXRpby5nZXRWYWx1ZVgoKSAvIHRoaXMuYXNwZWN0UmF0aW8uZ2V0VmFsdWVZKCkpO1xyXG4gICAgICAgIHRoaXMuc2l6ZVBlcmNlbnQgPSBzaXplUGVyY2VudDtcclxuICAgICAgICB0aGlzLnNldHVwTGlzdG5lcigpO1xyXG4gICAgfVxyXG5cclxuICAgIHNldHVwTGlzdG5lcigpIHtcclxuICAgICAgICBjb25zb2xlLmxvZygnc2V0dGluZyB1cCBicm93c2VyIGxpc3RuZXInKVxyXG4gICAgICAgIHRoaXMubGlzdG5lciA9IHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdyZXNpemUnLCAoKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMubGlzdGVuaW5nRm9yQnJvd3NlckNoYW5nZXMgPSB0cnVlO1xyXG4gICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcclxuXHJcbiAgICAgICAgICAgICAgICB0aGlzLmxpc3RlbmluZ0ZvckJyb3dzZXJDaGFuZ2VzID0gZmFsc2U7XHJcbiAgICAgICAgICAgIH0sIDUwMDApO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuXHJcbiAgICAvKipcclxuICAgICAqR2V0cyBhIHdpbmRvdyBpbiBhIHRoZSBnYW1lJ3MgYXNwZWN0IHJhdGlvXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtIVE1MRWxlbWVudH0gW2NhbnZhc2FibGVFbGVtZW50PW51bGxdXHJcbiAgICAgKiBAcmV0dXJucyB7VmVjdG9yMn1cclxuICAgICAqIEBtZW1iZXJvZiBWaWV3cG9ydFNlcnZpY2VcclxuICAgICAqL1xyXG4gICAgcHVibGljIEdldFdpbmRvd0luQXNwZWN0UmF0aW9Gb3JDYW52YXMoY2FudmFzYWJsZUVsZW1lbnQ6IEhUTUxFbGVtZW50ID0gbnVsbCk6IFZlY3RvcjIge1xyXG5cclxuICAgICAgICBpZiAoIWNhbnZhc2FibGVFbGVtZW50KSB7XHJcbiAgICAgICAgICAgIGNvbnNvbGUud2Fybihgc2V0dXAgd2l0aCBubyBjYW52YXNhYmxlIGVsZW1lbnQuIFdpbGwgdXNlIHRoZSBlbnRpcmUgd2luZG93YCk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgY29uc29sZS53YXJuKGBzZXR1cCB3aXRoIGlkIG9mICR7Y2FudmFzYWJsZUVsZW1lbnQuaWR9YCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIFxyXG5cclxuICAgICAgICBpZiAodGhpcy5zaXplUGVyY2VudC5nZXRWYWx1ZVgoKSAhPT0gdGhpcy5zaXplUGVyY2VudC5nZXRWYWx1ZVkoKSkge1xyXG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ3dpbmRvdyBoZWlnaHQgYW5kIHdpZHRoIHBlcmNlbnRhZ2VzIHRvIG5vdCBtYXRjaC4gVGhpcyB3aWxsIHJlc3VsdCBpbiBhbiBhYm5vcm1hbCBzY3JlZW4gc2l6ZScpXHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0aGlzLmFzcGVjdFJhdGlvLmdldFZhbHVlWCgpID4gdGhpcy5hc3BlY3RSYXRpby5nZXRWYWx1ZVkoKSkge1xyXG4gICAgICAgICAgICBjb25zb2xlLmxvZyhgc3RhcnRpbmcgaW4gcG9ydHJhaXQgbW9kZSAoJHt0aGlzLmFzcGVjdFJhdGlvLmdldFZhbHVlWCgpIH06JHt0aGlzLmFzcGVjdFJhdGlvLmdldFZhbHVlWSgpfSlgKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBjb25zb2xlLmluZm8oYHN0YXJ0aW5nIGluIGxhbmRzY2FwZSBtb2RlICgke3RoaXMuYXNwZWN0UmF0aW8uZ2V0VmFsdWVYKCkgfToke3RoaXMuYXNwZWN0UmF0aW8uZ2V0VmFsdWVZKCl9KWApO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgYWRqdXN0ZWRXaW5kb3dIZWlnaHQgPSB0aGlzLkdldEJyb3dzZXJIZWlnaHQoY2FudmFzYWJsZUVsZW1lbnQpICogdGhpcy5zaXplUGVyY2VudC5nZXRWYWx1ZVgoKTtcclxuICAgICAgICBjb25zdCBhZGp1c3RlZFdpbmRvd1dpZHRoID0gdGhpcy5HZXRCcm93c2VyV2lkdGgoY2FudmFzYWJsZUVsZW1lbnQpICogdGhpcy5zaXplUGVyY2VudC5nZXRWYWx1ZVkoKTtcclxuXHJcbiAgICAgICAgY29uc3QgZGlzcGxheVdpZHRoID0gTWF0aC5taW4oYWRqdXN0ZWRXaW5kb3dXaWR0aCwgKGFkanVzdGVkV2luZG93SGVpZ2h0ICogdGhpcy5hc3BlY3RSYXRpb0NhbGN1bGF0ZWQpKTtcclxuICAgICAgICBjb25zdCBkaXNwbGF5SGVpZ2h0ID0gTWF0aC5taW4oYWRqdXN0ZWRXaW5kb3dIZWlnaHQsIChhZGp1c3RlZFdpbmRvd1dpZHRoIC8gdGhpcy5hc3BlY3RSYXRpb0NhbGN1bGF0ZWQpKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIG5ldyBWZWN0b3IyKGRpc3BsYXlXaWR0aCwgZGlzcGxheUhlaWdodCk7XHJcbiAgICB9IFxyXG5cclxuICAgIHB1YmxpYyBHZXRTcXVhcmVJbkJyb3dzZXIoKTogVmVjdG9yMiB7XHJcbiAgICAgICAgY29uc3QgaCA9IHRoaXMuR2V0QnJvd3NlckhlaWdodCgpIC0gNTtcclxuICAgICAgICBjb25zdCB3ID0gdGhpcy5HZXRCcm93c2VyV2lkdGgoKSAtIDU7XHJcbiAgICAgICAgaWYgKGggPCB3KSB7XHJcbiAgICAgICAgICAgIHJldHVybiBuZXcgVmVjdG9yMihoLCBoKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICByZXR1cm4gbmV3IFZlY3RvcjIodywgdyk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBHZXRXaW5kb3dJbkFzcGVjdFJhdGlvKCkge1xyXG4gXHJcbiAgICAgICAgY29uc3QgYWRqdXN0ZWRXaW5kb3dIZWlnaHQgPSB0aGlzLkdldEJyb3dzZXJIZWlnaHQoKSAqIHRoaXMuc2l6ZVBlcmNlbnQuZ2V0VmFsdWVYKCk7XHJcbiAgICAgICAgY29uc3QgYWRqdXN0ZWRXaW5kb3dXaWR0aCA9IHRoaXMuR2V0QnJvd3NlcldpZHRoKCkgKiB0aGlzLnNpemVQZXJjZW50LmdldFZhbHVlWSgpO1xyXG5cclxuICAgICAgICBjb25zdCBkaXNwbGF5V2lkdGggPSBNYXRoLm1pbihhZGp1c3RlZFdpbmRvd1dpZHRoLCAoYWRqdXN0ZWRXaW5kb3dIZWlnaHQgKiB0aGlzLmFzcGVjdFJhdGlvQ2FsY3VsYXRlZCkpO1xyXG4gICAgICAgIGNvbnN0IGRpc3BsYXlIZWlnaHQgPSBNYXRoLm1pbihhZGp1c3RlZFdpbmRvd0hlaWdodCwgKGFkanVzdGVkV2luZG93V2lkdGggLyB0aGlzLmFzcGVjdFJhdGlvQ2FsY3VsYXRlZCkpO1xyXG5cclxuICAgICAgICByZXR1cm4gbmV3IFZlY3RvcjIoZGlzcGxheVdpZHRoLCBkaXNwbGF5SGVpZ2h0KTtcclxuICAgIH1cclxuXHJcblxyXG4gICAgcHVibGljIEdldEJyb3dzZXJXaWR0aChlbGVtZW50OiBIVE1MRWxlbWVudCA9IG51bGwpIHtcclxuICAgICAgICBpZiAoIWVsZW1lbnQpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHdpbmRvdy5pbm5lcldpZHRoO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHJldHVybiBlbGVtZW50LmNsaWVudFdpZHRoO1xyXG5cclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBwdWJsaWMgR2V0QnJvd3NlckhlaWdodChlbGVtZW50OiBIVE1MRWxlbWVudCA9IG51bGwpIHtcclxuICAgICAgICBpZiAoIWVsZW1lbnQpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHdpbmRvdy5pbm5lckhlaWdodDtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICByZXR1cm4gZWxlbWVudC5jbGllbnRIZWlnaHQ7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBnZXRCcm93c2VyU2l6ZSgpOiBWZWN0b3IyIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5icm93c2VyU2l6ZTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIHNldEJyb3dzZXJTaXplKGJyb3dzZXJTaXplOiBWZWN0b3IyKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5icm93c2VyU2l6ZSA9IGJyb3dzZXJTaXplO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBnZXRWaWV3cG9ydFNpemUoKTogVmVjdG9yMiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMudmlld3BvcnRTaXplO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgc2V0Vmlld3BvcnRTaXplKHZpZXdwb3J0U2l6ZTogVmVjdG9yMik6IHZvaWQge1xyXG4gICAgICAgIHRoaXMudmlld3BvcnRTaXplID0gdmlld3BvcnRTaXplO1xyXG4gICAgfVxyXG5cclxuXHJcbn0iLCJpbXBvcnQgeyBIdG1sU2VydmljZSB9IGZyb20gXCIuL0h0bWwvZ3JhcGhpY3MuaHRtbC5zZXJ2aWNlXCI7XHJcbmltcG9ydCB7IENhbnZhc1NlcnZpY2UgfSBmcm9tIFwiLi9DYW52YXMvZ3JhcGhpY3MuY2FudmFzLnNlcnZpY2VcIjtcclxuaW1wb3J0IHsgVGlsZVNlcnZpY2UgfSBmcm9tIFwiLi9UaWxlcy90aWxlLnNlcnZpY2VcIjtcclxuaW1wb3J0IHsgR2FtZUNhbWVyYVNlcnZpY2UgfSBmcm9tIFwiLi9DYW1lcmEvZ2FtZS1jYW1lcmEuc2VydmljZVwiO1xyXG5pbXBvcnQgeyBEcmF3aW5nU2VydmljZSB9IGZyb20gXCIuL0RyYXcvZHJhd2luZy5zZXJ2aWNlXCI7XHJcbmltcG9ydCB7IFRleHR1cmVTZXJ2aWNlIH0gZnJvbSBcIi4vVGV4dHVyZXMvdGV4dHVyZS5zZXJ2aWNlXCI7XHJcbmltcG9ydCB7IEFBQkIgfSBmcm9tIFwiLi4vLi4vbnVtZXJpY3MvbW9kZWxzL0FBQkIubW9kZWxcIjtcclxuaW1wb3J0IHsgVmVjdG9yMiB9IGZyb20gXCIuLi8uLi9udW1lcmljcy9tb2RlbHMvVmVjdG9yMi5tb2RlbFwiO1xyXG5cclxuZXhwb3J0IGNsYXNzIEdyYXBoaWNzU2VydmljZSB7XHJcbiAgICBcclxuICAgIHByaXZhdGUgaHRtbFNlcnZpY2U6IEh0bWxTZXJ2aWNlO1xyXG4gICAgcHJpdmF0ZSBjYW52YXNTZXJ2aWNlOiBDYW52YXNTZXJ2aWNlO1xyXG4gICAgcHJpdmF0ZSB0aWxlU2VydmljZTogVGlsZVNlcnZpY2U7XHJcbiAgICBwcml2YXRlIGdhbWVDYW1lcmFTZXJ2aWNlOiBHYW1lQ2FtZXJhU2VydmljZTtcclxuICAgIHByaXZhdGUgZHJhd2luZ1NlcnZpY2U6IERyYXdpbmdTZXJ2aWNlO1xyXG4gICAgcHJpdmF0ZSB0ZXh0dXJlU2VydmljZTogVGV4dHVyZVNlcnZpY2U7XHJcblxyXG4gICAgY29uc3RydWN0b3IoKSB7XHJcbiAgICAgICAgY29uc29sZS5sb2coJ3N0YXJ0aW5nIGdyYXBoaWNzIHNlcnZpY2UnKTtcclxuICAgICAgICB0aGlzLmh0bWxTZXJ2aWNlID0gbmV3IEh0bWxTZXJ2aWNlKCk7XHJcbiAgICAgICAgdGhpcy5jYW52YXNTZXJ2aWNlID0gbmV3IENhbnZhc1NlcnZpY2UodGhpcy5odG1sU2VydmljZSk7XHJcbiAgICAgICAgdGhpcy50aWxlU2VydmljZSA9IG5ldyBUaWxlU2VydmljZSh0aGlzLmNhbnZhc1NlcnZpY2UsIHRoaXMpO1xyXG4gICAgICAgIHRoaXMudGV4dHVyZVNlcnZpY2UgPSBuZXcgVGV4dHVyZVNlcnZpY2UoKTtcclxuICAgICAgICBjb25zdCBhcHBseUNhbWVyYVdvcmxkQm91bmRpbmcgPSBmYWxzZTtcclxuICAgICAgICB0aGlzLmdhbWVDYW1lcmFTZXJ2aWNlID0gbmV3IEdhbWVDYW1lcmFTZXJ2aWNlKDAsIDAsIGFwcGx5Q2FtZXJhV29ybGRCb3VuZGluZyk7XHJcbiAgICAgICAgdGhpcy5kcmF3aW5nU2VydmljZSA9IG5ldyBEcmF3aW5nU2VydmljZSh0aGlzLmdhbWVDYW1lcmFTZXJ2aWNlLCB0aGlzLmNhbnZhc1NlcnZpY2UsIHRoaXMudGV4dHVyZVNlcnZpY2UpO1xyXG4gICAgfVxyXG5cclxuXHJcblxyXG4gICAgSW5pdEdyYXBoaWNzU2VydmljZSgpIHtcclxuICAgICAgICB0aGlzLmh0bWxTZXJ2aWNlLkluaXQoKTtcclxuICAgICAgICB0aGlzLmNhbnZhc1NlcnZpY2UuSW5pdCgpO1xyXG4gICAgICAgIHRoaXMudGlsZVNlcnZpY2UuSW5pdCgpO1xyXG5cclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgR2V0VGV4dHVyZVNlcnZpY2UoKTogVGV4dHVyZVNlcnZpY2Uge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnRleHR1cmVTZXJ2aWNlO1xyXG4gICAgfVxyXG5cclxuICAgIEdldFRpbGVTZXJ2aWNlKCk6IFRpbGVTZXJ2aWNlIHtcclxuICAgICAgICByZXR1cm4gdGhpcy50aWxlU2VydmljZTtcclxuICAgIH1cclxuICAgIHB1YmxpYyBnZXRHYW1lQ2FtZXJhU2VydmljZSgpOiBHYW1lQ2FtZXJhU2VydmljZSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2FtZUNhbWVyYVNlcnZpY2U7XHJcbiAgICB9XHJcbiAgICBnZXREcmF3aW5nU2VydmljZSgpOiBEcmF3aW5nU2VydmljZSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZHJhd2luZ1NlcnZpY2U7XHJcbiAgICB9XHJcblxyXG4gICAgUmVnaXN0ZXJEcmF3YWJsZUVudGl0eShpZDogc3RyaW5nID0gbnVsbCk6IHN0cmluZyB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuY2FudmFzU2VydmljZS5SZWdpc3Rlck5ld0NhbnZhcyhpZCk7XHJcbiAgICB9XHJcblxyXG4gICAgR2V0Q2FudmFzKGlkOiBzdHJpbmcpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5jYW52YXNTZXJ2aWNlLkdldENhbnZhcyhpZCk7XHJcbiAgICB9XHJcblxyXG4gICAgUmVuZGVyKCkge1xyXG4gICAgICAgIC8vIGNvbnNvbGUubG9nKCdyZW5kZXJpbmcgaW4gZ3JhcGhpY3Mgc2VydmljZScpO1xyXG4gICAgICAgIHRoaXMuY2FudmFzU2VydmljZS5tYWluQ2FudmFzQ3R4LmNsZWFyUmVjdCgwLCAwLFxyXG4gICAgICAgICAgICB0aGlzLmNhbnZhc1NlcnZpY2UubWFpbkNhbnZhcy53aWR0aCwgdGhpcy5jYW52YXNTZXJ2aWNlLm1haW5DYW52YXMuaGVpZ2h0KTtcclxuXHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmNhbnZhc1NlcnZpY2UuZHJhd2FibGVBcmVhcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICB0aGlzLmNhbnZhc1NlcnZpY2UubWFpbkNhbnZhc0N0eC5kcmF3SW1hZ2UoXHJcbiAgICAgICAgICAgICAgICB0aGlzLmNhbnZhc1NlcnZpY2UuZHJhd2FibGVBcmVhc1tpXS5jYW52YXMsIDAsIDApO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufSIsImltcG9ydCB7IElucHV0U3RhdGUgfSBmcm9tIFwiLi9pbnB1dC1zdGF0ZVwiO1xyXG5pbXBvcnQgeyBWZWN0b3IyIH0gZnJvbSBcIi4uLy4uL251bWVyaWNzL21vZGVscy9WZWN0b3IyLm1vZGVsXCI7XHJcblxyXG5cclxuXHJcbmV4cG9ydCBjbGFzcyBJbnB1dE1hbmFnZXIge1xyXG5cclxuICAgIHByaXZhdGUgaW5wdXRTdGF0ZTogSW5wdXRTdGF0ZTtcclxuXHJcbiAgICBjdXJyZW50SW5wdXRzOiBBcnJheTxzdHJpbmc+O1xyXG4gICAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgdmFsaWRJbnB1dHM6IEFycmF5PHN0cmluZz4gPSBbJ3cnLCAnYScsICdzJywgJ2QnLCAnICddO1xyXG5cclxuXHJcbiAgICBwcml2YXRlIGdhbWVQYWRzOiBBcnJheTxHYW1lcGFkPiA9IEFycmF5PEdhbWVwYWQ+KCk7XHJcblxyXG4gICAgY29uc3RydWN0b3IoKSB7XHJcbiAgICAgICAgdGhpcy5pbnB1dFN0YXRlID0gbmV3IElucHV0U3RhdGUoKTtcclxuXHJcblxyXG4gICAgICAgIHRoaXMuY3VycmVudElucHV0cyA9IG5ldyBBcnJheTxzdHJpbmc+KCk7XHJcbiAgICAgICAgdGhpcy5nYW1lUGFkcyA9IG5ldyBBcnJheTxHYW1lcGFkPigpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogc2V0cyB1cCB0aGUgaW5wdXQgbWFuYWdlclxyXG4gICAgICpcclxuICAgICAqIEBtZW1iZXJvZiBJbnB1dE1hbmFnZXJcclxuICAgICAqL1xyXG4gICAgSW5pdElucHV0TWFuYWdlcigpIHtcclxuICAgICAgICB0aGlzLmlucHV0U3RhdGUuSW5pdCgpO1xyXG4gICAgICAgIC8vIHJldHVybjtcclxuXHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBjaGVja3MgZm9yIG5ldyBpbnB1dHMuIFNob3VsZCBiZSBjYWxsZWQgaW4gYSBsb29wXHJcbiAgICAgKlxyXG4gICAgICogQG1lbWJlcm9mIElucHV0TWFuYWdlclxyXG4gICAgICovXHJcbiAgICBOZXdJbnB1dExvb3BDaGVjaygpIHtcclxuICAgICAgICB0aGlzLmlucHV0U3RhdGUuVXBkYXRlSW5wdXRzKCk7XHJcbiAgICAgICAgLy8gdGhyb3cgbmV3IEVycm9yKFwiTWV0aG9kIG5vdCBpbXBsZW1lbnRlZC5cIik7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gcHJpdmF0ZSBSZWdpc3RlckdhbWVQYWQocGFkOiBHYW1lcGFkKSB7XHJcbiAgICAvLyAgICAgY29uc29sZS53YXJuKCdnYW1lcGFkIHJlZ2lzdGVyZWQnKTtcclxuICAgIC8vICAgICBjb25zb2xlLndhcm4oXCJHYW1lcGFkOiBjb25uZWN0ZWQgYXQgaW5kZXggJWQ6ICVzLiAlZCBidXR0b25zLCAlZCBheGVzLlwiLFxyXG4gICAgLy8gICAgICAgICBwYWQuaW5kZXgsIHBhZC5pZCxcclxuICAgIC8vICAgICAgICAgcGFkLmJ1dHRvbnMubGVuZ3RoLCBwYWQuYXhlcy5sZW5ndGgpO1xyXG4gICAgLy8gICAgIHRoaXMuZ2FtZVBhZHMgPSBuYXZpZ2F0b3IuZ2V0R2FtZXBhZHMoKTtcclxuICAgIC8vICAgICAvLyB0aGlzLmdhbWVQYWRzLnB1c2gocGFkKTsgLy8gID0gbmF2aWdhdG9yLmdldEdhbWVwYWRzID8gbmF2aWdhdG9yLmdldEdhbWVwYWRzKCkgOiAobmF2aWdhdG9yLmdldEdhbWVwYWRzID8gbmF2aWdhdG9yLmdldEdhbWVwYWRzIDogW10pO1xyXG5cclxuICAgIC8vICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuZ2FtZVBhZHMubGVuZ3RoOyBpKyspIHtcclxuICAgIC8vICAgICAgICAgY29uc3QgdGhpc0dwID0gdGhpcy5nYW1lUGFkc1tpXTtcclxuICAgIC8vICAgICAgICAgaWYgKHRoaXNHcCkge1xyXG4gICAgLy8gICAgICAgICAgICAgdGhpcy5kZXRhaWxzRGl2LmlubmVySFRNTCA9IFwiR2FtZXBhZCBjb25uZWN0ZWQgYXQgaW5kZXggXCIgKyB0aGlzR3AuaW5kZXggKyBcIjogXCIgKyB0aGlzR3AuaWQgK1xyXG4gICAgLy8gICAgICAgICAgICAgICAgIFwiLiBJdCBoYXMgXCIgKyB0aGlzR3AuYnV0dG9ucy5sZW5ndGggKyBcIiBidXR0b25zIGFuZCBcIiArIHRoaXNHcC5heGVzLmxlbmd0aCArIFwiIGF4ZXMuXCI7XHJcblxyXG4gICAgLy8gICAgICAgICB9XHJcbiAgICAvLyAgICAgfVxyXG4gICAgLy8gfVxyXG4gICAgLy8gcHJpdmF0ZSBEZVJlZ2lzdGVyR2FtZVBhZChwYWQ6IEdhbWVwYWQpIHtcclxuICAgIC8vICAgICBjb25zb2xlLndhcm4oJ2RlcmVnaXN0ZXJpbmcgZ2FtZXBhZCcpO1xyXG4gICAgLy8gICAgIGRlbGV0ZSB0aGlzLmdhbWVQYWRzW3BhZC5pbmRleF07XHJcbiAgICAvLyAgICAgdGhpcy5SZXBvcnRUb0h0bWwoXCJnYW1lcGFkIERDXCIpO1xyXG4gICAgLy8gfVxyXG5cclxuXHJcblxyXG5cclxuICAgIC8qKlxyXG4gICAgICogcHVibGljIG1ldGhvZCB0byBjaGVjayBpZiBhIGtleSBpcyBwcmVzc2VkIG9yIG5vdFxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXlcclxuICAgICAqIEByZXR1cm5zXHJcbiAgICAgKiBAbWVtYmVyb2YgSW5wdXRNYW5hZ2VyXHJcbiAgICAgKi9cclxuICAgIElzS2V5UHJlc3NlZChpbnB1dERlc2NyaXB0aW9uOiBzdHJpbmcpOiBib29sZWFuIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5pbnB1dFN0YXRlLklzSW5wdXRQcmVzc2VkKGlucHV0RGVzY3JpcHRpb24pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogZ2V0cyB0aGUgZm9yY2UgdmFsdWUgZm9yIGEgZ2l2ZW4gaW5wdXQuIElmIGl0J3MgaW4gXHJcbiAgICAgKiBrZXlib2FyZCBtb2RlLCB0aGVuIGl0IGp1c3QgcmV0dXJucyAwIG9yIDFcclxuICAgICAqIFxyXG4gICAgICogSWYgaXQncyBpbiBrZXlib2FyZCBtb2RlLCB0aGVuIGl0IHJldHVybnMgYSB2YWx1ZSBvZiAtMS4wIHRvICsxLjBcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gaW5wdXREZXNjcmlwdGlvblxyXG4gICAgICogQHJldHVybnMge251bWJlcn1cclxuICAgICAqIEBtZW1iZXJvZiBJbnB1dE1hbmFnZXJcclxuICAgICAqL1xyXG4gICAgR2V0Rm9yY2VWYWx1ZShpbnB1dERlc2NyaXB0aW9uOiBzdHJpbmcpOiBudW1iZXIge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmlucHV0U3RhdGUuR2V0Rm9yY2VWYWx1ZShpbnB1dERlc2NyaXB0aW9uKTtcclxuICAgIH1cclxuXHJcbn0iLCJpbXBvcnQgeyBJbnB1dCB9IGZyb20gXCIuL2lucHV0Lm1vZGVsXCI7XHJcblxyXG5leHBvcnQgY2xhc3MgSW5wdXRTdGF0ZSB7XHJcblxyXG4gICAgcHJpdmF0ZSBzdGF0aWMgU1lTVEVNX0tFWVM6IHN0cmluZ1tdID0gW1xyXG4gICAgICAgICdGMScsXHJcbiAgICAgICAgJ0YyJyxcclxuICAgICAgICAnRjMnLFxyXG4gICAgICAgICdGNCcsXHJcbiAgICAgICAgJ0Y1JyxcclxuICAgICAgICAnRjYnLFxyXG4gICAgICAgICdGNycsXHJcbiAgICAgICAgJ0Y4JyxcclxuICAgICAgICAnRjknLFxyXG4gICAgICAgICdGMTAnLFxyXG4gICAgICAgICdGMTEnLFxyXG4gICAgICAgICdGMTInLFxyXG4gICAgXTtcclxuICAgIHByaXZhdGUgc3RhdGljIERFRkFVTFRfTUFYX0lOUFVUUzogbnVtYmVyID0gNDtcclxuICAgIHByaXZhdGUgc3RhdGljIERFRkFVTFRfTUlOX0pPWVNUSUNLX1NFTlNJVElWSVRZOiBudW1iZXIgPSAwLjE7XHJcbiAgICBwcml2YXRlIGRldGFpbHNEaXY6IEhUTUxFbGVtZW50O1xyXG5cclxuICAgIHByaXZhdGUgcmVnaXN0ZXJlZEdhbWVQYWRzOiBHYW1lcGFkW107XHJcbiAgICBwcml2YXRlIGdhbWVQYWRzOiBHYW1lcGFkW107XHJcbiAgICBwcml2YXRlIGN1cnJlbnRJbnB1dHM6IEFycmF5PElucHV0PjtcclxuXHJcbiAgICBwcml2YXRlIGNvbnRyb2xsaW5nV2l0aFBhZCA9IGZhbHNlO1xyXG4gICAgY29uc3RydWN0b3IoKSB7XHJcbiAgICAgICAgY29uc29sZS5sb2coJ2lucHV0U3RhdGU6IGNvbnN0cnVjdGluZyBpbnB1dCBzdGF0ZScpO1xyXG4gICAgICAgIHRoaXMuZGV0YWlsc0RpdiA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdkZXRhaWxzX2RpdicpO1xyXG4gICAgICAgIHRoaXMucmVnaXN0ZXJlZEdhbWVQYWRzID0gbmV3IEFycmF5PEdhbWVwYWQ+KCk7XHJcbiAgICAgICAgdGhpcy5nYW1lUGFkcyA9IG5ldyBBcnJheTxHYW1lcGFkPigpO1xyXG4gICAgfVxyXG5cclxuICAgIEluaXQoKSB7XHJcbiAgICAgICAgY29uc29sZS5sb2coJ2lucHV0U3RhdGU6IGluaXQgaW5wdXRzdGF0ZScpO1xyXG4gICAgICAgIHRoaXMuc2V0dXBJbnB1dHMoKTtcclxuICAgICAgICB0aGlzLlNldHVwR2FtZVBhZFJlZ2lzdHJhdGlvbldhdGNoKCk7XHJcbiAgICAgICAgdGhpcy5TZXR1cEtleWJvYXJkSW5wdXRXYXRjaCgpO1xyXG4gICAgICAgIHRoaXMuU2V0R2FtZVBhZE1vZGUoZmFsc2UpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgU2V0R2FtZVBhZE1vZGUoY29udHJvbGxpbmdXaXRoUGFkOiBib29sZWFuKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5jb250cm9sbGluZ1dpdGhQYWQgPSBjb250cm9sbGluZ1dpdGhQYWQ7XHJcbiAgICAgICAgaWYgKGNvbnRyb2xsaW5nV2l0aFBhZCkge1xyXG4gICAgICAgICAgICB0aGlzLmRldGFpbHNEaXYuaW5uZXJIVE1MID0gJ2NvbnRyb2xsaW5nIHdpdGggZ2FtZXBhZC4gUHJlc3MgPj4gayA8PCB0byB1c2Uga2V5Ym9hcmQgbW9kZSc7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5kZXRhaWxzRGl2LmlubmVySFRNTCA9ICdjb250cm9sbGluZyB3aXRoIGtleWJvYXJkLiBQcmVzcyA+PiBzZWxlY3QgPDwgdG8gdXNlIGdhbWVwYWQgbW9kZSc7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcHJpdmF0ZSBHZXRHYW1lUGFkTW9kZSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5jb250cm9sbGluZ1dpdGhQYWQ7XHJcbiAgICB9XHJcblxyXG5cclxuICAgIC8qKlxyXG4gICAgICogLy8gaHR0cHM6Ly93M2MuZ2l0aHViLmlvL2dhbWVwYWQvI3JlbWFwcGluZ1xyXG4gICAgICpcclxuICAgICAqIEBtZW1iZXJvZiBJbnB1dFN0YXRlXHJcbiAgICAgKi9cclxuICAgIHNldHVwSW5wdXRzKCkge1xyXG4gICAgICAgIHRoaXMuY3VycmVudElucHV0cyA9IG5ldyBBcnJheTxJbnB1dD4oKTtcclxuICAgICAgICB0aGlzLmN1cnJlbnRJbnB1dHMucHVzaChcclxuICAgICAgICAgICAgbmV3IElucHV0KCdkaXJlY3Rpb25fbGVmdCcsICdhJywgMTQsIG51bGwpLFxyXG4gICAgICAgICAgICBuZXcgSW5wdXQoJ2RpcmVjdGlvbl9yaWdodCcsICdkJywgMTUsIG51bGwpLFxyXG4gICAgICAgICAgICBuZXcgSW5wdXQoJ2RpcmVjdGlvbl91cCcsICd3JywgMTIsIG51bGwpLFxyXG4gICAgICAgICAgICBuZXcgSW5wdXQoJ2RpcmVjdGlvbl9kb3duJywgJ3MnLCAxMywgbnVsbCksXHJcblxyXG4gICAgICAgICAgICBuZXcgSW5wdXQoJ2F4ZXNfcGFkX2xlZnRfaG9yaXpvbnRhbCcsIG51bGwsIG51bGwsIDApLFxyXG4gICAgICAgICAgICBuZXcgSW5wdXQoJ2F4ZXNfcGFkX2xlZnRfdmVydGljYWwnLCBudWxsLCBudWxsLCAxKSxcclxuICAgICAgICAgICAgbmV3IElucHV0KCdheGVzX3BhZF9yaWdodF9ob3Jpem9udGFsJywgbnVsbCwgbnVsbCwgMiksXHJcbiAgICAgICAgICAgIG5ldyBJbnB1dCgnYXhlc19wYWRfcmlnaHRfdmVydGljYWwnLCBudWxsLCBudWxsLCAzKSxcclxuXHJcbiAgICAgICAgICAgIG5ldyBJbnB1dCgndHJpZ2dlcl9vbmVfbGVmdCcsICdxJywgNCwgbnVsbCksXHJcbiAgICAgICAgICAgIG5ldyBJbnB1dCgndHJpZ2dlcl90d29fbGVmdCcsICd3JywgNiwgbnVsbCksXHJcbiAgICAgICAgICAgIG5ldyBJbnB1dCgndHJpZ2dlcl9vbmVfcmlnaHQnLCAnZScsIDUsIG51bGwpLFxyXG4gICAgICAgICAgICBuZXcgSW5wdXQoJ3RyaWdnZXJfdHdvX3JpZ2h0JywgJ3MnLCA3LCBudWxsKSxcclxuXHJcbiAgICAgICAgICAgIC8vICdhY3Rpb25fe3ZhbH0nIHdoZXJlIHt2YWx9IGlzIHRoZSBcclxuICAgICAgICAgICAgLy8gbmFtZSBvZiB0aGUgYnV0dG9uIG9uIGFuIFhCb3gzNjAgY29udHJvbGxlclxyXG4gICAgICAgICAgICBuZXcgSW5wdXQoJ2FjdGlvbl9hJywgJyAnLCAwLCBudWxsKSxcclxuICAgICAgICAgICAgbmV3IElucHV0KCdhY3Rpb25feScsICd6JywgMywgbnVsbCksXHJcbiAgICAgICAgICAgIG5ldyBJbnB1dCgnYWN0aW9uX3gnLCAneCcsIDIsIG51bGwpLFxyXG4gICAgICAgICAgICBuZXcgSW5wdXQoJ2FjdGlvbl9iJywgJ2MnLCAxLCBudWxsKSxcclxuICAgICAgICApO1xyXG4gICAgfVxyXG5cclxuXHJcbiAgICBwdWJsaWMgVXBkYXRlSW5wdXRzKCkge1xyXG4gICAgICAgIC8vIGNvbnNvbGUubG9nKCdpbnB1dHN0YXRlOiB1cGRhdGluZyBpbnB1dHMuIFRoZXJlIGFyZSAnICsgdGhpcy5yZWdpc3RlcmVkR2FtZVBhZHMubGVuZ3RoICsgJyBwYWRzIGNvbm5lY3RlZCcpXHJcblxyXG4gICAgICAgIHRoaXMuVXBkYXRlR2FtZVBhZElucHV0cygpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgUmVzZXRJbnB1dHNCZWZvcmVHYW1lUGFkSW5wdXQoKSB7XHJcbiAgICAgICAgZm9yIChsZXQgaW5wdXQgb2YgdGhpcy5jdXJyZW50SW5wdXRzKSB7XHJcbiAgICAgICAgICAgIGlucHV0Lndhc1ByZXNzZWRQcmV2aW91c0NoZWNrID0gaW5wdXQucHJlc3NlZDtcclxuICAgICAgICAgICAgaW5wdXQucHJlc3NlZCA9IGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHByaXZhdGUgVXBkYXRlR2FtZVBhZElucHV0cygpIHtcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMucmVnaXN0ZXJlZEdhbWVQYWRzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHBhZFRvQ2hlY2sgPSB0aGlzLkdldEdhbWVQYWQoaSk7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLkdldEdhbWVQYWRNb2RlKCkpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuUmVzZXRJbnB1dHNCZWZvcmVHYW1lUGFkSW5wdXQoKTtcclxuICAgICAgICAgICAgICAgIGZvciAobGV0IGJ0bkluZGV4ID0gMDsgYnRuSW5kZXggPCBwYWRUb0NoZWNrLmJ1dHRvbnMubGVuZ3RoOyBidG5JbmRleCsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuZ2FtZVBhZEJ1dHRvblByZXNzZWQocGFkVG9DaGVjay5idXR0b25zW2J0bkluZGV4XSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wdXNoVG9DdXJyZW50SW5wdXRzRnJvbUdhbWVQYWQoYnRuSW5kZXgsIHBhZFRvQ2hlY2suYnV0dG9uc1tidG5JbmRleF0udmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhgaW5wdXRzdGF0ZTogYnRuICR7YnRuSW5kZXh9IGlzIHByZXNzZWRgKVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGZvciAobGV0IGF4ZXNJbmRleCA9IDA7IGF4ZXNJbmRleCA8IHBhZFRvQ2hlY2suYXhlcy5sZW5ndGg7IGF4ZXNJbmRleCsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuZ2FtZVBhZEF4ZXNQcmVzc2VkKHBhZFRvQ2hlY2suYXhlc1theGVzSW5kZXhdKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnB1c2hUb0N1cnJlbnRJbnB1dHNGcm9tR2FtZVBhZEF4ZXMoYXhlc0luZGV4LCBwYWRUb0NoZWNrLmF4ZXNbYXhlc0luZGV4XSlcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5nYW1lUGFkQnV0dG9uUHJlc3NlZChwYWRUb0NoZWNrLmJ1dHRvbnNbOF0pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKCdpbnB1dHN0YXRlOiBpbiBnYW1lcGFkIG1vZGUnKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLlNldEdhbWVQYWRNb2RlKHRydWUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuXHJcbiAgICBJc0lucHV0UHJlc3NlZChpbnB1dERlc2NyaXB0aW9uOiBzdHJpbmcpOiBib29sZWFuIHtcclxuICAgICAgICBmb3IgKGxldCBpbnB1dCBvZiB0aGlzLmN1cnJlbnRJbnB1dHMpIHtcclxuICAgICAgICAgICAgaWYgKGlucHV0Lm5hbWUgPT09IGlucHV0RGVzY3JpcHRpb24pIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBpbnB1dC5wcmVzc2VkO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuICAgIEdldEZvcmNlVmFsdWUoaW5wdXREZXNjcmlwdGlvbjogc3RyaW5nKTogbnVtYmVyIHtcclxuICAgICAgICBmb3IgKGxldCBpbnB1dCBvZiB0aGlzLmN1cnJlbnRJbnB1dHMpIHtcclxuICAgICAgICAgICAgaWYgKGlucHV0Lm5hbWUgPT09IGlucHV0RGVzY3JpcHRpb24pIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBpbnB1dC5mb3JjZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gMDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIGNoZWNrcyBpZiB0aGlzIGtleSBpcyBpbiB0aGUgU1lTVEVNX0tFWVMgYXJyYXlcclxuICAgICAqIChpbmNsdWRlcyBrZXlzIGxpa2UgRjEgLSBGMTIpXHJcbiAgICAgKlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXlcclxuICAgICAqIEByZXR1cm5zXHJcbiAgICAgKiBAbWVtYmVyb2YgSW5wdXRTdGF0ZVxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGlzU3lzdGVtS2V5KGtleTogc3RyaW5nKSB7XHJcbiAgICAgICAgaWYgKElucHV0U3RhdGUuU1lTVEVNX0tFWVMuaW5jbHVkZXMoa2V5KSkge1xyXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgU2V0dXBLZXlib2FyZElucHV0V2F0Y2goKSB7XHJcbiAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLCBldmVudCA9PiB7XHJcbiAgICAgICAgICAgIGlmICghdGhpcy5pc1N5c3RlbUtleShldmVudC5rZXkpKSB7XHJcbiAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5wdXNoVG9DdXJyZW50SW5wdXRzRnJvbUtleWJvYXJkKGV2ZW50LmtleSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ2tleXVwJywgZXZlbnQgPT4ge1xyXG4gICAgICAgICAgICBpZiAoIXRoaXMuaXNTeXN0ZW1LZXkoZXZlbnQua2V5KSkge1xyXG5cclxuICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnBvcEZyb21DdXJyZW50SW5wdXRzRnJvbUtleWJvYXJkKGV2ZW50LmtleSk7XHJcbiAgICAgICAgICAgICAgICBpZiAoZXZlbnQua2V5ID09PSAnaycpIHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oYGlucHV0c3RhdGU6IGNvbnRyb2xsaW5nIGJ5IGtleWJvYXJkYClcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLlNldEdhbWVQYWRNb2RlKGZhbHNlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgcHVzaFRvQ3VycmVudElucHV0c0Zyb21LZXlib2FyZChrZXk6IHN0cmluZykge1xyXG4gICAgICAgIGlmICh0aGlzLkdldEdhbWVQYWRNb2RlKCkgPT09IGZhbHNlKSB7XHJcbiAgICAgICAgICAgIGZvciAobGV0IHRoaXNJbnB1dCBvZiB0aGlzLmN1cnJlbnRJbnB1dHMpIHtcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzSW5wdXQua2V5Ym9hcmRJZCA9PT0ga2V5KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpc0lucHV0LnByZXNzZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXNJbnB1dC5mb3JjZSA9IDE7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gY29uc29sZS5sb2coYGlucHV0c3RhdGUgbWFya2VkICR7dGhpc0lucHV0Lm5hbWV9IGFzIHByZXNzZWQgd2l0aCBmb3JjZSAke3RoaXNJbnB1dC5mb3JjZX1gKVxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHBvcEZyb21DdXJyZW50SW5wdXRzRnJvbUtleWJvYXJkKGtleTogc3RyaW5nKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuR2V0R2FtZVBhZE1vZGUoKSA9PT0gZmFsc2UpIHtcclxuXHJcbiAgICAgICAgICAgIGZvciAobGV0IGlucHV0IG9mIHRoaXMuY3VycmVudElucHV0cykge1xyXG4gICAgICAgICAgICAgICAgaWYgKGlucHV0LmtleWJvYXJkSWQgPT09IGtleSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlucHV0LnByZXNzZWQgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhgaW5wdXRzdGF0ZSBtYXJrZWQgJHtpbnB1dC5uYW1lfSBhcyBwcmVzc2VkYClcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHVzaFRvQ3VycmVudElucHV0c0Zyb21HYW1lUGFkKGJ0bklkOiBudW1iZXIsIHB1c2hGb3JjZTogbnVtYmVyKSB7XHJcbiAgICAgICAgZm9yIChsZXQgdGhpc0lucHV0IG9mIHRoaXMuY3VycmVudElucHV0cykge1xyXG4gICAgICAgICAgICBpZiAodGhpc0lucHV0LmdhbWVwYWRJZCA9PT0gYnRuSWQpIHtcclxuICAgICAgICAgICAgICAgIHRoaXNJbnB1dC5wcmVzc2VkID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIHRoaXNJbnB1dC5mb3JjZSA9IHB1c2hGb3JjZTtcclxuICAgICAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKGBpbnB1dHN0YXRlIG1hcmtlZCAke3RoaXNJbnB1dC5uYW1lfSBhcyBwcmVzc2VkIHdpdGggZm9yY2UgJHt0aGlzSW5wdXQuZm9yY2V9YClcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHB1c2hUb0N1cnJlbnRJbnB1dHNGcm9tR2FtZVBhZEF4ZXMoYXhlc0luZGV4OiBudW1iZXIsIHB1c2hGb3JjZTogbnVtYmVyKSB7XHJcbiAgICAgICAgZm9yIChsZXQgdGhpc0lucHV0IG9mIHRoaXMuY3VycmVudElucHV0cykge1xyXG4gICAgICAgICAgICBpZiAodGhpc0lucHV0LmdhbWVQYWRBeGVzSWQgPT09IGF4ZXNJbmRleCkge1xyXG4gICAgICAgICAgICAgICAgdGhpc0lucHV0LnByZXNzZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgdGhpc0lucHV0LmZvcmNlID0gcHVzaEZvcmNlO1xyXG4gICAgICAgICAgICAgICAgLy8gY29uc29sZS5sb2coYGlucHV0c3RhdGUgbWFya2VkICR7dGhpc0lucHV0Lm5hbWV9IGFzIHByZXNzZWQgd2l0aCBmb3JjZSAke3RoaXNJbnB1dC5mb3JjZX1gKVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcG9wRnJvbUN1cnJlbnRJbnB1dHNGcm9tR2FtZVBhZChidG5JZDogbnVtYmVyKSB7XHJcbiAgICAgICAgZm9yIChsZXQgaW5wdXQgb2YgdGhpcy5jdXJyZW50SW5wdXRzKSB7XHJcbiAgICAgICAgICAgIGlmIChpbnB1dC5nYW1lcGFkSWQgPT09IGJ0bklkKSB7XHJcbiAgICAgICAgICAgICAgICBpbnB1dC5wcmVzc2VkID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhgaW5wdXRzdGF0ZSBtYXJrZWQgJHtpbnB1dC5uYW1lfSBhcyBub3RgKVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuXHJcbiAgICAvKiBHYW1lUGFkIGNvZGUgKi9cclxuXHJcbiAgICAvKipcclxuICAgICAqICB3YXRjaGVzIGZvciB0aGUgZ2FtZSBwYWQgcmVnaXN0cmF0aW9uIGV2ZW50c1xyXG4gICAgICpcclxuICAgICAqIEBtZW1iZXJvZiBJbnB1dFN0YXRlXHJcbiAgICAgKi9cclxuICAgIFNldHVwR2FtZVBhZFJlZ2lzdHJhdGlvbldhdGNoKCkge1xyXG4gICAgICAgIGNvbnNvbGUubG9nKCdpbnB1dHN0YXRlIHNldHRpbmcgdXAgcmVnaXN0cmF0aW9ucycpXHJcblxyXG4gICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdnYW1lcGFkY29ubmVjdGVkJywgKGU6IEdhbWVwYWRFdmVudCkgPT4ge1xyXG4gICAgICAgICAgICBjb25zb2xlLmxvZygnaW5wdXRzdGF0ZSBnb3QgZ2FtZXBhZCcpXHJcbiAgICAgICAgICAgIHRoaXMuUmVnaXN0ZXJHYW1lUGFkKGUuZ2FtZXBhZCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ2dhbWVwYWRkaXNjb25uZWN0ZWQnLCAoZTogR2FtZXBhZEV2ZW50KSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ2lucHV0c3RhdGUgZ2FtZXBhZCB3YXMgZGlzY29ubmVjdGVkJyk7XHJcbiAgICAgICAgICAgIHRoaXMuRGVSZWdpc3RlckdhbWVQYWQoZS5nYW1lcGFkKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcblxyXG4gICAgcHJpdmF0ZSBSZWdpc3RlckdhbWVQYWQoZ2FtZVBhZDogR2FtZXBhZCkge1xyXG4gICAgICAgIGNvbnNvbGUud2FybihcImlucHV0c3RhdGU6IEdhbWVwYWQ6IGNvbm5lY3RlZCBhdCBpbmRleCAlZDogJXMuICVkIGJ1dHRvbnMsICVkIGF4ZXMuXCIsXHJcbiAgICAgICAgICAgIGdhbWVQYWQuaW5kZXgsIGdhbWVQYWQuaWQsXHJcbiAgICAgICAgICAgIGdhbWVQYWQuYnV0dG9ucy5sZW5ndGgsIGdhbWVQYWQuYXhlcy5sZW5ndGgpO1xyXG4gICAgICAgIHRoaXMucmVnaXN0ZXJlZEdhbWVQYWRzW2dhbWVQYWQuaW5kZXhdID0gZ2FtZVBhZDtcclxuICAgICAgICB0aGlzLmRldGFpbHNEaXYuaW5uZXJIVE1MID0gJ0dhbWVwYWQgaGFzIGJlZW4gY29ubmVjdGVkJztcclxuXHJcblxyXG4gICAgfVxyXG4gICAgcHJpdmF0ZSBEZVJlZ2lzdGVyR2FtZVBhZChnYW1lUGFkOiBHYW1lcGFkKSB7XHJcbiAgICAgICAgY29uc29sZS5lcnJvcihcImlucHV0c3RhdGU6IEdhbWVwYWQ6IGNvbm5lY3RlZCBhdCBpbmRleCAlZDogJXMuICVkIGJ1dHRvbnMsICVkIGF4ZXMuXCIsXHJcbiAgICAgICAgICAgIGdhbWVQYWQuaW5kZXgsIGdhbWVQYWQuaWQsXHJcbiAgICAgICAgICAgIGdhbWVQYWQuYnV0dG9ucy5sZW5ndGgsIGdhbWVQYWQuYXhlcy5sZW5ndGgpO1xyXG4gICAgICAgIHRoaXMuR2V0R2FtZVBhZHMoKTtcclxuICAgICAgICB0aGlzLmRldGFpbHNEaXYuaW5uZXJIVE1MID0gJ2lucHV0c3RhdGU6IEdhbWVwYWQgaGFzIGJlZW4gZGlzY29ubmVjdGVkJztcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIEdldEdhbWVQYWRzKCkge1xyXG4gICAgICAgIHRoaXMuZ2FtZVBhZHMgPSBuYXZpZ2F0b3IuZ2V0R2FtZXBhZHMoKTtcclxuICAgIH1cclxuICAgIHByaXZhdGUgR2V0R2FtZVBhZChpbmRleDogbnVtYmVyKSB7XHJcbiAgICAgICAgcmV0dXJuIG5hdmlnYXRvci5nZXRHYW1lcGFkcygpW2luZGV4XTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGdhbWVQYWRBeGVzUHJlc3NlZChheGVzOiBudW1iZXIpIHtcclxuICAgICAgICByZXR1cm4gKGF4ZXMgPiBJbnB1dFN0YXRlLkRFRkFVTFRfTUlOX0pPWVNUSUNLX1NFTlNJVElWSVRZIHx8IGF4ZXMgPCAtSW5wdXRTdGF0ZS5ERUZBVUxUX01JTl9KT1lTVElDS19TRU5TSVRJVklUWSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBnYW1lUGFkQnV0dG9uUHJlc3NlZChidG46IEdhbWVwYWRCdXR0b24pIHtcclxuICAgICAgICAvLyBjb25zb2xlLmxvZyh0eXBlb2YoYnRuKSk7XHJcbiAgICAgICAgaWYgKHR5cGVvZiAoYnRuKSA9PT0gJ29iamVjdCcpIHtcclxuICAgICAgICAgICAgLy8gZmlyZWZveFxyXG4gICAgICAgICAgICAvLyBjb25zb2xlLmxvZygnZ2FtZXBhZDogZmYnKVxyXG4gICAgICAgICAgICBpZiAoYnRuLnByZXNzZWQpIHtcclxuICAgICAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKCdpbnB1dHN0YXRlOiBidXR0b24gaXMgcHJlc3NlZCcpXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIGJ0bi52YWx1ZTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAvLyBjb25zb2xlLmxvZygnaW5wdXRzdGF0ZTogZ2FtZXBhZDogY2hyb21lJylcclxuICAgICAgICAgICAgcmV0dXJuIGJ0biA9PT0gMS4wO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufSIsImV4cG9ydCBjbGFzcyBJbnB1dCB7XHJcbiAgICBjb25zdHJ1Y3RvcihcclxuICAgICAgICBuYW1lOiBzdHJpbmcsIFxyXG4gICAgICAgIGtleWJvYXJkSWQ6IHN0cmluZywgXHJcbiAgICAgICAgZ2FtZXBhZElkOiBudW1iZXIsIFxyXG4gICAgICAgIGdhbWVQYWRBeGVzSWQ6IG51bWJlcikge1xyXG4gICAgICAgIHRoaXMubmFtZSA9IG5hbWU7XHJcbiAgICAgICAgdGhpcy5rZXlib2FyZElkID0ga2V5Ym9hcmRJZDtcclxuICAgICAgICB0aGlzLmdhbWVwYWRJZCA9IGdhbWVwYWRJZDtcclxuICAgICAgICB0aGlzLmdhbWVQYWRBeGVzSWQgPSBnYW1lUGFkQXhlc0lkO1xyXG4gICAgfVxyXG4gICAgbmFtZTogc3RyaW5nO1xyXG4gICAga2V5Ym9hcmRJZDogc3RyaW5nO1xyXG4gICAgZ2FtZXBhZElkOiBudW1iZXI7XHJcbiAgICBnYW1lUGFkQXhlc0lkOiBudW1iZXI7XHJcbiAgICBwcmVzc2VkOiBib29sZWFuID0gZmFsc2U7XHJcblxyXG4gICAgZm9yY2U6IG51bWJlciA9IDA7XHJcblxyXG4gICAgd2FzUHJlc3NlZFByZXZpb3VzQ2hlY2s6IGJvb2xlYW4gPSBmYWxzZTtcclxufVxyXG4iLCJpbXBvcnQgeyBCYXNlU3RhdGUgfSBmcm9tIFwiLi9fQmFzZVN0YXRlXCI7XHJcbmltcG9ydCB7IEdhbWVDYW1lcmFTZXJ2aWNlIH0gZnJvbSBcIi4uL0dyYXBoaWNzL0NhbWVyYS9nYW1lLWNhbWVyYS5zZXJ2aWNlXCI7XHJcbmltcG9ydCB7IEdyYXBoaWNzU2VydmljZSB9IGZyb20gXCIuLi9HcmFwaGljcy9ncmFwaGljcy5zZXJ2aWNlXCI7XHJcblxyXG5leHBvcnQgY2xhc3MgR2FtZVN0YXRlIGV4dGVuZHMgQmFzZVN0YXRlIHtcclxuXHJcbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIGdyYXBoaWNzU2VydmljZTogR3JhcGhpY3NTZXJ2aWNlKSB7XHJcbiAgICAgICAgc3VwZXIoKTtcclxuICAgICAgICBjb25zb2xlLmxvZygnY29uc3RydWN0aW5nIEdhbWVTdGF0ZScpXHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIFRpY2soKTogdm9pZCB7XHJcbiAgICAgICAgLy8gY29uc29sZS5lcnJvcihcIk1ldGhvZCBub3QgaW1wbGVtZW50ZWQuXCIpO1xyXG4gICAgICAgIC8vIHRoaXMuZ3JhcGhpY3NTZXJ2aWNlLmdldEdhbWVDYW1lcmFTZXJ2aWNlKCkuTW92ZUNhbWVyYSgxLCAwKTtcclxuXHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIFJlbmRlcigpOiB2b2lkIHtcclxuICAgICAgICAvLyBjb25zb2xlLmVycm9yKFwiTWV0aG9kIG5vdCBpbXBsZW1lbnRlZC5cIik7XHJcbiAgICB9XHJcblxyXG5cclxufSIsImltcG9ydCB7IEJhc2VTdGF0ZSB9IGZyb20gXCIuL19CYXNlU3RhdGVcIjtcclxuXHJcblxyXG5leHBvcnQgY2xhc3MgTWVudVN0YXRlIGV4dGVuZHMgQmFzZVN0YXRlIHtcclxuICAgIGNvbnN0cnVjdG9yKCkge1xyXG4gICAgICAgIHN1cGVyKCk7XHJcbiAgICAgICAgY29uc29sZS5sb2coYGNvbnN0cnVjdGluZyBNZW51U3RhdGVgKTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgVGljaygpOiB2b2lkIHtcclxuICAgICAgICBjb25zb2xlLmVycm9yKFwiTWV0aG9kIG5vdCBpbXBsZW1lbnRlZC5cIik7XHJcblxyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBSZW5kZXIoKTogdm9pZCB7XHJcbiAgICAgICAgY29uc29sZS5lcnJvcihcIk1ldGhvZCBub3QgaW1wbGVtZW50ZWQuXCIpO1xyXG5cclxuICAgIH1cclxufSIsImltcG9ydCB7IEJhc2VTdGF0ZSB9IGZyb20gXCIuL19CYXNlU3RhdGVcIjtcclxuXHJcbmV4cG9ydCBjbGFzcyBTZXR0aW5nc1N0YXRlIGV4dGVuZHMgQmFzZVN0YXRlIHtcclxuICAgIGNvbnN0cnVjdG9yKCkge1xyXG4gICAgICAgIHN1cGVyKCk7XHJcbiAgICAgICAgY29uc29sZS5sb2coYGNvbnN0cnVjdGluZyBTZXR0aW5nc1N0YXRlYCk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIFRpY2soKTogdm9pZCB7XHJcbiAgICAgICAgY29uc29sZS5lcnJvcihcIk1ldGhvZCBub3QgaW1wbGVtZW50ZWQuXCIpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBSZW5kZXIoKTogdm9pZCB7XHJcbiAgICAgICAgY29uc29sZS5lcnJvcihcIk1ldGhvZCBub3QgaW1wbGVtZW50ZWQuXCIpO1xyXG4gICAgfVxyXG59XHJcbiIsImV4cG9ydCBhYnN0cmFjdCBjbGFzcyBCYXNlU3RhdGUge1xyXG5cclxuICAgIHB1YmxpYyBhYnN0cmFjdCBUaWNrKCk6IHZvaWQ7XHJcbiAgICBwdWJsaWMgYWJzdHJhY3QgUmVuZGVyKCk6IHZvaWQ7XHJcbn0gIiwiaW1wb3J0IHsgQmFzZVN0YXRlIH0gZnJvbSBcIi4vX0Jhc2VTdGF0ZVwiO1xyXG5cclxuZXhwb3J0IGNsYXNzIFN0YXRlU2VydmljZSB7XHJcbiAgICBwcml2YXRlIGN1cnJlbnRTdGF0ZTogQmFzZVN0YXRlID0gbnVsbDtcclxuXHJcblxyXG4gICAgcHVibGljIHNldFN0YXRlKHN0YXRlOiBCYXNlU3RhdGUpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLmN1cnJlbnRTdGF0ZSA9IHN0YXRlO1xyXG4gICAgfVxyXG4gICAgcHVibGljIEdldFN0YXRlKCk6IEJhc2VTdGF0ZSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuY3VycmVudFN0YXRlO1xyXG4gICAgfVxyXG59IiwiXHJcbmV4cG9ydCBjbGFzcyBHdWlkR2VuZXJhdG9yIHtcclxuICAgIC8qKlxyXG4gICAgICogcmV0dXJucyBhIG5ldyBndWlkXHJcbiAgICAgKiBcclxuICAgICAqIGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8yMTE3NTIzXHJcbiAgICAgKlxyXG4gICAgICogQGV4cG9ydFxyXG4gICAgICogQHJldHVybnMgYSBndWlkXHJcbiAgICAgKi9cclxuICAgIHN0YXRpYyBOZXdHdWlkKCkge1xyXG4gICAgICAgIHJldHVybiAneHh4eHh4eHgteHh4eC00eHh4LXl4eHgteHh4eHh4eHh4eHh4Jy5yZXBsYWNlKC9beHldL2csIGZ1bmN0aW9uIChjKSB7XHJcbiAgICAgICAgICAgIHZhciByID0gTWF0aC5yYW5kb20oKSAqIDE2IHwgMCwgdiA9IGMgPT0gJ3gnID8gciA6IChyICYgMHgzIHwgMHg4KTtcclxuICAgICAgICAgICAgcmV0dXJuIHYudG9TdHJpbmcoMTYpO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgIH1cclxufSIsImltcG9ydCB7IFZlY3RvcjIgfSBmcm9tIFwiLi4vLi4vLi4vbnVtZXJpY3MvbW9kZWxzL1ZlY3RvcjIubW9kZWxcIjtcclxuXHJcbmV4cG9ydCBjbGFzcyBSYW5kb21OdW1iZXJHZW5lcmF0b3Ige1xyXG5cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdlbmVyYXRlcyBhIHJhbmRvbSBudW1iZXJcclxuICAgICAqXHJcbiAgICAgKiBAc3RhdGljXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbWluXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbWF4XHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfVxyXG4gICAgICogQG1lbWJlcm9mIFJhbmRvbU51bWJlckdlbmVyYXRvclxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc3RhdGljIEdldFJhbmRvbU51bWJlcihtaW46IG51bWJlciwgbWF4OiBudW1iZXIpOiBudW1iZXIge1xyXG4gICAgICAgIHJldHVybiBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiAobWF4IC0gbWluICsgMSkgKyBtaW4pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogZ2VuZXJhdGVzIGEgcmFuZG9tIFZlY3RvciAyXHJcbiAgICAgKlxyXG4gICAgICogQHN0YXRpY1xyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG1pblhcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBtYXhYXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbWluWVxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG1heFlcclxuICAgICAqIEByZXR1cm5zIHtWZWN0b3IyfVxyXG4gICAgICogQG1lbWJlcm9mIFJhbmRvbU51bWJlckdlbmVyYXRvclxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc3RhdGljIEdldFJhbmRvbVZlY3RvcjIoXHJcbiAgICAgICAgbWluWDogbnVtYmVyLCBtYXhYOiBudW1iZXIsIFxyXG4gICAgICAgIG1pblk6IG51bWJlciwgbWF4WTogbnVtYmVyKTogVmVjdG9yMiB7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBWZWN0b3IyKHRoaXMuR2V0UmFuZG9tTnVtYmVyKG1pblgsIG1heFgpLFxyXG4gICAgICAgICAgICB0aGlzLkdldFJhbmRvbU51bWJlcihtaW5ZLCBtYXhZKSk7XHJcbiAgICB9XHJcbn0iLCJleHBvcnQgY2xhc3MgUmFuZG9tU3RyaW5nR2VuZXJhdG9yIHtcclxuXHJcblxyXG4gICAgcHVibGljIHN0YXRpYyBHZXRSYW5kb21IZXhDb2xvdXIoKTogc3RyaW5nIHtcclxuICAgICAgICByZXR1cm4gJyMnICsgKE1hdGgucmFuZG9tKCkgKiAweEZGRkZGRiA8PCAwKS50b1N0cmluZygxNik7XHJcbiAgICB9XHJcbn0iLCJpbXBvcnQgKiBhcyBqc29uIGZyb20gJy4uLy4uL2Fzc2V0cy9fZGlzdC9Xb3JsZHMvd29ybGRzLmpzb24nO1xyXG5pbXBvcnQgeyBXb3JsZCB9IGZyb20gJy4vd29ybGQnO1xyXG5pbXBvcnQgeyBWZWN0b3IyIH0gZnJvbSAnLi4vLi4vbnVtZXJpY3MvbW9kZWxzL1ZlY3RvcjIubW9kZWwnO1xyXG5cclxuLyoqXHJcbiAqIHRoaXMgaXMgaW4gYSBkaWZmZXJlbnQgZmlsZSBiZWNhdXNlIGFkZGluZyAuanNvbiBmaWxlc1xyXG4gKiBjYXVzZXMgVlNDb2RlIHRvIG9ubHkgd2FudCB0byBsb2FkIC5qcyBpbXBvcnRzLCBhbmQgbm90XHJcbiAqIC50cyBpbXBvcnRzXHJcbiAqXHJcbiAqIEBleHBvcnRcclxuICogQGNsYXNzIFdvcmxkSnNvbkZpbGVMb2FkZXJcclxuICovXHJcbmV4cG9ydCBjbGFzcyBXb3JsZEpzb25GaWxlTG9hZGVyIHtcclxuICAgIHByaXZhdGUgc3RhdGljIHdvcmxkQ291bnQ6IG51bWJlciA9IDI7XHJcbiAgICBjb25zdHJ1Y3RvcigpIHtcclxuXHJcbiAgICB9XHJcbiAgICBwdWJsaWMgc3RhdGljIEdldFdvcmxkcygpOiBXb3JsZFtdIHtcclxuICAgICAgICBjb25zdCB3b3JsZEFyciA9IG5ldyBBcnJheTxXb3JsZD4oKTtcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMud29ybGRDb3VudDsgaSsrKSB7XHJcblxyXG4gICAgICAgICAgICBjb25zdCB3b3JsZCA9IGpzb25baV07XHJcbiAgICAgICAgICAgIHdvcmxkQXJyLnB1c2gobmV3IFdvcmxkKFxyXG4gICAgICAgICAgICAgICAgbmV3IFZlY3RvcjIoXHJcbiAgICAgICAgICAgICAgICAgICAgd29ybGQudGlsZXMubGVuZ3RoLFxyXG4gICAgICAgICAgICAgICAgICAgIHdvcmxkLnRpbGVzWzBdLmxlbmd0aCksXHJcbiAgICAgICAgICAgICAgICBuZXcgVmVjdG9yMihcclxuICAgICAgICAgICAgICAgICAgICB3b3JsZC5zdGFydC54LFxyXG4gICAgICAgICAgICAgICAgICAgIHdvcmxkLnN0YXJ0LnkpLFxyXG4gICAgICAgICAgICAgICAgd29ybGQudGlsZXMsXHJcbiAgICAgICAgICAgICAgICB3b3JsZC53b3JsZElkXHJcbiAgICAgICAgICAgICkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gd29ybGRBcnI7XHJcbiAgICB9XHJcbn0iLCJpbXBvcnQgeyBWZWN0b3IyIH0gZnJvbSAnLi4vLi4vbnVtZXJpY3MvbW9kZWxzL1ZlY3RvcjIubW9kZWwnO1xyXG5pbXBvcnQgeyBXb3JsZCB9IGZyb20gJy4vd29ybGQnO1xyXG5pbXBvcnQgeyBXb3JsZEpzb25GaWxlTG9hZGVyIH0gZnJvbSAnLi93b3JsZC5qc29uZmlsZXMnO1xyXG5pbXBvcnQgeyBUaWxlU2VydmljZSB9IGZyb20gJy4uL0dyYXBoaWNzL1RpbGVzL3RpbGUuc2VydmljZSc7XHJcbmltcG9ydCB7IEFBQkIgfSBmcm9tICcuLi8uLi9udW1lcmljcy9tb2RlbHMvQUFCQi5tb2RlbCc7XHJcbmltcG9ydCB7IFZlY3RvcjJIZWxwZXJzIH0gZnJvbSAnLi4vLi4vbnVtZXJpY3MvaGVscGVycy92ZWN0b3IyLmhlbHBlcic7XHJcblxyXG5leHBvcnQgY2xhc3MgV29ybGRTZXJ2aWNlIHtcclxuXHJcbiAgICBwcml2YXRlIGN1cnJlbnRXb3JsZElkOiBudW1iZXIgPSAwO1xyXG4gICAgcHJpdmF0ZSB3b3JsZHM6IFdvcmxkW10gPSBuZXcgQXJyYXk8V29ybGQ+KCk7XHJcbiAgICBwcml2YXRlIHRpbGVTZXJ2aWNlOiBUaWxlU2VydmljZTtcclxuICAgIHByaXZhdGUgc2l6ZTogVmVjdG9yMjtcclxuXHJcblxyXG4gICAgY29uc3RydWN0b3IodGlsZVNlcnZpY2U6IFRpbGVTZXJ2aWNlKSB7XHJcbiAgICAgICAgdGhpcy50aWxlU2VydmljZSA9IHRpbGVTZXJ2aWNlO1xyXG4gICAgICAgIFxyXG4gICAgfVxyXG5cclxuICAgIEluaXQoKSB7XHJcbiAgICAgICAgdGhpcy53b3JsZHMgPSBXb3JsZEpzb25GaWxlTG9hZGVyLkdldFdvcmxkcygpO1xyXG4gICAgICAgIGNvbnNvbGUubG9nKGB0aGlzLndvcmxkcyA9ICR7SlNPTi5zdHJpbmdpZnkodGhpcy53b3JsZHMpfSBsZW5ndGggaXMgJHt0aGlzLndvcmxkcy5sZW5ndGh9YCk7XHJcblxyXG4gICAgICAgIGNvbnNvbGUuaW5mbygnc2V0dGluZyBjdXJyZW50IHdvcmxkIHRvIGluZGV4IDAnKTtcclxuICAgICAgICB0aGlzLlNldFdvcmxkKDIpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBTZXRXb3JsZChpbmRleDogbnVtYmVyKSB7XHJcbiAgICAgICAgdGhpcy5EZVJlZ2lzdGVyV29ybGQoKTtcclxuICAgICAgICB0aGlzLnRpbGVTZXJ2aWNlLnNldHVwVGlsZXNGcm9tQXJyYXkodGhpcy5HZXRXb3JsZChpbmRleCkuR2V0VGlsZXMoKSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIEdldFdvcmxkU2l6ZSgpOiBBQUJCIHtcclxuICAgICAgICBjb25zdCB0aWxlU2l6ZSA9IHRoaXMudGlsZVNlcnZpY2UuR2V0VGlsZVNpemUoKTtcclxuICAgICAgICB0aGlzLnNpemUgPSBWZWN0b3IySGVscGVycy5NdWx0aXBseUJ5U2NhbGUodGlsZVNpemUsIDIpO1xyXG4gICAgICAgIGNvbnNvbGUubG9nKGB0aGlzLnNpemU6ICR7dGhpcy5zaXplfWApO1xyXG4gICAgICAgIGNvbnN0IHdvcmxkUG9zaXRpb24gPSBuZXcgVmVjdG9yMigwLCAwKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIG5ldyBBQUJCKFxyXG4gICAgICAgICAgICB3b3JsZFBvc2l0aW9uLFxyXG4gICAgICAgICAgICB0aGlzLnNpemVcclxuICAgICAgICApO1xyXG4gICAgfVxyXG5cclxuXHJcbiAgICBEZVJlZ2lzdGVyV29ybGQoKSB7XHJcbiAgICAgICAgY29uc29sZS5lcnJvcihcIiBEZVJlZ2lzdGVyV29ybGQ6IE1ldGhvZCBub3QgaW1wbGVtZW50ZWQuXCIpO1xyXG4gICAgfVxyXG5cclxuXHJcbiAgICBwdWJsaWMgR2V0U3RhcnRpbmdQb3NpdGlvbih3b3JsZEluZGV4OiBudW1iZXIpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy53b3JsZHNbd29ybGRJbmRleF0uR2V0U3RhcnRpbmdQb3NpdGlvbigpO1xyXG4gICAgfVxyXG5cclxuXHJcbiAgICBwdWJsaWMgR2V0V29ybGQoaW5kZXg6IG51bWJlcikge1xyXG4gICAgICAgIGlmIChpbmRleCA+IHRoaXMud29ybGRzLmxlbmd0aCkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGluZGV4IFske2luZGV4fV0gb3V0IG9mIHJhbmdlIG9mIHdvcmxkIGFycmF5IChsZW5ndGg6ICR7dGhpcy53b3JsZHMubGVuZ3RofSlgKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRoaXMud29ybGRzWzBdO1xyXG4gICAgfVxyXG5cclxufVxyXG5cclxuIiwiaW1wb3J0IHsgVmVjdG9yMiB9IGZyb20gXCIuLi8uLi9udW1lcmljcy9tb2RlbHMvVmVjdG9yMi5tb2RlbFwiO1xyXG5leHBvcnQgY2xhc3MgV29ybGQge1xyXG4gICAgLy8gcHJpdmF0ZSBnYW1lOiBHYW1lO1xyXG4gICAgXHJcbiAgICBwcml2YXRlIGlkOiBudW1iZXI7XHJcbiAgICBwcml2YXRlIGFyZWE6IFZlY3RvcjIgPSBuZXcgVmVjdG9yMigyMCwgMjApO1xyXG4gICAgcHJpdmF0ZSBzcGF3bjogVmVjdG9yMjtcclxuICAgIHByaXZhdGUgdGlsZXM6IG51bWJlcltdW107XHJcbiAgICBjb25zdHJ1Y3RvcihhcmVhOiBWZWN0b3IyLCBzcGF3bjogVmVjdG9yMiwgXHJcbiAgICAgICAgdGlsZXM6IG51bWJlcltdW10sIGlkOiBudW1iZXIpIHtcclxuICAgICAgICAgICAgdGhpcy5hcmVhID0gYXJlYTtcclxuICAgICAgICAgICAgdGhpcy5zcGF3biA9IHNwYXduOyBcclxuICAgICAgICAgICAgdGhpcy50aWxlcyA9IHRpbGVzO1xyXG4gICAgICAgICAgICB0aGlzLmlkID0gaWQ7XHJcbiAgICB9XHJcbiAgICBwdWJsaWMgR2V0VGlsZXMgKCk6IG51bWJlcltdW10ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnRpbGVzO1xyXG4gICAgfVxyXG4gICAgcHVibGljIEdldFN0YXJ0aW5nUG9zaXRpb24oKSB7XHJcbiAgICAgICByZXR1cm4gdGhpcy5zcGF3bjsgXHJcbiAgICB9XHJcbiAgICBwdWJsaWMgR2V0SWQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuaWQ7XHJcbiAgICB9XHJcbiAgICBcclxuICAgIFxyXG59ICIsImltcG9ydCB7IElEZWJ1Z1NlcnZpY2UgfSBmcm9tIFwiLi9kZWJ1Zy5zZXJ2aWNlXCI7XHJcbmltcG9ydCB7IERlYnVnS3ZwIH0gZnJvbSBcIi4vZGVidWdnYWJsZS1pdGVtcy5tb2RlbFwiO1xyXG5cclxuZXhwb3J0IGNsYXNzIERlYnVnQ29tcG9uZW50IHtcclxuICAgIHByaXZhdGUgX2RlYnVnU2VydmljZTogSURlYnVnU2VydmljZTtcclxuICAgIHByaXZhdGUgZGVidWdJbmZvRWxlbWVudDogSFRNTEVsZW1lbnQ7XHJcblxyXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBkZWJ1Z1NlcnZpY2U6IElEZWJ1Z1NlcnZpY2UpIHtcclxuICAgICAgICB0aGlzLl9kZWJ1Z1NlcnZpY2UgPSBkZWJ1Z1NlcnZpY2U7XHJcblxyXG5cclxuICAgIH1cclxuXHJcbiAgICBJbml0RGVidWdDb21wb25lbnQobWFpbkRpdklkOiBzdHJpbmcpIHtcclxuICAgICAgICB0aGlzLmNyZWF0ZURlYnVnRGl2KG1haW5EaXZJZCk7XHJcbiAgICAgICAgdGhpcy50aWNrKCk7XHJcbiAgICB9XHJcbiAgICBwcml2YXRlIGNyZWF0ZURlYnVnRGl2KHBhcmVudEVsZW1lbnRJZDogc3RyaW5nLCBpZDogc3RyaW5nID0gJ2VsX2RlYnVnX2luZm8nKTogSFRNTEVsZW1lbnQge1xyXG4gICAgICAgIGlmICh0aGlzLmRlYnVnU2VydmljZS5Jc0luRGVidWdNb2RlKCkpIHtcclxuICAgICAgICAgICAgY29uc3QgbWFpbkRpdiA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHBhcmVudEVsZW1lbnRJZCk7XHJcbiAgICAgICAgICAgIHRoaXMuZGVidWdJbmZvRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xyXG4gICAgICAgICAgICB0aGlzLmRlYnVnSW5mb0VsZW1lbnQuaWQgPSBpZDtcclxuICAgICAgICAgICAgbWFpbkRpdi5hcHBlbmRDaGlsZCh0aGlzLmRlYnVnSW5mb0VsZW1lbnQpO1xyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IDEwOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuZGVidWdTZXJ2aWNlLlB1c2hPclVwZGF0ZUluRGVidWdBcnJheSgnRGVidWcgSW5mbycgKyBpLCAnZGVidWcgdmFsdWUnKVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIHRoaXMuZGVidWdTZXJ2aWNlLlBvcEZyb21EZWJ1Z0FycmF5KCdEZWJ1ZyBJbmZvJylcclxuXHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmRlYnVnSW5mb0VsZW1lbnQ7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHRpY2soKSB7XHJcbiAgICAgICAgLy8gc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgLy8gICAgIHRoaXMudGlja3MrKztcclxuICAgICAgICAvLyB9KTtcclxuICAgICAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xyXG4gICAgICAgICAgICAvLyBjb25zb2xlLmxvZygndXBkYXRpbmcgZGVidWdnZXInKVxyXG4gICAgICAgICAgICB0aGlzLlVwZGF0ZSgpO1xyXG4gICAgICAgICAgICB0aGlzLnRpY2soKTtcclxuICAgICAgICB9KVxyXG4gICAgfVxyXG4gICAgVXBkYXRlKCkge1xyXG4gICAgICAgIC8vIGNvbnNvbGUubG9nKHRoaXMuZGVidWdTZXJ2aWNlLkdldERlYnVnSW5mbygpLCBudWxsLCAyKVxyXG4gICAgICAgIGxldCBEZWJ1Z3NBc1N0cmluZyA9ICcnO1xyXG4gICAgICAgIGNvbnN0IGRlYnVnSW5mb0FycmF5ID0gdGhpcy5kZWJ1Z1NlcnZpY2UuR2V0RGVidWdJbmZvKCk7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBkZWJ1Z0luZm9BcnJheS5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAvLyBEZWJ1Z3NBc1N0cmluZyArPSB0aGlzLkdldFRlbXBsYXRlRm9yS3ZwKGRlYnVnSW5mb0FycmF5W2ldKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5kZWJ1Z0luZm9FbGVtZW50LmlubmVySFRNTCA9IERlYnVnc0FzU3RyaW5nO1xyXG4gICAgfVxyXG5cclxuICAgIEdldFRlbXBsYXRlRm9yS3ZwKGl0ZW06IERlYnVnS3ZwKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdub3QgaW1wbGVtZW50ZWQnKVxyXG4gICAgICAgIHJldHVybiBgXHJcbiAgICAgICAgPGRpdiBjbGFzcz1cImRlYnVnX2l0ZW1cIj5cclxuICAgICAgICAgICAgPHByZSBjbGFzcz1cImtleVwiPlxyXG4gICAgICAgICAgICAgICAgJHtpdGVtLktleX1cclxuICAgICAgICAgICAgPC9wcmU+XHJcbiAgICAgICAgICAgIDxwcmUgY2xhc3M9XCJ2YWx1ZVwiPlxyXG4gICAgICAgICAgICAgICAgJHtKU09OLnN0cmluZ2lmeShpdGVtLlZhbHVlKX1cclxuICAgICAgICAgICAgPC9wcmU+XHJcbiAgICAgICAgPC9kaXY+YFxyXG4gICAgfVxyXG59IiwiaW1wb3J0IHsgRGVidWdnYWJsZUl0ZW1zLCBEZWJ1Z0t2cCB9IGZyb20gXCIuL2RlYnVnZ2FibGUtaXRlbXMubW9kZWxcIjtcclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgSURlYnVnU2VydmljZSB7XHJcbiAgICBJc0luRGVidWdNb2RlKCk6IGJvb2xlYW47XHJcbiAgICBQdXNoT3JVcGRhdGVJbkRlYnVnQXJyYXkoa2V5OiBzdHJpbmcsIHZhbHVlOiBhbnkpOiB2b2lkO1xyXG4gICAgUG9wRnJvbURlYnVnQXJyYXkoa2V5OiBzdHJpbmcpOiBib29sZWFuO1xyXG4gICAgR2V0RGVidWdJbmZvKCk6IEFycmF5PERlYnVnS3ZwPjtcclxufVxyXG5cclxuZXhwb3J0IGNsYXNzIERlYnVnU2VydmljZSBpbXBsZW1lbnRzIElEZWJ1Z1NlcnZpY2Uge1xyXG4gICAgcHJpdmF0ZSBpbkRlYnVnTW9kZTogYm9vbGVhbjtcclxuICAgIHByaXZhdGUgRGVidWdJbmZvOiBEZWJ1Z2dhYmxlSXRlbXM7XHJcblxyXG4gICAgY29uc3RydWN0b3IoaW5EZWJ1Z01vZGU6IGJvb2xlYW4gPSBmYWxzZSkge1xyXG4gICAgICAgIGNvbnNvbGUud2Fybihgc3RhcnRpbmcgZGVidWcgc2VydmljZS4gaW5EZWJ1Z01vZGUgWyR7aW5EZWJ1Z01vZGV9XWApO1xyXG4gICAgICAgIHRoaXMuaW5EZWJ1Z01vZGUgPSBpbkRlYnVnTW9kZTtcclxuICAgICAgICB0aGlzLkRlYnVnSW5mbyA9IG5ldyBEZWJ1Z2dhYmxlSXRlbXMoKTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgSXNJbkRlYnVnTW9kZSgpOiBib29sZWFuIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5pbkRlYnVnTW9kZTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgR2V0RGVidWdJbmZvKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLkRlYnVnSW5mby5kZWJ1Z0l0ZW1zO1xyXG4gICAgfVxyXG4gICAgcHVibGljIFB1c2hPclVwZGF0ZUluRGVidWdBcnJheShrZXk6IHN0cmluZywgdmFsdWU6IGFueSk6IHZvaWQge1xyXG4gICAgICAgIGNvbnNvbGUubG9nKGBhZGRpbmcgaXRlbSAke2tleX0gdG8gZGVidWcgYXJyYXlgKTtcclxuICAgICAgICBpZiAoIXRoaXMuY2hlY2tGb3JFeGlzdGluZyhrZXkpKSB7XHJcbiAgICAgICAgICAgIHRoaXMuRGVidWdJbmZvLmRlYnVnSXRlbXMucHVzaChuZXcgRGVidWdLdnAoa2V5LCB2YWx1ZSkpO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuUG9wRnJvbURlYnVnQXJyYXkoa2V5KSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5QdXNoT3JVcGRhdGVJbkRlYnVnQXJyYXkoa2V5LCB2YWx1ZSk7XHJcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oYHN1Y2Nlc3NmdWxseSB1cGRhdGVkIFske2tleX1dIGluIGRlYnVnIEtWUGApO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoYGF0dGVtcHRlZCB0byBwdXNoIG9yIHVwZGF0ZSBbJHtrZXl9XSwgYnV0IHRoZSBpdGVtIGRpZG4ndCBleGlzdCBpbiB0aGUgS1ZQYClcclxuICAgIH1cclxuICAgIHB1YmxpYyBQb3BGcm9tRGVidWdBcnJheShrZXk6IHN0cmluZyk6IGJvb2xlYW4ge1xyXG4gICAgICAgIGNvbnNvbGUubG9nKGByZW1vdmluZyBpdGVtICR7a2V5fSB0byBkZWJ1ZyBhcnJheWApO1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5EZWJ1Z0luZm8uZGVidWdJdGVtcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5EZWJ1Z0luZm8uZGVidWdJdGVtc1tpXS5LZXkgPT09IGtleSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5EZWJ1Z0luZm8uZGVidWdJdGVtcy5zcGxpY2UoaSwgMSk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc29sZS5lcnJvcihgYXR0ZW1wdGVkIHRvIHJlbW92ZSBbJHtrZXl9IGZyb20gZGVidWcgS1ZQLCBidXQgaXQgY291bGRuJ3QgYmUgZm91bmRdYCk7XHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgY2hlY2tGb3JFeGlzdGluZyhrZXk6IHN0cmluZyk6IGJvb2xlYW4ge1xyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuXHJcblxyXG59IiwiZXhwb3J0IGNsYXNzIERlYnVnZ2FibGVJdGVtcyB7XHJcbiAgICBkZWJ1Z0l0ZW1zOiBBcnJheTxEZWJ1Z0t2cD47XHJcbiAgICBjb25zdHJ1Y3RvcigpIHtcclxuICAgICAgICB0aGlzLmRlYnVnSXRlbXMgPSBuZXcgQXJyYXk8RGVidWdLdnA+KCk7XHJcbiAgICB9XHJcbn1cclxuZXhwb3J0IGNsYXNzIERlYnVnS3ZwIHtcclxuICAgIEtleTogc3RyaW5nO1xyXG4gICAgVmFsdWU6IGFueTtcclxuICAgIGNvbnN0cnVjdG9yKGtleTogc3RyaW5nLCB2YWx1ZTogYW55KSB7XHJcbiAgICAgICAgdGhpcy5LZXkgPSBrZXk7XHJcbiAgICAgICAgdGhpcy5WYWx1ZSA9IHZhbHVlO1xyXG4gICAgfVxyXG59IiwiaW1wb3J0IHsgSW5wdXRNYW5hZ2VyIH0gZnJvbSBcIi4vSW5wdXQvSW5wdXRNYW5hZ2VyXCI7XHJcbmltcG9ydCB7IElEZWJ1Z1NlcnZpY2UsIERlYnVnU2VydmljZSB9IGZyb20gJy4vX2RlYnVnL2RlYnVnLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBEZWJ1Z0NvbXBvbmVudCB9IGZyb20gXCIuL19kZWJ1Zy9kZWJ1Zy5jb21wb25lbnRcIjtcclxuaW1wb3J0IHsgRW50aXR5IH0gZnJvbSBcIi4vRW50aXRpZXMvX2Jhc2UtZW50aXR5XCI7XHJcbmltcG9ydCB7IENyZWF0dXJlIH0gZnJvbSBcIi4vRW50aXRpZXMvQ3JlYXR1cmVzL2NyZWF0dXJlXCI7XHJcbmltcG9ydCB7IFZlY3RvcjIgfSBmcm9tIFwiLi4vbnVtZXJpY3MvbW9kZWxzL1ZlY3RvcjIubW9kZWxcIjtcclxuaW1wb3J0IHsgQmFzZVN0YXRlIH0gZnJvbSBcIi4vU3RhdGVzL19CYXNlU3RhdGVcIjtcclxuaW1wb3J0IHsgR2FtZVN0YXRlIH0gZnJvbSBcIi4vU3RhdGVzL0dhbWVTdGF0ZVwiO1xyXG5pbXBvcnQgeyBTdGF0ZVNlcnZpY2UgfSBmcm9tIFwiLi9TdGF0ZXMvc3RhdGUuc2VydmljZVwiO1xyXG5pbXBvcnQgeyBNZW51U3RhdGUgfSBmcm9tIFwiLi9TdGF0ZXMvTWVudVN0YXRlXCI7XHJcbmltcG9ydCB7IFNldHRpbmdzU3RhdGUgfSBmcm9tIFwiLi9TdGF0ZXMvU2V0dGluZ3NTdGF0ZVwiO1xyXG5pbXBvcnQgeyBQbGF5ZXIgfSBmcm9tIFwiLi9FbnRpdGllcy9DcmVhdHVyZXMvcGxheWVyXCI7XHJcbmltcG9ydCB7IEdyYXBoaWNzU2VydmljZSB9IGZyb20gXCIuL0dyYXBoaWNzL2dyYXBoaWNzLnNlcnZpY2VcIjtcclxuaW1wb3J0IHsgQmFkZHkgfSBmcm9tIFwiLi9FbnRpdGllcy9DcmVhdHVyZXMvYmFkZHlcIjtcclxuaW1wb3J0IHsgUmFuZG9tU3RyaW5nR2VuZXJhdG9yIH0gZnJvbSBcIi4vVG9vbHMvcmFuZG9tX2dlbmVyYXRvcnMvcmFuZG9tX3N0cmluZy5nZW5lcmF0b3JcIjtcclxuaW1wb3J0IHsgUmFuZG9tTnVtYmVyR2VuZXJhdG9yIH0gZnJvbSBcIi4vVG9vbHMvcmFuZG9tX2dlbmVyYXRvcnMvcmFuZG9tX251bWJlci5nZW5lcmF0b3JzXCI7XHJcbmltcG9ydCB7IFdvcmxkU2VydmljZSB9IGZyb20gXCIuL1dvcmxkL3dvcmxkLnNlcnZpY2VcIjtcclxuaW1wb3J0IHsgR2FtZUNhbWVyYVNlcnZpY2UgfSBmcm9tIFwiLi9HcmFwaGljcy9DYW1lcmEvZ2FtZS1jYW1lcmEuc2VydmljZVwiO1xyXG5pbXBvcnQgeyBWaWV3cG9ydFNlcnZpY2UgfSBmcm9tIFwiLi9HcmFwaGljcy9WaWV3cG9ydC92aWV3cG9ydC5zZXJ2aWNlXCI7XHJcbmltcG9ydCB7IFBsYXllclNlcnZpY2UgfSBmcm9tIFwiLi9FbnRpdGllcy9wbGF5ZXIuc2VydmljZVwiO1xyXG5pbXBvcnQgeyBFbnRpdHlTZXJ2aWNlIH0gZnJvbSBcIi4vRW50aXRpZXMvZW50aXR5LnNlcnZpY2VcIjtcclxuaW1wb3J0IHsgRHJhd2luZ1NlcnZpY2UgfSBmcm9tIFwiLi9HcmFwaGljcy9EcmF3L2RyYXdpbmcuc2VydmljZVwiO1xyXG5pbXBvcnQgeyBUaW1lclNlcnZpY2UgfSBmcm9tIFwiLi9Db3JlL3RpbWVyLnNlcnZpY2VcIjtcclxuXHJcbmV4cG9ydCBjbGFzcyBHYW1lIHtcclxuICAgIHByaXZhdGUgdmlld3BvcnRTZXJ2aWNlOiBWaWV3cG9ydFNlcnZpY2U7XHJcbiAgICBwcml2YXRlIGdyYXBoaWNzU2VydmljZTogR3JhcGhpY3NTZXJ2aWNlO1xyXG4gICAgcHJpdmF0ZSBwbGF5ZXJTZXJ2aWNlOiBQbGF5ZXJTZXJ2aWNlO1xyXG4gICAgcHJpdmF0ZSBpbnB1dE1hbmFnZXI6IElucHV0TWFuYWdlcjtcclxuICAgIHByaXZhdGUgZGVidWdTZXJ2aWNlOiBJRGVidWdTZXJ2aWNlO1xyXG4gICAgcHJpdmF0ZSBzdGF0ZVNlcnZpY2U6IFN0YXRlU2VydmljZTtcclxuICAgIHByaXZhdGUgd29ybGRTZXJ2aWNlOiBXb3JsZFNlcnZpY2U7XHJcbiAgICBwcml2YXRlIGRlYnVnQ29tcG9uZW50OiBEZWJ1Z0NvbXBvbmVudDtcclxuICAgIHByaXZhdGUgdGltZXJTZXJ2aWNlOiBUaW1lclNlcnZpY2U7XHJcbiAgICBwcml2YXRlIGVudGl0eVNlcnZpY2U6IEVudGl0eVNlcnZpY2U7XHJcbiAgICBwcml2YXRlIHJ1bm5pbmc6IGJvb2xlYW4gPSBmYWxzZTtcclxuICAgIHByaXZhdGUgcmVhZG9ubHkgbGF1bmNoTWVzc2FnZTogc3RyaW5nID0gJ1N0YXJ0JztcclxuXHJcbiAgICBwcml2YXRlIGdhbWVTdGF0ZTogR2FtZVN0YXRlO1xyXG4gICAgcHJpdmF0ZSBtZW51U3RhdGU6IE1lbnVTdGF0ZTtcclxuICAgIHByaXZhdGUgc2V0dGluZ3NTdGF0ZTogU2V0dGluZ3NTdGF0ZTtcclxuXHJcbiAgICBnYW1lRW50aXRpZXM6IEVudGl0eVtdO1xyXG4gICAgcHJpdmF0ZSBwZXJmb3JtYW5jZUluZm9EaXY6IEhUTUxFbGVtZW50O1xyXG5cclxuXHJcbiAgICBjb25zdHJ1Y3RvcigpIHtcclxuICAgICAgICB0aGlzLnBlcmZvcm1hbmNlSW5mb0RpdiA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdwZXJmb3JtYW5jZV9kaXYnKTtcclxuICAgICAgICB0aGlzLnBlcmZvcm1hbmNlSW5mb0Rpdi5pbm5lckhUTUwgPSBgd2FpdGluZyBmb3IgcGVyZiBkYXRhYDtcclxuXHJcbiAgICAgICAgdGhpcy52aWV3cG9ydFNlcnZpY2UgPSBuZXcgVmlld3BvcnRTZXJ2aWNlKCk7XHJcbiAgICAgICAgY29uc3QgbG9hZGVkSW5EZWJ1Z01vZGUgPSB0aGlzLmNoZWNrRGVidWdNb2RlRnJvbVF1ZXJ5U3RyaW5nKCk7XHJcbiAgICAgICAgdGhpcy5ncmFwaGljc1NlcnZpY2UgPSBuZXcgR3JhcGhpY3NTZXJ2aWNlKCk7XHJcbiAgICAgICAgdGhpcy5zdGF0ZVNlcnZpY2UgPSBuZXcgU3RhdGVTZXJ2aWNlKCk7XHJcbiAgICAgICAgdGhpcy5kZWJ1Z1NlcnZpY2UgPSBuZXcgRGVidWdTZXJ2aWNlKGxvYWRlZEluRGVidWdNb2RlKTtcclxuICAgICAgICB0aGlzLmRlYnVnQ29tcG9uZW50ID0gbmV3IERlYnVnQ29tcG9uZW50KHRoaXMuZGVidWdTZXJ2aWNlKTtcclxuICAgICAgICB0aGlzLmlucHV0TWFuYWdlciA9IG5ldyBJbnB1dE1hbmFnZXIoKTtcclxuICAgICAgICB0aGlzLnRpbWVyU2VydmljZSA9IG5ldyBUaW1lclNlcnZpY2UoNjApO1xyXG4gICAgICAgIHRoaXMud29ybGRTZXJ2aWNlID0gbmV3IFdvcmxkU2VydmljZSh0aGlzLmdyYXBoaWNzU2VydmljZS5HZXRUaWxlU2VydmljZSgpKTtcclxuICAgICAgICB0aGlzLmVudGl0eVNlcnZpY2UgPSBuZXcgRW50aXR5U2VydmljZSgpO1xyXG4gICAgICAgIHRoaXMucGxheWVyU2VydmljZSA9IG5ldyBQbGF5ZXJTZXJ2aWNlKCk7XHJcbiAgICB9XHJcblxyXG4gICAgUnVuKCkge1xyXG4gICAgICAgIGNvbnNvbGUubG9nKCdSdW4gY2FsbGVkIGluIGdhbWUudHMnKTtcclxuICAgICAgICB0aGlzLkluaXQoKTtcclxuICAgICAgICB0aGlzLnJ1bm5pbmcgPSB0cnVlO1xyXG4gICAgICAgIHRoaXMuTG9vcCgpO1xyXG4gICAgfVxyXG5cclxuICAgIEluaXQoKTogc3RyaW5nIHtcclxuICAgICAgICBjb25zb2xlLmxvZyh0aGlzLmxhdW5jaE1lc3NhZ2UgKyAnIHdpbGwgbm93IGJlIHBvc3RlZCB0byB0aGUgZG9jdW1lbnQgJyk7XHJcbiAgICAgICAgdGhpcy5TZXR1cFN0YXRlcygpO1xyXG4gICAgICAgIHRoaXMuaW5wdXRNYW5hZ2VyLkluaXRJbnB1dE1hbmFnZXIoKTtcclxuICAgICAgICB0aGlzLmdyYXBoaWNzU2VydmljZS5Jbml0R3JhcGhpY3NTZXJ2aWNlKCk7XHJcbiAgICAgICAgdGhpcy53b3JsZFNlcnZpY2UuSW5pdCgpO1xyXG4gICAgICAgIHRoaXMuZ3JhcGhpY3NTZXJ2aWNlLmdldEdhbWVDYW1lcmFTZXJ2aWNlKCkuU2V0TGV2ZWxBQUJCKHRoaXMud29ybGRTZXJ2aWNlLkdldFdvcmxkU2l6ZSgpKTtcclxuXHJcbiAgICAgICAgdGhpcy5yZWdpc3RlckVudGl0aWVzKCk7XHJcbiAgICAgICAgLy8gdGhpcy5jYW52YXNNYW5hZ2VyLkluaXRDYW52YXNNYW5hZ2VyKCdtYWluX2RpdicsIHRoaXMuZ2FtZUVudGl0aWVzKTtcclxuICAgICAgICBpZiAodGhpcy5kZWJ1Z1NlcnZpY2UuSXNJbkRlYnVnTW9kZSgpKSB7XHJcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKCdzZXR0aW5nIHVwIHdpdGggZGVidWcgaW5mbycpO1xyXG4gICAgICAgICAgICB0aGlzLmRlYnVnQ29tcG9uZW50LkluaXREZWJ1Z0NvbXBvbmVudCgnbWFpbl9kaXYnKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRoaXMubGF1bmNoTWVzc2FnZTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIFNldHVwU3RhdGVzKCkge1xyXG4gICAgICAgIHRoaXMuZ2FtZVN0YXRlID0gbmV3IEdhbWVTdGF0ZSh0aGlzLmdyYXBoaWNzU2VydmljZSk7XHJcbiAgICAgICAgdGhpcy5tZW51U3RhdGUgPSBuZXcgTWVudVN0YXRlKCk7XHJcbiAgICAgICAgdGhpcy5zZXR0aW5nc1N0YXRlID0gbmV3IFNldHRpbmdzU3RhdGUoKTtcclxuXHJcbiAgICAgICAgdGhpcy5zdGF0ZVNlcnZpY2Uuc2V0U3RhdGUodGhpcy5nYW1lU3RhdGUpO1xyXG4gICAgfVxyXG5cclxuXHJcbiAgICAvKipcclxuICAgICAqIGxvb3BzIGNvbnRpbnVvdXNseSB3aGVuZXZlciB0aGUgYnJvd3NlciBpcyByZWFkeVxyXG4gICAgICogZm9yIGEgbmV3IGZyYW1lXHJcbiAgICAgKlxyXG4gICAgICogQG1lbWJlcm9mIEdhbWVcclxuICAgICAqL1xyXG4gICAgTG9vcCgpIHtcclxuICAgICAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5ydW5uaW5nKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy50aW1lclNlcnZpY2UuQ2hlY2tTaG91bGRSdW5Mb29wKCkpIHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBsYXN0RGVsdGEgPSB0aGlzLnRpbWVyU2VydmljZS5HZXRMYXN0VXBkYXRlVGltZVRvb2soKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLlVwZGF0ZShsYXN0RGVsdGEpO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuUmVuZGVyKGxhc3REZWx0YSk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy50aW1lclNlcnZpY2UuVXBkYXRlVGlja3NBbmRSZW5kZXJBZnRlckxvb3AoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICB0aGlzLlByaW50RGVidWdJbmZvVG9Db25zb2xlKGZhbHNlLCB0cnVlKTtcclxuICAgICAgICAgICAgICAgIHRoaXMudGltZXJTZXJ2aWNlLlJlc2V0VGltZXJzKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdGhpcy5Mb29wKCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBwcmludHMgZGVidWcgaW5mbyBmcm9tIHZhcmlvdXMgcGxhY2VzIGluIHRoZSBcclxuICAgICAqIGFwcGxpY2F0aW9uXHJcbiAgICAgKlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqIEBtZW1iZXJvZiBHYW1lXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgUHJpbnREZWJ1Z0luZm9Ub0NvbnNvbGUocHJpbnRUb0NvbnNvbGU6IGJvb2xlYW4gPSBmYWxzZSwgcHJpbnRUb0h0bWw6IGJvb2xlYW4gPSBmYWxzZSkge1xyXG4gICAgICAgIGlmICh0aGlzLnRpbWVyU2VydmljZS5TaG91bGRQcmludERlYnVnRGF0YSgpKSB7XHJcbiAgICAgICAgICAgIC8vIGNvbnNvbGUuY2xlYXIoKTtcclxuICAgICAgICAgICAgbGV0IGRlYnVnSW5mb3JtYXRpb246IHN0cmluZ1tdID0gbmV3IEFycmF5PHN0cmluZz4oKTtcclxuICAgICAgICAgICAgZGVidWdJbmZvcm1hdGlvbi5wdXNoKCdGUFMgU2VydjogJyArIHRoaXMudGltZXJTZXJ2aWNlLlByaW50Q3VycmVudEZwc1RvQ29uc29sZSgpKTtcclxuICAgICAgICAgICAgZGVidWdJbmZvcm1hdGlvbi5wdXNoKCdDYW0gU2VydjogJyArIHRoaXMuZ3JhcGhpY3NTZXJ2aWNlLmdldEdhbWVDYW1lcmFTZXJ2aWNlKCkuR2V0RGVidWdJbmZvKCkpO1xyXG4gICAgICAgICAgICBpZiAocHJpbnRUb0NvbnNvbGUpIHtcclxuICAgICAgICAgICAgICAgIGZvciAobGV0IGxpbmUgb2YgZGVidWdJbmZvcm1hdGlvbikge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChsaW5lLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coJyVjICcgKyBsaW5lICsgJyAnLCAnYmFja2dyb3VuZDogIzAwMDsgY29sb3I6d2hpdGU7ICcpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAocHJpbnRUb0h0bWwpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMucGVyZm9ybWFuY2VJbmZvRGl2LmlubmVySFRNTCA9IGA8cHJlPiR7ZGVidWdJbmZvcm1hdGlvbi5qb2luKCdcXG4nKX08L3ByZT5gO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvLyBkZWJ1Z0luZm9ybWF0aW9uID0gQXJyYXk8c3RyaW5nPigwKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgVXBkYXRlKGxhc3REZWx0YTogbnVtYmVyKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuc3RhdGVTZXJ2aWNlLkdldFN0YXRlKCkgIT09IG51bGwpIHtcclxuICAgICAgICAgICAgdGhpcy5pbnB1dE1hbmFnZXIuTmV3SW5wdXRMb29wQ2hlY2soKTtcclxuXHJcbiAgICAgICAgICAgIHRoaXMuc3RhdGVTZXJ2aWNlLkdldFN0YXRlKCkuVGljaygpO1xyXG5cclxuICAgICAgICAgICAgdGhpcy5lbnRpdHlTZXJ2aWNlLlRpY2tBbGxFbnRpdGllcyhsYXN0RGVsdGEpO1xyXG4gICAgICAgICAgICAvLyAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmdhbWVFbnRpdGllcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAvLyAgICAgIHRoaXMuZ2FtZUVudGl0aWVzW2ldLlRpY2soKTtcclxuICAgICAgICAgICAgLy8gIH1cclxuXHJcblxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBSZW5kZXIobGFzdERlbHRhOiBudW1iZXIpIHtcclxuICAgICAgICBpZiAodGhpcy5zdGF0ZVNlcnZpY2UuR2V0U3RhdGUoKSAhPT0gbnVsbCkge1xyXG4gICAgICAgICAgICB0aGlzLmdyYXBoaWNzU2VydmljZS5HZXRUaWxlU2VydmljZSgpLlJlZG5lcigpO1xyXG5cclxuICAgICAgICAgICAgdGhpcy5lbnRpdHlTZXJ2aWNlLlJlbmRlckFsbEVudGl0aWVzKHRoaXMuZ3JhcGhpY3NTZXJ2aWNlKTtcclxuICAgICAgICAgICAgdGhpcy5zdGF0ZVNlcnZpY2UuR2V0U3RhdGUoKS5SZW5kZXIoKTtcclxuICAgICAgICAgICAgdGhpcy5ncmFwaGljc1NlcnZpY2UuUmVuZGVyKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGNoZWNrRGVidWdNb2RlRnJvbVF1ZXJ5U3RyaW5nKCk6IGJvb2xlYW4ge1xyXG4gICAgICAgIGNvbnN0IHVybFBhcmFtcyA9IG5ldyBVUkxTZWFyY2hQYXJhbXMod2luZG93LmxvY2F0aW9uLnNlYXJjaCk7XHJcbiAgICAgICAgY29uc3QgZGVidWdNb2RlUGFyYW0gPSB1cmxQYXJhbXMuZ2V0KCdpbkRlYnVnTW9kZScpO1xyXG5cclxuICAgICAgICByZXR1cm4gSlNPTi5wYXJzZShkZWJ1Z01vZGVQYXJhbSk7XHJcbiAgICB9XHJcblxyXG4gICAgcmVnaXN0ZXJFbnRpdGllcyhiYWRkeUNvdW50OiBudW1iZXIgPSA3NSk6IHZvaWQge1xyXG5cclxuXHJcblxyXG5cclxuICAgICAgICBjb25zdCBzaGlwcyA9IFtcclxuICAgICAgICAgICAgJ21ldGFsaWNfMDEucG5nJyxcclxuICAgICAgICAgICAgJ21ldGFsaWNfMDIucG5nJyxcclxuICAgICAgICAgICAgJ21ldGFsaWNfMDMucG5nJyxcclxuICAgICAgICAgICAgJ21ldGFsaWNfMDQucG5nJyxcclxuICAgICAgICAgICAgJ21ldGFsaWNfMDUucG5nJyxcclxuICAgICAgICAgICAgJ21ldGFsaWNfMDYucG5nJyxcclxuICAgICAgICAgICAgJ29yYW5nZV8wMS5wbmcnLFxyXG4gICAgICAgICAgICAnb3JhbmdlXzAyLnBuZycsXHJcbiAgICAgICAgICAgICdvcmFuZ2VfMDMucG5nJyxcclxuICAgICAgICAgICAgJ29yYW5nZV8wNC5wbmcnLFxyXG4gICAgICAgICAgICAnb3JhbmdlXzA1LnBuZycsXHJcbiAgICAgICAgICAgICdvcmFuZ2VfMDYucG5nJ1xyXG4gICAgICAgIF07XHJcbiAgICAgICAgY29uc3QgZW50aXR5U2l6ZTogVmVjdG9yMiA9IG5ldyBWZWN0b3IyKDMwLCAzMCk7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBiYWRkeUNvdW50OyBpKyspIHtcclxuICAgICAgICAgICAgY29uc3QgaW1hZ2VMb2MgPSBSYW5kb21OdW1iZXJHZW5lcmF0b3IuR2V0UmFuZG9tTnVtYmVyKDAsIDYpO1xyXG4gICAgICAgICAgICBjb25zb2xlLmxvZygnaW1hZ2UgbG9jIHdpbGwgYmUgJyArIGltYWdlTG9jKTtcclxuICAgICAgICAgICAgY29uc3QgZW50aXR5ID0gbmV3IEJhZGR5KFxyXG4gICAgICAgICAgICAgICAgLy8gbmV3IFZlY3RvcjIoNTAwLCAzMDApLFxyXG4gICAgICAgICAgICAgICAgUmFuZG9tTnVtYmVyR2VuZXJhdG9yLkdldFJhbmRvbVZlY3RvcjIoXHJcbiAgICAgICAgICAgICAgICAgICAgMCwgdGhpcy52aWV3cG9ydFNlcnZpY2UuR2V0QnJvd3NlcldpZHRoKCksXHJcbiAgICAgICAgICAgICAgICAgICAgMCwgdGhpcy52aWV3cG9ydFNlcnZpY2UuR2V0QnJvd3NlckhlaWdodCgpKSxcclxuICAgICAgICAgICAgICAgIGVudGl0eVNpemUsXHJcbiAgICAgICAgICAgICAgICAnYmFkZHknICsgaS50b1N0cmluZygpLFxyXG4gICAgICAgICAgICAgICAgJy9TaGlwcy8nICsgc2hpcHNbaW1hZ2VMb2NdLFxyXG4gICAgICAgICAgICAgICAgdGhpcy5ncmFwaGljc1NlcnZpY2UsXHJcbiAgICAgICAgICAgICAgICBSYW5kb21TdHJpbmdHZW5lcmF0b3IuR2V0UmFuZG9tSGV4Q29sb3VyKCksXHJcbiAgICAgICAgICAgICAgICB0aGlzLnBsYXllclNlcnZpY2VcclxuICAgICAgICAgICAgKTtcclxuXHJcbiAgICAgICAgICAgIHRoaXMuZW50aXR5U2VydmljZS5SZWdpc3RlckVudGl0eShlbnRpdHkpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5wbGF5ZXJTZXJ2aWNlLlNldFBsYXllcihuZXcgUGxheWVyKFxyXG4gICAgICAgICAgICBuZXcgVmVjdG9yMihcclxuICAgICAgICAgICAgICAgIHRoaXMudmlld3BvcnRTZXJ2aWNlLkdldEJyb3dzZXJXaWR0aCgpIC8gMixcclxuICAgICAgICAgICAgICAgIHRoaXMudmlld3BvcnRTZXJ2aWNlLkdldEJyb3dzZXJIZWlnaHQoKSAvIDIpLFxyXG4gICAgICAgICAgICAvLyBuZXcgVmVjdG9yMigwLCAwKSxcclxuICAgICAgICAgICAgbmV3IFZlY3RvcjIoNTAsIDUwKSxcclxuICAgICAgICAgICAgJ3BsYXllcicsXHJcbiAgICAgICAgICAgICdTaGlwcy9sYXJnZV9wdXJwbGVfMDEucG5nJyxcclxuICAgICAgICAgICAgdGhpcy5pbnB1dE1hbmFnZXIsXHJcbiAgICAgICAgICAgIHRoaXMuZ3JhcGhpY3NTZXJ2aWNlKSk7XHJcblxyXG5cclxuICAgICAgICB0aGlzLmVudGl0eVNlcnZpY2UuUmVnaXN0ZXJFbnRpdHkodGhpcy5wbGF5ZXJTZXJ2aWNlLkdldFBsYXllcigpKTtcclxuXHJcbiAgICAgICAgLy8gcmV0dXJuIGVudGl0aWVzO1xyXG4gICAgfVxyXG59IiwiaW1wb3J0IHsgR2FtZSB9IGZyb20gJy4vYXBwbGljYXRpb24vZ2FtZSc7XHJcblxyXG5leHBvcnQgY2xhc3MgQXBwIHtcclxuICAgIHN0YXJ0KCkge1xyXG4gICAgICAgIGNvbnN0IGdhbWUgPSBuZXcgR2FtZSgpOyAgICAgXHJcbiAgICAgICAgZ2FtZS5SdW4oKTtcclxuICAgIH1cclxufVxyXG5cclxuY29uc3QgYXBwbGljYXRpb24gPSBuZXcgQXBwKCk7XHJcbmFwcGxpY2F0aW9uLnN0YXJ0KCk7IiwiZXhwb3J0IGNsYXNzIERlZ3JlZXNIZWxwZXIge1xyXG5cclxufVxyXG5cclxuXHJcbi8qKlxyXG4gKiBjb252ZXJ0cyBkZWdyZWVzIGludG8gcmFkaWFuc1xyXG4gKlxyXG4gKiBAZXhwb3J0XHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBkZWdyZWVzXHJcbiAqIEByZXR1cm5zXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gUmFkaWFucyhkZWdyZWVzOiBudW1iZXIpIHtcclxuICAgIHJldHVybiBkZWdyZWVzICogTWF0aC5QSSAvIDE4MDtcclxufVxyXG5cclxuXHJcbi8qKlxyXG4gKiBjb252ZXJ0cyByYWRpYW5zIGludG8gZGVncmVlc1xyXG4gKlxyXG4gKiBAZXhwb3J0XHJcbiAqIEBwYXJhbSB7bnVtYmVyfSByYWRpYW5zXHJcbiAqIEByZXR1cm5zXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gRGVncmVlcyhyYWRpYW5zOiBudW1iZXIpIHtcclxuICAgIHJldHVybiByYWRpYW5zICogMTgwIC8gTWF0aC5QSTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIEZhcnRoZXJSaWdodChmcm9tRGVncmVlczogbnVtYmVyLCB0b0RlZ3JlZXM6IG51bWJlcikge1xyXG5cclxuICAgIHJldHVybiB0cnVlO1xyXG59IiwiaW1wb3J0IHsgQUFCQiB9IGZyb20gXCIuLi9tb2RlbHMvQUFCQi5tb2RlbFwiO1xyXG5cclxuZXhwb3J0IGNsYXNzIEludGVyc2VjdGlvbkhlbHBlciB7XHJcbiAgICAvLyBjaGVja3MgaWYgdHdvIEFBQkJzIGludGVyc2VjdCAocmVjdGFuZ2xlIG9ubHkpXHJcbiAgICBwdWJsaWMgc3RhdGljIEFhYmJWc0FhYmIobGVmdDogQUFCQiwgcmlnaHQ6IEFBQkIpIHtcclxuICAgICAgICBpZiAoKGxlZnQubWF4LmdldFZhbHVlWCgpIDwgcmlnaHQubWluLmdldFZhbHVlWCgpKSB8fCAobGVmdC5taW4uZ2V0VmFsdWVYKCkgPiByaWdodC5tYXguZ2V0VmFsdWVYKCkpKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKChsZWZ0Lm1heC5nZXRWYWx1ZVkoKSA8IHJpZ2h0Lm1pbi5nZXRWYWx1ZVkoKSkgfHwgKGxlZnQubWluLmdldFZhbHVlWSgpID4gcmlnaHQubWF4LmdldFZhbHVlWSgpKSkge1xyXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIH1cclxufSIsImV4cG9ydCBmdW5jdGlvbiBCZXR3ZWVuKHg6IG51bWJlciwgbWluOiBudW1iZXIsIG1heDogbnVtYmVyKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4geCA+PSBtaW4gJiYgeCA8PSBtYXg7XHJcbn1cclxuXHJcblxyXG5leHBvcnQgZnVuY3Rpb24gTGVycChzdGFydDogbnVtYmVyLCBlbmQ6IG51bWJlciwgYW10OiBudW1iZXIpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuICgxLWFtdCkgKiBzdGFydCArIGFtdCAqIGVuZDtcclxufSIsImltcG9ydCB7IFZlY3RvcjIgfSBmcm9tIFwiLi4vbW9kZWxzL1ZlY3RvcjIubW9kZWxcIjtcclxuXHJcbmV4cG9ydCBjbGFzcyBWZWN0b3IySGVscGVycyB7XHJcbiAgICAvKlxyXG4gICogYWRkcyB0d28gVmVjdG9yMiB0b2dldGhlciBhbmQgcmV0dXJucyBhIG5ldyBWZWN0b3IyXHJcbiAgKiBjb250YWluaW5nIHRoZSByZXN1bHRzXHJcbiAgKi9cclxuICAgIHB1YmxpYyBzdGF0aWMgQWRkKGxlZnQ6IFZlY3RvcjIsIHJpZ2h0OiBWZWN0b3IyKTogVmVjdG9yMiB7XHJcbiAgICAgICAgY29uc3QgdmVjWCA9IGxlZnQuZ2V0VmFsdWVYKCkgKyByaWdodC5nZXRWYWx1ZVgoKTtcclxuICAgICAgICBjb25zdCB2ZWNZID0gbGVmdC5nZXRWYWx1ZVkoKSArIHJpZ2h0LmdldFZhbHVlWSgpO1xyXG5cclxuICAgICAgICByZXR1cm4gbmV3IFZlY3RvcjIodmVjWCwgdmVjWSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBjb21wYXJlcyB0d28gVmVjdG9yIDJzIGZvciBlcXVhbGl0eVxyXG4gICAgICogSWYgdGhlIHZlY3RvcnMgYXJlIGlkZW50aWNhLCB0aGlzIHJldHVybnMgdHJ1ZSBvdGhlcndpc2UgcmV0dXJucyBmYWxzZVxyXG4gICAgICpcclxuICAgICAqIEBzdGF0aWNcclxuICAgICAqIEBwYXJhbSB7VmVjdG9yMn0gbGVmdFxyXG4gICAgICogQHBhcmFtIHtWZWN0b3IyfSByaWdodFxyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAgICAgKiBAbWVtYmVyb2YgVmVjdG9yMkhlbHBlcnNcclxuICAgICAqL1xyXG4gICAgcHVibGljIHN0YXRpYyBDb21wYXJlRXF1YWxpdHkobGVmdDogVmVjdG9yMiwgcmlnaHQ6IFZlY3RvcjIpOiBib29sZWFuIHtcclxuICAgICAgICByZXR1cm4gIShsZWZ0LmdldFZhbHVlWCgpICE9PSByaWdodC5nZXRWYWx1ZVgoKSB8fCBsZWZ0LmdldFZhbHVlWSgpICE9PSByaWdodC5nZXRWYWx1ZVkoKSk7XHJcbiAgICB9XHJcblxyXG4gICAgLypcclxuICAgICogZGl2aWRlcyB0aGUgZmlyc3QgdmVjdG9yIGJ5IHRoZSBzZWNvbmRcclxuICAgICogdGhpcyBpcyBub3Qgc2NhbGFyIGRpdmlzaW9uXHJcbiAgICAqL1xyXG4gICAgcHVibGljIHN0YXRpYyBEaXZpZGUobGVmdDogVmVjdG9yMiwgcmlnaHQ6IFZlY3RvcjIpOiBWZWN0b3IyIHtcclxuICAgICAgICBjb25zdCB2ZWNYID0gbGVmdC5nZXRWYWx1ZVgoKSAvIHJpZ2h0LmdldFZhbHVlWCgpO1xyXG4gICAgICAgIGNvbnN0IHZlY1kgPSBsZWZ0LmdldFZhbHVlWSgpIC8gcmlnaHQuZ2V0VmFsdWVZKCk7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBWZWN0b3IyKHZlY1gsIHZlY1kpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qXHJcbiAgICAqIGRpdmlkZXMgYSBnaXZlbiBzb3VyY2UgdmVjdG9yMiBieSBhIHNjYWxlIGZhY3RvclxyXG4gICAgKi9cclxuICAgIHB1YmxpYyBzdGF0aWMgRGl2aWRlQnlTY2FsZShzb3VyY2U6IFZlY3RvcjIsIHNjYWxlRmFjdG9yOiBudW1iZXIpOiBWZWN0b3IyIHtcclxuICAgICAgICBjb25zdCBmYWN0b3I6IG51bWJlciA9IDEgLyBzY2FsZUZhY3RvcjtcclxuXHJcbiAgICAgICAgY29uc3QgdmVjWCA9IHNvdXJjZS5nZXRWYWx1ZVgoKSAqIGZhY3RvcjtcclxuICAgICAgICBjb25zdCB2ZWNZID0gc291cmNlLmdldFZhbHVlWSgpICogZmFjdG9yO1xyXG4gICAgICAgIHJldHVybiBuZXcgVmVjdG9yMih2ZWNYLCB2ZWNZKTtcclxuICAgIH1cclxuXHJcbiAgICAvKlxyXG4gICAgKiBnZXRzIHRoZSBkb3QgcHJvZHVjdCBvZiB0d28gdmVjdG9ycyxcclxuICAgICogcmV0dXJucyBhcyBhIG51bWJlciAoZmxvYXQ/KVxyXG4gICAgKi9cclxuICAgIHB1YmxpYyBzdGF0aWMgRG90KGxlZnQ6IFZlY3RvcjIsIHJpZ2h0OiBWZWN0b3IyKTogbnVtYmVyIHtcclxuXHJcbiAgICAgICAgY29uc3QgdmVjWCA9IGxlZnQuZ2V0VmFsdWVYKCkgKiByaWdodC5nZXRWYWx1ZVgoKTtcclxuICAgICAgICBjb25zdCB2ZWNZID0gbGVmdC5nZXRWYWx1ZVkoKSAqIHJpZ2h0LmdldFZhbHVlWSgpO1xyXG5cclxuICAgICAgICByZXR1cm4gdmVjWCArIHZlY1k7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIHN0YXRpYyBTdWJ0cmFjdChsZWZ0OiBWZWN0b3IyLCByaWdodDogVmVjdG9yMik6IFZlY3RvcjIge1xyXG4gICAgICAgIGNvbnN0IHZlY1ggPSBsZWZ0LmdldFZhbHVlWCgpIC0gcmlnaHQuZ2V0VmFsdWVYKCk7XHJcbiAgICAgICAgY29uc3QgdmVjWSA9IGxlZnQuZ2V0VmFsdWVZKCkgLSByaWdodC5nZXRWYWx1ZVkoKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIG5ldyBWZWN0b3IyKHZlY1gsIHZlY1kpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBzdGF0aWMgTmVnYXRpdmVPZihzb3VyY2U6IFZlY3RvcjIpIHtcclxuICAgICAgICBjb25zdCB2ZWNYID0gLXNvdXJjZS5nZXRWYWx1ZVgoKTtcclxuICAgICAgICBjb25zdCB2ZWNZID0gLXNvdXJjZS5nZXRWYWx1ZVkoKTtcclxuICAgICAgICByZXR1cm4gbmV3IFZlY3RvcjIodmVjWCwgdmVjWSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIHN0YXRpYyBNdWx0aXBseShsZWZ0OiBWZWN0b3IyLCByaWdodDogVmVjdG9yMikge1xyXG4gICAgICAgIGNvbnN0IHZlY1ggPSBsZWZ0LmdldFZhbHVlWCgpICogcmlnaHQuZ2V0VmFsdWVYKCk7XHJcbiAgICAgICAgY29uc3QgdmVjWSA9IGxlZnQuZ2V0VmFsdWVZKCkgKiByaWdodC5nZXRWYWx1ZVkoKTtcclxuICAgICAgICByZXR1cm4gbmV3IFZlY3RvcjIodmVjWCwgdmVjWSk7XHJcbiAgICB9XHJcbiAgICBwdWJsaWMgc3RhdGljIE11bHRpcGx5QnlTY2FsZShzb3VyY2U6IFZlY3RvcjIsIHNjYWxlRmFjdG9yOiBudW1iZXIpIHtcclxuICAgICAgICBjb25zdCB2ZWNYID0gc291cmNlLmdldFZhbHVlWCgpICogc2NhbGVGYWN0b3I7XHJcbiAgICAgICAgY29uc3QgdmVjWSA9IHNvdXJjZS5nZXRWYWx1ZVkoKSAqIHNjYWxlRmFjdG9yO1xyXG4gICAgICAgIHJldHVybiBuZXcgVmVjdG9yMih2ZWNYLCB2ZWNZKTtcclxuICAgIH1cclxufSIsImltcG9ydCB7IFZlY3RvcjIgfSBmcm9tIFwiLi9WZWN0b3IyLm1vZGVsXCI7XHJcblxyXG5leHBvcnQgY2xhc3MgQUFCQiB7XHJcbiAgICBtaW46IFZlY3RvcjI7XHJcbiAgICBtYXg6IFZlY3RvcjI7XHJcblxyXG4gICAgY29uc3RydWN0b3IocG9zaXRpb246IFZlY3RvcjIsIHNpemU6IFZlY3RvcjIpIHtcclxuICAgICAgICB0aGlzLm1pbiA9IG5ldyBWZWN0b3IyKFxyXG4gICAgICAgICAgICBwb3NpdGlvbi5nZXRWYWx1ZVgoKSxcclxuICAgICAgICAgICAgcG9zaXRpb24uZ2V0VmFsdWVZKCkpO1xyXG4gICAgICAgIHRoaXMubWF4ID0gbmV3IFZlY3RvcjIoXHJcbiAgICAgICAgICAgIHBvc2l0aW9uLmdldFZhbHVlWCgpICsgc2l6ZS5nZXRWYWx1ZVgoKSxcclxuICAgICAgICAgICAgcG9zaXRpb24uZ2V0VmFsdWVZKCkgKyBzaXplLmdldFZhbHVlWSgpXHJcbiAgICAgICAgKTtcclxuICAgIH1cclxuICAgIHB1YmxpYyBHZXRDZW50ZXIoKTogVmVjdG9yMiB7XHJcbiAgICAgICAgY29uc3QgeCA9ICgodGhpcy5tYXgueCAtIHRoaXMubWluLngpIC8gMikgKyB0aGlzLm1pbi54O1xyXG4gICAgICAgIGNvbnN0IHkgPSAoKHRoaXMubWF4LnkgLSB0aGlzLm1pbi55KSAvIDIpICsgdGhpcy5taW4ueTtcclxuXHJcbiAgICAgICAgcmV0dXJuIG5ldyBWZWN0b3IyKFxyXG4gICAgICAgICAgICB4LCB5XHJcbiAgICAgICAgKTtcclxuICAgIH1cclxuICAgIHB1YmxpYyBHZXRUb3AoKTogbnVtYmVyIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5taW4uZ2V0VmFsdWVZKCk7XHJcbiAgICB9IFxyXG4gICAgcHVibGljIEdldEJvdHRvbSgpOiBudW1iZXIge1xyXG4gICAgICAgIHJldHVybiB0aGlzLm1heC5nZXRWYWx1ZVkoKTtcclxuICAgIH1cclxuICAgIHB1YmxpYyBHZXRMZWZ0KCk6IG51bWJlciB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMubWluLmdldFZhbHVlWCgpO1xyXG4gICAgfVxyXG4gICAgcHVibGljIEdldFJpZ2h0KCk6IG51bWJlciB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMubWF4LmdldFZhbHVlWCgpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBJc0Fib3ZlKHRhcmdldDogQUFCQik6IGJvb2xlYW4ge1xyXG4gICAgICAgIGlmICh0aGlzLkdldEJvdHRvbSgpIDwgdGFyZ2V0LkdldFRvcCgpKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gZmFsc2U7ICAgICAgICBcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgSXNCZWxvdyh0YXJnZXQ6IEFBQkIpOiBib29sZWFuIHtcclxuICAgICAgICBpZiAodGhpcy5HZXRUb3AoKSA+IHRhcmdldC5HZXRCb3R0b20oKSkge1xyXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBJc1JpZ2h0KHRhcmdldDogQUFCQik6IGJvb2xlYW4ge1xyXG4gICAgICAgIGlmICh0aGlzLkdldFJpZ2h0KCkgPCB0YXJnZXQuR2V0TGVmdCgpKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIElzTGVmdCh0YXJnZXQ6IEFBQkIpOiBib29sZWFuIHtcclxuICAgICAgICBpZiAodGhpcy5HZXRMZWZ0KCkgPiB0YXJnZXQuR2V0UmlnaHQoKSkge1xyXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG5cclxufSIsImV4cG9ydCBjbGFzcyBWZWN0b3IyIHtcclxuICAgIHg6IG51bWJlcjtcclxuICAgIHk6IG51bWJlcjtcclxuXHJcbiAgICBjb25zdHJ1Y3Rvcih4OiBudW1iZXIsIHk6IG51bWJlcikge1xyXG4gICAgICAgIHRoaXMueCA9IHg7XHJcbiAgICAgICAgdGhpcy55ID0geTtcclxuICAgIH1cclxuXHJcbiAgICBjb25jYXQoZGVjaW1hbFBsYWNlczogbnVtYmVyID0gLTEpIHtcclxuICAgICAgICBpZiAoZGVjaW1hbFBsYWNlcyA+IC0xKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBgeDpbJHt0aGlzLngudG9GaXhlZChkZWNpbWFsUGxhY2VzKX1dLCB5Olske3RoaXMueS50b0ZpeGVkKGRlY2ltYWxQbGFjZXMpfV1gO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gYHg6WyR7dGhpcy54fV0sIHk6WyR7dGhpcy55fV1gO1xyXG4gICAgfVxyXG5cclxuICAgIGdldFZhbHVlWCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy54O1xyXG4gICAgfVxyXG4gICAgZ2V0VmFsdWVZKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnk7XHJcbiAgICB9XHJcblxyXG4gICAgc2V0VmFsdWVYKHg6IG51bWJlcikge1xyXG4gICAgICAgIHRoaXMueCA9IHg7XHJcbiAgICB9XHJcbiAgICBzZXRWYWx1ZVkoeTogbnVtYmVyKSB7XHJcbiAgICAgICAgdGhpcy55ID0geTtcclxuICAgIH1cclxuICAgIHNldFZhbHVlcyh4OiBudW1iZXIsIHk6IG51bWJlcikge1xyXG4gICAgICAgIHRoaXMueCA9IHg7XHJcbiAgICAgICAgdGhpcy55ID0geTtcclxuICAgIH1cclxuXHJcbn0iXSwic291cmNlUm9vdCI6IiJ9
\ No newline at end of file
diff --git a/dist/css/style.css b/dist/css/style.css
deleted file mode 100644
index d18dd3a..0000000
--- a/dist/css/style.css
+++ /dev/null
@@ -1,102 +0,0 @@
-/* http://meyerweb.com/eric/tools/css/reset/
- v2.0 | 20110126
- License: none (public domain)
-*/
-html, body, div, span, applet, object, iframe,
-h1, h2, h3, h4, h5, h6, p, blockquote, pre,
-a, abbr, acronym, address, big, cite, code,
-del, dfn, em, img, ins, kbd, q, s, samp,
-small, strike, strong, sub, sup, tt, var,
-b, u, i, center,
-dl, dt, dd, ol, ul, li,
-fieldset, form, label, legend,
-table, caption, tbody, tfoot, thead, tr, th, td,
-article, aside, canvas, details, embed,
-figure, figcaption, footer, header, hgroup,
-menu, nav, output, ruby, section, summary,
-time, mark, audio, video {
- margin: 0;
- padding: 0;
- border: 0;
- font-size: 100%;
- font: inherit;
- vertical-align: baseline;
- box-sizing: border-box; }
-
-/* HTML5 display-role reset for older browsers */
-article, aside, details, figcaption, figure,
-footer, header, hgroup, menu, nav, section {
- display: block; }
-
-body {
- line-height: 1; }
-
-ol, ul {
- list-style: none; }
-
-blockquote, q {
- quotes: none; }
-
-blockquote:before, blockquote:after,
-q:before, q:after {
- content: '';
- content: none; }
-
-table {
- border-collapse: collapse;
- border-spacing: 0; }
-
-#el_canvasable {
- height: 100%;
- width: 100%; }
-
-div.in_debug_mode #el_canvasable {
- height: 100%;
- width: 100%; }
-
-div.in_debug_mode #el_debug_info {
- position: absolute;
- right: 0;
- height: 100%;
- width: 30%;
- color: #c0c0c0;
- background-color: rgba(45, 45, 45, 0.5); }
-
-body {
- background: #ff0000; }
-
-body, html {
- height: 100%;
- width: 100%; }
-
-body {
- background: #2F4F4F; }
-
-#main_div {
- width: 100%;
- height: 100%;
- display: flex;
- align-items: center; }
-
-canvas {
- background: transparent;
- display: block;
- margin: 0 auto;
- box-sizing: border-box; }
- canvas.parent {
- background: black; }
-
-.notice-holder {
- padding: 20px;
- width: auto;
- clear: both;
- background: rgba(0, 0, 0, 0.7);
- color: white;
- position: absolute;
- left: 0;
- top: 0; }
- .notice-holder #details_div, .notice-holder #performance_div {
- position: relative;
- width: auto;
- border: 1px dashed pink;
- padding: 1rem; }
diff --git a/dist/index.html b/dist/index.html
index 147ea9b..8cea3b1 100644
--- a/dist/index.html
+++ b/dist/index.html
@@ -6,6 +6,8 @@
+
+
@@ -16,6 +18,5 @@
-