Kaynağa Gözat

添加highstock

Bhikkhu-Kosalla 5 yıl önce
ebeveyn
işleme
b550e0be93
100 değiştirilmiş dosya ile 22492 ekleme ve 67 silme
  1. 1 1
      app/article/style.css
  2. 67 66
      app/pcdl/css/basic_style.css
  3. 235 0
      app/public/js/Highstock-8.0.0/code/css/annotations/popup.css
  4. 239 0
      app/public/js/Highstock-8.0.0/code/css/annotations/popup.scss
  5. 926 0
      app/public/js/Highstock-8.0.0/code/css/highcharts.css
  6. 818 0
      app/public/js/Highstock-8.0.0/code/css/highcharts.scss
  7. 265 0
      app/public/js/Highstock-8.0.0/code/css/stocktools/gui.css
  8. 265 0
      app/public/js/Highstock-8.0.0/code/css/stocktools/gui.scss
  9. 987 0
      app/public/js/Highstock-8.0.0/code/css/themes/dark-unica.css
  10. 122 0
      app/public/js/Highstock-8.0.0/code/css/themes/dark-unica.scss
  11. 940 0
      app/public/js/Highstock-8.0.0/code/css/themes/grid-light.css
  12. 33 0
      app/public/js/Highstock-8.0.0/code/css/themes/grid-light.scss
  13. 956 0
      app/public/js/Highstock-8.0.0/code/css/themes/sand-signika.css
  14. 74 0
      app/public/js/Highstock-8.0.0/code/css/themes/sand-signika.scss
  15. 141 0
      app/public/js/Highstock-8.0.0/code/es-modules/annotations/ControlPoint.js
  16. 453 0
      app/public/js/Highstock-8.0.0/code/es-modules/annotations/MockPoint.js
  17. 1321 0
      app/public/js/Highstock-8.0.0/code/es-modules/annotations/annotations.src.js
  18. 84 0
      app/public/js/Highstock-8.0.0/code/es-modules/annotations/controllable/ControllableCircle.js
  19. 93 0
      app/public/js/Highstock-8.0.0/code/es-modules/annotations/controllable/ControllableImage.js
  20. 509 0
      app/public/js/Highstock-8.0.0/code/es-modules/annotations/controllable/ControllableLabel.js
  21. 177 0
      app/public/js/Highstock-8.0.0/code/es-modules/annotations/controllable/ControllablePath.js
  22. 85 0
      app/public/js/Highstock-8.0.0/code/es-modules/annotations/controllable/ControllableRect.js
  23. 444 0
      app/public/js/Highstock-8.0.0/code/es-modules/annotations/controllable/controllableMixin.js
  24. 220 0
      app/public/js/Highstock-8.0.0/code/es-modules/annotations/controllable/markerMixin.js
  25. 286 0
      app/public/js/Highstock-8.0.0/code/es-modules/annotations/eventEmitterMixin.js
  26. 1397 0
      app/public/js/Highstock-8.0.0/code/es-modules/annotations/navigationBindings.js
  27. 1082 0
      app/public/js/Highstock-8.0.0/code/es-modules/annotations/popup.js
  28. 203 0
      app/public/js/Highstock-8.0.0/code/es-modules/annotations/types/CrookedLine.js
  29. 77 0
      app/public/js/Highstock-8.0.0/code/es-modules/annotations/types/ElliottWave.js
  30. 247 0
      app/public/js/Highstock-8.0.0/code/es-modules/annotations/types/Fibonacci.js
  31. 185 0
      app/public/js/Highstock-8.0.0/code/es-modules/annotations/types/InfinityLine.js
  32. 939 0
      app/public/js/Highstock-8.0.0/code/es-modules/annotations/types/Measure.js
  33. 204 0
      app/public/js/Highstock-8.0.0/code/es-modules/annotations/types/Pitchfork.js
  34. 242 0
      app/public/js/Highstock-8.0.0/code/es-modules/annotations/types/Tunnel.js
  35. 158 0
      app/public/js/Highstock-8.0.0/code/es-modules/annotations/types/VerticalLine.js
  36. 133 0
      app/public/js/Highstock-8.0.0/code/es-modules/error-messages.js
  37. 1 0
      app/public/js/Highstock-8.0.0/code/es-modules/error.js
  38. 183 0
      app/public/js/Highstock-8.0.0/code/es-modules/indicators/acceleration-bands.src.js
  39. 109 0
      app/public/js/Highstock-8.0.0/code/es-modules/indicators/accumulation-distribution.src.js
  40. 162 0
      app/public/js/Highstock-8.0.0/code/es-modules/indicators/ao.src.js
  41. 129 0
      app/public/js/Highstock-8.0.0/code/es-modules/indicators/apo.src.js
  42. 112 0
      app/public/js/Highstock-8.0.0/code/es-modules/indicators/aroon-oscillator.src.js
  43. 154 0
      app/public/js/Highstock-8.0.0/code/es-modules/indicators/aroon.src.js
  44. 119 0
      app/public/js/Highstock-8.0.0/code/es-modules/indicators/atr.src.js
  45. 177 0
      app/public/js/Highstock-8.0.0/code/es-modules/indicators/bollinger-bands.src.js
  46. 111 0
      app/public/js/Highstock-8.0.0/code/es-modules/indicators/cci.src.js
  47. 144 0
      app/public/js/Highstock-8.0.0/code/es-modules/indicators/chaikin.src.js
  48. 184 0
      app/public/js/Highstock-8.0.0/code/es-modules/indicators/cmf.src.js
  49. 133 0
      app/public/js/Highstock-8.0.0/code/es-modules/indicators/dema.src.js
  50. 117 0
      app/public/js/Highstock-8.0.0/code/es-modules/indicators/dpo.src.js
  51. 115 0
      app/public/js/Highstock-8.0.0/code/es-modules/indicators/ema.src.js
  52. 639 0
      app/public/js/Highstock-8.0.0/code/es-modules/indicators/ichimoku-kinko-hyo.src.js
  53. 317 0
      app/public/js/Highstock-8.0.0/code/es-modules/indicators/indicators.src.js
  54. 172 0
      app/public/js/Highstock-8.0.0/code/es-modules/indicators/keltner-channels.src.js
  55. 348 0
      app/public/js/Highstock-8.0.0/code/es-modules/indicators/macd.src.js
  56. 155 0
      app/public/js/Highstock-8.0.0/code/es-modules/indicators/mfi.src.js
  57. 99 0
      app/public/js/Highstock-8.0.0/code/es-modules/indicators/momentum.src.js
  58. 72 0
      app/public/js/Highstock-8.0.0/code/es-modules/indicators/natr.src.js
  59. 288 0
      app/public/js/Highstock-8.0.0/code/es-modules/indicators/pivot-points.src.js
  60. 131 0
      app/public/js/Highstock-8.0.0/code/es-modules/indicators/ppo.src.js
  61. 135 0
      app/public/js/Highstock-8.0.0/code/es-modules/indicators/price-channel.src.js
  62. 213 0
      app/public/js/Highstock-8.0.0/code/es-modules/indicators/price-envelopes.src.js
  63. 231 0
      app/public/js/Highstock-8.0.0/code/es-modules/indicators/psar.src.js
  64. 377 0
      app/public/js/Highstock-8.0.0/code/es-modules/indicators/regressions.src.js
  65. 134 0
      app/public/js/Highstock-8.0.0/code/es-modules/indicators/roc.src.js
  66. 132 0
      app/public/js/Highstock-8.0.0/code/es-modules/indicators/rsi.src.js
  67. 112 0
      app/public/js/Highstock-8.0.0/code/es-modules/indicators/slow-stochastic.src.js
  68. 165 0
      app/public/js/Highstock-8.0.0/code/es-modules/indicators/stochastic.src.js
  69. 431 0
      app/public/js/Highstock-8.0.0/code/es-modules/indicators/supertrend.src.js
  70. 167 0
      app/public/js/Highstock-8.0.0/code/es-modules/indicators/tema.src.js
  71. 105 0
      app/public/js/Highstock-8.0.0/code/es-modules/indicators/trendline.src.js
  72. 80 0
      app/public/js/Highstock-8.0.0/code/es-modules/indicators/trix.src.js
  73. 489 0
      app/public/js/Highstock-8.0.0/code/es-modules/indicators/volume-by-price.src.js
  74. 149 0
      app/public/js/Highstock-8.0.0/code/es-modules/indicators/vwap.src.js
  75. 107 0
      app/public/js/Highstock-8.0.0/code/es-modules/indicators/williams-r.src.js
  76. 128 0
      app/public/js/Highstock-8.0.0/code/es-modules/indicators/wma.src.js
  77. 182 0
      app/public/js/Highstock-8.0.0/code/es-modules/indicators/zigzag.src.js
  78. 19 0
      app/public/js/Highstock-8.0.0/code/es-modules/masters/highcharts-3d.src.js
  79. 24 0
      app/public/js/Highstock-8.0.0/code/es-modules/masters/highcharts-more.src.js
  80. 14 0
      app/public/js/Highstock-8.0.0/code/es-modules/masters/highstock.src.js
  81. 14 0
      app/public/js/Highstock-8.0.0/code/es-modules/masters/indicators/acceleration-bands.src.js
  82. 14 0
      app/public/js/Highstock-8.0.0/code/es-modules/masters/indicators/accumulation-distribution.src.js
  83. 14 0
      app/public/js/Highstock-8.0.0/code/es-modules/masters/indicators/ao.src.js
  84. 14 0
      app/public/js/Highstock-8.0.0/code/es-modules/masters/indicators/apo.src.js
  85. 14 0
      app/public/js/Highstock-8.0.0/code/es-modules/masters/indicators/aroon-oscillator.src.js
  86. 14 0
      app/public/js/Highstock-8.0.0/code/es-modules/masters/indicators/aroon.src.js
  87. 14 0
      app/public/js/Highstock-8.0.0/code/es-modules/masters/indicators/atr.src.js
  88. 14 0
      app/public/js/Highstock-8.0.0/code/es-modules/masters/indicators/bollinger-bands.src.js
  89. 14 0
      app/public/js/Highstock-8.0.0/code/es-modules/masters/indicators/cci.src.js
  90. 14 0
      app/public/js/Highstock-8.0.0/code/es-modules/masters/indicators/chaikin.src.js
  91. 13 0
      app/public/js/Highstock-8.0.0/code/es-modules/masters/indicators/cmf.src.js
  92. 14 0
      app/public/js/Highstock-8.0.0/code/es-modules/masters/indicators/dema.src.js
  93. 14 0
      app/public/js/Highstock-8.0.0/code/es-modules/masters/indicators/dpo.src.js
  94. 14 0
      app/public/js/Highstock-8.0.0/code/es-modules/masters/indicators/ema.src.js
  95. 14 0
      app/public/js/Highstock-8.0.0/code/es-modules/masters/indicators/ichimoku-kinko-hyo.src.js
  96. 54 0
      app/public/js/Highstock-8.0.0/code/es-modules/masters/indicators/indicators-all.src.js
  97. 14 0
      app/public/js/Highstock-8.0.0/code/es-modules/masters/indicators/indicators.src.js
  98. 14 0
      app/public/js/Highstock-8.0.0/code/es-modules/masters/indicators/keltner-channels.src.js
  99. 14 0
      app/public/js/Highstock-8.0.0/code/es-modules/masters/indicators/macd.src.js
  100. 14 0
      app/public/js/Highstock-8.0.0/code/es-modules/masters/indicators/mfi.src.js

+ 1 - 1
app/article/style.css

@@ -20,7 +20,7 @@
 	/*height: 5em;*/
 	background-color: var(--tool-bg-color1);
 	border-bottom: 1px solid var(--tool-line-color);
-	padding: 10px;
+	padding: 0.5vh 0.5vw;
 	margin-top: 50px;
 	position: fixed;
 	top: 0;

+ 67 - 66
app/pcdl/css/basic_style.css

@@ -1,23 +1,23 @@
 body {
-    font-family: "Noto Sans", "Noto Sans SC", "Noto Sans TC", Arial, Verdana;
-    font-style: normal;
-    color: var(--main-color);
-    font-weight: 400;
-    font-size: 13px;
-    overflow-x: hidden;
-    margin: 0;
+	font-family: "Noto Sans", "Noto Sans SC", "Noto Sans TC", Arial, Verdana;
+	font-style: normal;
+	color: var(--main-color);
+	font-weight: 400;
+	font-size: 13px;
+	overflow-x: hidden;
+	margin: 0;
 }
 
 div {
-    -webkit-box-sizing: border-box;
-    -moz-box-sizing: border-box;
-    box-sizing: border-box;
+	-webkit-box-sizing: border-box;
+	-moz-box-sizing: border-box;
+	box-sizing: border-box;
 }
 
 hr {
-    margin: 14px 0;
-    border: 1px solid var(--tool-line-color);
-    transform: scaleY(0.4);
+	margin: 14px 0;
+	border: 1px solid var(--tool-line-color);
+	transform: scaleY(0.4);
 }
 
 input,
@@ -30,98 +30,99 @@ hr,
 h1,
 h2,
 h3 {
-    font-family: inherit;
-    font-size: inherit;
-    font-style: inherit;
-    font-weight: inherit;
-    color: inherit;
-    background-color: inherit;
-    -webkit-box-sizing: border-box;
-    -moz-box-sizing: border-box;
-    box-sizing: border-box;
+	font-family: inherit;
+	font-size: inherit;
+	font-style: inherit;
+	font-weight: inherit;
+	color: inherit;
+	background-color: inherit;
+	-webkit-box-sizing: border-box;
+	-moz-box-sizing: border-box;
+	box-sizing: border-box;
 }
 
 input[type="text"],
 input[type="input"],
 textarea {
-    font-weight: 300;
-    width: 100%;
-    border: 1px solid var(--btn-border-line-color);
-    border-radius: 4px;
-    padding: 0.1em 0.3em;
-    font-size: 100%;
-    min-height: 1.2em;
-    margin: 2px 0;
+	font-weight: 300;
+	width: 100%;
+	border: 1px solid var(--btn-border-line-color);
+	border-radius: 4px;
+	padding: 0.1em 0.3em;
+	font-size: 100%;
+	min-height: 1.2em;
+	margin: 2px 0;
 }
 
 select {
-    font-weight: 400;
-    border: 1px solid #aaaaaa;
-    padding: 2px 4px;
-    min-height: 2em;
-    border-radius: 4px;
-    cursor: pointer;
-    margin: 3px 0;
+	font-weight: 400;
+	border: 1px solid #aaaaaa;
+	padding: 2px 4px;
+	min-height: 2em;
+	border-radius: 4px;
+	cursor: pointer;
+	margin: 3px 0;
 }
 
 ul,
 li {
-    white-space: normal;
-    color: inherit;
-    margin: 0px;
-    padding: 0px;
-    word-break: keep-all;
-    text-overflow: ellipsis;
-    list-style-type: none;
+	white-space: normal;
+	color: inherit;
+	margin: 0px;
+	padding: 0px;
+	word-break: keep-all;
+	text-overflow: ellipsis;
+	list-style-type: none;
 }
 
 a,
 a:link,
 a:visited {
-    color: var(--link-color);
-    text-decoration: none;
-    cursor: pointer;
+	color: var(--link-color);
+	text-decoration: none;
+	cursor: pointer;
+	white-space: nowrap;
 }
 
 a:focus {
-    outline: 1px dotted;
+	outline: 1px dotted;
 }
 
 a:hover,
 a:active {
-    color: var(--tool-link-hover-color);
-    outline: none;
+	color: var(--tool-link-hover-color);
+	outline: none;
 }
 
 .footer_navbar {
-    display: flex;
-    flex-wrap: wrap;
-    width: 100%;
+	display: flex;
+	flex-wrap: wrap;
+	width: 100%;
 }
 
 .icon {
-    height: 20px;
-    width: 20px;
-    fill: #555;
-    transition: all 0.2s ease;
+	height: 20px;
+	width: 20px;
+	fill: #555;
+	transition: all 0.2s ease;
 }
 
 .small_icon {
-    height: 1em;
-    width: 1em;
-    fill: #555;
-    -webkit-transition-duration: 0.2s;
-    transition-duration: 0.2s;
+	height: 1em;
+	width: 1em;
+	fill: #555;
+	-webkit-transition-duration: 0.2s;
+	transition-duration: 0.2s;
 }
 
 .broder-1 {
-    border: 1px solid var(--border-line-color);
+	border: 1px solid var(--border-line-color);
 }
 
 .broder-2 {
-    border: 2px solid var(--border-line-color);
+	border: 2px solid var(--border-line-color);
 }
 
 .broder-r {
-    border-radius: 5px;
-}
+	border-radius: 5px;
+}

+ 235 - 0
app/public/js/Highstock-8.0.0/code/css/annotations/popup.css

@@ -0,0 +1,235 @@
+.highcharts-popup.highcharts-annotation-toolbar {
+  right: 10%;
+  left: auto;
+  height: 40px;
+  overflow: hidden;
+  padding-right: 40px;
+  width: auto;
+  min-width: 0;
+}
+
+.highcharts-popup.highcharts-annotation-toolbar button {
+  margin-top: 0px;
+}
+
+.highcharts-popup.highcharts-annotation-toolbar > span {
+  display: block;
+  float: left;
+  padding: 12px;
+}
+
+.highcharts-popup {
+  background-color: #fff;
+  color: #666;
+  display: none;
+  font-size: 0.876em;
+  max-height: 90%;
+  top: 5%;
+  left: 15%;
+  overflow-x: hidden;
+  overflow-y: auto;
+  width: 75%;
+  min-width: 300px;
+  max-width: 600px;
+  position: absolute;
+  z-index: 100;
+  -webkit-box-shadow: 0px 0px 8px 0px rgba(61, 61, 61, 0.3);
+  -moz-box-shadow: 0px 0px 8px 0px rgba(61, 61, 61, 0.3);
+  box-shadow: 0px 0px 8px 0px rgba(61, 61, 61, 0.3);
+}
+
+.highcharts-popup div, .highcharts-popup span {
+  box-sizing: content-box;
+}
+
+.highcharts-popup input, .highcharts-popup label, .highcharts-popup select {
+  clear: both;
+  float: left;
+  width: 100%;
+  margin-bottom: 10px;
+}
+
+.highcharts-popup input {
+  border: 1px solid #e6e6e6;
+  padding: 5px;
+  width: calc(100% - 12px);
+}
+
+.highcharts-popup-lhs-col, .highcharts-popup-rhs-col {
+  padding: 20px;
+  height: calc(100% - 84px);
+  /* 44px - padding, 40px - tabs*/
+  float: left;
+}
+
+.highcharts-popup-lhs-col.highcharts-popup-lhs-full {
+  width: calc(100% - 52px);
+  overflow-y: auto;
+  overflow-x: hidden;
+  height: calc(100% - 140px);
+  border: none;
+  padding: 0px 20px 20px 20px;
+}
+
+.highcharts-popup-lhs-col.highcharts-popup-lhs-full + .highcharts-popup-bottom-row {
+  width: calc(100% - 32px);
+}
+
+.highcharts-popup-lhs-col {
+  clear: both;
+  width: calc(30% - 44px);
+  border-right: 1px solid #e6e6e6;
+}
+
+.highcharts-popup-bottom-row {
+  float: left;
+  padding: 0px 20px;
+  width: calc(100% - 40px);
+}
+
+.highcharts-popup-rhs-col {
+  width: calc(70% - 40px);
+}
+
+.highcharts-popup-rhs-col-wrapper {
+  float: left;
+  width: calc(100% - 20px);
+  padding-right: 20px;
+  height: calc(100% - 40px);
+  overflow-y: auto;
+  overflow-x: hidden;
+}
+
+.highcharts-popup-rhs-col-wrapper h3 {
+  margin-top: 0px;
+  padding-bottom: 0px;
+}
+
+.highcharts-bindings-wrapper ul.highcharts-indicator-list,
+.highcharts-indicator-list {
+  float: left;
+  color: #666;
+  height: 100%;
+  width: 100%;
+  overflow-y: auto;
+  overflow-x: hidden;
+  margin: 0px;
+  padding: 0px;
+}
+
+.highcharts-indicator-list li {
+  cursor: pointer;
+  padding: 0px 0px 5px 0px;
+  margin: 0px;
+  width: 100%;
+  height: auto;
+  overflow: hidden;
+  word-break: break-all;
+}
+
+.highcharts-indicator-list li:hover {
+  background-color: #e6ebf5;
+}
+
+.highcharts-tab-item {
+  background-color: #f7f7f7;
+  cursor: pointer;
+  display: block;
+  float: left;
+  padding: 10px;
+  height: 20px;
+}
+
+.highcharts-tab-item.highcharts-tab-item-active {
+  background-color: #e6ebf5;
+}
+
+.highcharts-tab-item-content {
+  display: none;
+  float: left;
+  height: 100%;
+  overflow: hidden;
+  width: 100%;
+  border-top: 1px solid #e6e6e6;
+}
+
+.highcharts-tab-item-show {
+  display: block;
+}
+
+.highcharts-popup-close {
+  background-repeat: no-repeat;
+  background-position: 50% 50%;
+  width: 20px;
+  height: 20px;
+  cursor: pointer;
+  position: absolute;
+  padding: 10px;
+  top: 0%;
+  right: 0%;
+  color: #333333;
+}
+
+.highcharts-popup-close:hover,
+.highcharts-popup button:hover,
+.highcharts-popup button.highcharts-annotation-edit-button:hover,
+.highcharts-popup button.highcharts-annotation-remove-button:hover {
+  background-color: #e6ebf5;
+}
+
+.highcharts-popup button {
+  float: right;
+  border: none;
+  background: #f7f7f7;
+  color: #666;
+  margin-left: 5px;
+  margin-top: 12px;
+}
+
+.highcharts-popup button:first-child {
+  margin-left: 0;
+}
+
+.highcharts-tab-disabled {
+  color: #ccc;
+}
+
+/* annotation edit small popup */
+.highcharts-popup button.highcharts-annotation-edit-button,
+.highcharts-popup button.highcharts-annotation-remove-button {
+  width: 20px;
+  height: 40px;
+  padding: 20px;
+}
+
+.highcharts-popup button.highcharts-annotation-edit-button {
+  background-repeat: no-repeat;
+  background-position: 50% 50%;
+  text-indent: -9999px;
+}
+
+.highcharts-popup button.highcharts-annotation-remove-button {
+  background-repeat: no-repeat;
+  background-position: 50% 50%;
+  text-indent: -9999px;
+}
+
+.highcharts-popup .highcharts-annotation-title {
+  display: block;
+  float: left;
+  font-size: 1.2em;
+  font-weight: bold;
+  margin-bottom: 15px;
+  width: 100%;
+}
+
+.highcharts-popup .highcharts-popup-main-title {
+  border-bottom: 1px solid #e6e6e6;
+  margin: 0px 0px 20px 0px;
+  padding: 8px 0px 6px 20px;
+}
+
+.highcharts-indicator-title {
+  float: left;
+  padding-bottom: 15px;
+}

+ 239 - 0
app/public/js/Highstock-8.0.0/code/css/annotations/popup.scss

@@ -0,0 +1,239 @@
+// Colors for buttons.
+$button-background-color: #f7f7f7;
+$button-hover-color: #e6ebf5;
+
+
+.highcharts-popup.highcharts-annotation-toolbar {
+  right: 10%;
+  left: auto;
+  height: 40px;
+  overflow: hidden;
+  padding-right: 40px;
+  width: auto;
+  min-width: 0;
+}
+
+.highcharts-popup.highcharts-annotation-toolbar button {
+  margin-top:0px;
+}
+
+.highcharts-popup.highcharts-annotation-toolbar > span {
+  display:block;
+  float:left;
+  padding: 12px;
+}
+
+
+.highcharts-popup {
+  background-color: #fff;
+  color: #666;
+  display: none;
+  font-size: 0.876em;
+  max-height: 90%;
+  top: 5%;
+  left: 15%;
+  overflow-x: hidden;
+  overflow-y: auto;
+  width: 75%;
+  min-width: 300px;
+  max-width: 600px;
+  position: absolute;
+  z-index: 100;
+  -webkit-box-shadow: 0px 0px 8px 0px rgba(61,61,61,0.3);
+  -moz-box-shadow: 0px 0px 8px 0px rgba(61,61,61,0.3);
+  box-shadow: 0px 0px 8px 0px rgba(61,61,61,0.3);
+}
+
+.highcharts-popup div, .highcharts-popup span {
+  box-sizing: content-box;
+}
+
+.highcharts-popup input, .highcharts-popup label, .highcharts-popup select {
+  clear: both;
+  float: left;
+  width: 100%;
+  margin-bottom: 10px;
+}
+
+.highcharts-popup input {
+  border: 1px solid #e6e6e6;
+  padding: 5px;
+  width: calc(100% - 12px);
+}
+
+.highcharts-popup-lhs-col, .highcharts-popup-rhs-col {
+  padding: 20px;
+  height: calc(100% - 84px); /* 44px - padding, 40px - tabs*/
+  float: left;
+}
+
+.highcharts-popup-lhs-col.highcharts-popup-lhs-full { 
+  width: calc(100% - 52px);
+  overflow-y: auto;
+  overflow-x: hidden;
+  height: calc(100% - 140px);
+  border: none;
+  padding: 0px 20px 20px 20px;
+}
+
+.highcharts-popup-lhs-col.highcharts-popup-lhs-full + .highcharts-popup-bottom-row {
+  width: calc(100% - 32px);
+}
+
+.highcharts-popup-lhs-col {
+  clear: both;
+  width: calc(30% - 44px);
+  border-right: 1px solid #e6e6e6;
+}
+
+.highcharts-popup-bottom-row {
+  float: left;
+  padding: 0px 20px;
+  width: calc(100% - 40px);
+}
+
+.highcharts-popup-rhs-col {
+  width: calc(70% - 40px);
+}
+
+.highcharts-popup-rhs-col-wrapper {
+  float: left;
+  width: calc(100% - 20px);
+  padding-right: 20px;
+  height: calc(100% - 40px);
+  overflow-y: auto;
+  overflow-x: hidden;
+}
+
+.highcharts-popup-rhs-col-wrapper h3 {
+  margin-top:0px;
+  padding-bottom:0px;
+}
+
+.highcharts-bindings-wrapper ul.highcharts-indicator-list,
+.highcharts-indicator-list {
+  float: left;
+  color: #666;
+  height: 100%;
+  width: 100%;
+  overflow-y: auto;
+  overflow-x: hidden;
+  margin: 0px;
+  padding: 0px;
+}
+
+.highcharts-indicator-list li {
+  cursor: pointer;
+  padding: 0px 0px 5px 0px;
+  margin: 0px;
+  width: 100%;
+  height: auto;
+  overflow: hidden;
+  word-break: break-all;
+}
+
+.highcharts-indicator-list li:hover {
+  background-color: $button-hover-color;
+}
+
+.highcharts-tab-item {
+  background-color: $button-background-color;
+  cursor: pointer;
+  display: block;
+  float:left;
+  padding: 10px;
+  height: 20px;
+}
+
+.highcharts-tab-item.highcharts-tab-item-active {
+  background-color: $button-hover-color;
+}
+
+.highcharts-tab-item-content {
+  display: none; 
+  float: left;
+  height: 100%;
+  overflow: hidden;
+  width: 100%;
+  border-top: 1px solid #e6e6e6;
+}
+
+.highcharts-tab-item-show {
+  display: block;
+}
+
+.highcharts-popup-close {
+  background-repeat: no-repeat;
+  background-position: 50% 50%;
+  width: 20px;
+  height: 20px;
+  cursor: pointer;
+  position: absolute;
+  padding: 10px;
+  top: 0%;
+  right: 0%;
+  color: #333333;
+}
+
+.highcharts-popup-close:hover,
+.highcharts-popup button:hover,
+.highcharts-popup button.highcharts-annotation-edit-button:hover,
+.highcharts-popup button.highcharts-annotation-remove-button:hover {
+  background-color: $button-hover-color;
+}
+
+.highcharts-popup button {
+  float: right;
+  border: none;
+  background: $button-background-color;
+  color: #666;
+  margin-left:5px;
+  margin-top:12px;
+}
+.highcharts-popup button:first-child {
+  margin-left: 0;
+}
+
+.highcharts-tab-disabled {
+  color: #ccc;
+}
+
+/* annotation edit small popup */
+.highcharts-popup button.highcharts-annotation-edit-button,
+.highcharts-popup button.highcharts-annotation-remove-button {
+  width: 20px;
+  height: 40px;
+  padding: 20px;
+}
+
+.highcharts-popup button.highcharts-annotation-edit-button {
+  background-repeat: no-repeat;
+  background-position: 50% 50%;
+  text-indent: -9999px;
+}
+
+.highcharts-popup button.highcharts-annotation-remove-button {
+  background-repeat: no-repeat;
+  background-position: 50% 50%;
+  text-indent: -9999px;
+}
+
+.highcharts-popup .highcharts-annotation-title {
+  display: block;
+  float: left;
+  font-size: 1.2em;
+  font-weight: bold;
+  margin-bottom: 15px;
+  width: 100%;
+}
+
+.highcharts-popup .highcharts-popup-main-title {
+  border-bottom: 1px solid #e6e6e6;
+  margin: 0px 0px 20px 0px;
+  padding: 8px 0px 6px 20px;
+}
+
+.highcharts-indicator-title {
+  float: left;
+  padding-bottom: 15px;
+}

+ 926 - 0
app/public/js/Highstock-8.0.0/code/css/highcharts.css

@@ -0,0 +1,926 @@
+/**
+ * @license Highcharts
+ *
+ * (c) 2009-2016 Torstein Honsi
+ *
+ * License: www.highcharts.com/license
+ */
+.highcharts-container {
+  position: relative;
+  overflow: hidden;
+  width: 100%;
+  height: 100%;
+  text-align: left;
+  line-height: normal;
+  z-index: 0;
+  /* #1072 */
+  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+  font-family: "Lucida Grande", "Lucida Sans Unicode", Arial, Helvetica, sans-serif;
+  font-size: 12px;
+}
+
+.highcharts-root {
+  display: block;
+}
+
+.highcharts-root text {
+  stroke-width: 0;
+}
+
+.highcharts-strong {
+  font-weight: bold;
+}
+
+.highcharts-emphasized {
+  font-style: italic;
+}
+
+.highcharts-anchor {
+  cursor: pointer;
+}
+
+.highcharts-background {
+  fill: #ffffff;
+}
+
+.highcharts-plot-border, .highcharts-plot-background {
+  fill: none;
+}
+
+.highcharts-label-box {
+  fill: none;
+}
+
+.highcharts-button-box {
+  fill: inherit;
+}
+
+.highcharts-tracker-line {
+  stroke-linejoin: round;
+  stroke: rgba(192, 192, 192, 0.0001);
+  stroke-width: 22;
+  fill: none;
+}
+
+.highcharts-tracker-area {
+  fill: rgba(192, 192, 192, 0.0001);
+  stroke-width: 0;
+}
+
+/* Titles */
+.highcharts-title {
+  fill: #333333;
+  font-size: 1.5em;
+}
+
+.highcharts-subtitle {
+  fill: #666666;
+}
+
+/* Axes */
+.highcharts-axis-line {
+  fill: none;
+  stroke: #ccd6eb;
+}
+
+.highcharts-yaxis .highcharts-axis-line {
+  stroke-width: 0;
+}
+
+.highcharts-axis-title {
+  fill: #666666;
+}
+
+.highcharts-axis-labels {
+  fill: #666666;
+  cursor: default;
+  font-size: 0.9em;
+}
+
+.highcharts-grid-line {
+  fill: none;
+  stroke: #e6e6e6;
+}
+
+.highcharts-xaxis-grid .highcharts-grid-line {
+  stroke-width: 0px;
+}
+
+.highcharts-tick {
+  stroke: #ccd6eb;
+}
+
+.highcharts-yaxis .highcharts-tick {
+  stroke-width: 0;
+}
+
+.highcharts-minor-grid-line {
+  stroke: #f2f2f2;
+}
+
+.highcharts-crosshair-thin {
+  stroke-width: 1px;
+  stroke: #cccccc;
+}
+
+.highcharts-crosshair-category {
+  stroke: #ccd6eb;
+  stroke-opacity: 0.25;
+}
+
+/* Credits */
+.highcharts-credits {
+  cursor: pointer;
+  fill: #999999;
+  font-size: 0.7em;
+  transition: fill 250ms, font-size 250ms;
+}
+
+.highcharts-credits:hover {
+  fill: black;
+  font-size: 1em;
+}
+
+/* Tooltip */
+.highcharts-tooltip {
+  cursor: default;
+  pointer-events: none;
+  white-space: nowrap;
+  transition: stroke 150ms;
+}
+
+.highcharts-tooltip text {
+  fill: #333333;
+}
+
+.highcharts-tooltip .highcharts-header {
+  font-size: 0.85em;
+}
+
+.highcharts-tooltip-box {
+  stroke-width: 1px;
+  fill: #f7f7f7;
+  fill-opacity: 0.85;
+}
+
+.highcharts-tooltip-box .highcharts-label-box {
+  fill: #f7f7f7;
+  fill-opacity: 0.85;
+}
+
+div.highcharts-tooltip {
+  filter: none;
+}
+
+.highcharts-selection-marker {
+  fill: #335cad;
+  fill-opacity: 0.25;
+}
+
+.highcharts-graph {
+  fill: none;
+  stroke-width: 2px;
+  stroke-linecap: round;
+  stroke-linejoin: round;
+}
+
+.highcharts-state-hover .highcharts-graph {
+  stroke-width: 3;
+}
+
+.highcharts-point-inactive {
+  opacity: 0.2;
+  transition: opacity 50ms;
+  /* quick in */
+}
+
+.highcharts-series-inactive {
+  opacity: 0.2;
+  transition: opacity 50ms;
+  /* quick in */
+}
+
+.highcharts-state-hover path {
+  transition: stroke-width 50ms;
+  /* quick in */
+}
+
+.highcharts-state-normal path {
+  transition: stroke-width 250ms;
+  /* slow out */
+}
+
+/* Legend hover affects points and series */
+g.highcharts-series,
+.highcharts-point,
+.highcharts-markers,
+.highcharts-data-labels {
+  transition: opacity 250ms;
+}
+
+.highcharts-legend-series-active g.highcharts-series:not(.highcharts-series-hover),
+.highcharts-legend-point-active .highcharts-point:not(.highcharts-point-hover),
+.highcharts-legend-series-active .highcharts-markers:not(.highcharts-series-hover),
+.highcharts-legend-series-active .highcharts-data-labels:not(.highcharts-series-hover) {
+  opacity: 0.2;
+}
+
+/* Series options */
+/* Default colors */
+.highcharts-color-0 {
+  fill: #7cb5ec;
+  stroke: #7cb5ec;
+}
+
+.highcharts-color-1 {
+  fill: #434348;
+  stroke: #434348;
+}
+
+.highcharts-color-2 {
+  fill: #90ed7d;
+  stroke: #90ed7d;
+}
+
+.highcharts-color-3 {
+  fill: #f7a35c;
+  stroke: #f7a35c;
+}
+
+.highcharts-color-4 {
+  fill: #8085e9;
+  stroke: #8085e9;
+}
+
+.highcharts-color-5 {
+  fill: #f15c80;
+  stroke: #f15c80;
+}
+
+.highcharts-color-6 {
+  fill: #e4d354;
+  stroke: #e4d354;
+}
+
+.highcharts-color-7 {
+  fill: #2b908f;
+  stroke: #2b908f;
+}
+
+.highcharts-color-8 {
+  fill: #f45b5b;
+  stroke: #f45b5b;
+}
+
+.highcharts-color-9 {
+  fill: #91e8e1;
+  stroke: #91e8e1;
+}
+
+.highcharts-area {
+  fill-opacity: 0.75;
+  stroke-width: 0;
+}
+
+.highcharts-markers {
+  stroke-width: 1px;
+  stroke: #ffffff;
+}
+
+.highcharts-point {
+  stroke-width: 1px;
+}
+
+.highcharts-dense-data .highcharts-point {
+  stroke-width: 0;
+}
+
+.highcharts-data-label {
+  font-size: 0.9em;
+  font-weight: bold;
+}
+
+.highcharts-data-label-box {
+  fill: none;
+  stroke-width: 0;
+}
+
+.highcharts-data-label text, text.highcharts-data-label {
+  fill: #333333;
+}
+
+.highcharts-data-label-connector {
+  fill: none;
+}
+
+.highcharts-halo {
+  fill-opacity: 0.25;
+  stroke-width: 0;
+}
+
+.highcharts-series:not(.highcharts-pie-series) .highcharts-point-select,
+.highcharts-markers .highcharts-point-select {
+  fill: #cccccc;
+  stroke: #000000;
+}
+
+.highcharts-column-series rect.highcharts-point {
+  stroke: #ffffff;
+}
+
+.highcharts-column-series .highcharts-point {
+  transition: fill-opacity 250ms;
+}
+
+.highcharts-column-series .highcharts-point-hover {
+  fill-opacity: 0.75;
+  transition: fill-opacity 50ms;
+}
+
+.highcharts-pie-series .highcharts-point {
+  stroke-linejoin: round;
+  stroke: #ffffff;
+}
+
+.highcharts-pie-series .highcharts-point-hover {
+  fill-opacity: 0.75;
+  transition: fill-opacity 50ms;
+}
+
+.highcharts-funnel-series .highcharts-point {
+  stroke-linejoin: round;
+  stroke: #ffffff;
+}
+
+.highcharts-funnel-series .highcharts-point-hover {
+  fill-opacity: 0.75;
+  transition: fill-opacity 50ms;
+}
+
+.highcharts-funnel-series .highcharts-point-select {
+  fill: inherit;
+  stroke: inherit;
+}
+
+.highcharts-pyramid-series .highcharts-point {
+  stroke-linejoin: round;
+  stroke: #ffffff;
+}
+
+.highcharts-pyramid-series .highcharts-point-hover {
+  fill-opacity: 0.75;
+  transition: fill-opacity 50ms;
+}
+
+.highcharts-pyramid-series .highcharts-point-select {
+  fill: inherit;
+  stroke: inherit;
+}
+
+.highcharts-solidgauge-series .highcharts-point {
+  stroke-width: 0;
+}
+
+.highcharts-treemap-series .highcharts-point {
+  stroke-width: 1px;
+  stroke: #e6e6e6;
+  transition: stroke 250ms, fill 250ms, fill-opacity 250ms;
+}
+
+.highcharts-treemap-series .highcharts-point-hover {
+  stroke: #999999;
+  transition: stroke 25ms, fill 25ms, fill-opacity 25ms;
+}
+
+.highcharts-treemap-series .highcharts-above-level {
+  display: none;
+}
+
+.highcharts-treemap-series .highcharts-internal-node {
+  fill: none;
+}
+
+.highcharts-treemap-series .highcharts-internal-node-interactive {
+  fill-opacity: 0.15;
+  cursor: pointer;
+}
+
+.highcharts-treemap-series .highcharts-internal-node-interactive:hover {
+  fill-opacity: 0.75;
+}
+
+.highcharts-vector-series .highcharts-point {
+  fill: none;
+  stroke-width: 2px;
+}
+
+.highcharts-windbarb-series .highcharts-point {
+  fill: none;
+  stroke-width: 2px;
+}
+
+/* Dumbbell/lollipop connector */
+.highcharts-lollipop-stem {
+  stroke: #000000;
+}
+
+/* Legend */
+.highcharts-legend-box {
+  fill: none;
+  stroke-width: 0;
+}
+
+.highcharts-legend-item > text {
+  fill: #333333;
+  font-weight: bold;
+  font-size: 1em;
+  cursor: pointer;
+  stroke-width: 0;
+}
+
+.highcharts-legend-item:hover text {
+  fill: #000000;
+}
+
+.highcharts-legend-item-hidden * {
+  fill: #cccccc !important;
+  stroke: #cccccc !important;
+  transition: fill 250ms;
+}
+
+.highcharts-legend-nav-active {
+  fill: #003399;
+  cursor: pointer;
+}
+
+.highcharts-legend-nav-inactive {
+  fill: #cccccc;
+}
+
+circle.highcharts-legend-nav-active, circle.highcharts-legend-nav-inactive {
+  /* tracker */
+  fill: rgba(192, 192, 192, 0.0001);
+}
+
+.highcharts-legend-title-box {
+  fill: none;
+  stroke-width: 0;
+}
+
+/* Bubble legend */
+.highcharts-bubble-legend-symbol {
+  stroke-width: 2;
+  fill-opacity: 0.5;
+}
+
+.highcharts-bubble-legend-connectors {
+  stroke-width: 1;
+}
+
+.highcharts-bubble-legend-labels {
+  fill: #333333;
+}
+
+/* Loading */
+.highcharts-loading {
+  position: absolute;
+  background-color: #ffffff;
+  opacity: 0.5;
+  text-align: center;
+  z-index: 10;
+  transition: opacity 250ms;
+}
+
+.highcharts-loading-hidden {
+  height: 0 !important;
+  opacity: 0;
+  overflow: hidden;
+  transition: opacity 250ms, height 250ms step-end;
+}
+
+.highcharts-loading-inner {
+  font-weight: bold;
+  position: relative;
+  top: 45%;
+}
+
+/* Plot bands and polar pane backgrounds */
+.highcharts-plot-band, .highcharts-pane {
+  fill: #000000;
+  fill-opacity: 0.05;
+}
+
+.highcharts-plot-line {
+  fill: none;
+  stroke: #999999;
+  stroke-width: 1px;
+}
+
+/* Highcharts More and modules */
+.highcharts-boxplot-box {
+  fill: #ffffff;
+}
+
+.highcharts-boxplot-median {
+  stroke-width: 2px;
+}
+
+.highcharts-bubble-series .highcharts-point {
+  fill-opacity: 0.5;
+}
+
+.highcharts-errorbar-series .highcharts-point {
+  stroke: #000000;
+}
+
+.highcharts-gauge-series .highcharts-data-label-box {
+  stroke: #cccccc;
+  stroke-width: 1px;
+}
+
+.highcharts-gauge-series .highcharts-dial {
+  fill: #000000;
+  stroke-width: 0;
+}
+
+.highcharts-polygon-series .highcharts-graph {
+  fill: inherit;
+  stroke-width: 0;
+}
+
+.highcharts-waterfall-series .highcharts-graph {
+  stroke: #333333;
+  stroke-dasharray: 1, 3;
+}
+
+.highcharts-sankey-series .highcharts-point {
+  stroke-width: 0;
+}
+
+.highcharts-sankey-series .highcharts-link {
+  transition: fill 250ms, fill-opacity 250ms;
+  fill-opacity: 0.5;
+}
+
+.highcharts-sankey-series .highcharts-point-hover.highcharts-link {
+  transition: fill 50ms, fill-opacity 50ms;
+  fill-opacity: 1;
+}
+
+.highcharts-venn-series .highcharts-point {
+  fill-opacity: 0.75;
+  stroke: #cccccc;
+  transition: stroke 250ms, fill-opacity 250ms;
+}
+
+.highcharts-venn-series .highcharts-point-hover {
+  fill-opacity: 1;
+  stroke: #cccccc;
+}
+
+/* Highstock */
+.highcharts-navigator-mask-outside {
+  fill-opacity: 0;
+}
+
+.highcharts-navigator-mask-inside {
+  fill: #6685c2;
+  /* navigator.maskFill option */
+  fill-opacity: 0.25;
+  cursor: ew-resize;
+}
+
+.highcharts-navigator-outline {
+  stroke: #cccccc;
+  fill: none;
+}
+
+.highcharts-navigator-handle {
+  stroke: #cccccc;
+  fill: #f2f2f2;
+  cursor: ew-resize;
+}
+
+.highcharts-navigator-series {
+  fill: #335cad;
+  stroke: #335cad;
+}
+
+.highcharts-navigator-series .highcharts-graph {
+  stroke-width: 1px;
+}
+
+.highcharts-navigator-series .highcharts-area {
+  fill-opacity: 0.05;
+}
+
+.highcharts-navigator-xaxis .highcharts-axis-line {
+  stroke-width: 0;
+}
+
+.highcharts-navigator-xaxis .highcharts-grid-line {
+  stroke-width: 1px;
+  stroke: #e6e6e6;
+}
+
+.highcharts-navigator-xaxis.highcharts-axis-labels {
+  fill: #999999;
+}
+
+.highcharts-navigator-yaxis .highcharts-grid-line {
+  stroke-width: 0;
+}
+
+.highcharts-scrollbar-thumb {
+  fill: #cccccc;
+  stroke: #cccccc;
+  stroke-width: 1px;
+}
+
+.highcharts-scrollbar-button {
+  fill: #e6e6e6;
+  stroke: #cccccc;
+  stroke-width: 1px;
+}
+
+.highcharts-scrollbar-arrow {
+  fill: #666666;
+}
+
+.highcharts-scrollbar-rifles {
+  stroke: #666666;
+  stroke-width: 1px;
+}
+
+.highcharts-scrollbar-track {
+  fill: #f2f2f2;
+  stroke: #f2f2f2;
+  stroke-width: 1px;
+}
+
+.highcharts-button {
+  fill: #f7f7f7;
+  stroke: #cccccc;
+  cursor: default;
+  stroke-width: 1px;
+  transition: fill 250ms;
+}
+
+.highcharts-button text {
+  fill: #333333;
+}
+
+.highcharts-button-hover {
+  transition: fill 0ms;
+  fill: #e6e6e6;
+  stroke: #cccccc;
+}
+
+.highcharts-button-hover text {
+  fill: #333333;
+}
+
+.highcharts-button-pressed {
+  font-weight: bold;
+  fill: #e6ebf5;
+  stroke: #cccccc;
+}
+
+.highcharts-button-pressed text {
+  fill: #333333;
+  font-weight: bold;
+}
+
+.highcharts-button-disabled text {
+  fill: #333333;
+}
+
+.highcharts-range-selector-buttons .highcharts-button {
+  stroke-width: 0px;
+}
+
+.highcharts-range-label rect {
+  fill: none;
+}
+
+.highcharts-range-label text {
+  fill: #666666;
+}
+
+.highcharts-range-input rect {
+  fill: none;
+}
+
+.highcharts-range-input text {
+  fill: #333333;
+}
+
+.highcharts-range-input {
+  stroke-width: 1px;
+  stroke: #cccccc;
+}
+
+input.highcharts-range-selector {
+  position: absolute;
+  border: 0;
+  width: 1px;
+  /* Chrome needs a pixel to see it */
+  height: 1px;
+  padding: 0;
+  text-align: center;
+  left: -9em;
+  /* #4798 */
+}
+
+.highcharts-crosshair-label text {
+  fill: #ffffff;
+  font-size: 1.1em;
+}
+
+.highcharts-crosshair-label .highcharts-label-box {
+  fill: inherit;
+}
+
+.highcharts-candlestick-series .highcharts-point {
+  stroke: #000000;
+  stroke-width: 1px;
+}
+
+.highcharts-candlestick-series .highcharts-point-up {
+  fill: #ffffff;
+}
+
+.highcharts-ohlc-series .highcharts-point-hover {
+  stroke-width: 3px;
+}
+
+.highcharts-flags-series .highcharts-point .highcharts-label-box {
+  stroke: #999999;
+  fill: #ffffff;
+  transition: fill 250ms;
+}
+
+.highcharts-flags-series .highcharts-point-hover .highcharts-label-box {
+  stroke: #000000;
+  fill: #ccd6eb;
+}
+
+.highcharts-flags-series .highcharts-point text {
+  fill: #000000;
+  font-size: 0.9em;
+  font-weight: bold;
+}
+
+/* Highmaps */
+.highcharts-map-series .highcharts-point {
+  transition: fill 500ms, fill-opacity 500ms, stroke-width 250ms;
+  stroke: #cccccc;
+}
+
+.highcharts-map-series .highcharts-point-hover {
+  transition: fill 0ms, fill-opacity 0ms;
+  fill-opacity: 0.5;
+  stroke-width: 2px;
+}
+
+.highcharts-mapline-series .highcharts-point {
+  fill: none;
+}
+
+.highcharts-heatmap-series .highcharts-point {
+  stroke-width: 0;
+}
+
+.highcharts-map-navigation {
+  font-size: 1.3em;
+  font-weight: bold;
+  text-align: center;
+}
+
+.highcharts-coloraxis {
+  stroke-width: 0;
+}
+
+.highcharts-coloraxis-marker {
+  fill: #999999;
+}
+
+.highcharts-null-point {
+  fill: #f7f7f7;
+}
+
+/* 3d charts */
+.highcharts-3d-frame {
+  fill: transparent;
+}
+
+/* Exporting module */
+.highcharts-contextbutton {
+  fill: #ffffff;
+  /* needed to capture hover */
+  stroke: none;
+  stroke-linecap: round;
+}
+
+.highcharts-contextbutton:hover {
+  fill: #e6e6e6;
+  stroke: #e6e6e6;
+}
+
+.highcharts-button-symbol {
+  stroke: #666666;
+  stroke-width: 3px;
+}
+
+.highcharts-menu {
+  border: 1px solid #999999;
+  background: #ffffff;
+  padding: 5px 0;
+  box-shadow: 3px 3px 10px #888;
+}
+
+.highcharts-menu-item {
+  padding: 0.5em 1em;
+  background: none;
+  color: #333333;
+  cursor: pointer;
+  transition: background 250ms, color 250ms;
+}
+
+.highcharts-menu-item:hover {
+  background: #335cad;
+  color: #ffffff;
+}
+
+/* Drilldown module */
+.highcharts-drilldown-point {
+  cursor: pointer;
+}
+
+.highcharts-drilldown-data-label text,
+text.highcharts-drilldown-data-label,
+.highcharts-drilldown-axis-label {
+  cursor: pointer;
+  fill: #003399;
+  font-weight: bold;
+  text-decoration: underline;
+}
+
+/* No-data module */
+.highcharts-no-data text {
+  font-weight: bold;
+  font-size: 12px;
+  fill: #666666;
+}
+
+/* Drag-panes module */
+.highcharts-axis-resizer {
+  cursor: ns-resize;
+  stroke: black;
+  stroke-width: 2px;
+}
+
+/* Bullet type series */
+.highcharts-bullet-target {
+  stroke-width: 0;
+}
+
+/* Lineargauge type series */
+.highcharts-lineargauge-target {
+  stroke-width: 1px;
+  stroke: #333333;
+}
+
+.highcharts-lineargauge-target-line {
+  stroke-width: 1px;
+  stroke: #333333;
+}
+
+/* Annotations module */
+.highcharts-annotation-label-box {
+  stroke-width: 1px;
+  stroke: #000000;
+  fill: #000000;
+  fill-opacity: 0.75;
+}
+
+.highcharts-annotation-label text {
+  fill: #e6e6e6;
+}
+
+/* Gantt */
+.highcharts-treegrid-node-collapsed, .highcharts-treegrid-node-expanded {
+  cursor: pointer;
+}
+
+.highcharts-point-connecting-path {
+  fill: none;
+}
+
+.highcharts-grid-axis .highcharts-tick {
+  stroke-width: 1px;
+}
+
+.highcharts-grid-axis .highcharts-axis-line {
+  stroke-width: 1px;
+}

+ 818 - 0
app/public/js/Highstock-8.0.0/code/css/highcharts.scss

@@ -0,0 +1,818 @@
+/**
+ * @license Highcharts
+ *
+ * (c) 2009-2016 Torstein Honsi
+ *
+ * License: www.highcharts.com/license
+ */
+
+// Colors for data series and points.
+$colors: #7cb5ec #434348 #90ed7d #f7a35c #8085e9 #f15c80 #e4d354 #2b908f #f45b5b #91e8e1 !default;
+
+// Chart background, point stroke for markers and columns etc
+$background-color: #ffffff !default;
+
+// Neutral colors, grayscale by default. The default colors are defined by mixing the
+// background-color with neutral, with a weight corresponding to the number in the name.
+$neutral-color-100: #000000 !default; // Strong text.
+$neutral-color-80: #333333 !default; // Main text and some strokes.
+$neutral-color-60: #666666 !default; // Axis labels, axis title, connector fallback.
+$neutral-color-40: #999999 !default; // Credits text, export menu stroke.
+$neutral-color-20: #cccccc !default; // Disabled texts, button strokes, crosshair etc.
+$neutral-color-10: #e6e6e6 !default; // Grid lines etc.
+$neutral-color-5: #f2f2f2 !default; // Minor grid lines etc.
+$neutral-color-3: #f7f7f7 !default; // Tooltip backgroud, button fills, map null points.
+
+// Colored, shades of blue by default
+$highlight-color-100: #003399 !default; // Drilldown clickable labels, color axis max color.
+$highlight-color-80: #335cad !default; // Selection marker, menu hover, button hover, chart border, navigator series.
+$highlight-color-60: #6685c2 !default; // Navigator mask fill.
+$highlight-color-20: #ccd6eb !default; // Ticks and axis line.
+$highlight-color-10: #e6ebf5 !default; // Pressed button, color axis min color.
+
+// Fonts
+$font-family: "Lucida Grande", "Lucida Sans Unicode", Arial, Helvetica, sans-serif !default;
+$title-font-size: 1.5em !default;
+$subtitle-font-size: 1em !default;
+$legend-font-size: 1em !default;
+$axis-labels-font-size: 0.9em !default;
+
+// Tooltip
+$tooltip-border: 1px !default;
+$tooltip-background: $neutral-color-3 !default;
+
+// Axes
+$xaxis-grid-line: 0px !default;
+
+// Range-selector
+$range-selector-button-border: 0px !default;
+$range-selector-input-text: $neutral-color-80 !default;
+$range-selector-input-border: $neutral-color-20 !default;
+
+// Data-labels
+$data-label-color: $neutral-color-80 !default;
+
+// Buttons
+$context-button-background: $background-color !default;
+
+$highcharts-button-background: $neutral-color-3 !default;
+$highcharts-button-border: $neutral-color-20 !default;
+$highcharts-button-text:  $neutral-color-80 !default;
+
+$highcharts-button-pressed-background: $highlight-color-10 !default;
+$highcharts-button-pressed-border: $neutral-color-20 !default;
+$highcharts-button-pressed-text:  $neutral-color-80 !default;
+
+$highcharts-button-hover-background: $neutral-color-10 !default;
+$highcharts-button-hover-border: $neutral-color-20 !default;
+$highcharts-button-hover-text:  $neutral-color-80 !default;
+
+// Navigator
+$navigator-series-fill: $highlight-color-80 !default;
+$navigator-series-border: $highlight-color-80 !default;
+
+// Scrollbar
+$scrollbar-track-background: $neutral-color-5 !default;
+$scrollbar-track-border: $neutral-color-5 !default;
+
+// Indicators
+$indicator-positive-line: #06B535;
+$indicator-negative-line: #F21313;
+
+.highcharts-container {
+    position: relative;
+    overflow: hidden;
+    width: 100%;
+    height: 100%;
+    text-align: left;
+    line-height: normal;
+    z-index: 0; /* #1072 */
+    -webkit-tap-highlight-color: rgba(0,0,0,0);
+    font-family: $font-family;
+    font-size: 12px;
+}
+.highcharts-root {
+    display: block;
+}
+.highcharts-root text {
+    stroke-width: 0;
+}
+.highcharts-strong {
+    font-weight: bold;
+}
+.highcharts-emphasized {
+    font-style: italic;
+}
+.highcharts-anchor {
+    cursor: pointer;
+}
+.highcharts-background {
+    fill: $background-color;
+}
+.highcharts-plot-border, .highcharts-plot-background {
+    fill: none;
+}
+.highcharts-label-box {
+    fill: none;
+}
+.highcharts-button-box {
+    fill: inherit;
+}
+.highcharts-tracker-line {
+    stroke-linejoin: round;
+    stroke: rgba(192, 192, 192, 0.0001);
+    stroke-width: 22;
+    fill: none;
+}
+.highcharts-tracker-area {
+    fill: rgba(192, 192, 192, 0.0001);
+    stroke-width: 0;
+}
+
+/* Titles */
+.highcharts-title {
+    fill: $neutral-color-80;
+    font-size: $title-font-size;
+}
+.highcharts-subtitle {
+    fill: $neutral-color-60;
+}
+
+/* Axes */
+.highcharts-axis-line {
+    fill: none;
+    stroke: $highlight-color-20;
+}
+.highcharts-yaxis .highcharts-axis-line {
+    stroke-width: 0;
+}
+.highcharts-axis-title {
+    fill: $neutral-color-60;
+}
+.highcharts-axis-labels {
+    fill: $neutral-color-60;
+    cursor: default;
+    font-size: $axis-labels-font-size;
+}
+.highcharts-grid-line {
+    fill: none;
+    stroke: $neutral-color-10;
+}
+.highcharts-xaxis-grid .highcharts-grid-line {
+    stroke-width: $xaxis-grid-line;
+}
+.highcharts-tick {
+    stroke: $highlight-color-20;
+}
+.highcharts-yaxis .highcharts-tick {
+    stroke-width: 0;
+}
+.highcharts-minor-grid-line {
+    stroke: $neutral-color-5;
+}
+.highcharts-crosshair-thin {
+    stroke-width: 1px;
+    stroke: $neutral-color-20;
+}
+.highcharts-crosshair-category {
+    stroke: $highlight-color-20;
+    stroke-opacity: 0.25;
+}
+
+
+/* Credits */
+.highcharts-credits {
+    cursor: pointer;
+    fill: $neutral-color-40;
+    font-size: 0.7em;
+    transition: fill 250ms, font-size 250ms;
+}
+.highcharts-credits:hover {
+    fill: black;
+    font-size: 1em;
+}
+
+/* Tooltip */
+.highcharts-tooltip {
+    cursor: default;
+    pointer-events: none;
+    white-space: nowrap;
+    transition: stroke 150ms;
+}
+.highcharts-tooltip text {
+    fill: $neutral-color-80;
+}
+.highcharts-tooltip .highcharts-header {
+    font-size: 0.85em;
+}
+.highcharts-tooltip-box {
+    stroke-width: $tooltip-border;
+    fill: $tooltip-background;
+    fill-opacity: 0.85;
+}
+.highcharts-tooltip-box .highcharts-label-box {
+    fill: $tooltip-background;
+    fill-opacity: 0.85;
+}
+div.highcharts-tooltip {
+    filter: none;
+}
+
+.highcharts-selection-marker {
+    fill: $highlight-color-80;
+    fill-opacity: 0.25;
+}
+
+.highcharts-graph {
+    fill: none;
+    stroke-width: 2px;
+    stroke-linecap: round;
+    stroke-linejoin: round;
+}
+.highcharts-state-hover .highcharts-graph {
+    stroke-width: 3;
+}
+
+.highcharts-point-inactive {
+    opacity: 0.2;
+    transition: opacity 50ms; /* quick in */
+}
+
+.highcharts-series-inactive {
+    opacity: 0.2;
+    transition: opacity 50ms; /* quick in */
+}
+
+.highcharts-state-hover path {
+    transition: stroke-width 50ms; /* quick in */
+}
+.highcharts-state-normal path {
+    transition: stroke-width 250ms; /* slow out */
+}
+/* Legend hover affects points and series */
+g.highcharts-series,
+.highcharts-point,
+.highcharts-markers,
+.highcharts-data-labels {
+    transition: opacity 250ms;
+}
+.highcharts-legend-series-active g.highcharts-series:not(.highcharts-series-hover),
+.highcharts-legend-point-active .highcharts-point:not(.highcharts-point-hover),
+.highcharts-legend-series-active .highcharts-markers:not(.highcharts-series-hover),
+.highcharts-legend-series-active .highcharts-data-labels:not(.highcharts-series-hover) {
+    opacity: 0.2;
+}
+
+/* Series options */
+
+/* Default colors */
+@for $i from 1 through length($colors) {
+  $color: nth($colors, $i);
+  .highcharts-color-#{$i - 1} {
+    fill: $color;
+    stroke: $color;
+  }
+}
+
+.highcharts-area {
+    fill-opacity: 0.75;
+    stroke-width: 0;
+}
+.highcharts-markers {
+    stroke-width: 1px;
+    stroke: $background-color;
+}
+.highcharts-point {
+    stroke-width: 1px;
+}
+.highcharts-dense-data .highcharts-point {
+    stroke-width: 0;
+}
+
+.highcharts-data-label {
+    font-size: 0.9em;
+    font-weight: bold;
+}
+.highcharts-data-label-box {
+    fill: none;
+    stroke-width: 0;
+}
+.highcharts-data-label text, text.highcharts-data-label {
+    fill: $data-label-color;
+}
+.highcharts-data-label-connector {
+    fill: none;
+}
+.highcharts-halo {
+    fill-opacity: 0.25;
+    stroke-width: 0;
+}
+.highcharts-series:not(.highcharts-pie-series) .highcharts-point-select,
+.highcharts-markers .highcharts-point-select {
+    fill: $neutral-color-20;
+    stroke: $neutral-color-100;
+}
+.highcharts-column-series rect.highcharts-point {
+    // rect to prevent stroke on 3D columns
+    stroke: $background-color;
+}
+.highcharts-column-series .highcharts-point {
+    transition: fill-opacity 250ms;
+}
+.highcharts-column-series .highcharts-point-hover {
+    fill-opacity: 0.75;
+    transition: fill-opacity 50ms;
+}
+.highcharts-pie-series .highcharts-point {
+    stroke-linejoin: round;
+    stroke: $background-color;
+}
+.highcharts-pie-series .highcharts-point-hover {
+    fill-opacity: 0.75;
+    transition: fill-opacity 50ms;
+}
+.highcharts-funnel-series .highcharts-point {
+    stroke-linejoin: round;
+    stroke: $background-color;
+}
+.highcharts-funnel-series .highcharts-point-hover {
+    fill-opacity: 0.75;
+    transition: fill-opacity 50ms;
+}
+.highcharts-funnel-series .highcharts-point-select {
+    fill: inherit;
+    stroke: inherit;
+}
+.highcharts-pyramid-series .highcharts-point {
+    stroke-linejoin: round;
+    stroke: $background-color;
+}
+.highcharts-pyramid-series .highcharts-point-hover {
+    fill-opacity: 0.75;
+    transition: fill-opacity 50ms;
+}
+.highcharts-pyramid-series .highcharts-point-select {
+    fill: inherit;
+    stroke: inherit;
+}
+.highcharts-solidgauge-series .highcharts-point {
+    stroke-width: 0;
+}
+.highcharts-treemap-series .highcharts-point {
+    stroke-width: 1px;
+    stroke: $neutral-color-10;
+    transition: stroke 250ms, fill 250ms, fill-opacity 250ms;
+}
+.highcharts-treemap-series .highcharts-point-hover {
+    stroke: $neutral-color-40;
+    transition: stroke 25ms, fill 25ms, fill-opacity 25ms;
+}
+
+.highcharts-treemap-series .highcharts-above-level {
+    display: none;
+}
+.highcharts-treemap-series .highcharts-internal-node {
+    fill: none;
+}
+.highcharts-treemap-series .highcharts-internal-node-interactive {
+    fill-opacity: 0.15;
+    cursor: pointer;
+}
+.highcharts-treemap-series .highcharts-internal-node-interactive:hover {
+    fill-opacity: 0.75;
+}
+
+.highcharts-vector-series .highcharts-point {
+    fill: none;
+    stroke-width: 2px;
+}
+
+.highcharts-windbarb-series .highcharts-point {
+    fill: none;
+    stroke-width: 2px;
+ }
+
+/* Dumbbell/lollipop connector */
+.highcharts-lollipop-stem {
+	stroke: $neutral-color-100;
+}
+
+
+/* Legend */
+.highcharts-legend-box {
+    fill: none;
+    stroke-width: 0;
+}
+.highcharts-legend-item > text {
+    fill: $neutral-color-80;
+    font-weight: bold;
+    font-size: $legend-font-size;
+    cursor: pointer;
+    stroke-width: 0;
+}
+.highcharts-legend-item:hover text {
+    fill: $neutral-color-100;
+}
+.highcharts-legend-item-hidden * {
+    fill: $neutral-color-20 !important;
+    stroke: $neutral-color-20 !important;
+    transition: fill 250ms;
+}
+.highcharts-legend-nav-active {
+    fill: $highlight-color-100;
+    cursor: pointer;
+}
+.highcharts-legend-nav-inactive {
+    fill: $neutral-color-20;
+}
+circle.highcharts-legend-nav-active, circle.highcharts-legend-nav-inactive { /* tracker */
+    fill: rgba(192, 192, 192, 0.0001);
+}
+.highcharts-legend-title-box {
+    fill: none;
+    stroke-width: 0;
+}
+
+/* Bubble legend */
+.highcharts-bubble-legend-symbol {
+    stroke-width: 2;
+    fill-opacity: 0.5;
+}
+.highcharts-bubble-legend-connectors {
+    stroke-width: 1;
+}
+.highcharts-bubble-legend-labels {
+    fill: $neutral-color-80;
+}
+
+/* Loading */
+.highcharts-loading {
+    position: absolute;
+    background-color: $background-color;
+    opacity: 0.5;
+    text-align: center;
+    z-index: 10;
+    transition: opacity 250ms;
+}
+.highcharts-loading-hidden {
+    height: 0 !important;
+    opacity: 0;
+    overflow: hidden;
+    transition: opacity 250ms, height 250ms step-end;
+}
+.highcharts-loading-inner {
+    font-weight: bold;
+    position: relative;
+    top: 45%;
+}
+
+/* Plot bands and polar pane backgrounds */
+.highcharts-plot-band, .highcharts-pane {
+    fill: $neutral-color-100;
+    fill-opacity: 0.05;
+}
+.highcharts-plot-line {
+    fill: none;
+    stroke: $neutral-color-40;
+    stroke-width: 1px;
+}
+
+/* Highcharts More and modules */
+.highcharts-boxplot-box {
+    fill: $background-color;
+}
+.highcharts-boxplot-median {
+    stroke-width: 2px;
+}
+.highcharts-bubble-series .highcharts-point {
+    fill-opacity: 0.5;
+}
+.highcharts-errorbar-series .highcharts-point {
+    stroke: $neutral-color-100;
+}
+.highcharts-gauge-series .highcharts-data-label-box {
+    stroke: $neutral-color-20;
+    stroke-width: 1px;
+}
+.highcharts-gauge-series .highcharts-dial {
+    fill: $neutral-color-100;
+    stroke-width: 0;
+}
+.highcharts-polygon-series .highcharts-graph {
+    fill: inherit;
+    stroke-width: 0;
+}
+.highcharts-waterfall-series .highcharts-graph {
+    stroke: $neutral-color-80;
+    stroke-dasharray: 1, 3;
+}
+.highcharts-sankey-series .highcharts-point {
+    stroke-width: 0;
+}
+.highcharts-sankey-series .highcharts-link {
+    transition: fill 250ms, fill-opacity 250ms;
+    fill-opacity: 0.5;
+}
+.highcharts-sankey-series .highcharts-point-hover.highcharts-link {
+    transition: fill 50ms, fill-opacity 50ms;
+    fill-opacity: 1;
+}
+.highcharts-venn-series .highcharts-point {
+    fill-opacity: 0.75;
+    stroke: $neutral-color-20;
+    transition: stroke 250ms, fill-opacity 250ms;
+}
+.highcharts-venn-series .highcharts-point-hover {
+    fill-opacity: 1;
+    stroke: $neutral-color-20;
+}
+
+/* Highstock */
+.highcharts-navigator-mask-outside {
+    fill-opacity: 0;
+}
+.highcharts-navigator-mask-inside {
+    fill: $highlight-color-60; /* navigator.maskFill option */
+    fill-opacity: 0.25;
+    cursor: ew-resize;
+}
+.highcharts-navigator-outline {
+    stroke: $neutral-color-20;
+    fill: none;
+}
+.highcharts-navigator-handle {
+    stroke: $neutral-color-20;
+    fill: $neutral-color-5;
+    cursor: ew-resize;
+}
+.highcharts-navigator-series {
+    fill: $navigator-series-fill;
+    stroke: $navigator-series-border;
+}
+.highcharts-navigator-series .highcharts-graph {
+    stroke-width: 1px;
+}
+.highcharts-navigator-series .highcharts-area {
+    fill-opacity: 0.05;
+}
+.highcharts-navigator-xaxis .highcharts-axis-line {
+    stroke-width: 0;
+}
+.highcharts-navigator-xaxis .highcharts-grid-line {
+    stroke-width: 1px;
+    stroke: $neutral-color-10;
+}
+.highcharts-navigator-xaxis.highcharts-axis-labels {
+    fill: $neutral-color-40;
+}
+.highcharts-navigator-yaxis .highcharts-grid-line {
+    stroke-width: 0;
+}
+.highcharts-scrollbar-thumb {
+    fill: $neutral-color-20;
+    stroke: $neutral-color-20;
+    stroke-width: 1px;
+}
+.highcharts-scrollbar-button {
+    fill: $neutral-color-10;
+    stroke: $neutral-color-20;
+    stroke-width: 1px;
+}
+.highcharts-scrollbar-arrow {
+    fill: $neutral-color-60;
+}
+.highcharts-scrollbar-rifles {
+    stroke: $neutral-color-60;
+    stroke-width: 1px;
+}
+.highcharts-scrollbar-track {
+    fill: $scrollbar-track-background;
+    stroke: $scrollbar-track-border;
+    stroke-width: 1px;
+}
+.highcharts-button {
+    fill: $highcharts-button-background;
+    stroke: $highcharts-button-border;
+    cursor: default;
+    stroke-width: 1px;
+    transition: fill 250ms;
+}
+.highcharts-button text {
+    fill: $highcharts-button-text;
+}
+.highcharts-button-hover {
+    transition: fill 0ms;
+    fill: $highcharts-button-hover-background;
+    stroke: $highcharts-button-hover-border;
+}
+.highcharts-button-hover text {
+    fill: $highcharts-button-hover-text;
+}
+.highcharts-button-pressed {
+    font-weight: bold;
+    fill: $highcharts-button-pressed-background;
+    stroke: $highcharts-button-pressed-border;
+}
+.highcharts-button-pressed text {
+    fill: $highcharts-button-pressed-text;
+    font-weight: bold;
+}
+.highcharts-button-disabled text {
+    fill: $highcharts-button-text;
+}
+.highcharts-range-selector-buttons .highcharts-button {
+    stroke-width: $range-selector-button-border;
+}
+.highcharts-range-label rect {
+    fill: none;
+}
+.highcharts-range-label text {
+    fill: $neutral-color-60;
+}
+.highcharts-range-input rect {
+    fill: none;
+}
+.highcharts-range-input text {
+    fill: $range-selector-input-text;
+}
+.highcharts-range-input {
+    stroke-width:1px;
+    stroke: $range-selector-input-border;
+}
+input.highcharts-range-selector {
+    position: absolute;
+    border: 0;
+    width: 1px; /* Chrome needs a pixel to see it */
+    height: 1px;
+    padding: 0;
+    text-align: center;
+    left: -9em; /* #4798 */
+}
+.highcharts-crosshair-label text {
+    fill: $background-color;
+    font-size: 1.1em;
+}
+.highcharts-crosshair-label .highcharts-label-box {
+    fill: inherit;
+}
+
+
+.highcharts-candlestick-series .highcharts-point {
+    stroke: $neutral-color-100;
+    stroke-width: 1px;
+}
+.highcharts-candlestick-series .highcharts-point-up {
+    fill: $background-color;
+}
+.highcharts-ohlc-series .highcharts-point-hover {
+    stroke-width: 3px;
+}
+.highcharts-flags-series .highcharts-point .highcharts-label-box {
+    stroke: $neutral-color-40;
+    fill: $background-color;
+    transition: fill 250ms;
+}
+.highcharts-flags-series .highcharts-point-hover .highcharts-label-box {
+    stroke: $neutral-color-100;
+    fill: $highlight-color-20;
+}
+.highcharts-flags-series .highcharts-point text {
+    fill: $neutral-color-100;
+    font-size: 0.9em;
+    font-weight: bold;
+}
+
+/* Highmaps */
+.highcharts-map-series .highcharts-point {
+    transition: fill 500ms, fill-opacity 500ms, stroke-width 250ms;
+    stroke: $neutral-color-20;
+}
+.highcharts-map-series .highcharts-point-hover {
+    transition: fill 0ms, fill-opacity 0ms;
+    fill-opacity: 0.5;
+    stroke-width: 2px;
+}
+.highcharts-mapline-series .highcharts-point {
+    fill: none;
+}
+.highcharts-heatmap-series .highcharts-point {
+    stroke-width: 0;
+}
+.highcharts-map-navigation {
+    font-size: 1.3em;
+    font-weight: bold;
+    text-align: center;
+}
+.highcharts-coloraxis {
+    stroke-width: 0;
+}
+.highcharts-coloraxis-marker {
+    fill: $neutral-color-40;
+}
+.highcharts-null-point {
+    fill: $neutral-color-3;
+}
+
+/* 3d charts */
+.highcharts-3d-frame {
+    fill: transparent;
+}
+
+/* Exporting module */
+.highcharts-contextbutton {
+    fill: $context-button-background; /* needed to capture hover */
+    stroke: none;
+    stroke-linecap: round;
+}
+.highcharts-contextbutton:hover {
+    fill: $neutral-color-10;
+    stroke: $neutral-color-10;
+}
+.highcharts-button-symbol {
+    stroke: $neutral-color-60;
+    stroke-width: 3px;
+}
+.highcharts-menu {
+    border: 1px solid $neutral-color-40;
+    background: $background-color;
+    padding: 5px 0;
+    box-shadow: 3px 3px 10px #888;
+}
+.highcharts-menu-item {
+    padding: 0.5em 1em;
+    background: none;
+    color: $neutral-color-80;
+    cursor: pointer;
+    transition: background 250ms, color 250ms;
+}
+.highcharts-menu-item:hover {
+    background: $highlight-color-80;
+    color: $background-color;
+}
+
+/* Drilldown module */
+.highcharts-drilldown-point {
+    cursor: pointer;
+}
+.highcharts-drilldown-data-label text,
+text.highcharts-drilldown-data-label,
+.highcharts-drilldown-axis-label {
+    cursor: pointer;
+    fill: $highlight-color-100;
+    font-weight: bold;
+    text-decoration: underline;
+}
+
+/* No-data module */
+.highcharts-no-data text {
+    font-weight: bold;
+    font-size: 12px;
+    fill: $neutral-color-60;
+}
+
+/* Drag-panes module */
+.highcharts-axis-resizer {
+    cursor: ns-resize;
+    stroke: black;
+    stroke-width: 2px;
+}
+
+/* Bullet type series */
+.highcharts-bullet-target {
+    stroke-width: 0;
+}
+
+/* Lineargauge type series */
+.highcharts-lineargauge-target {
+	stroke-width: 1px;
+	stroke: $neutral-color-80;
+}
+.highcharts-lineargauge-target-line {
+	stroke-width: 1px;
+    stroke: $neutral-color-80;
+}
+
+/* Annotations module */
+.highcharts-annotation-label-box {
+    stroke-width: 1px;
+    stroke: $neutral-color-100;
+    fill: $neutral-color-100;
+    fill-opacity: 0.75;
+}
+.highcharts-annotation-label text {
+    fill: $neutral-color-10;
+}
+
+/* Gantt */
+.highcharts-treegrid-node-collapsed, .highcharts-treegrid-node-expanded {
+    cursor: pointer;
+}
+.highcharts-point-connecting-path {
+    fill: none;
+}
+.highcharts-grid-axis .highcharts-tick {
+    stroke-width: 1px;
+}
+.highcharts-grid-axis .highcharts-axis-line {
+    stroke-width: 1px;
+}

+ 265 - 0
app/public/js/Highstock-8.0.0/code/css/stocktools/gui.css

@@ -0,0 +1,265 @@
+.chart:-webkit-full-screen {
+  width: 100%;
+  height: 100%;
+}
+
+.chart:-moz-full-screen {
+  width: 100%;
+  height: 100%;
+}
+
+.chart:-ms-fullscreen {
+  width: 100%;
+  height: 100%;
+}
+
+.chart:fullscreen {
+  width: 100%;
+  height: 100%;
+}
+
+.chart {
+  width: 100%;
+  float: left;
+  height: 400px;
+  position: relative;
+}
+
+.highcharts-draw-mode {
+  cursor: crosshair;
+}
+
+.highcharts-bindings-wrapper * {
+  box-sizing: content-box;
+}
+
+.highcharts-bindings-wrapper {
+  display: block;
+  width: 40px;
+  height: 100%;
+  position: absolute;
+  z-index: 10;
+}
+
+.highcharts-stocktools-popup {
+  width: 100%;
+}
+
+.highcharts-menu-wrapper {
+  float: left;
+  width: 40px;
+  height: calc(100% - 50px);
+  overflow: hidden;
+  position: absolute;
+  left: 0px;
+  top: 0px;
+  padding: 10px;
+}
+
+.highcharts-bindings-wrapper .highcharts-submenu-wrapper {
+  display: none;
+  position: absolute;
+  z-index: 10;
+  left: 0px;
+  top: 0px;
+  background: #fff;
+  width: 40px;
+}
+
+.highcharts-bindings-wrapper .highcharts-arrow-wrapper {
+  text-align: center;
+  width: 40px;
+  position: absolute;
+  left: 10px;
+  bottom: 10px;
+  font-size: 1.5em;
+}
+
+.highcharts-bindings-wrapper .highcharts-arrow-wrapper > div {
+  cursor: pointer;
+}
+
+.highcharts-bindings-wrapper .highcharts-arrow-down {
+  background-size: cover;
+  /* Safari */
+  -webkit-transform: rotate(90deg);
+  /* Firefox */
+  -moz-transform: rotate(90deg);
+  /* IE */
+  -ms-transform: rotate(90deg);
+  /* Opera */
+  -o-transform: rotate(90deg);
+  /* Internet Explorer */
+  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1);
+  transform: rotate(90deg);
+}
+
+.highcharts-bindings-wrapper .highcharts-arrow-up {
+  background-size: cover;
+  outline: none;
+  display: inline-block;
+  width: 25px;
+  cursor: pointer;
+  -webkit-user-select: none;
+  /* Chrome/Safari */
+  -moz-user-select: none;
+  /* Firefox */
+  -ms-user-select: none;
+  /* IE10+ */
+  /* Rules below not implemented in browsers yet */
+  -o-user-select: none;
+  user-select: none;
+  /* Safari */
+  -webkit-transform: rotate(-90deg);
+  /* Firefox */
+  -moz-transform: rotate(-90deg);
+  /* IE */
+  -ms-transform: rotate(-90deg);
+  /* Opera */
+  -o-transform: rotate(-90deg);
+  /* Internet Explorer */
+  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3);
+  transform: rotate(-90deg);
+}
+
+.highcharts-bindings-wrapper .highcharts-arrow-right {
+  background-repeat: no-repeat;
+  background-position: right bottom;
+  background-size: contain;
+}
+
+.highcharts-bindings-wrapper .highcharts-arrow-left.highcharts-arrow-right {
+  /* Safari */
+  -webkit-transform: rotate(0deg);
+  /* Firefox */
+  -moz-transform: rotate(0deg);
+  /* IE */
+  -ms-transform: rotate(0deg);
+  /* Opera */
+  -o-transform: rotate(0deg);
+  /* Internet Explorer */
+  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2);
+  transform: rotate(0deg);
+}
+
+.highcharts-bindings-wrapper .highcharts-arrow-left {
+  /* Safari */
+  -webkit-transform: rotate(180deg);
+  /* Firefox */
+  -moz-transform: rotate(180deg);
+  /* IE */
+  -ms-transform: rotate(180deg);
+  /* Opera */
+  -o-transform: rotate(180deg);
+  /* Internet Explorer */
+  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2);
+  transform: rotate(180deg);
+}
+
+.highcharts-bindings-wrapper ul {
+  width: 40px;
+  /* 30px spacing for arrows to scroll */
+  margin: 0px;
+  padding: 0px;
+  float: left;
+  transition: margin 250ms;
+}
+
+.highcharts-bindings-wrapper > ul {
+  width: 40px;
+  position: relative;
+}
+
+.highcharts-bindings-wrapper .highcharts-stocktools-toolbar li {
+  list-style: none;
+  margin-bottom: 3px;
+  padding: 0px;
+  clear: both;
+  width: 100%;
+  height: 40px;
+  cursor: pointer;
+  position: relative;
+  background-color: #f7f7f7;
+}
+
+.highcharts-bindings-wrapper .highcharts-stocktools-toolbar li.highcharts-disabled-btn {
+  cursor: default;
+}
+
+.highcharts-bindings-wrapper .highcharts-stocktools-toolbar li.highcharts-disabled-btn > .highcharts-menu-item-btn {
+  opacity: 0.5;
+}
+
+.highcharts-bindings-wrapper .highcharts-stocktools-toolbar li.highcharts-disabled-btn.highcharts-active {
+  background: #f7f7f7;
+}
+
+.highcharts-bindings-wrapper .highcharts-stocktools-toolbar li.highcharts-disabled-btn .highcharts-menu-item-btn:hover {
+  background-color: transparent;
+}
+
+.highcharts-bindings-wrapper li > span.highcharts-menu-item-btn {
+  display: block;
+  float: left;
+  width: 100%;
+  height: 100%;
+  background-repeat: no-repeat;
+  background-position: 50% 50%;
+}
+
+.highcharts-submenu-wrapper li > span.highcharts-menu-item-btn {
+  width: 40px;
+}
+
+.highcharts-bindings-wrapper li > span.highcharts-submenu-item-arrow {
+  float: left;
+  width: 10px;
+  height: 100%;
+  cursor: pointer;
+  position: absolute;
+  bottom: 0px;
+  right: 0px;
+}
+
+.highcharts-bindings-wrapper li.highcharts-separator {
+  height: 15px;
+  background-color: transparent;
+  width: 36px;
+  pointer-events: none;
+}
+
+.highcharts-bindings-wrapper li.highcharts-separator > span.highcharts-menu-item-btn {
+  width: 100%;
+}
+
+.highcharts-bindings-wrapper li.highcharts-active > span.highcharts-menu-item-btn,
+.highcharts-bindings-wrapper li > span.highcharts-menu-item-btn:hover,
+.highcharts-bindings-wrapper .highcharts-arrow-wrapper > div:hover,
+.highcharts-bindings-wrapper li.highcharts-active,
+.highcharts-toggle-toolbar:hover {
+  background-color: #e6ebf5;
+  transition: background-color 100ms;
+}
+
+.highcharts-toggle-toolbar {
+  position: absolute;
+  cursor: pointer;
+  width: 10px;
+  height: 10px;
+  background-color: #f7f7f7;
+  background-size: cover;
+}
+
+.highcharts-hide {
+  display: none;
+}
+
+.highcharts-bindings-wrapper li:hover, .highcharts-submenu-item-arrow:hover {
+  background-color: #e6ebf5;
+}
+
+.highcharts-bindings-wrapper .highcharts-arrow-down, .highcharts-bindings-wrapper .highcharts-arrow-up {
+  width: 50%;
+  height: 20px;
+  float: left;
+}

+ 265 - 0
app/public/js/Highstock-8.0.0/code/css/stocktools/gui.scss

@@ -0,0 +1,265 @@
+// Colors for buttons.
+$button-background-color: #f7f7f7;
+$button-hover-color: #e6ebf5;
+
+.chart:-webkit-full-screen {
+  width: 100%;
+  height: 100%;
+}
+
+.chart:-moz-full-screen {
+  width: 100%;
+  height: 100%;
+}
+
+.chart:-ms-fullscreen {
+  width: 100%;
+  height: 100%;
+}
+
+.chart:fullscreen {
+  width: 100%;
+  height: 100%;
+}
+
+.chart {
+  width: 100%;
+  float: left;
+  height: 400px;
+  position: relative;
+}
+
+.highcharts-draw-mode { cursor: crosshair; }
+
+.highcharts-bindings-wrapper * {
+  box-sizing: content-box;
+}
+
+.highcharts-bindings-wrapper {
+  display: block;
+  width: 40px;
+  height: 100%;
+  position: absolute;
+  z-index: 10;
+}
+
+.highcharts-stocktools-popup {
+  width: 100%;
+}
+
+.highcharts-menu-wrapper {
+  float: left;
+  width: 40px;
+  height: calc(100% - 50px);
+  overflow: hidden;
+  position: absolute;
+  left: 0px;
+  top: 0px;
+  padding: 10px;
+}
+
+.highcharts-bindings-wrapper .highcharts-submenu-wrapper {
+  display: none;
+  position: absolute;
+  z-index: 10;
+  left: 0px;
+  top: 0px;
+  background: #fff;
+  width: 40px;
+}
+
+.highcharts-bindings-wrapper .highcharts-arrow-wrapper {
+  text-align: center;
+  width: 40px;
+  position: absolute;
+  left: 10px;
+  bottom: 10px;
+  font-size: 1.5em;
+}
+
+.highcharts-bindings-wrapper .highcharts-arrow-wrapper > div {
+  cursor: pointer;
+}
+
+.highcharts-bindings-wrapper .highcharts-arrow-down {
+  background-size: cover;
+  /* Safari */
+  -webkit-transform: rotate(90deg);
+  /* Firefox */
+  -moz-transform: rotate(90deg);
+  /* IE */
+  -ms-transform: rotate(90deg);
+  /* Opera */
+  -o-transform: rotate(90deg);
+  /* Internet Explorer */
+  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1);
+  transform: rotate(90deg);
+}
+.highcharts-bindings-wrapper .highcharts-arrow-up {
+  background-size: cover;
+  outline: none;
+  display: inline-block;
+  width: 25px;
+  cursor: pointer;
+  -webkit-user-select: none;
+  /* Chrome/Safari */
+  -moz-user-select: none;
+  /* Firefox */
+  -ms-user-select: none;
+  /* IE10+ */
+  /* Rules below not implemented in browsers yet */
+  -o-user-select: none;
+  user-select: none;
+  /* Safari */
+  -webkit-transform: rotate(-90deg);
+  /* Firefox */
+  -moz-transform: rotate(-90deg);
+  /* IE */
+  -ms-transform: rotate(-90deg);
+  /* Opera */
+  -o-transform: rotate(-90deg);
+  /* Internet Explorer */
+  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3);
+  transform: rotate(-90deg);
+}
+
+.highcharts-bindings-wrapper .highcharts-arrow-right {
+  background-repeat: no-repeat;
+  background-position: right bottom;
+  background-size: contain;
+}
+
+.highcharts-bindings-wrapper .highcharts-arrow-left.highcharts-arrow-right {
+   /* Safari */
+  -webkit-transform: rotate(0deg);
+  /* Firefox */
+  -moz-transform: rotate(0deg);
+  /* IE */
+  -ms-transform: rotate(0deg);
+  /* Opera */
+  -o-transform: rotate(0deg);
+  /* Internet Explorer */
+  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2);
+  transform: rotate(0deg);
+}
+
+.highcharts-bindings-wrapper .highcharts-arrow-left {
+  /* Safari */
+  -webkit-transform: rotate(180deg);
+  /* Firefox */
+  -moz-transform: rotate(180deg);
+  /* IE */
+  -ms-transform: rotate(180deg);
+  /* Opera */
+  -o-transform: rotate(180deg);
+  /* Internet Explorer */
+  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2);
+  transform: rotate(180deg);
+}
+
+.highcharts-bindings-wrapper ul {
+  width: 40px;
+  /* 30px spacing for arrows to scroll */
+  margin: 0px;
+  padding: 0px;
+  float: left;
+  transition: margin 250ms;
+}
+
+.highcharts-bindings-wrapper>ul {
+  width: 40px;
+  position: relative;
+}
+
+.highcharts-bindings-wrapper .highcharts-stocktools-toolbar li {
+  list-style: none;
+  margin-bottom: 3px;
+  padding: 0px;
+  clear: both;
+  width: 100%;
+  height: 40px;
+  cursor: pointer;
+  position: relative;
+  background-color: $button-background-color;
+}
+.highcharts-bindings-wrapper .highcharts-stocktools-toolbar li.highcharts-disabled-btn {
+  cursor: default;
+}
+
+.highcharts-bindings-wrapper .highcharts-stocktools-toolbar li.highcharts-disabled-btn > .highcharts-menu-item-btn {
+  opacity: 0.5;
+}
+
+.highcharts-bindings-wrapper .highcharts-stocktools-toolbar li.highcharts-disabled-btn.highcharts-active {
+  background: $button-background-color;
+}
+
+.highcharts-bindings-wrapper .highcharts-stocktools-toolbar li.highcharts-disabled-btn .highcharts-menu-item-btn:hover {
+  background-color: transparent;
+}
+
+.highcharts-bindings-wrapper li>span.highcharts-menu-item-btn {
+  display: block;
+  float: left;
+  width: 100%;
+  height: 100%;
+  background-repeat: no-repeat;
+  background-position: 50% 50%;
+}
+
+.highcharts-submenu-wrapper li>span.highcharts-menu-item-btn {
+  width: 40px;
+}
+
+.highcharts-bindings-wrapper li>span.highcharts-submenu-item-arrow {
+  float: left;
+  width: 10px;
+  height: 100%;
+  cursor: pointer;
+  position: absolute;
+  bottom: 0px;
+  right: 0px;
+}
+
+.highcharts-bindings-wrapper li.highcharts-separator {
+  height: 15px;
+  background-color: transparent;
+  width: 36px;
+  pointer-events: none;
+}
+
+.highcharts-bindings-wrapper li.highcharts-separator>span.highcharts-menu-item-btn {
+  width: 100%;
+}
+
+.highcharts-bindings-wrapper li.highcharts-active>span.highcharts-menu-item-btn,
+.highcharts-bindings-wrapper li>span.highcharts-menu-item-btn:hover,
+.highcharts-bindings-wrapper .highcharts-arrow-wrapper > div:hover,
+.highcharts-bindings-wrapper li.highcharts-active,
+.highcharts-toggle-toolbar:hover {
+  background-color: $button-hover-color;
+  transition: background-color 100ms;
+}
+
+.highcharts-toggle-toolbar {
+  position: absolute;
+  cursor: pointer;
+  width: 10px;
+  height: 10px;
+  background-color: $button-background-color;
+  background-size: cover;
+}
+
+.highcharts-hide {
+  display: none;
+}
+
+.highcharts-bindings-wrapper li:hover, .highcharts-submenu-item-arrow:hover {
+  background-color: $button-hover-color;
+}
+
+.highcharts-bindings-wrapper .highcharts-arrow-down, .highcharts-bindings-wrapper .highcharts-arrow-up {
+  width: 50%;
+  height: 20px;
+  float: left;
+}

+ 987 - 0
app/public/js/Highstock-8.0.0/code/css/themes/dark-unica.css

@@ -0,0 +1,987 @@
+@import 'https://fonts.googleapis.com/css?family=Unica+One';
+.highcharts-title, .highcharts-subtitle {
+  text-transform: uppercase;
+}
+
+.highcharts-tooltip text {
+  fill: #F0F0F0;
+}
+
+.highcharts-range-selector-buttons text {
+  fill: silver;
+}
+
+.highcharts-yaxis-grid {
+  stroke-width: 1px;
+}
+
+.highcharts-axis-labels, .highcharts-axis-title {
+  fill: #E0E0E3;
+}
+
+.highcharts-navigator .highcharts-navigator-handle {
+  fill: #666;
+  stroke: #aaa;
+}
+
+.highcharts-navigator .highcharts-navigator-outline {
+  stroke: #CCC;
+}
+
+.highcharts-navigator .highcharts-navigator-xaxis .highcharts-grid-line {
+  stroke: #505053;
+}
+
+.highcharts-scrollbar .highcharts-scrollbar-rifles {
+  stroke: #fff;
+}
+
+.highcharts-scrollbar .highcharts-scrollbar-button {
+  stroke: #606063;
+  fill: #606063;
+}
+
+.highcharts-scrollbar .highcharts-scrollbar-arrow {
+  fill: #CCC;
+}
+
+.highcharts-scrollbar .highcharts-scrollbar-thumb {
+  fill: #808083;
+  stroke: #808083;
+}
+
+.highcharts-contextbutton .highcharts-button-symbol {
+  stroke: #DDDDDD;
+}
+
+/**
+ * @license Highcharts
+ *
+ * (c) 2009-2016 Torstein Honsi
+ *
+ * License: www.highcharts.com/license
+ */
+.highcharts-container {
+  position: relative;
+  overflow: hidden;
+  width: 100%;
+  height: 100%;
+  text-align: left;
+  line-height: normal;
+  z-index: 0;
+  /* #1072 */
+  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+  font-family: "Unica One", Arial, Helvetica, sans-serif;
+  font-size: 12px;
+}
+
+.highcharts-root {
+  display: block;
+}
+
+.highcharts-root text {
+  stroke-width: 0;
+}
+
+.highcharts-strong {
+  font-weight: bold;
+}
+
+.highcharts-emphasized {
+  font-style: italic;
+}
+
+.highcharts-anchor {
+  cursor: pointer;
+}
+
+.highcharts-background {
+  fill: #2a2a2b;
+}
+
+.highcharts-plot-border, .highcharts-plot-background {
+  fill: none;
+}
+
+.highcharts-label-box {
+  fill: none;
+}
+
+.highcharts-button-box {
+  fill: inherit;
+}
+
+.highcharts-tracker-line {
+  stroke-linejoin: round;
+  stroke: rgba(192, 192, 192, 0.0001);
+  stroke-width: 22;
+  fill: none;
+}
+
+.highcharts-tracker-area {
+  fill: rgba(192, 192, 192, 0.0001);
+  stroke-width: 0;
+}
+
+/* Titles */
+.highcharts-title {
+  fill: #E0E0E3;
+  font-size: 20px;
+}
+
+.highcharts-subtitle {
+  fill: #E0E0E3;
+}
+
+/* Axes */
+.highcharts-axis-line {
+  fill: none;
+  stroke: #707073;
+}
+
+.highcharts-yaxis .highcharts-axis-line {
+  stroke-width: 0;
+}
+
+.highcharts-axis-title {
+  fill: #E0E0E3;
+}
+
+.highcharts-axis-labels {
+  fill: #E0E0E3;
+  cursor: default;
+  font-size: 0.9em;
+}
+
+.highcharts-grid-line {
+  fill: none;
+  stroke: #707073;
+}
+
+.highcharts-xaxis-grid .highcharts-grid-line {
+  stroke-width: 0px;
+}
+
+.highcharts-tick {
+  stroke: #707073;
+}
+
+.highcharts-yaxis .highcharts-tick {
+  stroke-width: 0;
+}
+
+.highcharts-minor-grid-line {
+  stroke: #505053;
+}
+
+.highcharts-crosshair-thin {
+  stroke-width: 1px;
+  stroke: #606063;
+}
+
+.highcharts-crosshair-category {
+  stroke: #707073;
+  stroke-opacity: 0.25;
+}
+
+/* Credits */
+.highcharts-credits {
+  cursor: pointer;
+  fill: #666;
+  font-size: 0.7em;
+  transition: fill 250ms, font-size 250ms;
+}
+
+.highcharts-credits:hover {
+  fill: black;
+  font-size: 1em;
+}
+
+/* Tooltip */
+.highcharts-tooltip {
+  cursor: default;
+  pointer-events: none;
+  white-space: nowrap;
+  transition: stroke 150ms;
+}
+
+.highcharts-tooltip text {
+  fill: #E0E0E3;
+}
+
+.highcharts-tooltip .highcharts-header {
+  font-size: 0.85em;
+}
+
+.highcharts-tooltip-box {
+  stroke-width: 1px;
+  fill: rgba(0, 0, 0, 0.85);
+  fill-opacity: 0.85;
+}
+
+.highcharts-tooltip-box .highcharts-label-box {
+  fill: rgba(0, 0, 0, 0.85);
+  fill-opacity: 0.85;
+}
+
+div.highcharts-tooltip {
+  filter: none;
+}
+
+.highcharts-selection-marker {
+  fill: #335cad;
+  fill-opacity: 0.25;
+}
+
+.highcharts-graph {
+  fill: none;
+  stroke-width: 2px;
+  stroke-linecap: round;
+  stroke-linejoin: round;
+}
+
+.highcharts-state-hover .highcharts-graph {
+  stroke-width: 3;
+}
+
+.highcharts-point-inactive {
+  opacity: 0.2;
+  transition: opacity 50ms;
+  /* quick in */
+}
+
+.highcharts-series-inactive {
+  opacity: 0.2;
+  transition: opacity 50ms;
+  /* quick in */
+}
+
+.highcharts-state-hover path {
+  transition: stroke-width 50ms;
+  /* quick in */
+}
+
+.highcharts-state-normal path {
+  transition: stroke-width 250ms;
+  /* slow out */
+}
+
+/* Legend hover affects points and series */
+g.highcharts-series,
+.highcharts-point,
+.highcharts-markers,
+.highcharts-data-labels {
+  transition: opacity 250ms;
+}
+
+.highcharts-legend-series-active g.highcharts-series:not(.highcharts-series-hover),
+.highcharts-legend-point-active .highcharts-point:not(.highcharts-point-hover),
+.highcharts-legend-series-active .highcharts-markers:not(.highcharts-series-hover),
+.highcharts-legend-series-active .highcharts-data-labels:not(.highcharts-series-hover) {
+  opacity: 0.2;
+}
+
+/* Series options */
+/* Default colors */
+.highcharts-color-0 {
+  fill: #2b908f;
+  stroke: #2b908f;
+}
+
+.highcharts-color-1 {
+  fill: #90ee7e;
+  stroke: #90ee7e;
+}
+
+.highcharts-color-2 {
+  fill: #f45b5b;
+  stroke: #f45b5b;
+}
+
+.highcharts-color-3 {
+  fill: #7798BF;
+  stroke: #7798BF;
+}
+
+.highcharts-color-4 {
+  fill: #aaeeee;
+  stroke: #aaeeee;
+}
+
+.highcharts-color-5 {
+  fill: #ff0066;
+  stroke: #ff0066;
+}
+
+.highcharts-color-6 {
+  fill: #eeaaee;
+  stroke: #eeaaee;
+}
+
+.highcharts-color-7 {
+  fill: #55BF3B;
+  stroke: #55BF3B;
+}
+
+.highcharts-color-8 {
+  fill: #DF5353;
+  stroke: #DF5353;
+}
+
+.highcharts-color-9 {
+  fill: #7798BF;
+  stroke: #7798BF;
+}
+
+.highcharts-color-10 {
+  fill: #aaeeee;
+  stroke: #aaeeee;
+}
+
+.highcharts-area {
+  fill-opacity: 0.75;
+  stroke-width: 0;
+}
+
+.highcharts-markers {
+  stroke-width: 1px;
+  stroke: #2a2a2b;
+}
+
+.highcharts-point {
+  stroke-width: 1px;
+}
+
+.highcharts-dense-data .highcharts-point {
+  stroke-width: 0;
+}
+
+.highcharts-data-label {
+  font-size: 0.9em;
+  font-weight: bold;
+}
+
+.highcharts-data-label-box {
+  fill: none;
+  stroke-width: 0;
+}
+
+.highcharts-data-label text, text.highcharts-data-label {
+  fill: #B0B0B3;
+}
+
+.highcharts-data-label-connector {
+  fill: none;
+}
+
+.highcharts-halo {
+  fill-opacity: 0.25;
+  stroke-width: 0;
+}
+
+.highcharts-series:not(.highcharts-pie-series) .highcharts-point-select,
+.highcharts-markers .highcharts-point-select {
+  fill: #606063;
+  stroke: #fff;
+}
+
+.highcharts-column-series rect.highcharts-point {
+  stroke: #2a2a2b;
+}
+
+.highcharts-column-series .highcharts-point {
+  transition: fill-opacity 250ms;
+}
+
+.highcharts-column-series .highcharts-point-hover {
+  fill-opacity: 0.75;
+  transition: fill-opacity 50ms;
+}
+
+.highcharts-pie-series .highcharts-point {
+  stroke-linejoin: round;
+  stroke: #2a2a2b;
+}
+
+.highcharts-pie-series .highcharts-point-hover {
+  fill-opacity: 0.75;
+  transition: fill-opacity 50ms;
+}
+
+.highcharts-funnel-series .highcharts-point {
+  stroke-linejoin: round;
+  stroke: #2a2a2b;
+}
+
+.highcharts-funnel-series .highcharts-point-hover {
+  fill-opacity: 0.75;
+  transition: fill-opacity 50ms;
+}
+
+.highcharts-funnel-series .highcharts-point-select {
+  fill: inherit;
+  stroke: inherit;
+}
+
+.highcharts-pyramid-series .highcharts-point {
+  stroke-linejoin: round;
+  stroke: #2a2a2b;
+}
+
+.highcharts-pyramid-series .highcharts-point-hover {
+  fill-opacity: 0.75;
+  transition: fill-opacity 50ms;
+}
+
+.highcharts-pyramid-series .highcharts-point-select {
+  fill: inherit;
+  stroke: inherit;
+}
+
+.highcharts-solidgauge-series .highcharts-point {
+  stroke-width: 0;
+}
+
+.highcharts-treemap-series .highcharts-point {
+  stroke-width: 1px;
+  stroke: #707073;
+  transition: stroke 250ms, fill 250ms, fill-opacity 250ms;
+}
+
+.highcharts-treemap-series .highcharts-point-hover {
+  stroke: #666;
+  transition: stroke 25ms, fill 25ms, fill-opacity 25ms;
+}
+
+.highcharts-treemap-series .highcharts-above-level {
+  display: none;
+}
+
+.highcharts-treemap-series .highcharts-internal-node {
+  fill: none;
+}
+
+.highcharts-treemap-series .highcharts-internal-node-interactive {
+  fill-opacity: 0.15;
+  cursor: pointer;
+}
+
+.highcharts-treemap-series .highcharts-internal-node-interactive:hover {
+  fill-opacity: 0.75;
+}
+
+.highcharts-vector-series .highcharts-point {
+  fill: none;
+  stroke-width: 2px;
+}
+
+.highcharts-windbarb-series .highcharts-point {
+  fill: none;
+  stroke-width: 2px;
+}
+
+/* Dumbbell/lollipop connector */
+.highcharts-lollipop-stem {
+  stroke: #fff;
+}
+
+/* Legend */
+.highcharts-legend-box {
+  fill: none;
+  stroke-width: 0;
+}
+
+.highcharts-legend-item > text {
+  fill: #E0E0E3;
+  font-weight: bold;
+  font-size: 1em;
+  cursor: pointer;
+  stroke-width: 0;
+}
+
+.highcharts-legend-item:hover text {
+  fill: #fff;
+}
+
+.highcharts-legend-item-hidden * {
+  fill: #606063 !important;
+  stroke: #606063 !important;
+  transition: fill 250ms;
+}
+
+.highcharts-legend-nav-active {
+  fill: #F0F0F3;
+  cursor: pointer;
+}
+
+.highcharts-legend-nav-inactive {
+  fill: #606063;
+}
+
+circle.highcharts-legend-nav-active, circle.highcharts-legend-nav-inactive {
+  /* tracker */
+  fill: rgba(192, 192, 192, 0.0001);
+}
+
+.highcharts-legend-title-box {
+  fill: none;
+  stroke-width: 0;
+}
+
+/* Bubble legend */
+.highcharts-bubble-legend-symbol {
+  stroke-width: 2;
+  fill-opacity: 0.5;
+}
+
+.highcharts-bubble-legend-connectors {
+  stroke-width: 1;
+}
+
+.highcharts-bubble-legend-labels {
+  fill: #E0E0E3;
+}
+
+/* Loading */
+.highcharts-loading {
+  position: absolute;
+  background-color: #2a2a2b;
+  opacity: 0.5;
+  text-align: center;
+  z-index: 10;
+  transition: opacity 250ms;
+}
+
+.highcharts-loading-hidden {
+  height: 0 !important;
+  opacity: 0;
+  overflow: hidden;
+  transition: opacity 250ms, height 250ms step-end;
+}
+
+.highcharts-loading-inner {
+  font-weight: bold;
+  position: relative;
+  top: 45%;
+}
+
+/* Plot bands and polar pane backgrounds */
+.highcharts-plot-band, .highcharts-pane {
+  fill: #fff;
+  fill-opacity: 0.05;
+}
+
+.highcharts-plot-line {
+  fill: none;
+  stroke: #666;
+  stroke-width: 1px;
+}
+
+/* Highcharts More and modules */
+.highcharts-boxplot-box {
+  fill: #2a2a2b;
+}
+
+.highcharts-boxplot-median {
+  stroke-width: 2px;
+}
+
+.highcharts-bubble-series .highcharts-point {
+  fill-opacity: 0.5;
+}
+
+.highcharts-errorbar-series .highcharts-point {
+  stroke: #fff;
+}
+
+.highcharts-gauge-series .highcharts-data-label-box {
+  stroke: #606063;
+  stroke-width: 1px;
+}
+
+.highcharts-gauge-series .highcharts-dial {
+  fill: #fff;
+  stroke-width: 0;
+}
+
+.highcharts-polygon-series .highcharts-graph {
+  fill: inherit;
+  stroke-width: 0;
+}
+
+.highcharts-waterfall-series .highcharts-graph {
+  stroke: #E0E0E3;
+  stroke-dasharray: 1, 3;
+}
+
+.highcharts-sankey-series .highcharts-point {
+  stroke-width: 0;
+}
+
+.highcharts-sankey-series .highcharts-link {
+  transition: fill 250ms, fill-opacity 250ms;
+  fill-opacity: 0.5;
+}
+
+.highcharts-sankey-series .highcharts-point-hover.highcharts-link {
+  transition: fill 50ms, fill-opacity 50ms;
+  fill-opacity: 1;
+}
+
+.highcharts-venn-series .highcharts-point {
+  fill-opacity: 0.75;
+  stroke: #606063;
+  transition: stroke 250ms, fill-opacity 250ms;
+}
+
+.highcharts-venn-series .highcharts-point-hover {
+  fill-opacity: 1;
+  stroke: #606063;
+}
+
+/* Highstock */
+.highcharts-navigator-mask-outside {
+  fill-opacity: 0;
+}
+
+.highcharts-navigator-mask-inside {
+  fill: rgba(255, 255, 255, 0.1);
+  /* navigator.maskFill option */
+  fill-opacity: 0.25;
+  cursor: ew-resize;
+}
+
+.highcharts-navigator-outline {
+  stroke: #606063;
+  fill: none;
+}
+
+.highcharts-navigator-handle {
+  stroke: #606063;
+  fill: #505053;
+  cursor: ew-resize;
+}
+
+.highcharts-navigator-series {
+  fill: #7798BF;
+  stroke: #A6C7ED;
+}
+
+.highcharts-navigator-series .highcharts-graph {
+  stroke-width: 1px;
+}
+
+.highcharts-navigator-series .highcharts-area {
+  fill-opacity: 0.05;
+}
+
+.highcharts-navigator-xaxis .highcharts-axis-line {
+  stroke-width: 0;
+}
+
+.highcharts-navigator-xaxis .highcharts-grid-line {
+  stroke-width: 1px;
+  stroke: #707073;
+}
+
+.highcharts-navigator-xaxis.highcharts-axis-labels {
+  fill: #666;
+}
+
+.highcharts-navigator-yaxis .highcharts-grid-line {
+  stroke-width: 0;
+}
+
+.highcharts-scrollbar-thumb {
+  fill: #606063;
+  stroke: #606063;
+  stroke-width: 1px;
+}
+
+.highcharts-scrollbar-button {
+  fill: #707073;
+  stroke: #606063;
+  stroke-width: 1px;
+}
+
+.highcharts-scrollbar-arrow {
+  fill: #E0E0E3;
+}
+
+.highcharts-scrollbar-rifles {
+  stroke: #E0E0E3;
+  stroke-width: 1px;
+}
+
+.highcharts-scrollbar-track {
+  fill: #404043;
+  stroke: #404043;
+  stroke-width: 1px;
+}
+
+.highcharts-button {
+  fill: #505053;
+  stroke: #606063;
+  cursor: default;
+  stroke-width: 1px;
+  transition: fill 250ms;
+}
+
+.highcharts-button text {
+  fill: #ccc;
+}
+
+.highcharts-button-hover {
+  transition: fill 0ms;
+  fill: #707073;
+  stroke: #606063;
+}
+
+.highcharts-button-hover text {
+  fill: #fff;
+}
+
+.highcharts-button-pressed {
+  font-weight: bold;
+  fill: #000003;
+  stroke: #606063;
+}
+
+.highcharts-button-pressed text {
+  fill: #fff;
+  font-weight: bold;
+}
+
+.highcharts-button-disabled text {
+  fill: #ccc;
+}
+
+.highcharts-range-selector-buttons .highcharts-button {
+  stroke-width: 0px;
+}
+
+.highcharts-range-label rect {
+  fill: none;
+}
+
+.highcharts-range-label text {
+  fill: #E0E0E3;
+}
+
+.highcharts-range-input rect {
+  fill: none;
+}
+
+.highcharts-range-input text {
+  fill: silver;
+}
+
+.highcharts-range-input {
+  stroke-width: 1px;
+  stroke: #505053;
+}
+
+input.highcharts-range-selector {
+  position: absolute;
+  border: 0;
+  width: 1px;
+  /* Chrome needs a pixel to see it */
+  height: 1px;
+  padding: 0;
+  text-align: center;
+  left: -9em;
+  /* #4798 */
+}
+
+.highcharts-crosshair-label text {
+  fill: #2a2a2b;
+  font-size: 1.1em;
+}
+
+.highcharts-crosshair-label .highcharts-label-box {
+  fill: inherit;
+}
+
+.highcharts-candlestick-series .highcharts-point {
+  stroke: #fff;
+  stroke-width: 1px;
+}
+
+.highcharts-candlestick-series .highcharts-point-up {
+  fill: #2a2a2b;
+}
+
+.highcharts-ohlc-series .highcharts-point-hover {
+  stroke-width: 3px;
+}
+
+.highcharts-flags-series .highcharts-point .highcharts-label-box {
+  stroke: #666;
+  fill: #2a2a2b;
+  transition: fill 250ms;
+}
+
+.highcharts-flags-series .highcharts-point-hover .highcharts-label-box {
+  stroke: #fff;
+  fill: #707073;
+}
+
+.highcharts-flags-series .highcharts-point text {
+  fill: #fff;
+  font-size: 0.9em;
+  font-weight: bold;
+}
+
+/* Highmaps */
+.highcharts-map-series .highcharts-point {
+  transition: fill 500ms, fill-opacity 500ms, stroke-width 250ms;
+  stroke: #606063;
+}
+
+.highcharts-map-series .highcharts-point-hover {
+  transition: fill 0ms, fill-opacity 0ms;
+  fill-opacity: 0.5;
+  stroke-width: 2px;
+}
+
+.highcharts-mapline-series .highcharts-point {
+  fill: none;
+}
+
+.highcharts-heatmap-series .highcharts-point {
+  stroke-width: 0;
+}
+
+.highcharts-map-navigation {
+  font-size: 1.3em;
+  font-weight: bold;
+  text-align: center;
+}
+
+.highcharts-coloraxis {
+  stroke-width: 0;
+}
+
+.highcharts-coloraxis-marker {
+  fill: #666;
+}
+
+.highcharts-null-point {
+  fill: #f7f7f7;
+}
+
+/* 3d charts */
+.highcharts-3d-frame {
+  fill: transparent;
+}
+
+/* Exporting module */
+.highcharts-contextbutton {
+  fill: #505053;
+  /* needed to capture hover */
+  stroke: none;
+  stroke-linecap: round;
+}
+
+.highcharts-contextbutton:hover {
+  fill: #707073;
+  stroke: #707073;
+}
+
+.highcharts-button-symbol {
+  stroke: #E0E0E3;
+  stroke-width: 3px;
+}
+
+.highcharts-menu {
+  border: 1px solid #666;
+  background: #2a2a2b;
+  padding: 5px 0;
+  box-shadow: 3px 3px 10px #888;
+}
+
+.highcharts-menu-item {
+  padding: 0.5em 1em;
+  background: none;
+  color: #E0E0E3;
+  cursor: pointer;
+  transition: background 250ms, color 250ms;
+}
+
+.highcharts-menu-item:hover {
+  background: #335cad;
+  color: #2a2a2b;
+}
+
+/* Drilldown module */
+.highcharts-drilldown-point {
+  cursor: pointer;
+}
+
+.highcharts-drilldown-data-label text,
+text.highcharts-drilldown-data-label,
+.highcharts-drilldown-axis-label {
+  cursor: pointer;
+  fill: #F0F0F3;
+  font-weight: bold;
+  text-decoration: underline;
+}
+
+/* No-data module */
+.highcharts-no-data text {
+  font-weight: bold;
+  font-size: 12px;
+  fill: #E0E0E3;
+}
+
+/* Drag-panes module */
+.highcharts-axis-resizer {
+  cursor: ns-resize;
+  stroke: black;
+  stroke-width: 2px;
+}
+
+/* Bullet type series */
+.highcharts-bullet-target {
+  stroke-width: 0;
+}
+
+/* Lineargauge type series */
+.highcharts-lineargauge-target {
+  stroke-width: 1px;
+  stroke: #E0E0E3;
+}
+
+.highcharts-lineargauge-target-line {
+  stroke-width: 1px;
+  stroke: #E0E0E3;
+}
+
+/* Annotations module */
+.highcharts-annotation-label-box {
+  stroke-width: 1px;
+  stroke: #fff;
+  fill: #fff;
+  fill-opacity: 0.75;
+}
+
+.highcharts-annotation-label text {
+  fill: #707073;
+}
+
+/* Gantt */
+.highcharts-treegrid-node-collapsed, .highcharts-treegrid-node-expanded {
+  cursor: pointer;
+}
+
+.highcharts-point-connecting-path {
+  fill: none;
+}
+
+.highcharts-grid-axis .highcharts-tick {
+  stroke-width: 1px;
+}
+
+.highcharts-grid-axis .highcharts-axis-line {
+  stroke-width: 1px;
+}

+ 122 - 0
app/public/js/Highstock-8.0.0/code/css/themes/dark-unica.scss

@@ -0,0 +1,122 @@
+// Global font
+@import 'https://fonts.googleapis.com/css?family=Unica+One';
+
+// Chart background, point stroke for markers and columns etc
+$background-color: #2a2a2b;
+
+// Colors for data series and points.
+$colors: #2b908f #90ee7e #f45b5b #7798BF #aaeeee #ff0066 #eeaaee #55BF3B #DF5353 #7798BF #aaeeee;
+
+// Neutral colors
+$neutral-color-100: #fff;
+$neutral-color-80: #E0E0E3;
+$neutral-color-60: #E0E0E3;
+$neutral-color-40: #666;
+$neutral-color-20: #606063;
+$neutral-color-10: #707073;
+$neutral-color-5: #505053;
+
+// Colored, shades
+$highlight-color-100: #F0F0F3;
+$highlight-color-60: rgba(255,255,255,0.1);
+$highlight-color-20: $neutral-color-10;
+
+// Data-labels
+$data-label-color: #B0B0B3;
+
+// Fonts
+$font-family: 'Unica One', Arial, Helvetica, sans-serif;
+$title-font-size: 20px;
+
+// Tooltip
+$tooltip-background: rgba(0, 0, 0, 0.85);
+
+// Range-selector
+$range-selector-input-text: silver;
+$range-selector-input-border: $neutral-color-5;
+
+// Buttons
+$highcharts-button-background: $neutral-color-5;
+$highcharts-button-text:  #ccc;
+
+$highcharts-button-pressed-background: #000003;
+$highcharts-button-pressed-text:  $neutral-color-100;
+
+$highcharts-button-hover-background: $neutral-color-10;
+$highcharts-button-hover-text:  $neutral-color-100;
+
+$context-button-background: $neutral-color-5;
+
+// Navigator
+$navigator-series-fill: #7798BF;
+$navigator-series-border: #A6C7ED;
+
+// Navigator
+$scrollbar-track-background: #404043;
+$scrollbar-track-border: #404043;
+
+// Titles
+.highcharts-title, .highcharts-subtitle {
+	text-transform: uppercase;
+}
+
+// Tooltip
+.highcharts-tooltip text { 
+	fill: #F0F0F0
+}
+
+// Range-selector
+.highcharts-range-selector-buttons text {
+	fill: silver;
+}
+
+// Axes
+.highcharts-yaxis-grid  {
+	stroke-width: 1px;
+}
+
+.highcharts-axis-labels, .highcharts-axis-title {
+	fill: #E0E0E3;
+}
+
+// Navigator
+.highcharts-navigator .highcharts-navigator-handle {
+  fill: $neutral-color-40;
+  stroke: #aaa;
+}
+
+.highcharts-navigator .highcharts-navigator-outline {
+  stroke: #CCC;
+}
+
+.highcharts-navigator .highcharts-navigator-xaxis .highcharts-grid-line {
+  stroke: $neutral-color-5;
+} 
+
+// Scrollbar
+.highcharts-scrollbar .highcharts-scrollbar-rifles {
+  stroke: $neutral-color-100;
+}
+
+.highcharts-scrollbar .highcharts-scrollbar-button { 
+  stroke: #606063;
+  fill: #606063;
+}
+
+.highcharts-scrollbar .highcharts-scrollbar-arrow { 
+  fill: #CCC;
+}
+
+.highcharts-scrollbar .highcharts-scrollbar-thumb { 
+   fill: #808083;
+   stroke: #808083;
+}
+
+// Navigation
+.highcharts-contextbutton .highcharts-button-symbol { 
+   stroke: #DDDDDD;
+}
+
+@import '../highcharts';
+
+

+ 940 - 0
app/public/js/Highstock-8.0.0/code/css/themes/grid-light.css

@@ -0,0 +1,940 @@
+@import 'https://fonts.googleapis.com/css?family=Dosis:400,600';
+.highcharts-title, .highcharts-subtitle, .highcharts-yaxis .highcharts-axis-title {
+  text-transform: uppercase;
+}
+
+.highcharts-title {
+  font-weight: bold;
+}
+
+/**
+ * @license Highcharts
+ *
+ * (c) 2009-2016 Torstein Honsi
+ *
+ * License: www.highcharts.com/license
+ */
+.highcharts-container {
+  position: relative;
+  overflow: hidden;
+  width: 100%;
+  height: 100%;
+  text-align: left;
+  line-height: normal;
+  z-index: 0;
+  /* #1072 */
+  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+  font-family: "Dosis", Arial, Helvetica, sans-serif;
+  font-size: 12px;
+}
+
+.highcharts-root {
+  display: block;
+}
+
+.highcharts-root text {
+  stroke-width: 0;
+}
+
+.highcharts-strong {
+  font-weight: bold;
+}
+
+.highcharts-emphasized {
+  font-style: italic;
+}
+
+.highcharts-anchor {
+  cursor: pointer;
+}
+
+.highcharts-background {
+  fill: #ffffff;
+}
+
+.highcharts-plot-border, .highcharts-plot-background {
+  fill: none;
+}
+
+.highcharts-label-box {
+  fill: none;
+}
+
+.highcharts-button-box {
+  fill: inherit;
+}
+
+.highcharts-tracker-line {
+  stroke-linejoin: round;
+  stroke: rgba(192, 192, 192, 0.0001);
+  stroke-width: 22;
+  fill: none;
+}
+
+.highcharts-tracker-area {
+  fill: rgba(192, 192, 192, 0.0001);
+  stroke-width: 0;
+}
+
+/* Titles */
+.highcharts-title {
+  fill: #000;
+  font-size: 16px;
+}
+
+.highcharts-subtitle {
+  fill: #666666;
+}
+
+/* Axes */
+.highcharts-axis-line {
+  fill: none;
+  stroke: #ccd6eb;
+}
+
+.highcharts-yaxis .highcharts-axis-line {
+  stroke-width: 0;
+}
+
+.highcharts-axis-title {
+  fill: #666666;
+}
+
+.highcharts-axis-labels {
+  fill: #666666;
+  cursor: default;
+  font-size: 12px;
+}
+
+.highcharts-grid-line {
+  fill: none;
+  stroke: #e6e6e6;
+}
+
+.highcharts-xaxis-grid .highcharts-grid-line {
+  stroke-width: 1px;
+}
+
+.highcharts-tick {
+  stroke: #ccd6eb;
+}
+
+.highcharts-yaxis .highcharts-tick {
+  stroke-width: 0;
+}
+
+.highcharts-minor-grid-line {
+  stroke: #f2f2f2;
+}
+
+.highcharts-crosshair-thin {
+  stroke-width: 1px;
+  stroke: #cccccc;
+}
+
+.highcharts-crosshair-category {
+  stroke: #ccd6eb;
+  stroke-opacity: 0.25;
+}
+
+/* Credits */
+.highcharts-credits {
+  cursor: pointer;
+  fill: #999999;
+  font-size: 0.7em;
+  transition: fill 250ms, font-size 250ms;
+}
+
+.highcharts-credits:hover {
+  fill: black;
+  font-size: 1em;
+}
+
+/* Tooltip */
+.highcharts-tooltip {
+  cursor: default;
+  pointer-events: none;
+  white-space: nowrap;
+  transition: stroke 150ms;
+}
+
+.highcharts-tooltip text {
+  fill: #000;
+}
+
+.highcharts-tooltip .highcharts-header {
+  font-size: 0.85em;
+}
+
+.highcharts-tooltip-box {
+  stroke-width: 0px;
+  fill: rgba(219, 219, 216, 0.8);
+  fill-opacity: 0.85;
+}
+
+.highcharts-tooltip-box .highcharts-label-box {
+  fill: rgba(219, 219, 216, 0.8);
+  fill-opacity: 0.85;
+}
+
+div.highcharts-tooltip {
+  filter: none;
+}
+
+.highcharts-selection-marker {
+  fill: #335cad;
+  fill-opacity: 0.25;
+}
+
+.highcharts-graph {
+  fill: none;
+  stroke-width: 2px;
+  stroke-linecap: round;
+  stroke-linejoin: round;
+}
+
+.highcharts-state-hover .highcharts-graph {
+  stroke-width: 3;
+}
+
+.highcharts-point-inactive {
+  opacity: 0.2;
+  transition: opacity 50ms;
+  /* quick in */
+}
+
+.highcharts-series-inactive {
+  opacity: 0.2;
+  transition: opacity 50ms;
+  /* quick in */
+}
+
+.highcharts-state-hover path {
+  transition: stroke-width 50ms;
+  /* quick in */
+}
+
+.highcharts-state-normal path {
+  transition: stroke-width 250ms;
+  /* slow out */
+}
+
+/* Legend hover affects points and series */
+g.highcharts-series,
+.highcharts-point,
+.highcharts-markers,
+.highcharts-data-labels {
+  transition: opacity 250ms;
+}
+
+.highcharts-legend-series-active g.highcharts-series:not(.highcharts-series-hover),
+.highcharts-legend-point-active .highcharts-point:not(.highcharts-point-hover),
+.highcharts-legend-series-active .highcharts-markers:not(.highcharts-series-hover),
+.highcharts-legend-series-active .highcharts-data-labels:not(.highcharts-series-hover) {
+  opacity: 0.2;
+}
+
+/* Series options */
+/* Default colors */
+.highcharts-color-0 {
+  fill: #7cb5ec;
+  stroke: #7cb5ec;
+}
+
+.highcharts-color-1 {
+  fill: #f7a35c;
+  stroke: #f7a35c;
+}
+
+.highcharts-color-2 {
+  fill: #90ee7e;
+  stroke: #90ee7e;
+}
+
+.highcharts-color-3 {
+  fill: #7798BF;
+  stroke: #7798BF;
+}
+
+.highcharts-color-4 {
+  fill: #aaeeee;
+  stroke: #aaeeee;
+}
+
+.highcharts-color-5 {
+  fill: #ff0066;
+  stroke: #ff0066;
+}
+
+.highcharts-color-6 {
+  fill: #eeaaee;
+  stroke: #eeaaee;
+}
+
+.highcharts-color-7 {
+  fill: #55BF3B;
+  stroke: #55BF3B;
+}
+
+.highcharts-color-8 {
+  fill: #DF5353;
+  stroke: #DF5353;
+}
+
+.highcharts-color-9 {
+  fill: #7798BF;
+  stroke: #7798BF;
+}
+
+.highcharts-color-10 {
+  fill: #aaeeee;
+  stroke: #aaeeee;
+}
+
+.highcharts-area {
+  fill-opacity: 0.75;
+  stroke-width: 0;
+}
+
+.highcharts-markers {
+  stroke-width: 1px;
+  stroke: #ffffff;
+}
+
+.highcharts-point {
+  stroke-width: 1px;
+}
+
+.highcharts-dense-data .highcharts-point {
+  stroke-width: 0;
+}
+
+.highcharts-data-label {
+  font-size: 0.9em;
+  font-weight: bold;
+}
+
+.highcharts-data-label-box {
+  fill: none;
+  stroke-width: 0;
+}
+
+.highcharts-data-label text, text.highcharts-data-label {
+  fill: #000;
+}
+
+.highcharts-data-label-connector {
+  fill: none;
+}
+
+.highcharts-halo {
+  fill-opacity: 0.25;
+  stroke-width: 0;
+}
+
+.highcharts-series:not(.highcharts-pie-series) .highcharts-point-select,
+.highcharts-markers .highcharts-point-select {
+  fill: #cccccc;
+  stroke: #404048;
+}
+
+.highcharts-column-series rect.highcharts-point {
+  stroke: #ffffff;
+}
+
+.highcharts-column-series .highcharts-point {
+  transition: fill-opacity 250ms;
+}
+
+.highcharts-column-series .highcharts-point-hover {
+  fill-opacity: 0.75;
+  transition: fill-opacity 50ms;
+}
+
+.highcharts-pie-series .highcharts-point {
+  stroke-linejoin: round;
+  stroke: #ffffff;
+}
+
+.highcharts-pie-series .highcharts-point-hover {
+  fill-opacity: 0.75;
+  transition: fill-opacity 50ms;
+}
+
+.highcharts-funnel-series .highcharts-point {
+  stroke-linejoin: round;
+  stroke: #ffffff;
+}
+
+.highcharts-funnel-series .highcharts-point-hover {
+  fill-opacity: 0.75;
+  transition: fill-opacity 50ms;
+}
+
+.highcharts-funnel-series .highcharts-point-select {
+  fill: inherit;
+  stroke: inherit;
+}
+
+.highcharts-pyramid-series .highcharts-point {
+  stroke-linejoin: round;
+  stroke: #ffffff;
+}
+
+.highcharts-pyramid-series .highcharts-point-hover {
+  fill-opacity: 0.75;
+  transition: fill-opacity 50ms;
+}
+
+.highcharts-pyramid-series .highcharts-point-select {
+  fill: inherit;
+  stroke: inherit;
+}
+
+.highcharts-solidgauge-series .highcharts-point {
+  stroke-width: 0;
+}
+
+.highcharts-treemap-series .highcharts-point {
+  stroke-width: 1px;
+  stroke: #e6e6e6;
+  transition: stroke 250ms, fill 250ms, fill-opacity 250ms;
+}
+
+.highcharts-treemap-series .highcharts-point-hover {
+  stroke: #999999;
+  transition: stroke 25ms, fill 25ms, fill-opacity 25ms;
+}
+
+.highcharts-treemap-series .highcharts-above-level {
+  display: none;
+}
+
+.highcharts-treemap-series .highcharts-internal-node {
+  fill: none;
+}
+
+.highcharts-treemap-series .highcharts-internal-node-interactive {
+  fill-opacity: 0.15;
+  cursor: pointer;
+}
+
+.highcharts-treemap-series .highcharts-internal-node-interactive:hover {
+  fill-opacity: 0.75;
+}
+
+.highcharts-vector-series .highcharts-point {
+  fill: none;
+  stroke-width: 2px;
+}
+
+.highcharts-windbarb-series .highcharts-point {
+  fill: none;
+  stroke-width: 2px;
+}
+
+/* Dumbbell/lollipop connector */
+.highcharts-lollipop-stem {
+  stroke: #404048;
+}
+
+/* Legend */
+.highcharts-legend-box {
+  fill: none;
+  stroke-width: 0;
+}
+
+.highcharts-legend-item > text {
+  fill: #000;
+  font-weight: bold;
+  font-size: 13px;
+  cursor: pointer;
+  stroke-width: 0;
+}
+
+.highcharts-legend-item:hover text {
+  fill: #404048;
+}
+
+.highcharts-legend-item-hidden * {
+  fill: #cccccc !important;
+  stroke: #cccccc !important;
+  transition: fill 250ms;
+}
+
+.highcharts-legend-nav-active {
+  fill: #003399;
+  cursor: pointer;
+}
+
+.highcharts-legend-nav-inactive {
+  fill: #cccccc;
+}
+
+circle.highcharts-legend-nav-active, circle.highcharts-legend-nav-inactive {
+  /* tracker */
+  fill: rgba(192, 192, 192, 0.0001);
+}
+
+.highcharts-legend-title-box {
+  fill: none;
+  stroke-width: 0;
+}
+
+/* Bubble legend */
+.highcharts-bubble-legend-symbol {
+  stroke-width: 2;
+  fill-opacity: 0.5;
+}
+
+.highcharts-bubble-legend-connectors {
+  stroke-width: 1;
+}
+
+.highcharts-bubble-legend-labels {
+  fill: #000;
+}
+
+/* Loading */
+.highcharts-loading {
+  position: absolute;
+  background-color: #ffffff;
+  opacity: 0.5;
+  text-align: center;
+  z-index: 10;
+  transition: opacity 250ms;
+}
+
+.highcharts-loading-hidden {
+  height: 0 !important;
+  opacity: 0;
+  overflow: hidden;
+  transition: opacity 250ms, height 250ms step-end;
+}
+
+.highcharts-loading-inner {
+  font-weight: bold;
+  position: relative;
+  top: 45%;
+}
+
+/* Plot bands and polar pane backgrounds */
+.highcharts-plot-band, .highcharts-pane {
+  fill: #404048;
+  fill-opacity: 0.05;
+}
+
+.highcharts-plot-line {
+  fill: none;
+  stroke: #999999;
+  stroke-width: 1px;
+}
+
+/* Highcharts More and modules */
+.highcharts-boxplot-box {
+  fill: #ffffff;
+}
+
+.highcharts-boxplot-median {
+  stroke-width: 2px;
+}
+
+.highcharts-bubble-series .highcharts-point {
+  fill-opacity: 0.5;
+}
+
+.highcharts-errorbar-series .highcharts-point {
+  stroke: #404048;
+}
+
+.highcharts-gauge-series .highcharts-data-label-box {
+  stroke: #cccccc;
+  stroke-width: 1px;
+}
+
+.highcharts-gauge-series .highcharts-dial {
+  fill: #404048;
+  stroke-width: 0;
+}
+
+.highcharts-polygon-series .highcharts-graph {
+  fill: inherit;
+  stroke-width: 0;
+}
+
+.highcharts-waterfall-series .highcharts-graph {
+  stroke: #000;
+  stroke-dasharray: 1, 3;
+}
+
+.highcharts-sankey-series .highcharts-point {
+  stroke-width: 0;
+}
+
+.highcharts-sankey-series .highcharts-link {
+  transition: fill 250ms, fill-opacity 250ms;
+  fill-opacity: 0.5;
+}
+
+.highcharts-sankey-series .highcharts-point-hover.highcharts-link {
+  transition: fill 50ms, fill-opacity 50ms;
+  fill-opacity: 1;
+}
+
+.highcharts-venn-series .highcharts-point {
+  fill-opacity: 0.75;
+  stroke: #cccccc;
+  transition: stroke 250ms, fill-opacity 250ms;
+}
+
+.highcharts-venn-series .highcharts-point-hover {
+  fill-opacity: 1;
+  stroke: #cccccc;
+}
+
+/* Highstock */
+.highcharts-navigator-mask-outside {
+  fill-opacity: 0;
+}
+
+.highcharts-navigator-mask-inside {
+  fill: #6685c2;
+  /* navigator.maskFill option */
+  fill-opacity: 0.25;
+  cursor: ew-resize;
+}
+
+.highcharts-navigator-outline {
+  stroke: #cccccc;
+  fill: none;
+}
+
+.highcharts-navigator-handle {
+  stroke: #cccccc;
+  fill: #f2f2f2;
+  cursor: ew-resize;
+}
+
+.highcharts-navigator-series {
+  fill: #335cad;
+  stroke: #335cad;
+}
+
+.highcharts-navigator-series .highcharts-graph {
+  stroke-width: 1px;
+}
+
+.highcharts-navigator-series .highcharts-area {
+  fill-opacity: 0.05;
+}
+
+.highcharts-navigator-xaxis .highcharts-axis-line {
+  stroke-width: 0;
+}
+
+.highcharts-navigator-xaxis .highcharts-grid-line {
+  stroke-width: 1px;
+  stroke: #e6e6e6;
+}
+
+.highcharts-navigator-xaxis.highcharts-axis-labels {
+  fill: #999999;
+}
+
+.highcharts-navigator-yaxis .highcharts-grid-line {
+  stroke-width: 0;
+}
+
+.highcharts-scrollbar-thumb {
+  fill: #cccccc;
+  stroke: #cccccc;
+  stroke-width: 1px;
+}
+
+.highcharts-scrollbar-button {
+  fill: #e6e6e6;
+  stroke: #cccccc;
+  stroke-width: 1px;
+}
+
+.highcharts-scrollbar-arrow {
+  fill: #666666;
+}
+
+.highcharts-scrollbar-rifles {
+  stroke: #666666;
+  stroke-width: 1px;
+}
+
+.highcharts-scrollbar-track {
+  fill: #f2f2f2;
+  stroke: #f2f2f2;
+  stroke-width: 1px;
+}
+
+.highcharts-button {
+  fill: #f7f7f7;
+  stroke: #cccccc;
+  cursor: default;
+  stroke-width: 1px;
+  transition: fill 250ms;
+}
+
+.highcharts-button text {
+  fill: #000;
+}
+
+.highcharts-button-hover {
+  transition: fill 0ms;
+  fill: #e6e6e6;
+  stroke: #cccccc;
+}
+
+.highcharts-button-hover text {
+  fill: #000;
+}
+
+.highcharts-button-pressed {
+  font-weight: bold;
+  fill: #e6ebf5;
+  stroke: #cccccc;
+}
+
+.highcharts-button-pressed text {
+  fill: #000;
+  font-weight: bold;
+}
+
+.highcharts-button-disabled text {
+  fill: #000;
+}
+
+.highcharts-range-selector-buttons .highcharts-button {
+  stroke-width: 0px;
+}
+
+.highcharts-range-label rect {
+  fill: none;
+}
+
+.highcharts-range-label text {
+  fill: #666666;
+}
+
+.highcharts-range-input rect {
+  fill: none;
+}
+
+.highcharts-range-input text {
+  fill: #000;
+}
+
+.highcharts-range-input {
+  stroke-width: 1px;
+  stroke: #cccccc;
+}
+
+input.highcharts-range-selector {
+  position: absolute;
+  border: 0;
+  width: 1px;
+  /* Chrome needs a pixel to see it */
+  height: 1px;
+  padding: 0;
+  text-align: center;
+  left: -9em;
+  /* #4798 */
+}
+
+.highcharts-crosshair-label text {
+  fill: #ffffff;
+  font-size: 1.1em;
+}
+
+.highcharts-crosshair-label .highcharts-label-box {
+  fill: inherit;
+}
+
+.highcharts-candlestick-series .highcharts-point {
+  stroke: #404048;
+  stroke-width: 1px;
+}
+
+.highcharts-candlestick-series .highcharts-point-up {
+  fill: #ffffff;
+}
+
+.highcharts-ohlc-series .highcharts-point-hover {
+  stroke-width: 3px;
+}
+
+.highcharts-flags-series .highcharts-point .highcharts-label-box {
+  stroke: #999999;
+  fill: #ffffff;
+  transition: fill 250ms;
+}
+
+.highcharts-flags-series .highcharts-point-hover .highcharts-label-box {
+  stroke: #404048;
+  fill: #ccd6eb;
+}
+
+.highcharts-flags-series .highcharts-point text {
+  fill: #404048;
+  font-size: 0.9em;
+  font-weight: bold;
+}
+
+/* Highmaps */
+.highcharts-map-series .highcharts-point {
+  transition: fill 500ms, fill-opacity 500ms, stroke-width 250ms;
+  stroke: #cccccc;
+}
+
+.highcharts-map-series .highcharts-point-hover {
+  transition: fill 0ms, fill-opacity 0ms;
+  fill-opacity: 0.5;
+  stroke-width: 2px;
+}
+
+.highcharts-mapline-series .highcharts-point {
+  fill: none;
+}
+
+.highcharts-heatmap-series .highcharts-point {
+  stroke-width: 0;
+}
+
+.highcharts-map-navigation {
+  font-size: 1.3em;
+  font-weight: bold;
+  text-align: center;
+}
+
+.highcharts-coloraxis {
+  stroke-width: 0;
+}
+
+.highcharts-coloraxis-marker {
+  fill: #999999;
+}
+
+.highcharts-null-point {
+  fill: #f7f7f7;
+}
+
+/* 3d charts */
+.highcharts-3d-frame {
+  fill: transparent;
+}
+
+/* Exporting module */
+.highcharts-contextbutton {
+  fill: #ffffff;
+  /* needed to capture hover */
+  stroke: none;
+  stroke-linecap: round;
+}
+
+.highcharts-contextbutton:hover {
+  fill: #e6e6e6;
+  stroke: #e6e6e6;
+}
+
+.highcharts-button-symbol {
+  stroke: #666666;
+  stroke-width: 3px;
+}
+
+.highcharts-menu {
+  border: 1px solid #999999;
+  background: #ffffff;
+  padding: 5px 0;
+  box-shadow: 3px 3px 10px #888;
+}
+
+.highcharts-menu-item {
+  padding: 0.5em 1em;
+  background: none;
+  color: #000;
+  cursor: pointer;
+  transition: background 250ms, color 250ms;
+}
+
+.highcharts-menu-item:hover {
+  background: #335cad;
+  color: #ffffff;
+}
+
+/* Drilldown module */
+.highcharts-drilldown-point {
+  cursor: pointer;
+}
+
+.highcharts-drilldown-data-label text,
+text.highcharts-drilldown-data-label,
+.highcharts-drilldown-axis-label {
+  cursor: pointer;
+  fill: #003399;
+  font-weight: bold;
+  text-decoration: underline;
+}
+
+/* No-data module */
+.highcharts-no-data text {
+  font-weight: bold;
+  font-size: 12px;
+  fill: #666666;
+}
+
+/* Drag-panes module */
+.highcharts-axis-resizer {
+  cursor: ns-resize;
+  stroke: black;
+  stroke-width: 2px;
+}
+
+/* Bullet type series */
+.highcharts-bullet-target {
+  stroke-width: 0;
+}
+
+/* Lineargauge type series */
+.highcharts-lineargauge-target {
+  stroke-width: 1px;
+  stroke: #000;
+}
+
+.highcharts-lineargauge-target-line {
+  stroke-width: 1px;
+  stroke: #000;
+}
+
+/* Annotations module */
+.highcharts-annotation-label-box {
+  stroke-width: 1px;
+  stroke: #404048;
+  fill: #404048;
+  fill-opacity: 0.75;
+}
+
+.highcharts-annotation-label text {
+  fill: #e6e6e6;
+}
+
+/* Gantt */
+.highcharts-treegrid-node-collapsed, .highcharts-treegrid-node-expanded {
+  cursor: pointer;
+}
+
+.highcharts-point-connecting-path {
+  fill: none;
+}
+
+.highcharts-grid-axis .highcharts-tick {
+  stroke-width: 1px;
+}
+
+.highcharts-grid-axis .highcharts-axis-line {
+  stroke-width: 1px;
+}

+ 33 - 0
app/public/js/Highstock-8.0.0/code/css/themes/grid-light.scss

@@ -0,0 +1,33 @@
+// Global font
+@import 'https://fonts.googleapis.com/css?family=Dosis:400,600';
+
+// Colors for data series and points.
+$colors: #7cb5ec #f7a35c #90ee7e #7798BF #aaeeee #ff0066 #eeaaee #55BF3B #DF5353 #7798BF #aaeeee;
+
+// Neutral colors
+$neutral-color-100: #404048;
+$neutral-color-80: #000;
+
+// Fonts
+$font-family: 'Dosis', Arial, Helvetica, sans-serif;
+$title-font-size: 16px;
+$legend-font-size: 13px;
+$axis-labels-font-size: 12px;
+
+// Tooltip
+$tooltip-border: 0px;
+$tooltip-background: rgba(219,219,216,0.8);
+
+// Axes
+$xaxis-grid-line: 1px !default;
+
+// Title
+.highcharts-title, .highcharts-subtitle, .highcharts-yaxis .highcharts-axis-title {
+	text-transform: uppercase;
+}
+
+.highcharts-title {
+	font-weight: bold;
+}
+
+@import '../highcharts';

+ 956 - 0
app/public/js/Highstock-8.0.0/code/css/themes/sand-signika.css

@@ -0,0 +1,956 @@
+@import 'https://fonts.googleapis.com/css?family=Signika:400,700';
+.highcharts-container {
+  background: url(https://www.highcharts.com/samples/graphics/sand.png);
+}
+
+.highcharts-boxplot-box {
+  fill: #505053;
+}
+
+.highcharts-navigator-xaxis .highcharts-grid-line {
+  stroke: #D0D0D8;
+}
+
+.highcharts-scrollbar-track {
+  stroke: #C0C0C8;
+}
+
+.highcharts-title {
+  font-weight: bold;
+}
+
+.highcharts-button-box {
+  stroke-width: 1px;
+}
+
+/**
+ * @license Highcharts
+ *
+ * (c) 2009-2016 Torstein Honsi
+ *
+ * License: www.highcharts.com/license
+ */
+.highcharts-container {
+  position: relative;
+  overflow: hidden;
+  width: 100%;
+  height: 100%;
+  text-align: left;
+  line-height: normal;
+  z-index: 0;
+  /* #1072 */
+  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+  font-family: "Signika", Arial, Helvetica, sans-serif;
+  font-size: 12px;
+}
+
+.highcharts-root {
+  display: block;
+}
+
+.highcharts-root text {
+  stroke-width: 0;
+}
+
+.highcharts-strong {
+  font-weight: bold;
+}
+
+.highcharts-emphasized {
+  font-style: italic;
+}
+
+.highcharts-anchor {
+  cursor: pointer;
+}
+
+.highcharts-background {
+  fill: none;
+}
+
+.highcharts-plot-border, .highcharts-plot-background {
+  fill: none;
+}
+
+.highcharts-label-box {
+  fill: none;
+}
+
+.highcharts-button-box {
+  fill: inherit;
+}
+
+.highcharts-tracker-line {
+  stroke-linejoin: round;
+  stroke: rgba(192, 192, 192, 0.0001);
+  stroke-width: 22;
+  fill: none;
+}
+
+.highcharts-tracker-area {
+  fill: rgba(192, 192, 192, 0.0001);
+  stroke-width: 0;
+}
+
+/* Titles */
+.highcharts-title {
+  fill: #000;
+  font-size: 16px;
+}
+
+.highcharts-subtitle {
+  fill: #666666;
+}
+
+/* Axes */
+.highcharts-axis-line {
+  fill: none;
+  stroke: #ccd6eb;
+}
+
+.highcharts-yaxis .highcharts-axis-line {
+  stroke-width: 0;
+}
+
+.highcharts-axis-title {
+  fill: #666666;
+}
+
+.highcharts-axis-labels {
+  fill: #666666;
+  cursor: default;
+  font-size: 12px;
+}
+
+.highcharts-grid-line {
+  fill: none;
+  stroke: #e6e6e6;
+}
+
+.highcharts-xaxis-grid .highcharts-grid-line {
+  stroke-width: 0px;
+}
+
+.highcharts-tick {
+  stroke: #ccd6eb;
+}
+
+.highcharts-yaxis .highcharts-tick {
+  stroke-width: 0;
+}
+
+.highcharts-minor-grid-line {
+  stroke: #f2f2f2;
+}
+
+.highcharts-crosshair-thin {
+  stroke-width: 1px;
+  stroke: #cccccc;
+}
+
+.highcharts-crosshair-category {
+  stroke: #ccd6eb;
+  stroke-opacity: 0.25;
+}
+
+/* Credits */
+.highcharts-credits {
+  cursor: pointer;
+  fill: #999999;
+  font-size: 0.7em;
+  transition: fill 250ms, font-size 250ms;
+}
+
+.highcharts-credits:hover {
+  fill: black;
+  font-size: 1em;
+}
+
+/* Tooltip */
+.highcharts-tooltip {
+  cursor: default;
+  pointer-events: none;
+  white-space: nowrap;
+  transition: stroke 150ms;
+}
+
+.highcharts-tooltip text {
+  fill: #000;
+}
+
+.highcharts-tooltip .highcharts-header {
+  font-size: 0.85em;
+}
+
+.highcharts-tooltip-box {
+  stroke-width: 0px;
+  fill: #fff;
+  fill-opacity: 0.85;
+}
+
+.highcharts-tooltip-box .highcharts-label-box {
+  fill: #fff;
+  fill-opacity: 0.85;
+}
+
+div.highcharts-tooltip {
+  filter: none;
+}
+
+.highcharts-selection-marker {
+  fill: #335cad;
+  fill-opacity: 0.25;
+}
+
+.highcharts-graph {
+  fill: none;
+  stroke-width: 2px;
+  stroke-linecap: round;
+  stroke-linejoin: round;
+}
+
+.highcharts-state-hover .highcharts-graph {
+  stroke-width: 3;
+}
+
+.highcharts-point-inactive {
+  opacity: 0.2;
+  transition: opacity 50ms;
+  /* quick in */
+}
+
+.highcharts-series-inactive {
+  opacity: 0.2;
+  transition: opacity 50ms;
+  /* quick in */
+}
+
+.highcharts-state-hover path {
+  transition: stroke-width 50ms;
+  /* quick in */
+}
+
+.highcharts-state-normal path {
+  transition: stroke-width 250ms;
+  /* slow out */
+}
+
+/* Legend hover affects points and series */
+g.highcharts-series,
+.highcharts-point,
+.highcharts-markers,
+.highcharts-data-labels {
+  transition: opacity 250ms;
+}
+
+.highcharts-legend-series-active g.highcharts-series:not(.highcharts-series-hover),
+.highcharts-legend-point-active .highcharts-point:not(.highcharts-point-hover),
+.highcharts-legend-series-active .highcharts-markers:not(.highcharts-series-hover),
+.highcharts-legend-series-active .highcharts-data-labels:not(.highcharts-series-hover) {
+  opacity: 0.2;
+}
+
+/* Series options */
+/* Default colors */
+.highcharts-color-0 {
+  fill: #f45b5b;
+  stroke: #f45b5b;
+}
+
+.highcharts-color-1 {
+  fill: #8085e9;
+  stroke: #8085e9;
+}
+
+.highcharts-color-2 {
+  fill: #8d4654;
+  stroke: #8d4654;
+}
+
+.highcharts-color-3 {
+  fill: #7798BF;
+  stroke: #7798BF;
+}
+
+.highcharts-color-4 {
+  fill: #aaeeee;
+  stroke: #aaeeee;
+}
+
+.highcharts-color-5 {
+  fill: #ff0066;
+  stroke: #ff0066;
+}
+
+.highcharts-color-6 {
+  fill: #eeaaee;
+  stroke: #eeaaee;
+}
+
+.highcharts-color-7 {
+  fill: #55BF3B;
+  stroke: #55BF3B;
+}
+
+.highcharts-color-8 {
+  fill: #DF5353;
+  stroke: #DF5353;
+}
+
+.highcharts-color-9 {
+  fill: #7798BF;
+  stroke: #7798BF;
+}
+
+.highcharts-color-10 {
+  fill: #aaeeee;
+  stroke: #aaeeee;
+}
+
+.highcharts-area {
+  fill-opacity: 0.75;
+  stroke-width: 0;
+}
+
+.highcharts-markers {
+  stroke-width: 1px;
+  stroke: none;
+}
+
+.highcharts-point {
+  stroke-width: 1px;
+}
+
+.highcharts-dense-data .highcharts-point {
+  stroke-width: 0;
+}
+
+.highcharts-data-label {
+  font-size: 0.9em;
+  font-weight: bold;
+}
+
+.highcharts-data-label-box {
+  fill: none;
+  stroke-width: 0;
+}
+
+.highcharts-data-label text, text.highcharts-data-label {
+  fill: #000;
+}
+
+.highcharts-data-label-connector {
+  fill: none;
+}
+
+.highcharts-halo {
+  fill-opacity: 0.25;
+  stroke-width: 0;
+}
+
+.highcharts-series:not(.highcharts-pie-series) .highcharts-point-select,
+.highcharts-markers .highcharts-point-select {
+  fill: #cccccc;
+  stroke: #fff;
+}
+
+.highcharts-column-series rect.highcharts-point {
+  stroke: none;
+}
+
+.highcharts-column-series .highcharts-point {
+  transition: fill-opacity 250ms;
+}
+
+.highcharts-column-series .highcharts-point-hover {
+  fill-opacity: 0.75;
+  transition: fill-opacity 50ms;
+}
+
+.highcharts-pie-series .highcharts-point {
+  stroke-linejoin: round;
+  stroke: none;
+}
+
+.highcharts-pie-series .highcharts-point-hover {
+  fill-opacity: 0.75;
+  transition: fill-opacity 50ms;
+}
+
+.highcharts-funnel-series .highcharts-point {
+  stroke-linejoin: round;
+  stroke: none;
+}
+
+.highcharts-funnel-series .highcharts-point-hover {
+  fill-opacity: 0.75;
+  transition: fill-opacity 50ms;
+}
+
+.highcharts-funnel-series .highcharts-point-select {
+  fill: inherit;
+  stroke: inherit;
+}
+
+.highcharts-pyramid-series .highcharts-point {
+  stroke-linejoin: round;
+  stroke: none;
+}
+
+.highcharts-pyramid-series .highcharts-point-hover {
+  fill-opacity: 0.75;
+  transition: fill-opacity 50ms;
+}
+
+.highcharts-pyramid-series .highcharts-point-select {
+  fill: inherit;
+  stroke: inherit;
+}
+
+.highcharts-solidgauge-series .highcharts-point {
+  stroke-width: 0;
+}
+
+.highcharts-treemap-series .highcharts-point {
+  stroke-width: 1px;
+  stroke: #e6e6e6;
+  transition: stroke 250ms, fill 250ms, fill-opacity 250ms;
+}
+
+.highcharts-treemap-series .highcharts-point-hover {
+  stroke: #999999;
+  transition: stroke 25ms, fill 25ms, fill-opacity 25ms;
+}
+
+.highcharts-treemap-series .highcharts-above-level {
+  display: none;
+}
+
+.highcharts-treemap-series .highcharts-internal-node {
+  fill: none;
+}
+
+.highcharts-treemap-series .highcharts-internal-node-interactive {
+  fill-opacity: 0.15;
+  cursor: pointer;
+}
+
+.highcharts-treemap-series .highcharts-internal-node-interactive:hover {
+  fill-opacity: 0.75;
+}
+
+.highcharts-vector-series .highcharts-point {
+  fill: none;
+  stroke-width: 2px;
+}
+
+.highcharts-windbarb-series .highcharts-point {
+  fill: none;
+  stroke-width: 2px;
+}
+
+/* Dumbbell/lollipop connector */
+.highcharts-lollipop-stem {
+  stroke: #fff;
+}
+
+/* Legend */
+.highcharts-legend-box {
+  fill: none;
+  stroke-width: 0;
+}
+
+.highcharts-legend-item > text {
+  fill: #000;
+  font-weight: bold;
+  font-size: 13px;
+  cursor: pointer;
+  stroke-width: 0;
+}
+
+.highcharts-legend-item:hover text {
+  fill: #fff;
+}
+
+.highcharts-legend-item-hidden * {
+  fill: #cccccc !important;
+  stroke: #cccccc !important;
+  transition: fill 250ms;
+}
+
+.highcharts-legend-nav-active {
+  fill: #003399;
+  cursor: pointer;
+}
+
+.highcharts-legend-nav-inactive {
+  fill: #cccccc;
+}
+
+circle.highcharts-legend-nav-active, circle.highcharts-legend-nav-inactive {
+  /* tracker */
+  fill: rgba(192, 192, 192, 0.0001);
+}
+
+.highcharts-legend-title-box {
+  fill: none;
+  stroke-width: 0;
+}
+
+/* Bubble legend */
+.highcharts-bubble-legend-symbol {
+  stroke-width: 2;
+  fill-opacity: 0.5;
+}
+
+.highcharts-bubble-legend-connectors {
+  stroke-width: 1;
+}
+
+.highcharts-bubble-legend-labels {
+  fill: #000;
+}
+
+/* Loading */
+.highcharts-loading {
+  position: absolute;
+  background-color: none;
+  opacity: 0.5;
+  text-align: center;
+  z-index: 10;
+  transition: opacity 250ms;
+}
+
+.highcharts-loading-hidden {
+  height: 0 !important;
+  opacity: 0;
+  overflow: hidden;
+  transition: opacity 250ms, height 250ms step-end;
+}
+
+.highcharts-loading-inner {
+  font-weight: bold;
+  position: relative;
+  top: 45%;
+}
+
+/* Plot bands and polar pane backgrounds */
+.highcharts-plot-band, .highcharts-pane {
+  fill: #fff;
+  fill-opacity: 0.05;
+}
+
+.highcharts-plot-line {
+  fill: none;
+  stroke: #999999;
+  stroke-width: 1px;
+}
+
+/* Highcharts More and modules */
+.highcharts-boxplot-box {
+  fill: none;
+}
+
+.highcharts-boxplot-median {
+  stroke-width: 2px;
+}
+
+.highcharts-bubble-series .highcharts-point {
+  fill-opacity: 0.5;
+}
+
+.highcharts-errorbar-series .highcharts-point {
+  stroke: #fff;
+}
+
+.highcharts-gauge-series .highcharts-data-label-box {
+  stroke: #cccccc;
+  stroke-width: 1px;
+}
+
+.highcharts-gauge-series .highcharts-dial {
+  fill: #fff;
+  stroke-width: 0;
+}
+
+.highcharts-polygon-series .highcharts-graph {
+  fill: inherit;
+  stroke-width: 0;
+}
+
+.highcharts-waterfall-series .highcharts-graph {
+  stroke: #000;
+  stroke-dasharray: 1, 3;
+}
+
+.highcharts-sankey-series .highcharts-point {
+  stroke-width: 0;
+}
+
+.highcharts-sankey-series .highcharts-link {
+  transition: fill 250ms, fill-opacity 250ms;
+  fill-opacity: 0.5;
+}
+
+.highcharts-sankey-series .highcharts-point-hover.highcharts-link {
+  transition: fill 50ms, fill-opacity 50ms;
+  fill-opacity: 1;
+}
+
+.highcharts-venn-series .highcharts-point {
+  fill-opacity: 0.75;
+  stroke: #cccccc;
+  transition: stroke 250ms, fill-opacity 250ms;
+}
+
+.highcharts-venn-series .highcharts-point-hover {
+  fill-opacity: 1;
+  stroke: #cccccc;
+}
+
+/* Highstock */
+.highcharts-navigator-mask-outside {
+  fill-opacity: 0;
+}
+
+.highcharts-navigator-mask-inside {
+  fill: #6685c2;
+  /* navigator.maskFill option */
+  fill-opacity: 0.25;
+  cursor: ew-resize;
+}
+
+.highcharts-navigator-outline {
+  stroke: #cccccc;
+  fill: none;
+}
+
+.highcharts-navigator-handle {
+  stroke: #cccccc;
+  fill: #f2f2f2;
+  cursor: ew-resize;
+}
+
+.highcharts-navigator-series {
+  fill: #f45b5b;
+  stroke: #f45b5b;
+}
+
+.highcharts-navigator-series .highcharts-graph {
+  stroke-width: 1px;
+}
+
+.highcharts-navigator-series .highcharts-area {
+  fill-opacity: 0.05;
+}
+
+.highcharts-navigator-xaxis .highcharts-axis-line {
+  stroke-width: 0;
+}
+
+.highcharts-navigator-xaxis .highcharts-grid-line {
+  stroke-width: 1px;
+  stroke: #e6e6e6;
+}
+
+.highcharts-navigator-xaxis.highcharts-axis-labels {
+  fill: #999999;
+}
+
+.highcharts-navigator-yaxis .highcharts-grid-line {
+  stroke-width: 0;
+}
+
+.highcharts-scrollbar-thumb {
+  fill: #cccccc;
+  stroke: #cccccc;
+  stroke-width: 1px;
+}
+
+.highcharts-scrollbar-button {
+  fill: #e6e6e6;
+  stroke: #cccccc;
+  stroke-width: 1px;
+}
+
+.highcharts-scrollbar-arrow {
+  fill: #666666;
+}
+
+.highcharts-scrollbar-rifles {
+  stroke: #666666;
+  stroke-width: 1px;
+}
+
+.highcharts-scrollbar-track {
+  fill: #f2f2f2;
+  stroke: #C0C0C8;
+  stroke-width: 1px;
+}
+
+.highcharts-button {
+  fill: #fff;
+  stroke: #C0C0C8;
+  cursor: default;
+  stroke-width: 1px;
+  transition: fill 250ms;
+}
+
+.highcharts-button text {
+  fill: #000;
+}
+
+.highcharts-button-hover {
+  transition: fill 0ms;
+  fill: #e6e6e6;
+  stroke: #cccccc;
+}
+
+.highcharts-button-hover text {
+  fill: #000;
+}
+
+.highcharts-button-pressed {
+  font-weight: bold;
+  fill: #D0D0D8;
+  stroke: #cccccc;
+}
+
+.highcharts-button-pressed text {
+  fill: #000;
+  font-weight: bold;
+}
+
+.highcharts-button-disabled text {
+  fill: #000;
+}
+
+.highcharts-range-selector-buttons .highcharts-button {
+  stroke-width: 0px;
+}
+
+.highcharts-range-label rect {
+  fill: none;
+}
+
+.highcharts-range-label text {
+  fill: #666666;
+}
+
+.highcharts-range-input rect {
+  fill: none;
+}
+
+.highcharts-range-input text {
+  fill: #000;
+}
+
+.highcharts-range-input {
+  stroke-width: 1px;
+  stroke: #cccccc;
+}
+
+input.highcharts-range-selector {
+  position: absolute;
+  border: 0;
+  width: 1px;
+  /* Chrome needs a pixel to see it */
+  height: 1px;
+  padding: 0;
+  text-align: center;
+  left: -9em;
+  /* #4798 */
+}
+
+.highcharts-crosshair-label text {
+  fill: none;
+  font-size: 1.1em;
+}
+
+.highcharts-crosshair-label .highcharts-label-box {
+  fill: inherit;
+}
+
+.highcharts-candlestick-series .highcharts-point {
+  stroke: #fff;
+  stroke-width: 1px;
+}
+
+.highcharts-candlestick-series .highcharts-point-up {
+  fill: none;
+}
+
+.highcharts-ohlc-series .highcharts-point-hover {
+  stroke-width: 3px;
+}
+
+.highcharts-flags-series .highcharts-point .highcharts-label-box {
+  stroke: #999999;
+  fill: none;
+  transition: fill 250ms;
+}
+
+.highcharts-flags-series .highcharts-point-hover .highcharts-label-box {
+  stroke: #fff;
+  fill: #ccd6eb;
+}
+
+.highcharts-flags-series .highcharts-point text {
+  fill: #fff;
+  font-size: 0.9em;
+  font-weight: bold;
+}
+
+/* Highmaps */
+.highcharts-map-series .highcharts-point {
+  transition: fill 500ms, fill-opacity 500ms, stroke-width 250ms;
+  stroke: #cccccc;
+}
+
+.highcharts-map-series .highcharts-point-hover {
+  transition: fill 0ms, fill-opacity 0ms;
+  fill-opacity: 0.5;
+  stroke-width: 2px;
+}
+
+.highcharts-mapline-series .highcharts-point {
+  fill: none;
+}
+
+.highcharts-heatmap-series .highcharts-point {
+  stroke-width: 0;
+}
+
+.highcharts-map-navigation {
+  font-size: 1.3em;
+  font-weight: bold;
+  text-align: center;
+}
+
+.highcharts-coloraxis {
+  stroke-width: 0;
+}
+
+.highcharts-coloraxis-marker {
+  fill: #999999;
+}
+
+.highcharts-null-point {
+  fill: #f7f7f7;
+}
+
+/* 3d charts */
+.highcharts-3d-frame {
+  fill: transparent;
+}
+
+/* Exporting module */
+.highcharts-contextbutton {
+  fill: #fff;
+  /* needed to capture hover */
+  stroke: none;
+  stroke-linecap: round;
+}
+
+.highcharts-contextbutton:hover {
+  fill: #e6e6e6;
+  stroke: #e6e6e6;
+}
+
+.highcharts-button-symbol {
+  stroke: #666666;
+  stroke-width: 3px;
+}
+
+.highcharts-menu {
+  border: 1px solid #999999;
+  background: none;
+  padding: 5px 0;
+  box-shadow: 3px 3px 10px #888;
+}
+
+.highcharts-menu-item {
+  padding: 0.5em 1em;
+  background: none;
+  color: #000;
+  cursor: pointer;
+  transition: background 250ms, color 250ms;
+}
+
+.highcharts-menu-item:hover {
+  background: #335cad;
+  color: none;
+}
+
+/* Drilldown module */
+.highcharts-drilldown-point {
+  cursor: pointer;
+}
+
+.highcharts-drilldown-data-label text,
+text.highcharts-drilldown-data-label,
+.highcharts-drilldown-axis-label {
+  cursor: pointer;
+  fill: #003399;
+  font-weight: bold;
+  text-decoration: underline;
+}
+
+/* No-data module */
+.highcharts-no-data text {
+  font-weight: bold;
+  font-size: 12px;
+  fill: #666666;
+}
+
+/* Drag-panes module */
+.highcharts-axis-resizer {
+  cursor: ns-resize;
+  stroke: black;
+  stroke-width: 2px;
+}
+
+/* Bullet type series */
+.highcharts-bullet-target {
+  stroke-width: 0;
+}
+
+/* Lineargauge type series */
+.highcharts-lineargauge-target {
+  stroke-width: 1px;
+  stroke: #000;
+}
+
+.highcharts-lineargauge-target-line {
+  stroke-width: 1px;
+  stroke: #000;
+}
+
+/* Annotations module */
+.highcharts-annotation-label-box {
+  stroke-width: 1px;
+  stroke: #fff;
+  fill: #fff;
+  fill-opacity: 0.75;
+}
+
+.highcharts-annotation-label text {
+  fill: #e6e6e6;
+}
+
+/* Gantt */
+.highcharts-treegrid-node-collapsed, .highcharts-treegrid-node-expanded {
+  cursor: pointer;
+}
+
+.highcharts-point-connecting-path {
+  fill: none;
+}
+
+.highcharts-grid-axis .highcharts-tick {
+  stroke-width: 1px;
+}
+
+.highcharts-grid-axis .highcharts-axis-line {
+  stroke-width: 1px;
+}

+ 74 - 0
app/public/js/Highstock-8.0.0/code/css/themes/sand-signika.scss

@@ -0,0 +1,74 @@
+// Global font
+@import 'https://fonts.googleapis.com/css?family=Signika:400,700';
+
+// Chart background, point stroke for markers and columns etc
+$background-color: none;
+
+// Colors for data series and points.
+$colors: #f45b5b #8085e9 #8d4654 #7798BF #aaeeee #ff0066 #eeaaee #55BF3B #DF5353 #7798BF #aaeeee;
+
+// Neutral colors
+$neutral-color-100: #fff;
+$neutral-color-80: #000;
+
+// Data-labels
+$data-label-color: #000;
+
+// Fonts
+$font-family: 'Signika', Arial, Helvetica, sans-serif;
+$title-font-size: 16px;
+$legend-font-size: 13px;
+$axis-labels-font-size: 12px;
+
+// Tooltip
+$tooltip-border: 0px;
+$tooltip-background: $neutral-color-100;
+
+// Buttons
+$highcharts-button-background: $neutral-color-100;
+$highcharts-button-border: #C0C0C8;
+$highcharts-button-text:  #000;
+
+$highcharts-button-pressed-background: #D0D0D8;
+$highcharts-button-pressed-text:  #000;
+
+$context-button-background: $neutral-color-100;
+
+// Navigator
+$navigator-series-fill: #f45b5b;
+$navigator-series-border: #f45b5b;
+
+// Scrollbar
+$scrollbar-track-border: #C0C0C8;
+
+// General
+.highcharts-container {
+  background: url(https://www.highcharts.com/samples/graphics/sand.png);
+}
+
+// Boxplot
+.highcharts-boxplot-box {
+   fill: #505053;
+}
+
+// Navigator
+.highcharts-navigator-xaxis .highcharts-grid-line {
+  stroke: #D0D0D8;
+}
+
+// Scrollbar
+.highcharts-scrollbar-track {
+  stroke: #C0C0C8;
+}
+
+// Title
+.highcharts-title {
+	font-weight: bold;
+}
+
+// Buttons
+.highcharts-button-box {
+	stroke-width: 1px;
+}
+
+@import '../highcharts';

+ 141 - 0
app/public/js/Highstock-8.0.0/code/es-modules/annotations/ControlPoint.js

@@ -0,0 +1,141 @@
+import H from './../parts/Globals.js';
+import U from './../parts/Utilities.js';
+var extend = U.extend,
+    pick = U.pick;
+
+import eventEmitterMixin from './eventEmitterMixin.js';
+
+/**
+ * A control point class which is a connection between controllable
+ * transform methods and a user actions.
+ *
+ * @constructor
+ * @mixes eventEmitterMixin
+ * @memberOf Annotation
+ *
+ * @param {Highcharts.Chart} chart a chart instance
+ * @param {Object} target a controllable instance which is a target for
+ *        a control point
+ * @param {Annotation.ControlPoint.Options} options an options object
+ * @param {number} [index]
+ */
+function ControlPoint(chart, target, options, index) {
+    this.chart = chart;
+    this.target = target;
+    this.options = options;
+    this.index = pick(options.index, index);
+}
+
+/**
+ * @typedef {Object} Annotation.ControlPoint.Position
+ * @property {number} x
+ * @property {number} y
+ */
+
+/**
+ * @callback Annotation.ControlPoint.Positioner
+ * @param {Object} e event
+ * @param {Controllable} target
+ * @return {Annotation.ControlPoint.Position} position
+ */
+
+/**
+ * @typedef {Object} Annotation.ControlPoint.Options
+ * @property {string} symbol
+ * @property {number} width
+ * @property {number} height
+ * @property {Object} style
+ * @property {boolean} visible
+ * @property {Annotation.ControlPoint.Positioner} positioner
+ * @property {Object} events
+ */
+
+extend(
+    ControlPoint.prototype,
+    eventEmitterMixin
+);
+
+/**
+ * List of events for `anntation.options.events` that should not be
+ * added to `annotation.graphic` but to the `annotation`.
+ *
+ * @type {Array<string>}
+ */
+ControlPoint.prototype.nonDOMEvents = ['drag'];
+
+/**
+ * Set the visibility.
+ *
+ * @param {boolean} [visible]
+ **/
+ControlPoint.prototype.setVisibility = function (visible) {
+    this.graphic.attr('visibility', visible ? 'visible' : 'hidden');
+
+    this.options.visible = visible;
+};
+
+/**
+ * Render the control point.
+ */
+ControlPoint.prototype.render = function () {
+    var chart = this.chart,
+        options = this.options;
+
+    this.graphic = chart.renderer
+        .symbol(
+            options.symbol,
+            0,
+            0,
+            options.width,
+            options.height
+        )
+        .add(chart.controlPointsGroup)
+        .css(options.style);
+
+    this.setVisibility(options.visible);
+    this.addEvents();
+};
+
+/**
+ * Redraw the control point.
+ *
+ * @param {boolean} [animation]
+ */
+ControlPoint.prototype.redraw = function (animation) {
+    this.graphic[animation ? 'animate' : 'attr'](
+        this.options.positioner.call(this, this.target)
+    );
+};
+
+
+/**
+ * Destroy the control point.
+ */
+ControlPoint.prototype.destroy = function () {
+    eventEmitterMixin.destroy.call(this);
+
+    if (this.graphic) {
+        this.graphic = this.graphic.destroy();
+    }
+
+    this.chart = null;
+    this.target = null;
+    this.options = null;
+};
+
+/**
+ * Update the control point.
+ */
+ControlPoint.prototype.update = function (userOptions) {
+    var chart = this.chart,
+        target = this.target,
+        index = this.index,
+        options = H.merge(true, this.options, userOptions);
+
+    this.destroy();
+    this.constructor(chart, target, options, index);
+    this.render(chart.controlPointsGroup);
+    this.redraw();
+};
+
+export default ControlPoint;

+ 453 - 0
app/public/js/Highstock-8.0.0/code/es-modules/annotations/MockPoint.js

@@ -0,0 +1,453 @@
+import H from '../parts/Globals.js';
+
+import U from '../parts/Utilities.js';
+var defined = U.defined,
+    extend = U.extend;
+
+import '../parts/Axis.js';
+import '../parts/Series.js';
+
+/**
+ * A mock point label configuration.
+ *
+ * @interface Annotation.MockLabelOptionsObject
+ *//**
+ * X value translated to x axis scale
+ * @name Annotation.MockLabelOptionsObject#x
+ * @type {number|undefined}
+ *//**
+ * Y value translated to y axis scale
+ * @name Annotation.MockLabelOptionsObject#y
+ * @type {number|undefined}
+ *//**
+ * @name Annotation.MockLabelOptionsObject#point
+ * @type {Highcharts.Point}
+ */
+
+/**
+ * A mock point configuration.
+ *
+ * @interface Highcharts.MockPointOptionsObject
+ *//**
+ * x value for the point in xAxis scale or pixels
+ * @name Highcharts.MockPointOptionsObject#x
+ * @type {number}
+ *//**
+ * y value for the point in yAxis scale or pixels
+ * @name Highcharts.MockPointOptionsObject#y
+ * @type {number}
+ *//**
+ * xAxis index or id
+ * @name Highcharts.MockPointOptionsObject#xAxis
+ * @type {Highcharts.Axis|number|string|undefined}
+ *//**
+ * yAxis index or id
+ * @name Highcharts.MockPointOptionsObject#yAxis
+ * @property {Highcharts.Axis|number|string|undefined}
+ */
+
+/**
+ * A point-like object, a mock point or a point uses in series.
+ *
+ * @private
+ * @typedef {Highcharts.Point|Highcharts.MockPoint} Highcharts.PointLike
+ */
+
+/**
+ * A trimmed point object which imitates {@link Highchart.Point} class.
+ * It is created when there is a need of pointing to some chart's position
+ * using axis values or pixel values
+ *
+ * @private
+ * @class
+ * @name Highcharts.MockPoint
+ *
+ * @param {Highcharts.Chart} chart
+ *        The chart object
+ *
+ * @param {Highcharts.MockPointOptionsObject} options
+ *        The options object
+ */
+function MockPoint(chart, target, options) {
+    /**
+     * A mock series instance imitating a real series from a real point.
+     *
+     * @type {Object}
+     * @property {boolean} series.visible=true - whether a series is visible
+     * @property {Chart} series.chart - a chart instance
+     * @property {function} series.getPlotBox
+     */
+    this.series = {
+        visible: true,
+        chart: chart,
+        getPlotBox: H.Series.prototype.getPlotBox
+    };
+
+    /**
+     * @type {?Controllable}
+     */
+    this.target = target || null;
+
+    /**
+     * Options for the mock point.
+     *
+     * @type {Highcharts.MockPointOptionsObject}
+     */
+    this.options = options;
+
+    /**
+     * If an xAxis is set it represents the point's value in terms of the xAxis.
+     *
+     * @name Annotation.MockPoint#x
+     * @type {?number}
+     */
+
+    /**
+     * If an yAxis is set it represents the point's value in terms of the yAxis.
+     *
+     * @name Annotation.MockPoint#y
+     * @type {?number}
+     */
+
+    /**
+     * It represents the point's pixel x coordinate relative to its plot box.
+     *
+     * @name Annotation.MockPoint#plotX
+     * @type {?number}
+     */
+
+    /**
+     * It represents the point's pixel y position relative to its plot box.
+     *
+     * @name Annotation.MockPoint#plotY
+     * @type {?number}
+     */
+
+    /**
+     * Whether the point is inside the plot box.
+     *
+     * @name Annotation.MockPoint#isInside
+     * @type {boolean}
+     */
+
+    this.applyOptions(this.getOptions());
+}
+
+/**
+ * Create a mock point from a real Highcharts point.
+ *
+ * @param {Point} point
+ *
+ * @return {Annotation.MockPoint} a mock point instance.
+ */
+MockPoint.fromPoint = function (point) {
+    return new MockPoint(point.series.chart, null, {
+        x: point.x,
+        y: point.y,
+        xAxis: point.series.xAxis,
+        yAxis: point.series.yAxis
+    });
+};
+
+/**
+ * @typedef Annotation.MockPoint.Position
+ * @property {number} x
+ * @property {number} y
+ */
+
+/**
+ * Get the pixel position from the point like object.
+ *
+ * @param {Annotation.PointLike} point
+ * @param {boolean} [paneCoordinates]
+ *        whether the pixel position should be relative
+ *
+ * @return {Annotation.MockPoint.Position} pixel position
+ */
+MockPoint.pointToPixels = function (point, paneCoordinates) {
+    var series = point.series,
+        chart = series.chart,
+        x = point.plotX,
+        y = point.plotY,
+        plotBox;
+
+    if (chart.inverted) {
+        if (point.mock) {
+            x = point.plotY;
+            y = point.plotX;
+        } else {
+            x = chart.plotWidth - point.plotY;
+            y = chart.plotHeight - point.plotX;
+        }
+    }
+
+    if (series && !paneCoordinates) {
+        plotBox = series.getPlotBox();
+        x += plotBox.translateX;
+        y += plotBox.translateY;
+    }
+
+    return {
+        x: x,
+        y: y
+    };
+};
+
+/**
+ * Get fresh mock point options from the point like object.
+ *
+ * @param {Annotation.PointLike} point
+ *
+ * @return {Annotation.MockPoint.Options} mock point's options
+ */
+MockPoint.pointToOptions = function (point) {
+    return {
+        x: point.x,
+        y: point.y,
+        xAxis: point.series.xAxis,
+        yAxis: point.series.yAxis
+    };
+};
+
+extend(MockPoint.prototype, /** @lends Annotation.MockPoint# */ {
+    /**
+     * A flag indicating that a point is not the real one.
+     *
+     * @type {boolean}
+     * @default true
+     */
+    mock: true,
+
+    /**
+     * Check if the point has dynamic options.
+     *
+     * @return {boolean} A positive flag if the point has dynamic options.
+     */
+    hasDynamicOptions: function () {
+        return typeof this.options === 'function';
+    },
+
+    /**
+     * Get the point's options.
+     *
+     * @return {Annotation.MockPoint.Options} the mock point's options.
+     */
+    getOptions: function () {
+        return this.hasDynamicOptions() ?
+            this.options(this.target) :
+            this.options;
+    },
+
+    /**
+     * Apply options for the point.
+     *
+     * @param {Annotation.MockPoint.Options} options
+     */
+    applyOptions: function (options) {
+        this.command = options.command;
+
+        this.setAxis(options, 'x');
+        this.setAxis(options, 'y');
+
+        this.refresh();
+    },
+
+    /**
+     * Set x or y axis.
+     *
+     * @param {Annotation.MockPoint.Options} options
+     * @param {string} xOrY 'x' or 'y' string literal
+     */
+    setAxis: function (options, xOrY) {
+        var axisName = xOrY + 'Axis',
+            axisOptions = options[axisName],
+            chart = this.series.chart;
+
+        this.series[axisName] =
+            axisOptions instanceof H.Axis ?
+                axisOptions :
+                defined(axisOptions) ?
+                    chart[axisName][axisOptions] || chart.get(axisOptions) :
+                    null;
+    },
+
+    /**
+     * Transform the mock point to an anchor
+     * (relative position on the chart).
+     *
+     * @return {Array<number>} A quadruple of numbers which denotes x, y,
+     * width and height of the box
+     **/
+    toAnchor: function () {
+        var anchor = [this.plotX, this.plotY, 0, 0];
+
+        if (this.series.chart.inverted) {
+            anchor[0] = this.plotY;
+            anchor[1] = this.plotX;
+        }
+
+        return anchor;
+    },
+
+    /**
+     * @typedef {Object} Annotation.MockPoint.LabelConfig
+     * @property {number|undefined} x x value translated to x axis scale
+     * @property {number|undefined} y y value translated to y axis scale
+     * @property {Annotation.MockPoint} point instance of the point
+     */
+
+    /**
+     * Returns a label config object -
+     * the same as Highcharts.Point.prototype.getLabelConfig
+     *
+     * @return {Annotation.MockPoint.LabelConfig} the point's label config
+     */
+    getLabelConfig: function () {
+        return {
+            x: this.x,
+            y: this.y,
+            point: this
+        };
+    },
+
+    /**
+     * Check if the point is inside its pane.
+     *
+     * @return {boolean} A flag indicating whether the point is inside the pane.
+     */
+    isInsidePane: function () {
+        var plotX = this.plotX,
+            plotY = this.plotY,
+            xAxis = this.series.xAxis,
+            yAxis = this.series.yAxis,
+            isInside = true;
+
+        if (xAxis) {
+            isInside = defined(plotX) && plotX >= 0 && plotX <= xAxis.len;
+        }
+
+        if (yAxis) {
+            isInside =
+                isInside &&
+                defined(plotY) &&
+                plotY >= 0 && plotY <= yAxis.len;
+        }
+
+        return isInside;
+    },
+
+    /**
+     * Refresh point values and coordinates based on its options.
+     */
+    refresh: function () {
+        var series = this.series,
+            xAxis = series.xAxis,
+            yAxis = series.yAxis,
+            options = this.getOptions();
+
+        if (xAxis) {
+            this.x = options.x;
+            this.plotX = xAxis.toPixels(options.x, true);
+        } else {
+            this.x = null;
+            this.plotX = options.x;
+        }
+
+        if (yAxis) {
+            this.y = options.y;
+            this.plotY = yAxis.toPixels(options.y, true);
+        } else {
+            this.y = null;
+            this.plotY = options.y;
+        }
+
+        this.isInside = this.isInsidePane();
+    },
+
+    /**
+     * Translate the point.
+     *
+     * @param {number} [cx] origin x transformation
+     * @param {number} [cy] origin y transformation
+     * @param {number} dx translation for x coordinate
+     * @param {number} dy translation for y coordinate
+     **/
+    translate: function (cx, cy, dx, dy) {
+        if (!this.hasDynamicOptions()) {
+            this.plotX += dx;
+            this.plotY += dy;
+
+            this.refreshOptions();
+        }
+    },
+
+    /**
+     * Scale the point.
+     *
+     * @param {number} cx origin x transformation
+     * @param {number} cy origin y transformation
+     * @param {number} sx scale factor x
+     * @param {number} sy scale factor y
+     */
+    scale: function (cx, cy, sx, sy) {
+        if (!this.hasDynamicOptions()) {
+            var x = this.plotX * sx,
+                y = this.plotY * sy,
+                tx = (1 - sx) * cx,
+                ty = (1 - sy) * cy;
+
+            this.plotX = tx + x;
+            this.plotY = ty + y;
+
+            this.refreshOptions();
+        }
+    },
+
+    /**
+     * Rotate the point.
+     *
+     * @param {number} cx origin x rotation
+     * @param {number} cy origin y rotation
+     * @param {number} radians
+     */
+    rotate: function (cx, cy, radians) {
+        if (!this.hasDynamicOptions()) {
+            var cos = Math.cos(radians),
+                sin = Math.sin(radians),
+                x = this.plotX,
+                y = this.plotY,
+                tx,
+                ty;
+
+            x -= cx;
+            y -= cy;
+
+            tx = x * cos - y * sin;
+            ty = x * sin + y * cos;
+
+            this.plotX = tx + cx;
+            this.plotY = ty + cy;
+
+            this.refreshOptions();
+        }
+    },
+
+    /**
+     * Refresh point options based on its plot coordinates.
+     */
+    refreshOptions: function () {
+        var series = this.series,
+            xAxis = series.xAxis,
+            yAxis = series.yAxis;
+
+        this.x = this.options.x = xAxis ?
+            this.options.x = xAxis.toValue(this.plotX, true) :
+            this.plotX;
+
+        this.y = this.options.y = yAxis ?
+            yAxis.toValue(this.plotY, true) :
+            this.plotY;
+    }
+});
+
+export default MockPoint;

+ 1321 - 0
app/public/js/Highstock-8.0.0/code/es-modules/annotations/annotations.src.js

@@ -0,0 +1,1321 @@
+/* *
+ *
+ *  (c) 2009-2017 Highsoft, Black Label
+ *
+ *  License: www.highcharts.com/license
+ *
+ * */
+
+'use strict';
+
+import H from '../parts/Globals.js';
+
+import U from '../parts/Utilities.js';
+var defined = U.defined,
+    destroyObjectProperties = U.destroyObjectProperties,
+    erase = U.erase,
+    extend = U.extend,
+    pick = U.pick,
+    splat = U.splat,
+    wrap = U.wrap;
+
+import '../parts/Chart.js';
+import controllableMixin from './controllable/controllableMixin.js';
+import ControllableRect from './controllable/ControllableRect.js';
+import ControllableCircle from './controllable/ControllableCircle.js';
+import ControllablePath from './controllable/ControllablePath.js';
+import ControllableImage from './controllable/ControllableImage.js';
+import ControllableLabel from './controllable/ControllableLabel.js';
+import eventEmitterMixin from './eventEmitterMixin.js';
+import MockPoint from './MockPoint.js';
+import ControlPoint from './ControlPoint.js';
+
+var merge = H.merge,
+    addEvent = H.addEvent,
+    fireEvent = H.fireEvent,
+    find = H.find,
+    reduce = H.reduce,
+    chartProto = H.Chart.prototype;
+
+/* *********************************************************************
+ *
+ * ANNOTATION
+ *
+ ******************************************************************** */
+
+/**
+ * @typedef {
+ *          Annotation.ControllableCircle|
+ *          Annotation.ControllableImage|
+ *          Annotation.ControllablePath|
+ *          Annotation.ControllableRect
+ *          }
+ *          Annotation.Shape
+ */
+
+/**
+ * @typedef {Annotation.ControllableLabel} Annotation.Label
+ */
+
+/**
+ * An annotation class which serves as a container for items like labels or
+ * shapes. Created items are positioned on the chart either by linking them to
+ * existing points or created mock points
+ *
+ * @class
+ * @name Highcharts.Annotation
+ *
+ * @param {Highcharts.Chart} chart a chart instance
+ * @param {Highcharts.AnnotationsOptions} userOptions the options object
+ */
+var Annotation = H.Annotation = function (chart, userOptions) {
+    var labelsAndShapes;
+
+    /**
+     * The chart that the annotation belongs to.
+     *
+     * @type {Highcharts.Chart}
+     */
+    this.chart = chart;
+
+    /**
+     * The array of points which defines the annotation.
+     *
+     * @type {Array<Highcharts.Point>}
+     */
+    this.points = [];
+
+    /**
+     * The array of control points.
+     *
+     * @type {Array<Annotation.ControlPoint>}
+     */
+    this.controlPoints = [];
+
+    this.coll = 'annotations';
+
+    /**
+     * The array of labels which belong to the annotation.
+     *
+     * @type {Array<Annotation.Label>}
+     */
+    this.labels = [];
+
+    /**
+     * The array of shapes which belong to the annotation.
+     *
+     * @type {Array<Annotation.Shape>}
+     */
+    this.shapes = [];
+
+    /**
+     * The options for the annotations.
+     *
+     * @type {Highcharts.AnnotationsOptions}
+     */
+    this.options = merge(this.defaultOptions, userOptions);
+
+    /**
+     * The user options for the annotations.
+     *
+     * @type {Highcharts.AnnotationsOptions}
+     */
+    this.userOptions = userOptions;
+
+    // Handle labels and shapes - those are arrays
+    // Merging does not work with arrays (stores reference)
+    labelsAndShapes = this.getLabelsAndShapesOptions(
+        this.options,
+        userOptions
+    );
+    this.options.labels = labelsAndShapes.labels;
+    this.options.shapes = labelsAndShapes.shapes;
+
+    /**
+     * The callback that reports to the overlapping-labels module which
+     * labels it should account for.
+     *
+     * @name labelCollector
+     * @memberOf Annotation#
+     * @type {Function}
+     */
+
+    /**
+     * The group svg element.
+     *
+     * @name group
+     * @memberOf Annotation#
+     * @type {Highcharts.SVGElement}
+     */
+
+    /**
+     * The group svg element of the annotation's shapes.
+     *
+     * @name shapesGroup
+     * @memberOf Annotation#
+     * @type {Highcharts.SVGElement}
+     */
+
+    /**
+     * The group svg element of the annotation's labels.
+     *
+     * @name labelsGroup
+     * @memberOf Annotation#
+     * @type {Highcharts.SVGElement}
+     */
+
+    this.init(chart, this.options);
+};
+
+
+merge(
+    true,
+    Annotation.prototype,
+    controllableMixin,
+    eventEmitterMixin,
+    /** @lends Annotation# */
+    {
+
+        /**
+         * List of events for `annotation.options.events` that should not be
+         * added to `annotation.graphic` but to the `annotation`.
+         *
+         * @type {Array<string>}
+         */
+        nonDOMEvents: ['add', 'afterUpdate', 'drag', 'remove'],
+
+        /**
+         * A basic type of an annotation. It allows to add custom labels
+         * or shapes. The items  can be tied to points, axis coordinates
+         * or chart pixel coordinates.
+         *
+         * @sample highcharts/annotations/basic/
+         *         Basic annotations
+         * @sample highcharts/demo/annotations/
+         *         Advanced annotations
+         * @sample highcharts/css/annotations
+         *         Styled mode
+         * @sample highcharts/annotations-advanced/controllable
+         *         Controllable items
+         * @sample {highstock} stock/annotations/fibonacci-retracements
+         *         Custom annotation, Fibonacci retracement
+         *
+         * @type         {Array<*>}
+         * @since        6.0.0
+         * @requires     modules/annotations
+         * @optionparent annotations
+         */
+        defaultOptions: {
+
+            /**
+             * Sets an ID for an annotation. Can be user later when removing an
+             * annotation in [Chart#removeAnnotation(id)](
+             * /class-reference/Highcharts.Chart#removeAnnotation) method.
+             *
+             * @type      {string|number}
+             * @apioption annotations.id
+             */
+
+            /**
+             * Whether the annotation is visible.
+             *
+             * @sample highcharts/annotations/visible/
+             *         Set annotation visibility
+             */
+            visible: true,
+
+            /**
+             * Allow an annotation to be draggable by a user. Possible
+             * values are `"x"`, `"xy"`, `"y"` and `""` (disabled).
+             *
+             * @sample highcharts/annotations/draggable/
+             *         Annotations draggable: 'xy'
+             *
+             * @type       {string}
+             * @validvalue ["x", "xy", "y", ""]
+             */
+            draggable: 'xy',
+
+            /**
+             * Options for annotation's labels. Each label inherits options
+             * from the labelOptions object. An option from the labelOptions
+             * can be overwritten by config for a specific label.
+             *
+             * @requires modules/annotations
+             */
+            labelOptions: {
+
+                /**
+                 * The alignment of the annotation's label. If right,
+                 * the right side of the label should be touching the point.
+                 *
+                 * @sample highcharts/annotations/label-position/
+                 *         Set labels position
+                 *
+                 * @type {Highcharts.AlignValue}
+                 */
+                align: 'center',
+
+                /**
+                 * Whether to allow the annotation's labels to overlap.
+                 * To make the labels less sensitive for overlapping,
+                 * the can be set to 0.
+                 *
+                 * @sample highcharts/annotations/tooltip-like/
+                 *         Hide overlapping labels
+                 */
+                allowOverlap: false,
+
+                /**
+                 * The background color or gradient for the annotation's label.
+                 *
+                 * @sample highcharts/annotations/label-presentation/
+                 *         Set labels graphic options
+                 *
+                 * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
+                 */
+                backgroundColor: 'rgba(0, 0, 0, 0.75)',
+
+                /**
+                 * The border color for the annotation's label.
+                 *
+                 * @sample highcharts/annotations/label-presentation/
+                 *         Set labels graphic options
+                 *
+                 * @type {Highcharts.ColorString}
+                 */
+                borderColor: 'black',
+
+                /**
+                 * The border radius in pixels for the annotaiton's label.
+                 *
+                 * @sample highcharts/annotations/label-presentation/
+                 *         Set labels graphic options
+                 */
+                borderRadius: 3,
+
+                /**
+                 * The border width in pixels for the annotation's label
+                 *
+                 * @sample highcharts/annotations/label-presentation/
+                 *         Set labels graphic options
+                 */
+                borderWidth: 1,
+
+                /**
+                 * A class name for styling by CSS.
+                 *
+                 * @sample highcharts/css/annotations
+                 *         Styled mode annotations
+                 *
+                 * @since 6.0.5
+                 */
+                className: '',
+
+                /**
+                 * Whether to hide the annotation's label
+                 * that is outside the plot area.
+                 *
+                 * @sample highcharts/annotations/label-crop-overflow/
+                 *         Crop or justify labels
+                 */
+                crop: false,
+
+                /**
+                 * The label's pixel distance from the point.
+                 *
+                 * @sample highcharts/annotations/label-position/
+                 *         Set labels position
+                 *
+                 * @type      {number}
+                 * @apioption annotations.labelOptions.distance
+                 */
+
+                /**
+                 * A
+                 * [format](https://www.highcharts.com/docs/chart-concepts/labels-and-string-formatting)
+                 * string for the data label.
+                 *
+                 * @see [plotOptions.series.dataLabels.format](plotOptions.series.dataLabels.format.html)
+                 *
+                 * @sample highcharts/annotations/label-text/
+                 *         Set labels text
+                 *
+                 * @type      {string}
+                 * @apioption annotations.labelOptions.format
+                 */
+
+                /**
+                 * Alias for the format option.
+                 *
+                 * @see [format](annotations.labelOptions.format.html)
+                 *
+                 * @sample highcharts/annotations/label-text/
+                 *         Set labels text
+                 *
+                 * @type      {string}
+                 * @apioption annotations.labelOptions.text
+                 */
+
+                /**
+                 * Callback JavaScript function to format the annotation's
+                 * label. Note that if a `format` or `text` are defined, the
+                 * format or text take precedence and the formatter is ignored.
+                 * `This` refers to a point object.
+                 *
+                 * @sample highcharts/annotations/label-text/
+                 *         Set labels text
+                 *
+                 * @type    {Highcharts.FormatterCallbackFunction<Highcharts.Point>}
+                 * @default function () { return defined(this.y) ? this.y : 'Annotation label'; }
+                 */
+                formatter: function () {
+                    return defined(this.y) ? this.y : 'Annotation label';
+                },
+
+                /**
+                 * How to handle the annotation's label that flow outside the
+                 * plot area. The justify option aligns the label inside the
+                 * plot area.
+                 *
+                 * @sample highcharts/annotations/label-crop-overflow/
+                 *         Crop or justify labels
+                 *
+                 * @validvalue ["allow", "justify"]
+                 */
+                overflow: 'justify',
+
+                /**
+                 * When either the borderWidth or the backgroundColor is set,
+                 * this    is the padding within the box.
+                 *
+                 * @sample highcharts/annotations/label-presentation/
+                 *         Set labels graphic options
+                 */
+                padding: 5,
+
+                /**
+                 * The shadow of the box. The shadow can be an object
+                 * configuration containing `color`, `offsetX`, `offsetY`,
+                 * `opacity` and `width`.
+                 *
+                 * @sample highcharts/annotations/label-presentation/
+                 *         Set labels graphic options
+                 *
+                 * @type {boolean|Highcharts.ShadowOptionsObject}
+                 */
+                shadow: false,
+
+                /**
+                 * The name of a symbol to use for the border around the label.
+                 * Symbols are predefined functions on the Renderer object.
+                 *
+                 * @sample highcharts/annotations/shapes/
+                 *         Available shapes for labels
+                 */
+                shape: 'callout',
+
+                /**
+                 * Styles for the annotation's label.
+                 *
+                 * @see [plotOptions.series.dataLabels.style](plotOptions.series.dataLabels.style.html)
+                 *
+                 * @sample highcharts/annotations/label-presentation/
+                 *         Set labels graphic options
+                 *
+                 * @type {Highcharts.CSSObject}
+                 */
+                style: {
+                    /** @ignore */
+                    fontSize: '11px',
+                    /** @ignore */
+                    fontWeight: 'normal',
+                    /** @ignore */
+                    color: 'contrast'
+                },
+
+                /**
+                 * Whether to [use HTML](https://www.highcharts.com/docs/chart-concepts/labels-and-string-formatting#html)
+                 * to render the annotation's label.
+                 */
+                useHTML: false,
+
+                /**
+                 * The vertical alignment of the annotation's label.
+                 *
+                 * @sample highcharts/annotations/label-position/
+                 *         Set labels position
+                 *
+                 * @type {Highcharts.VerticalAlignValue}
+                 */
+                verticalAlign: 'bottom',
+
+                /**
+                 * The x position offset of the label relative to the point.
+                 * Note that if a `distance` is defined, the distance takes
+                 * precedence over `x` and `y` options.
+                 *
+                 * @sample highcharts/annotations/label-position/
+                 *         Set labels position
+                 */
+                x: 0,
+
+                /**
+                 * The y position offset of the label relative to the point.
+                 * Note that if a `distance` is defined, the distance takes
+                 * precedence over `x` and `y` options.
+                 *
+                 * @sample highcharts/annotations/label-position/
+                 *         Set labels position
+                 */
+                y: -16
+            },
+
+            /**
+             * An array of labels for the annotation. For options that apply to
+             * multiple labels, they can be added to the
+             * [labelOptions](annotations.labelOptions.html).
+             *
+             * @type      {Array<*>}
+             * @extends   annotations.labelOptions
+             * @apioption annotations.labels
+             */
+
+            /**
+             * This option defines the point to which the label will be
+             * connected. It can be either the point which exists in the
+             * series - it is referenced by the point's id - or a new point with
+             * defined x, y properties and optionally axes.
+             *
+             * @sample highcharts/annotations/mock-point/
+             *         Attach annotation to a mock point
+             *
+             * @type      {string|Highcharts.MockPointOptionsObject}
+             * @requires  modules/annotations
+             * @apioption annotations.labels.point
+             */
+
+            /**
+             * The x position of the point. Units can be either in axis
+             * or chart pixel coordinates.
+             *
+             * @type      {number}
+             * @apioption annotations.labels.point.x
+             */
+
+            /**
+             * The y position of the point. Units can be either in axis
+             * or chart pixel coordinates.
+             *
+             * @type      {number}
+             * @apioption annotations.labels.point.y
+             */
+
+            /**
+             * This number defines which xAxis the point is connected to. It
+             * refers to either the axis id or the index of the axis in the
+             * xAxis array. If the option is not configured or the axis is not
+             * found the point's x coordinate refers to the chart pixels.
+             *
+             * @type      {number|string}
+             * @apioption annotations.labels.point.xAxis
+             */
+
+            /**
+             * This number defines which yAxis the point is connected to. It
+             * refers to either the axis id or the index of the axis in the
+             * yAxis array. If the option is not configured or the axis is not
+             * found the point's y coordinate refers to the chart pixels.
+             *
+             * @type      {number|string}
+             * @apioption annotations.labels.point.yAxis
+             */
+
+
+            /**
+             * An array of shapes for the annotation. For options that apply to
+             * multiple shapes, then can be added to the
+             * [shapeOptions](annotations.shapeOptions.html).
+             *
+             * @type      {Array<*>}
+             * @extends   annotations.shapeOptions
+             * @apioption annotations.shapes
+             */
+
+            /**
+             * This option defines the point to which the shape will be
+             * connected. It can be either the point which exists in the
+             * series - it is referenced by the point's id - or a new point with
+             * defined x, y properties and optionally axes.
+             *
+             * @type      {string|Highcharts.MockPointOptionsObject}
+             * @extends   annotations.labels.point
+             * @apioption annotations.shapes.point
+             */
+
+            /**
+             * An array of points for the shape. This option is available for
+             * shapes which can use multiple points such as path. A point can be
+             * either a point object or a point's id.
+             *
+             * @see [annotations.shapes.point](annotations.shapes.point.html)
+             *
+             * @type      {Array<string|Highcharts.MockPointOptionsObject>}
+             * @extends   annotations.labels.point
+             * @apioption annotations.shapes.points
+             */
+
+            /**
+             * Id of the marker which will be drawn at the final vertex of the
+             * path. Custom markers can be defined in defs property.
+             *
+             * @see [defs.markers](defs.markers.html)
+             *
+             * @sample highcharts/annotations/custom-markers/
+             *         Define a custom marker for annotations
+             *
+             * @type      {string}
+             * @apioption annotations.shapes.markerEnd
+             */
+
+            /**
+             * Id of the marker which will be drawn at the first vertex of the
+             * path. Custom markers can be defined in defs property.
+             *
+             * @see [defs.markers](defs.markers.html)
+             *
+             * @sample {highcharts} highcharts/annotations/custom-markers/
+             *         Define a custom marker for annotations
+             *
+             * @type      {string}
+             * @apioption annotations.shapes.markerStart
+             */
+
+
+            /**
+             * Options for annotation's shapes. Each shape inherits options from
+             * the shapeOptions object. An option from the shapeOptions can be
+             * overwritten by config for a specific shape.
+             *
+             * @requires  modules/annotations
+             */
+            shapeOptions: {
+
+                /**
+                 * The width of the shape.
+                 *
+                 * @sample highcharts/annotations/shape/
+                 *         Basic shape annotation
+                 *
+                 * @type      {number}
+                 * @apioption annotations.shapeOptions.width
+                 **/
+
+                /**
+                 * The height of the shape.
+                 *
+                 * @sample highcharts/annotations/shape/
+                 *         Basic shape annotation
+                 *
+                 * @type      {number}
+                 * @apioption annotations.shapeOptions.height
+                 */
+
+                /**
+                 * The type of the shape, e.g. circle or rectangle.
+                 *
+                 * @sample highcharts/annotations/shape/
+                 *         Basic shape annotation
+                 *
+                 * @type      {string}
+                 * @default   'rect'
+                 * @apioption annotations.shapeOptions.type
+                 */
+
+                /**
+                 * The color of the shape's stroke.
+                 *
+                 * @sample highcharts/annotations/shape/
+                 *         Basic shape annotation
+                 *
+                 * @type {Highcharts.ColorString}
+                 */
+                stroke: 'rgba(0, 0, 0, 0.75)',
+
+                /**
+                 * The pixel stroke width of the shape.
+                 *
+                 * @sample highcharts/annotations/shape/
+                 *         Basic shape annotation
+                 */
+                strokeWidth: 1,
+
+                /**
+                 * The color of the shape's fill.
+                 *
+                 * @sample highcharts/annotations/shape/
+                 *         Basic shape annotation
+                 *
+                 * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
+                 */
+                fill: 'rgba(0, 0, 0, 0.75)',
+
+                /**
+                 * The radius of the shape.
+                 *
+                 * @sample highcharts/annotations/shape/
+                 *         Basic shape annotation
+                 */
+                r: 0,
+
+                /**
+                 * Defines additional snapping area around an annotation
+                 * making this annotation to focus. Defined in pixels.
+                 */
+                snap: 2
+            },
+
+            /**
+             * Options for annotation's control points. Each control point
+             * inherits options from controlPointOptions object.
+             * Options from the controlPointOptions can be overwritten
+             * by options in a specific control point.
+             *
+             * @type      {Annotation.ControlPoint.Options}
+             * @requires  modules/annotations
+             * @apioption annotations.controlPointOptions
+             */
+            controlPointOptions: {
+
+                /**
+                 * @function {Annotation.ControlPoint.Positioner}
+                 * @apioption annotations.controlPointOptions.positioner
+                 */
+
+                symbol: 'circle',
+                width: 10,
+                height: 10,
+                style: {
+                    stroke: 'black',
+                    'stroke-width': 2,
+                    fill: 'white'
+                },
+                visible: false,
+                events: {}
+            },
+
+            /**
+             * Event callback when annotation is added to the chart.
+             *
+             * @type      {Highcharts.EventCallbackFunction<Highcharts.Annotation>}
+             * @since     7.1.0
+             * @apioption annotations.events.add
+             */
+
+            /**
+             * Event callback when annotation is updated (e.g. drag and
+             * droppped or resized by control points).
+             *
+             * @type      {Highcharts.EventCallbackFunction<Highcharts.Annotation>}
+             * @since     7.1.0
+             * @apioption annotations.events.afterUpdate
+             */
+
+            /**
+             * Event callback when annotation is removed from the chart.
+             *
+             * @type      {Highcharts.EventCallbackFunction<Highcharts.Annotation>}
+             * @since     7.1.0
+             * @apioption annotations.events.remove
+             */
+
+            /**
+             * Events available in annotations.
+             *
+             * @requires modules/annotations
+             */
+            events: {},
+
+            /**
+             * The Z index of the annotation.
+             */
+            zIndex: 6
+
+        },
+
+        /**
+         * Initialize the annotation.
+         *
+         * @param {Highcharts.Chart}
+         *        The chart
+         * @param {Highcharts.AnnotationsOptions}
+         *        The user options for the annotation
+         */
+        init: function () {
+            this.linkPoints();
+            this.addControlPoints();
+            this.addShapes();
+            this.addLabels();
+            this.addClipPaths();
+            this.setLabelCollector();
+        },
+
+        getLabelsAndShapesOptions: function (baseOptions, newOptions) {
+            var mergedOptions = {};
+
+            ['labels', 'shapes'].forEach(function (name) {
+                if (baseOptions[name]) {
+                    mergedOptions[name] = splat(newOptions[name]).map(
+                        function (basicOptions, i) {
+                            return merge(baseOptions[name][i], basicOptions);
+                        }
+                    );
+                }
+            });
+
+            return mergedOptions;
+        },
+
+        addShapes: function () {
+            (this.options.shapes || []).forEach(function (shapeOptions, i) {
+                var shape = this.initShape(shapeOptions, i);
+
+                merge(true, this.options.shapes[i], shape.options);
+            }, this);
+        },
+
+        addLabels: function () {
+            (this.options.labels || []).forEach(function (labelsOptions, i) {
+                var labels = this.initLabel(labelsOptions, i);
+
+                merge(true, this.options.labels[i], labels.options);
+            }, this);
+        },
+
+        addClipPaths: function () {
+            this.setClipAxes();
+
+            if (this.clipXAxis && this.clipYAxis) {
+                this.clipRect = this.chart.renderer.clipRect(
+                    this.getClipBox()
+                );
+            }
+        },
+
+        setClipAxes: function () {
+            var xAxes = this.chart.xAxis,
+                yAxes = this.chart.yAxis,
+                linkedAxes = reduce(
+                    (this.options.labels || [])
+                        .concat(this.options.shapes || []),
+                    function (axes, labelOrShape) {
+                        return [
+                            xAxes[
+                                labelOrShape &&
+                                labelOrShape.point &&
+                                labelOrShape.point.xAxis
+                            ] || axes[0],
+                            yAxes[
+                                labelOrShape &&
+                                labelOrShape.point &&
+                                labelOrShape.point.yAxis
+                            ] || axes[1]
+                        ];
+                    },
+                    []
+                );
+
+            this.clipXAxis = linkedAxes[0];
+            this.clipYAxis = linkedAxes[1];
+        },
+
+        getClipBox: function () {
+            return {
+                x: this.clipXAxis.left,
+                y: this.clipYAxis.top,
+                width: this.clipXAxis.width,
+                height: this.clipYAxis.height
+            };
+        },
+
+        setLabelCollector: function () {
+            var annotation = this;
+
+            annotation.labelCollector = function () {
+                return annotation.labels.reduce(
+                    function (labels, label) {
+                        if (!label.options.allowOverlap) {
+                            labels.push(label.graphic);
+                        }
+
+                        return labels;
+                    },
+                    []
+                );
+            };
+
+            annotation.chart.labelCollectors.push(
+                annotation.labelCollector
+            );
+        },
+
+        /**
+         * Set an annotation options.
+         *
+         * @param {Highcharts.AnnotationsOptions} - user options for an annotation
+         */
+        setOptions: function (userOptions) {
+            this.options = merge(this.defaultOptions, userOptions);
+        },
+
+        redraw: function (animation) {
+            this.linkPoints();
+
+            if (!this.graphic) {
+                this.render();
+            }
+
+            if (this.clipRect) {
+                this.clipRect.animate(this.getClipBox());
+            }
+
+            this.redrawItems(this.shapes, animation);
+            this.redrawItems(this.labels, animation);
+
+
+            controllableMixin.redraw.call(this, animation);
+        },
+
+        /**
+         * @param {Array<(Annotation.Label|Annotation.Shape)>} items
+         * @param {boolean} [animation]
+         */
+        redrawItems: function (items, animation) {
+            var i = items.length;
+
+            // needs a backward loop
+            // labels/shapes array might be modified
+            // due to destruction of the item
+            while (i--) {
+                this.redrawItem(items[i], animation);
+            }
+        },
+
+        render: function () {
+            var renderer = this.chart.renderer;
+
+            this.graphic = renderer
+                .g('annotation')
+                .attr({
+                    zIndex: this.options.zIndex,
+                    visibility: this.options.visible ?
+                        'visible' :
+                        'hidden'
+                })
+                .add();
+
+            this.shapesGroup = renderer
+                .g('annotation-shapes')
+                .add(this.graphic)
+                .clip(this.chart.plotBoxClip);
+
+            this.labelsGroup = renderer
+                .g('annotation-labels')
+                .attr({
+                    // hideOverlappingLabels requires translation
+                    translateX: 0,
+                    translateY: 0
+                })
+                .add(this.graphic);
+
+            if (this.clipRect) {
+                this.graphic.clip(this.clipRect);
+            }
+
+            this.addEvents();
+
+            controllableMixin.render.call(this);
+        },
+
+        /**
+         * Set the annotation's visibility.
+         *
+         * @param {Boolean} [visible] - Whether to show or hide an annotation.
+         * If the param is omitted, the annotation's visibility is toggled.
+         */
+        setVisibility: function (visibility) {
+            var options = this.options,
+                visible = pick(visibility, !options.visible);
+
+            this.graphic.attr(
+                'visibility',
+                visible ? 'visible' : 'hidden'
+            );
+
+            if (!visible) {
+                this.setControlPointsVisibility(false);
+            }
+
+            options.visible = visible;
+        },
+
+        setControlPointsVisibility: function (visible) {
+            var setItemControlPointsVisibility = function (item) {
+                item.setControlPointsVisibility(visible);
+            };
+
+            controllableMixin.setControlPointsVisibility.call(
+                this,
+                visible
+            );
+
+            this.shapes.forEach(setItemControlPointsVisibility);
+            this.labels.forEach(setItemControlPointsVisibility);
+        },
+
+        /**
+         * Destroy the annotation. This function does not touch the chart
+         * that the annotation belongs to (all annotations are kept in
+         * the chart.annotations array) - it is recommended to use
+         * {@link Highcharts.Chart#removeAnnotation} instead.
+         */
+        destroy: function () {
+            var chart = this.chart,
+                destroyItem = function (item) {
+                    item.destroy();
+                };
+
+            this.labels.forEach(destroyItem);
+            this.shapes.forEach(destroyItem);
+
+            this.clipXAxis = null;
+            this.clipYAxis = null;
+
+            erase(chart.labelCollectors, this.labelCollector);
+
+            eventEmitterMixin.destroy.call(this);
+            controllableMixin.destroy.call(this);
+
+            destroyObjectProperties(this, chart);
+        },
+
+        /**
+         * See {@link Highcharts.Chart#removeAnnotation}.
+         */
+        remove: function () {
+            // Let chart.update() remove annoations on demand
+            return this.chart.removeAnnotation(this);
+        },
+
+        update: function (userOptions) {
+            var chart = this.chart,
+                labelsAndShapes = this.getLabelsAndShapesOptions(
+                    this.userOptions,
+                    userOptions
+                ),
+                userOptionsIndex = chart.annotations.indexOf(this),
+                options = H.merge(true, this.userOptions, userOptions);
+
+            options.labels = labelsAndShapes.labels;
+            options.shapes = labelsAndShapes.shapes;
+
+            this.destroy();
+            this.constructor(chart, options);
+
+            // Update options in chart options, used in exporting (#9767):
+            chart.options.annotations[userOptionsIndex] = options;
+
+            this.isUpdating = true;
+            this.redraw();
+            this.isUpdating = false;
+            fireEvent(this, 'afterUpdate');
+        },
+
+        /* *************************************************************
+         * ITEM SECTION
+         * Contains methods for handling a single item in an annotation
+         **************************************************************** */
+
+        /**
+         * Initialisation of a single shape
+         *
+         * @param {Object} shapeOptions - a confg object for a single shape
+         */
+        initShape: function (shapeOptions, index) {
+            var options = merge(
+                    this.options.shapeOptions,
+                    {
+                        controlPointOptions: this.options.controlPointOptions
+                    },
+                    shapeOptions
+                ),
+                shape = new Annotation.shapesMap[options.type](
+                    this,
+                    options,
+                    index
+                );
+
+            shape.itemType = 'shape';
+
+            this.shapes.push(shape);
+
+            return shape;
+        },
+
+        /**
+         * Initialisation of a single label
+         *
+         * @param {Object} labelOptions
+         **/
+        initLabel: function (labelOptions, index) {
+            var options = merge(
+                    this.options.labelOptions,
+                    {
+                        controlPointOptions: this.options.controlPointOptions
+                    },
+                    labelOptions
+                ),
+                label = new ControllableLabel(
+                    this,
+                    options,
+                    index
+                );
+
+            label.itemType = 'label';
+
+            this.labels.push(label);
+
+            return label;
+        },
+
+        /**
+         * Redraw a single item.
+         *
+         * @param {Annotation.Label|Annotation.Shape} item
+         * @param {boolean} [animation]
+         */
+        redrawItem: function (item, animation) {
+            item.linkPoints();
+
+            if (!item.shouldBeDrawn()) {
+                this.destroyItem(item);
+            } else {
+                if (!item.graphic) {
+                    this.renderItem(item);
+                }
+
+                item.redraw(
+                    pick(animation, true) && item.graphic.placed
+                );
+
+                if (item.points.length) {
+                    this.adjustVisibility(item);
+                }
+            }
+        },
+
+        /**
+         * Hide or show annotaiton attached to points.
+         *
+         * @param {Annotation.Label|Annotation.Shape} item
+         */
+
+        adjustVisibility: function (item) { // #9481
+            var hasVisiblePoints = false,
+                label = item.graphic;
+
+            item.points.forEach(function (point) {
+                if (
+                    point.series.visible !== false &&
+                    point.visible !== false
+                ) {
+                    hasVisiblePoints = true;
+                }
+            });
+
+            if (!hasVisiblePoints) {
+                label.hide();
+
+            } else if (label.visibility === 'hidden') {
+                label.show();
+            }
+        },
+
+        /**
+         * Destroy a single item.
+         *
+         * @param {Annotation.Label|Annotation.Shape} item
+         */
+        destroyItem: function (item) {
+            // erase from shapes or labels array
+            erase(this[item.itemType + 's'], item);
+            item.destroy();
+        },
+
+        /**
+         * @private
+         */
+        renderItem: function (item) {
+            item.render(
+                item.itemType === 'label' ?
+                    this.labelsGroup :
+                    this.shapesGroup
+            );
+        }
+    }
+);
+
+/**
+ * An object uses for mapping between a shape type and a constructor.
+ * To add a new shape type extend this object with type name as a key
+ * and a constructor as its value.
+ */
+Annotation.shapesMap = {
+    'rect': ControllableRect,
+    'circle': ControllableCircle,
+    'path': ControllablePath,
+    'image': ControllableImage
+};
+
+Annotation.types = {};
+
+Annotation.MockPoint = MockPoint;
+Annotation.ControlPoint = ControlPoint;
+
+H.extendAnnotation = function (
+    Constructor,
+    BaseConstructor,
+    prototype,
+    defaultOptions
+) {
+    BaseConstructor = BaseConstructor || Annotation;
+
+    merge(
+        true,
+        Constructor.prototype,
+        BaseConstructor.prototype,
+        prototype
+    );
+
+    Constructor.prototype.defaultOptions = merge(
+        Constructor.prototype.defaultOptions,
+        defaultOptions || {}
+    );
+};
+
+/* *********************************************************************
+ *
+ * EXTENDING CHART PROTOTYPE
+ *
+ ******************************************************************** */
+
+extend(chartProto, /** @lends Highcharts.Chart# */ {
+    initAnnotation: function (userOptions) {
+        var Constructor =
+            Annotation.types[userOptions.type] || Annotation,
+            annotation = new Constructor(this, userOptions);
+
+        this.annotations.push(annotation);
+
+        return annotation;
+    },
+
+    /**
+     * Add an annotation to the chart after render time.
+     *
+     * @param  {Highcharts.AnnotationsOptions} options
+     *         The annotation options for the new, detailed annotation.
+     * @param {boolean} [redraw]
+     *
+     * @return {Highcharts.Annotation} - The newly generated annotation.
+     */
+    addAnnotation: function (userOptions, redraw) {
+        var annotation = this.initAnnotation(userOptions);
+
+        this.options.annotations.push(annotation.options);
+
+        if (pick(redraw, true)) {
+            annotation.redraw();
+        }
+
+        return annotation;
+    },
+
+    /**
+     * Remove an annotation from the chart.
+     *
+     * @param {String|Number|Annotation} idOrAnnotation - The annotation's id or
+     *      direct annotation object.
+     */
+    removeAnnotation: function (idOrAnnotation) {
+        var annotations = this.annotations,
+            annotation = idOrAnnotation.coll === 'annotations' ?
+                idOrAnnotation :
+                find(
+                    annotations,
+                    function (annotation) {
+                        return annotation.options.id === idOrAnnotation;
+                    }
+                );
+
+        if (annotation) {
+            fireEvent(annotation, 'remove');
+            erase(this.options.annotations, annotation.options);
+            erase(annotations, annotation);
+            annotation.destroy();
+        }
+    },
+
+    drawAnnotations: function () {
+        this.plotBoxClip.attr(this.plotBox);
+
+        this.annotations.forEach(function (annotation) {
+            annotation.redraw();
+        });
+    }
+});
+
+// Let chart.update() update annotations
+chartProto.collectionsWithUpdate.push('annotations');
+
+// Let chart.update() create annoations on demand
+chartProto.collectionsWithInit.annotations = [chartProto.addAnnotation];
+
+chartProto.callbacks.push(function (chart) {
+    chart.annotations = [];
+
+    if (!chart.options.annotations) {
+        chart.options.annotations = [];
+    }
+
+    chart.plotBoxClip = this.renderer.clipRect(this.plotBox);
+
+    chart.controlPointsGroup = chart.renderer
+        .g('control-points')
+        .attr({ zIndex: 99 })
+        .clip(chart.plotBoxClip)
+        .add();
+
+    chart.options.annotations.forEach(function (annotationOptions, i) {
+        var annotation = chart.initAnnotation(annotationOptions);
+
+        chart.options.annotations[i] = annotation.options;
+    });
+
+    chart.drawAnnotations();
+    addEvent(chart, 'redraw', chart.drawAnnotations);
+    addEvent(chart, 'destroy', function () {
+        chart.plotBoxClip.destroy();
+        chart.controlPointsGroup.destroy();
+    });
+});
+
+wrap(
+    H.Pointer.prototype,
+    'onContainerMouseDown',
+    function (proceed) {
+        if (!this.chart.hasDraggedAnnotation) {
+            proceed.apply(this, Array.prototype.slice.call(arguments, 1));
+        }
+    }
+);

+ 84 - 0
app/public/js/Highstock-8.0.0/code/es-modules/annotations/controllable/ControllableCircle.js

@@ -0,0 +1,84 @@
+'use strict';
+import H from './../../parts/Globals.js';
+import './../../parts/Utilities.js';
+import controllableMixin from './controllableMixin.js';
+import ControllablePath from './ControllablePath.js';
+
+/**
+ * A controllable circle class.
+ *
+ * @constructor
+ * @mixes Annotation.controllableMixin
+ * @memberOf Annotation
+ *
+ * @param {Highcharts.Annotation} annotation an annotation instance
+ * @param {Object} options a shape's options
+ * @param {number} index of the circle
+ **/
+function ControllableCircle(annotation, options, index) {
+    this.init(annotation, options, index);
+    this.collection = 'shapes';
+}
+
+/**
+ * A map object which allows to map options attributes to element attributes.
+ */
+ControllableCircle.attrsMap = H.merge(ControllablePath.attrsMap, {
+    r: 'r'
+});
+
+H.merge(
+    true,
+    ControllableCircle.prototype,
+    controllableMixin, /** @lends Annotation.ControllableCircle# */ {
+        /**
+         * @type 'circle'
+         */
+        type: 'circle',
+
+        translate: controllableMixin.translateShape,
+
+        render: function (parent) {
+            var attrs = this.attrsFromOptions(this.options);
+
+            this.graphic = this.annotation.chart.renderer
+                .circle(0, -9e9, 0)
+                .attr(attrs)
+                .add(parent);
+
+            controllableMixin.render.call(this);
+        },
+
+        redraw: function (animation) {
+            var position = this.anchor(this.points[0]).absolutePosition;
+
+            if (position) {
+                this.graphic[animation ? 'animate' : 'attr']({
+                    x: position.x,
+                    y: position.y,
+                    r: this.options.r
+                });
+            } else {
+                this.graphic.attr({
+                    x: 0,
+                    y: -9e9
+                });
+            }
+
+            this.graphic.placed = Boolean(position);
+
+            controllableMixin.redraw.call(this, animation);
+        },
+
+        /**
+         * Set the radius.
+         *
+         * @param {number} r a radius to be set
+         */
+        setRadius: function (r) {
+            this.options.r = r;
+        }
+    }
+);
+
+export default ControllableCircle;

+ 93 - 0
app/public/js/Highstock-8.0.0/code/es-modules/annotations/controllable/ControllableImage.js

@@ -0,0 +1,93 @@
+'use strict';
+import H from './../../parts/Globals.js';
+import './../../parts/Utilities.js';
+import controllableMixin from './controllableMixin.js';
+import ControllableLabel from './ControllableLabel.js';
+
+/**
+ * A controllable image class.
+ *
+ * @class
+ * @mixes Annotation.controllableMixin
+ * @memberOf Annotation
+ *
+ * @param {Highcharts.Annotation} annotation - an annotation instance
+ * @param {Object} options a controllable's options
+ * @param {number} index of the image
+ **/
+function ControllableImage(annotation, options, index) {
+    this.init(annotation, options, index);
+    this.collection = 'shapes';
+}
+
+/**
+ * @typedef {Object} Annotation.ControllableImage.AttrsMap
+ * @property {string} width=width
+ * @property {string} height=height
+ * @property {string} zIndex=zIndex
+ */
+
+/**
+ * A map object which allows to map options attributes to element attributes
+ *
+ * @type {Annotation.ControllableImage.AttrsMap}
+ */
+ControllableImage.attrsMap = {
+    width: 'width',
+    height: 'height',
+    zIndex: 'zIndex'
+};
+
+H.merge(
+    true,
+    ControllableImage.prototype,
+    controllableMixin, /** @lends Annotation.ControllableImage# */ {
+        /**
+         * @type 'image'
+         */
+        type: 'image',
+
+        translate: controllableMixin.translateShape,
+
+        render: function (parent) {
+            var attrs = this.attrsFromOptions(this.options),
+                options = this.options;
+
+            this.graphic = this.annotation.chart.renderer
+                .image(options.src, 0, -9e9, options.width, options.height)
+                .attr(attrs)
+                .add(parent);
+
+            this.graphic.width = options.width;
+            this.graphic.height = options.height;
+
+            controllableMixin.render.call(this);
+        },
+
+        redraw: function (animation) {
+            var anchor = this.anchor(this.points[0]),
+                position = ControllableLabel.prototype.position.call(
+                    this,
+                    anchor
+                );
+
+            if (position) {
+                this.graphic[animation ? 'animate' : 'attr']({
+                    x: position.x,
+                    y: position.y
+                });
+            } else {
+                this.graphic.attr({
+                    x: 0,
+                    y: -9e9
+                });
+            }
+
+            this.graphic.placed = Boolean(position);
+
+            controllableMixin.redraw.call(this, animation);
+        }
+    }
+);
+
+export default ControllableImage;

+ 509 - 0
app/public/js/Highstock-8.0.0/code/es-modules/annotations/controllable/ControllableLabel.js

@@ -0,0 +1,509 @@
+'use strict';
+import H from './../../parts/Globals.js';
+
+import U from './../../parts/Utilities.js';
+var extend = U.extend,
+    isNumber = U.isNumber,
+    pick = U.pick;
+
+import './../../parts/SvgRenderer.js';
+import controllableMixin from './controllableMixin.js';
+import MockPoint from './../MockPoint.js';
+
+
+/**
+ * @private
+ * @interface Highcharts.AnnotationAnchorObject
+ *//**
+ * Relative to the plot area position
+ * @name Highcharts.AnnotationAnchorObject#relativePosition
+ * @type {Highcharts.AnnotationAnchorPositionObject}
+ *//**
+ * Absolute position
+ * @name Highcharts.AnnotationAnchorObject#absolutePosition
+ * @type {Highcharts.AnnotationAnchorPositionObject}
+ */
+
+/**
+ * An object which denotes an anchor position
+ *
+ * @private
+ * @interface Highcharts.AnnotationAnchorPositionObject
+ *//**
+ * @name Highcharts.AnnotationAnchorPositionObject#x
+ * @property {number}
+ *//**
+ * @name Highcharts.AnnotationAnchorPositionObject#y
+ * @property {number}
+ *//**
+ * @name Highcharts.AnnotationAnchorPositionObject#height
+ * @property {number}
+ *//**
+ * @name Highcharts.AnnotationAnchorPositionObject#width
+ * @property {number}
+ */
+
+/**
+ * A controllable label class.
+ *
+ * @private
+ * @class
+ * @name Annotation.ControllableLabel
+ *
+ * @mixes Annotation.controllableMixin
+ *
+ * @param {Highcharts.Annotation} annotation an annotation instance
+ * @param {object} options a label's options
+ * @param {number} index of the label
+ **/
+function ControllableLabel(annotation, options, index) {
+    this.init(annotation, options, index);
+    this.collection = 'labels';
+}
+
+/**
+ * Shapes which do not have background - the object is used for proper
+ * setting of the contrast color.
+ *
+ * @type {Array<string>}
+ */
+ControllableLabel.shapesWithoutBackground = ['connector'];
+
+/**
+ * Returns new aligned position based alignment options and box to align to.
+ * It is almost a one-to-one copy from SVGElement.prototype.align
+ * except it does not use and mutate an element
+ *
+ * @param {Object} alignOptions
+ * @param {Object} box
+ * @return {Annotation.controllableMixin.Position} aligned position
+ */
+ControllableLabel.alignedPosition = function (alignOptions, box) {
+    var align = alignOptions.align,
+        vAlign = alignOptions.verticalAlign,
+        x = (box.x || 0) + (alignOptions.x || 0),
+        y = (box.y || 0) + (alignOptions.y || 0),
+
+        alignFactor,
+        vAlignFactor;
+
+    if (align === 'right') {
+        alignFactor = 1;
+    } else if (align === 'center') {
+        alignFactor = 2;
+    }
+    if (alignFactor) {
+        x += (box.width - (alignOptions.width || 0)) / alignFactor;
+    }
+
+    if (vAlign === 'bottom') {
+        vAlignFactor = 1;
+    } else if (vAlign === 'middle') {
+        vAlignFactor = 2;
+    }
+    if (vAlignFactor) {
+        y += (box.height - (alignOptions.height || 0)) / vAlignFactor;
+    }
+
+    return {
+        x: Math.round(x),
+        y: Math.round(y)
+    };
+};
+
+/**
+ * Returns new alignment options for a label if the label is outside the
+ * plot area. It is almost a one-to-one copy from
+ * Series.prototype.justifyDataLabel except it does not mutate the label and
+ * it works with absolute instead of relative position.
+ *
+ * @param {Object} label
+ * @param {Object} alignOptions
+ * @param {Object} alignAttr
+ * @return {Object} justified options
+ **/
+ControllableLabel.justifiedOptions = function (
+    chart,
+    label,
+    alignOptions,
+    alignAttr
+) {
+    var align = alignOptions.align,
+        verticalAlign = alignOptions.verticalAlign,
+        padding = label.box ? 0 : (label.padding || 0),
+        bBox = label.getBBox(),
+        off,
+
+        options = {
+            align: align,
+            verticalAlign: verticalAlign,
+            x: alignOptions.x,
+            y: alignOptions.y,
+            width: label.width,
+            height: label.height
+        },
+
+        x = alignAttr.x - chart.plotLeft,
+        y = alignAttr.y - chart.plotTop;
+
+    // Off left
+    off = x + padding;
+    if (off < 0) {
+        if (align === 'right') {
+            options.align = 'left';
+        } else {
+            options.x = -off;
+        }
+    }
+
+    // Off right
+    off = x + bBox.width - padding;
+    if (off > chart.plotWidth) {
+        if (align === 'left') {
+            options.align = 'right';
+        } else {
+            options.x = chart.plotWidth - off;
+        }
+    }
+
+    // Off top
+    off = y + padding;
+    if (off < 0) {
+        if (verticalAlign === 'bottom') {
+            options.verticalAlign = 'top';
+        } else {
+            options.y = -off;
+        }
+    }
+
+    // Off bottom
+    off = y + bBox.height - padding;
+    if (off > chart.plotHeight) {
+        if (verticalAlign === 'top') {
+            options.verticalAlign = 'bottom';
+        } else {
+            options.y = chart.plotHeight - off;
+        }
+    }
+
+    return options;
+};
+
+/**
+ * @typedef {Object} Annotation.ControllableLabel.AttrsMap
+ * @property {string} backgroundColor=fill
+ * @property {string} borderColor=stroke
+ * @property {string} borderWidth=stroke-width
+ * @property {string} zIndex=zIndex
+ * @property {string} borderRadius=r
+ * @property {string} padding=padding
+ */
+
+/**
+ * A map object which allows to map options attributes to element attributes
+ *
+ * @type {Annotation.ControllableLabel.AttrsMap}
+ */
+ControllableLabel.attrsMap = {
+    backgroundColor: 'fill',
+    borderColor: 'stroke',
+    borderWidth: 'stroke-width',
+    zIndex: 'zIndex',
+    borderRadius: 'r',
+    padding: 'padding'
+};
+
+H.merge(
+    true,
+    ControllableLabel.prototype,
+    controllableMixin, /** @lends Annotation.ControllableLabel# */ {
+        /**
+         * Translate the point of the label by deltaX and deltaY translations.
+         * The point is the label's anchor.
+         *
+         * @param {number} dx translation for x coordinate
+         * @param {number} dy translation for y coordinate
+         **/
+        translatePoint: function (dx, dy) {
+            controllableMixin.translatePoint.call(this, dx, dy, 0);
+        },
+
+        /**
+         * Translate x and y position relative to the label's anchor.
+         *
+         * @param {number} dx translation for x coordinate
+         * @param {number} dy translation for y coordinate
+         **/
+        translate: function (dx, dy) {
+            var chart = this.annotation.chart,
+                // Annotation.options
+                labelOptions = this.annotation.userOptions,
+                // Chart.options.annotations
+                annotationIndex = chart.annotations.indexOf(this.annotation),
+                chartAnnotations = chart.options.annotations,
+                chartOptions = chartAnnotations[annotationIndex],
+                temp;
+
+            if (chart.inverted) {
+                temp = dx;
+                dx = dy;
+                dy = temp;
+            }
+
+            // Local options:
+            this.options.x += dx;
+            this.options.y += dy;
+
+            // Options stored in chart:
+            chartOptions[this.collection][this.index].x = this.options.x;
+            chartOptions[this.collection][this.index].y = this.options.y;
+
+            labelOptions[this.collection][this.index].x = this.options.x;
+            labelOptions[this.collection][this.index].y = this.options.y;
+        },
+
+        render: function (parent) {
+            var options = this.options,
+                attrs = this.attrsFromOptions(options),
+                style = options.style;
+
+            this.graphic = this.annotation.chart.renderer
+                .label(
+                    '',
+                    0,
+                    -9999, // #10055
+                    options.shape,
+                    null,
+                    null,
+                    options.useHTML,
+                    null,
+                    'annotation-label'
+                )
+                .attr(attrs)
+                .add(parent);
+
+            if (!this.annotation.chart.styledMode) {
+                if (style.color === 'contrast') {
+                    style.color = this.annotation.chart.renderer.getContrast(
+                        ControllableLabel.shapesWithoutBackground.indexOf(
+                            options.shape
+                        ) > -1 ? '#FFFFFF' : options.backgroundColor
+                    );
+                }
+                this.graphic
+                    .css(options.style)
+                    .shadow(options.shadow);
+            }
+
+            if (options.className) {
+                this.graphic.addClass(options.className);
+            }
+
+            this.graphic.labelrank = options.labelrank;
+
+            controllableMixin.render.call(this);
+        },
+
+        redraw: function (animation) {
+            var options = this.options,
+                text = this.text || options.format || options.text,
+                label = this.graphic,
+                point = this.points[0],
+                show = false,
+                anchor,
+                attrs;
+
+            label.attr({
+                text: text ?
+                    H.format(
+                        text,
+                        point.getLabelConfig(),
+                        this.annotation.chart
+                    ) :
+                    options.formatter.call(point, this)
+            });
+
+            anchor = this.anchor(point);
+            attrs = this.position(anchor);
+            show = attrs;
+
+            if (show) {
+                label.alignAttr = attrs;
+
+                attrs.anchorX = anchor.absolutePosition.x;
+                attrs.anchorY = anchor.absolutePosition.y;
+
+                label[animation ? 'animate' : 'attr'](attrs);
+            } else {
+                label.attr({
+                    x: 0,
+                    y: -9999 // #10055
+                });
+            }
+
+            label.placed = Boolean(show);
+
+            controllableMixin.redraw.call(this, animation);
+        },
+        /**
+         * All basic shapes don't support alignTo() method except label.
+         * For a controllable label, we need to subtract translation from
+         * options.
+         */
+        anchor: function () {
+            var anchor = controllableMixin.anchor.apply(this, arguments),
+                x = this.options.x || 0,
+                y = this.options.y || 0;
+
+            anchor.absolutePosition.x -= x;
+            anchor.absolutePosition.y -= y;
+
+            anchor.relativePosition.x -= x;
+            anchor.relativePosition.y -= y;
+
+            return anchor;
+        },
+
+        /**
+         * Returns the label position relative to its anchor.
+         *
+         * @param {Highcharts.AnnotationAnchorObject} anchor
+         *
+         * @return {Highcharts.AnnotationAnchorPositionObject|null} position
+         */
+        position: function (anchor) {
+            var item = this.graphic,
+                chart = this.annotation.chart,
+                point = this.points[0],
+                itemOptions = this.options,
+                anchorAbsolutePosition = anchor.absolutePosition,
+                anchorRelativePosition = anchor.relativePosition,
+                itemPosition,
+                alignTo,
+                itemPosRelativeX,
+                itemPosRelativeY,
+
+                showItem =
+                    point.series.visible &&
+                    MockPoint.prototype.isInsidePane.call(point);
+
+            if (showItem) {
+
+                if (itemOptions.distance) {
+                    itemPosition = H.Tooltip.prototype.getPosition.call(
+                        {
+                            chart: chart,
+                            distance: pick(itemOptions.distance, 16)
+                        },
+                        item.width,
+                        item.height,
+                        {
+                            plotX: anchorRelativePosition.x,
+                            plotY: anchorRelativePosition.y,
+                            negative: point.negative,
+                            ttBelow: point.ttBelow,
+                            h: anchorRelativePosition.height ||
+                            anchorRelativePosition.width
+                        }
+                    );
+                } else if (itemOptions.positioner) {
+                    itemPosition = itemOptions.positioner.call(this);
+                } else {
+                    alignTo = {
+                        x: anchorAbsolutePosition.x,
+                        y: anchorAbsolutePosition.y,
+                        width: 0,
+                        height: 0
+                    };
+
+                    itemPosition = ControllableLabel.alignedPosition(
+                        extend(itemOptions, {
+                            width: item.width,
+                            height: item.height
+                        }),
+                        alignTo
+                    );
+
+                    if (this.options.overflow === 'justify') {
+                        itemPosition = ControllableLabel.alignedPosition(
+                            ControllableLabel.justifiedOptions(
+                                chart,
+                                item,
+                                itemOptions,
+                                itemPosition
+                            ),
+                            alignTo
+                        );
+                    }
+                }
+
+
+                if (itemOptions.crop) {
+                    itemPosRelativeX = itemPosition.x - chart.plotLeft;
+                    itemPosRelativeY = itemPosition.y - chart.plotTop;
+
+                    showItem =
+                        chart.isInsidePlot(
+                            itemPosRelativeX,
+                            itemPosRelativeY
+                        ) &&
+                        chart.isInsidePlot(
+                            itemPosRelativeX + item.width,
+                            itemPosRelativeY + item.height
+                        );
+                }
+            }
+
+            return showItem ? itemPosition : null;
+        }
+    }
+);
+
+/* ********************************************************************** */
+
+/**
+ * General symbol definition for labels with connector
+ * @private
+ */
+H.SVGRenderer.prototype.symbols.connector = function (x, y, w, h, options) {
+    var anchorX = options && options.anchorX,
+        anchorY = options && options.anchorY,
+        path,
+        yOffset,
+        lateral = w / 2;
+
+    if (isNumber(anchorX) && isNumber(anchorY)) {
+
+        path = ['M', anchorX, anchorY];
+
+        // Prefer 45 deg connectors
+        yOffset = y - anchorY;
+        if (yOffset < 0) {
+            yOffset = -h - yOffset;
+        }
+        if (yOffset < w) {
+            lateral = anchorX < x + (w / 2) ? yOffset : w - yOffset;
+        }
+
+        // Anchor below label
+        if (anchorY > y + h) {
+            path.push('L', x + lateral, y + h);
+
+            // Anchor above label
+        } else if (anchorY < y) {
+            path.push('L', x + lateral, y);
+
+            // Anchor left of label
+        } else if (anchorX < x) {
+            path.push('L', x, y + h / 2);
+
+            // Anchor right of label
+        } else if (anchorX > x + w) {
+            path.push('L', x + w, y + h / 2);
+        }
+    }
+
+    return path || [];
+};
+
+export default ControllableLabel;

+ 177 - 0
app/public/js/Highstock-8.0.0/code/es-modules/annotations/controllable/ControllablePath.js

@@ -0,0 +1,177 @@
+'use strict';
+import H from './../../parts/Globals.js';
+import U from './../../parts/Utilities.js';
+var extend = U.extend;
+
+import controllableMixin from './controllableMixin.js';
+import markerMixin from './markerMixin.js';
+
+// See TRACKER_FILL in highcharts.src.js
+var TRACKER_FILL = 'rgba(192,192,192,' + (H.svg ? 0.0001 : 0.002) + ')';
+
+/**
+ * A controllable path class.
+ *
+ * @class
+ * @mixes Annotation.controllableMixin
+ * @mixes Annotation.markerMixin
+ * @memberOf Annotation
+ *
+ * @param {Highcharts.Annotation}
+ * @param {Object} options a path's options object
+ * @param {number} index of the path
+ **/
+function ControllablePath(annotation, options, index) {
+    this.init(annotation, options, index);
+    this.collection = 'shapes';
+}
+
+/**
+ * @typedef {Object} Annotation.ControllablePath.AttrsMap
+ * @property {string} dashStyle=dashstyle
+ * @property {string} strokeWidth=stroke-width
+ * @property {string} stroke=stroke
+ * @property {string} fill=fill
+ * @property {string} zIndex=zIndex
+ */
+
+/**
+ * A map object which allows to map options attributes to element attributes
+ *
+ * @type {Annotation.ControllablePath.AttrsMap}
+ */
+ControllablePath.attrsMap = {
+    dashStyle: 'dashstyle',
+    strokeWidth: 'stroke-width',
+    stroke: 'stroke',
+    fill: 'fill',
+    zIndex: 'zIndex'
+};
+
+H.merge(
+    true,
+    ControllablePath.prototype,
+    controllableMixin, /** @lends Annotation.ControllablePath# */ {
+        /**
+         * @type 'path'
+         */
+        type: 'path',
+
+        setMarkers: markerMixin.setItemMarkers,
+
+        /**
+         * Map the controllable path to 'd' path attribute
+         *
+         * @return {Array<(string|number)>} a path's d attribute
+         */
+        toD: function () {
+            var d = this.options.d;
+
+            if (d) {
+                return typeof d === 'function' ?
+                    d.call(this) :
+                    d;
+            }
+
+            var points = this.points,
+                len = points.length,
+                showPath = len,
+                point = points[0],
+                position = showPath && this.anchor(point).absolutePosition,
+                pointIndex = 0,
+                dIndex = 2,
+                command;
+
+            d = position && ['M', position.x, position.y];
+
+            while (++pointIndex < len && showPath) {
+                point = points[pointIndex];
+                command = point.command || 'L';
+                position = this.anchor(point).absolutePosition;
+
+                if (command === 'Z') {
+                    d[++dIndex] = command;
+                } else {
+                    if (command !== points[pointIndex - 1].command) {
+                        d[++dIndex] = command;
+                    }
+
+                    d[++dIndex] = position.x;
+                    d[++dIndex] = position.y;
+                }
+
+                showPath = point.series.visible;
+            }
+
+            return showPath ?
+                this.chart.renderer.crispLine(d, this.graphic.strokeWidth()) :
+                null;
+        },
+
+        shouldBeDrawn: function () {
+            return controllableMixin.shouldBeDrawn.call(this) ||
+                Boolean(this.options.d);
+        },
+
+        render: function (parent) {
+            var options = this.options,
+                attrs = this.attrsFromOptions(options);
+
+            this.graphic = this.annotation.chart.renderer
+                .path(['M', 0, 0])
+                .attr(attrs)
+                .add(parent);
+
+            if (options.className) {
+                this.graphic.addClass(options.className);
+            }
+
+            this.tracker = this.annotation.chart.renderer
+                .path(['M', 0, 0])
+                .addClass('highcharts-tracker-line')
+                .attr({
+                    zIndex: 2
+                })
+                .add(parent);
+
+            if (!this.annotation.chart.styledMode) {
+                this.tracker.attr({
+                    'stroke-linejoin': 'round', // #1225
+                    stroke: TRACKER_FILL,
+                    fill: TRACKER_FILL,
+                    'stroke-width': this.graphic.strokeWidth() +
+                        options.snap * 2
+                });
+            }
+
+            controllableMixin.render.call(this);
+
+            extend(this.graphic, {
+                markerStartSetter: markerMixin.markerStartSetter,
+                markerEndSetter: markerMixin.markerEndSetter
+            });
+
+            this.setMarkers(this);
+        },
+
+        redraw: function (animation) {
+
+            var d = this.toD(),
+                action = animation ? 'animate' : 'attr';
+
+            if (d) {
+                this.graphic[action]({ d: d });
+                this.tracker[action]({ d: d });
+            } else {
+                this.graphic.attr({ d: 'M 0 ' + -9e9 });
+                this.tracker.attr({ d: 'M 0 ' + -9e9 });
+            }
+
+            this.graphic.placed = this.tracker.placed = Boolean(d);
+
+            controllableMixin.redraw.call(this, animation);
+        }
+    }
+);
+
+export default ControllablePath;

+ 85 - 0
app/public/js/Highstock-8.0.0/code/es-modules/annotations/controllable/ControllableRect.js

@@ -0,0 +1,85 @@
+import H from '../../parts/Globals.js';
+import '../../parts/Utilities.js';
+import controllableMixin from './controllableMixin.js';
+import ControllablePath from './ControllablePath.js';
+
+/**
+ * A controllable rect class.
+ *
+ * @class
+ * @mixes Annotation.controllableMixin
+ * @memberOf Annotation
+ *
+ * @param {Highcharts.Annotation} annotation an annotation instance
+ * @param {Object} options a rect's options
+ * @param {number} index of the rectangle
+ **/
+function ControllableRect(annotation, options, index) {
+    this.init(annotation, options, index);
+    this.collection = 'shapes';
+}
+
+/**
+ * @typedef {Annotation.ControllablePath.AttrsMap}
+ *          Annotation.ControllableRect.AttrsMap
+ * @property {string} width=width
+ * @property {string} height=height
+ */
+
+/**
+ * A map object which allows to map options attributes to element attributes
+ *
+ * @type {Annotation.ControllableRect.AttrsMap}
+ */
+ControllableRect.attrsMap = H.merge(ControllablePath.attrsMap, {
+    width: 'width',
+    height: 'height'
+});
+
+H.merge(
+    true,
+    ControllableRect.prototype,
+    controllableMixin, /** @lends Annotation.ControllableRect# */ {
+        /**
+         * @type 'rect'
+         */
+        type: 'rect',
+
+        translate: controllableMixin.translateShape,
+
+        render: function (parent) {
+            var attrs = this.attrsFromOptions(this.options);
+
+            this.graphic = this.annotation.chart.renderer
+                .rect(0, -9e9, 0, 0)
+                .attr(attrs)
+                .add(parent);
+
+            controllableMixin.render.call(this);
+        },
+
+        redraw: function (animation) {
+            var position = this.anchor(this.points[0]).absolutePosition;
+
+            if (position) {
+                this.graphic[animation ? 'animate' : 'attr']({
+                    x: position.x,
+                    y: position.y,
+                    width: this.options.width,
+                    height: this.options.height
+                });
+            } else {
+                this.attr({
+                    x: 0,
+                    y: -9e9
+                });
+            }
+
+            this.graphic.placed = Boolean(position);
+
+            controllableMixin.redraw.call(this, animation);
+        }
+    }
+);
+
+export default ControllableRect;

+ 444 - 0
app/public/js/Highstock-8.0.0/code/es-modules/annotations/controllable/controllableMixin.js

@@ -0,0 +1,444 @@
+'use strict';
+import H from './../../parts/Globals.js';
+
+import U from './../../parts/Utilities.js';
+var isObject = U.isObject,
+    isString = U.isString,
+    splat = U.splat;
+
+import './../../parts/Tooltip.js';
+import ControlPoint from './../ControlPoint.js';
+import MockPoint from './../MockPoint.js';
+
+/**
+ * It provides methods for handling points, control points
+ * and points transformations.
+ *
+ * @private
+ * @mixin
+ * @memberOf Annotation
+ */
+var controllableMixin = {
+    /**
+     * Init the controllable
+     *
+     * @param {Annotation} annotation - an annotation instance
+     * @param {Object} options - options specific for controllable
+     * @param {number} index - index of the controllable element
+     **/
+    init: function (annotation, options, index) {
+        this.annotation = annotation;
+        this.chart = annotation.chart;
+        this.options = options;
+        this.points = [];
+        this.controlPoints = [];
+        this.index = index;
+
+        this.linkPoints();
+        this.addControlPoints();
+    },
+
+    /**
+     * Redirect attr usage on the controllable graphic element.
+     **/
+    attr: function () {
+        this.graphic.attr.apply(this.graphic, arguments);
+    },
+
+
+    /**
+     * Get the controllable's points options.
+     *
+     * @return {Array<PointLikeOptions>} - an array of points' options.
+     *
+     */
+    getPointsOptions: function () {
+        var options = this.options;
+
+        return options.points || (options.point && splat(options.point));
+    },
+
+    /**
+     * Utility function for mapping item's options
+     * to element's attribute
+     *
+     * @param {Object} options
+     * @return {Object} mapped options
+     **/
+    attrsFromOptions: function (options) {
+        var map = this.constructor.attrsMap,
+            attrs = {},
+            key,
+            mappedKey,
+            styledMode = this.chart.styledMode;
+
+        for (key in options) {
+            mappedKey = map[key];
+
+            if (
+                mappedKey &&
+                (
+                    !styledMode ||
+                    ['fill', 'stroke', 'stroke-width']
+                        .indexOf(mappedKey) === -1
+                )
+            ) {
+                attrs[mappedKey] = options[key];
+            }
+        }
+
+        return attrs;
+    },
+
+    /**
+     * @typedef {Object} Annotation.controllableMixin.Position
+     * @property {number} x
+     * @property {number} y
+     */
+
+    /**
+     * An object which denotes an anchor position
+     *
+     * @typedef Annotation.controllableMixin.AnchorPosition
+     *          Annotation.controllableMixin.Position
+     * @property {number} height
+     * @property {number} width
+     */
+
+    /**
+     * An object which denots a controllable's anchor positions
+     * - relative and absolute.
+     *
+     * @typedef {Object} Annotation.controllableMixin.Anchor
+     * @property {Annotation.controllableMixin.AnchorPosition} relativePosition
+     * @property {Annotation.controllableMixin.AnchorPosition} absolutePosition
+     */
+
+    /**
+     * Returns object which denotes anchor position - relative and absolute.
+     *
+     * @param {Annotation.PointLike} point a point like object
+     * @return {Annotation.controllableMixin.Anchor} a controllable anchor
+     */
+    anchor: function (point) {
+        var plotBox = point.series.getPlotBox(),
+
+            box = point.mock ?
+                point.toAnchor() :
+                H.Tooltip.prototype.getAnchor.call({
+                    chart: point.series.chart
+                }, point),
+
+            anchor = {
+                x: box[0] + (this.options.x || 0),
+                y: box[1] + (this.options.y || 0),
+                height: box[2] || 0,
+                width: box[3] || 0
+            };
+
+        return {
+            relativePosition: anchor,
+            absolutePosition: H.merge(anchor, {
+                x: anchor.x + plotBox.translateX,
+                y: anchor.y + plotBox.translateY
+            })
+        };
+    },
+
+    /**
+     * Map point's options to a point-like object.
+     *
+     * @param {Highcharts.MockPointOptionsObject} pointOptions
+     *        point's options
+     * @param {Highcharts.PointLike} point
+     *        a point like instance
+     *
+     * @return {Highcharts.PointLike|null}
+     *         if the point is found/set returns this point, otherwise null
+     */
+    point: function (pointOptions, point) {
+        if (pointOptions && pointOptions.series) {
+            return pointOptions;
+        }
+
+        if (!point || point.series === null) {
+            if (isObject(pointOptions)) {
+                point = new MockPoint(
+                    this.chart,
+                    this,
+                    pointOptions
+                );
+            } else if (isString(pointOptions)) {
+                point = this.chart.get(pointOptions) || null;
+            } else if (typeof pointOptions === 'function') {
+                var pointConfig = pointOptions.call(point, this);
+
+                point = pointConfig.series ?
+                    pointConfig :
+                    new MockPoint(
+                        this.chart,
+                        this,
+                        pointOptions
+                    );
+            }
+        }
+
+        return point;
+    },
+
+    /**
+     * Find point-like objects based on points options.
+     *
+     * @return {Array<Annotation.PointLike>} an array of point-like objects
+     */
+    linkPoints: function () {
+        var pointsOptions = this.getPointsOptions(),
+            points = this.points,
+            len = (pointsOptions && pointsOptions.length) || 0,
+            i,
+            point;
+
+        for (i = 0; i < len; i++) {
+            point = this.point(pointsOptions[i], points[i]);
+
+            if (!point) {
+                points.length = 0;
+
+                return;
+            }
+
+            if (point.mock) {
+                point.refresh();
+            }
+
+            points[i] = point;
+        }
+
+        return points;
+    },
+
+
+    /**
+     * Add control points to a controllable.
+     */
+    addControlPoints: function () {
+        var controlPointsOptions = this.options.controlPoints;
+
+        (controlPointsOptions || []).forEach(
+            function (controlPointOptions, i) {
+                var options = H.merge(
+                    this.options.controlPointOptions,
+                    controlPointOptions
+                );
+
+                if (!options.index) {
+                    options.index = i;
+                }
+
+                controlPointsOptions[i] = options;
+
+                this.controlPoints.push(
+                    new ControlPoint(this.chart, this, options)
+                );
+            },
+            this
+        );
+    },
+
+    /**
+     * Check if a controllable should be rendered/redrawn.
+     *
+     * @return {boolean} whether a controllable should be drawn.
+     */
+    shouldBeDrawn: function () {
+        return Boolean(this.points.length);
+    },
+
+    /**
+     * Render a controllable.
+     **/
+    render: function () {
+        this.controlPoints.forEach(function (controlPoint) {
+            controlPoint.render();
+        });
+    },
+
+    /**
+     * Redraw a controllable.
+     *
+     * @param {boolean} animation
+     **/
+    redraw: function (animation) {
+        this.controlPoints.forEach(function (controlPoint) {
+            controlPoint.redraw(animation);
+        });
+    },
+
+    /**
+     * Transform a controllable with a specific transformation.
+     *
+     * @param {string} transformation a transformation name
+     * @param {number} cx origin x transformation
+     * @param {number} cy origin y transformation
+     * @param {number} p1 param for the transformation
+     * @param {number} p2 param for the transformation
+     **/
+    transform: function (transformation, cx, cy, p1, p2) {
+        if (this.chart.inverted) {
+            var temp = cx;
+
+            cx = cy;
+            cy = temp;
+        }
+
+        this.points.forEach(function (point, i) {
+            this.transformPoint(transformation, cx, cy, p1, p2, i);
+        }, this);
+    },
+
+    /**
+     * Transform a point with a specific transformation
+     * If a transformed point is a real point it is replaced with
+     * the mock point.
+     *
+     * @param {string} transformation a transformation name
+     * @param {number} cx origin x transformation
+     * @param {number} cy origin y transformation
+     * @param {number} p1 param for the transformation
+     * @param {number} p2 param for the transformation
+     * @param {number} i index of the point
+     *
+     **/
+    transformPoint: function (transformation, cx, cy, p1, p2, i) {
+        var point = this.points[i];
+
+        if (!point.mock) {
+            point = this.points[i] = MockPoint.fromPoint(point);
+        }
+
+        point[transformation](cx, cy, p1, p2);
+    },
+
+    /**
+     * Translate a controllable.
+     *
+     * @param {number} dx translation for x coordinate
+     * @param {number} dy translation for y coordinate
+     **/
+    translate: function (dx, dy) {
+        this.transform('translate', null, null, dx, dy);
+    },
+
+    /**
+     * Translate a specific point within a controllable.
+     *
+     * @param {number} dx translation for x coordinate
+     * @param {number} dy translation for y coordinate
+     * @param {number} i index of the point
+     **/
+    translatePoint: function (dx, dy, i) {
+        this.transformPoint('translate', null, null, dx, dy, i);
+    },
+
+    /**
+     * Translate shape within controllable item.
+     * Replaces `controllable.translate` method.
+     *
+     * @param {number} dx translation for x coordinate
+     * @param {number} dy translation for y coordinate
+     */
+    translateShape: function (dx, dy) {
+        var chart = this.annotation.chart,
+            // Annotation.options
+            shapeOptions = this.annotation.userOptions,
+            // Chart.options.annotations
+            annotationIndex = chart.annotations.indexOf(this.annotation),
+            chartOptions = chart.options.annotations[annotationIndex];
+
+        this.translatePoint(dx, dy, 0);
+
+        // Options stored in:
+        // - chart (for exporting)
+        // - current config (for redraws)
+        chartOptions[this.collection][this.index].point = this.options.point;
+        shapeOptions[this.collection][this.index].point = this.options.point;
+    },
+
+    /**
+     * Rotate a controllable.
+     *
+     * @param {number} cx origin x rotation
+     * @param {number} cy origin y rotation
+     * @param {number} radians
+     **/
+    rotate: function (cx, cy, radians) {
+        this.transform('rotate', cx, cy, radians);
+    },
+
+    /**
+     * Scale a controllable.
+     *
+     * @param {number} cx origin x rotation
+     * @param {number} cy origin y rotation
+     * @param {number} sx scale factor x
+     * @param {number} sy scale factor y
+     */
+    scale: function (cx, cy, sx, sy) {
+        this.transform('scale', cx, cy, sx, sy);
+    },
+
+    /**
+     * Set control points' visibility.
+     *
+     * @param {boolean} [visible]
+     */
+    setControlPointsVisibility: function (visible) {
+        this.controlPoints.forEach(function (controlPoint) {
+            controlPoint.setVisibility(visible);
+        });
+    },
+
+    /**
+     * Destroy a controllable.
+     */
+    destroy: function () {
+        if (this.graphic) {
+            this.graphic = this.graphic.destroy();
+        }
+
+        if (this.tracker) {
+            this.tracker = this.tracker.destroy();
+        }
+
+        this.controlPoints.forEach(function (controlPoint) {
+            controlPoint.destroy();
+        });
+
+        this.chart = null;
+        this.points = null;
+        this.controlPoints = null;
+        this.options = null;
+
+        if (this.annotation) {
+            this.annotation = null;
+        }
+    },
+
+    /**
+     * Update a controllable.
+     *
+     * @param {Object} newOptions
+     */
+    update: function (newOptions) {
+        var annotation = this.annotation,
+            options = H.merge(true, this.options, newOptions),
+            parentGroup = this.graphic.parentGroup;
+
+        this.destroy();
+        this.constructor(annotation, options);
+        this.render(parentGroup);
+        this.redraw();
+    }
+};
+
+export default controllableMixin;

+ 220 - 0
app/public/js/Highstock-8.0.0/code/es-modules/annotations/controllable/markerMixin.js

@@ -0,0 +1,220 @@
+'use strict';
+import H from './../../parts/Globals.js';
+import './../../parts/Chart.js';
+
+import U from './../../parts/Utilities.js';
+var defined = U.defined,
+    objectEach = U.objectEach,
+    splat = U.splat;
+
+import './../../parts/SvgRenderer.js';
+
+/**
+ * Options for configuring markers for annotations.
+ *
+ * An example of the arrow marker:
+ * <pre>
+ * {
+ *   arrow: {
+ *     id: 'arrow',
+ *     tagName: 'marker',
+ *     refY: 5,
+ *     refX: 5,
+ *     markerWidth: 10,
+ *     markerHeight: 10,
+ *     children: [{
+ *       tagName: 'path',
+ *       attrs: {
+ *         d: 'M 0 0 L 10 5 L 0 10 Z',
+ *         strokeWidth: 0
+ *       }
+ *     }]
+ *   }
+ * }
+ * </pre>
+ * @type {Object}
+ * @sample highcharts/annotations/custom-markers/
+ *         Define a custom marker for annotations
+ * @sample highcharts/css/annotations-markers/
+ *         Define markers in a styled mode
+ * @since 6.0.0
+ * @apioption defs
+ */
+var defaultMarkers = {
+    arrow: {
+        tagName: 'marker',
+        render: false,
+        id: 'arrow',
+        refY: 5,
+        refX: 9,
+        markerWidth: 10,
+        markerHeight: 10,
+        children: [{
+            tagName: 'path',
+            d: 'M 0 0 L 10 5 L 0 10 Z', // triangle (used as an arrow)
+            strokeWidth: 0
+        }]
+    },
+
+    'reverse-arrow': {
+        tagName: 'marker',
+        render: false,
+        id: 'reverse-arrow',
+        refY: 5,
+        refX: 1,
+        markerWidth: 10,
+        markerHeight: 10,
+        children: [{
+            tagName: 'path',
+            // reverse triangle (used as an arrow)
+            d: 'M 0 5 L 10 0 L 10 10 Z',
+            strokeWidth: 0
+        }]
+    }
+};
+
+H.SVGRenderer.prototype.addMarker = function (id, markerOptions) {
+    var options = { id: id };
+
+    var attrs = {
+        stroke: markerOptions.color || 'none',
+        fill: markerOptions.color || 'rgba(0, 0, 0, 0.75)'
+    };
+
+    options.children = markerOptions.children.map(function (child) {
+        return H.merge(attrs, child);
+    });
+
+    var marker = this.definition(H.merge(true, {
+        markerWidth: 20,
+        markerHeight: 20,
+        refX: 0,
+        refY: 0,
+        orient: 'auto'
+    }, markerOptions, options));
+
+    marker.id = id;
+
+    return marker;
+};
+
+var createMarkerSetter = function (markerType) {
+    return function (value) {
+        this.attr(markerType, 'url(#' + value + ')');
+    };
+};
+
+/**
+ * @private
+ * @mixin
+ */
+var markerMixin = {
+    markerEndSetter: createMarkerSetter('marker-end'),
+    markerStartSetter: createMarkerSetter('marker-start'),
+
+    /*
+     * Set markers.
+     *
+     * @param {Controllable} item
+     */
+    setItemMarkers: function (item) {
+        var itemOptions = item.options,
+            chart = item.chart,
+            defs = chart.options.defs,
+            fill = itemOptions.fill,
+            color = defined(fill) && fill !== 'none' ?
+                fill :
+                itemOptions.stroke,
+
+            setMarker = function (markerType) {
+                var markerId = itemOptions[markerType],
+                    def,
+                    predefinedMarker,
+                    key,
+                    marker;
+
+                if (markerId) {
+                    for (key in defs) {
+                        def = defs[key];
+
+                        if (
+                            markerId === def.id && def.tagName === 'marker'
+                        ) {
+                            predefinedMarker = def;
+                            break;
+                        }
+                    }
+
+                    if (predefinedMarker) {
+                        marker = item[markerType] = chart.renderer
+                            .addMarker(
+                                (itemOptions.id || H.uniqueKey()) + '-' +
+                                predefinedMarker.id,
+                                H.merge(predefinedMarker, { color: color })
+                            );
+
+                        item.attr(markerType, marker.attr('id'));
+                    }
+                }
+            };
+
+        ['markerStart', 'markerEnd'].forEach(setMarker);
+    }
+};
+
+// In a styled mode definition is implemented
+H.SVGRenderer.prototype.definition = function (def) {
+    var ren = this;
+
+    function recurse(config, parent) {
+        var ret;
+
+        splat(config).forEach(function (item) {
+            var node = ren.createElement(item.tagName),
+                attr = {};
+
+            // Set attributes
+            objectEach(item, function (val, key) {
+                if (
+                    key !== 'tagName' &&
+                    key !== 'children' &&
+                    key !== 'textContent'
+                ) {
+                    attr[key] = val;
+                }
+            });
+            node.attr(attr);
+
+            // Add to the tree
+            node.add(parent || ren.defs);
+
+            // Add text content
+            if (item.textContent) {
+                node.element.appendChild(
+                    H.doc.createTextNode(item.textContent)
+                );
+            }
+
+            // Recurse
+            recurse(item.children || [], node);
+
+            ret = node;
+        });
+
+        // Return last node added (on top level it's the only one)
+        return ret;
+    }
+    return recurse(def);
+};
+
+H.addEvent(H.Chart, 'afterGetContainer', function () {
+    this.options.defs = H.merge(defaultMarkers, this.options.defs || {});
+
+    objectEach(this.options.defs, function (def) {
+        if (def.tagName === 'marker' && def.render !== false) {
+            this.renderer.addMarker(def.id, def);
+        }
+    }, this);
+});
+
+export default markerMixin;

+ 286 - 0
app/public/js/Highstock-8.0.0/code/es-modules/annotations/eventEmitterMixin.js

@@ -0,0 +1,286 @@
+import H from '../parts/Globals.js';
+import U from '../parts/Utilities.js';
+var objectEach = U.objectEach,
+    pick = U.pick;
+
+var fireEvent = H.fireEvent;
+
+/**
+ * It provides methods for:
+ * - adding and handling DOM events and a drag event,
+ * - mapping a mouse move event to the distance between two following events.
+ *   The units of the distance are specific to a transformation,
+ *   e.g. for rotation they are radians, for scaling they are scale factors.
+ *
+ * @private
+ * @mixin
+ * @memberOf Annotation
+ */
+var eventEmitterMixin = {
+    /**
+     * Add emitter events.
+     */
+    addEvents: function () {
+        var emitter = this;
+
+        H.addEvent(
+            emitter.graphic.element,
+            'mousedown',
+            function (e) {
+                emitter.onMouseDown(e);
+            }
+        );
+
+        objectEach(emitter.options.events, function (event, type) {
+            var eventHandler = function (e) {
+                if (type !== 'click' || !emitter.cancelClick) {
+                    event.call(
+                        emitter,
+                        emitter.chart.pointer.normalize(e),
+                        emitter.target
+                    );
+                }
+            };
+
+            if (H.inArray(type, emitter.nonDOMEvents || []) === -1) {
+                emitter.graphic.on(type, eventHandler);
+            } else {
+                H.addEvent(emitter, type, eventHandler);
+            }
+        });
+
+        if (emitter.options.draggable) {
+
+            H.addEvent(emitter, 'drag', emitter.onDrag);
+
+            if (!emitter.graphic.renderer.styledMode) {
+                emitter.graphic.css({
+                    cursor: {
+                        x: 'ew-resize',
+                        y: 'ns-resize',
+                        xy: 'move'
+                    }[emitter.options.draggable]
+                });
+            }
+        }
+
+        if (!emitter.isUpdating) {
+            fireEvent(emitter, 'add');
+        }
+    },
+
+    /**
+     * Remove emitter document events.
+     */
+    removeDocEvents: function () {
+        if (this.removeDrag) {
+            this.removeDrag = this.removeDrag();
+        }
+
+        if (this.removeMouseUp) {
+            this.removeMouseUp = this.removeMouseUp();
+        }
+    },
+
+    /**
+     * Mouse down handler.
+     *
+     * @param {Object} e event
+     */
+    onMouseDown: function (e) {
+        var emitter = this,
+            pointer = emitter.chart.pointer,
+            prevChartX,
+            prevChartY;
+
+        if (e.preventDefault) {
+            e.preventDefault();
+        }
+
+        // On right click, do nothing:
+        if (e.button === 2) {
+            return;
+        }
+
+        e = pointer.normalize(e);
+        prevChartX = e.chartX;
+        prevChartY = e.chartY;
+
+        emitter.cancelClick = false;
+        emitter.chart.hasDraggedAnnotation = true;
+
+        emitter.removeDrag = H.addEvent(
+            H.doc,
+            'mousemove',
+            function (e) {
+                emitter.hasDragged = true;
+
+                e = pointer.normalize(e);
+                e.prevChartX = prevChartX;
+                e.prevChartY = prevChartY;
+
+                fireEvent(emitter, 'drag', e);
+
+                prevChartX = e.chartX;
+                prevChartY = e.chartY;
+            }
+        );
+
+        emitter.removeMouseUp = H.addEvent(
+            H.doc,
+            'mouseup',
+            function (e) {
+                emitter.cancelClick = emitter.hasDragged;
+                emitter.hasDragged = false;
+                emitter.chart.hasDraggedAnnotation = false;
+                // ControlPoints vs Annotation:
+                fireEvent(pick(emitter.target, emitter), 'afterUpdate');
+                emitter.onMouseUp(e);
+            }
+        );
+    },
+
+    /**
+     * Mouse up handler.
+     *
+     * @param {Object} e event
+     */
+    onMouseUp: function () {
+        var chart = this.chart,
+            annotation = this.target || this,
+            annotationsOptions = chart.options.annotations,
+            index = chart.annotations.indexOf(annotation);
+
+        this.removeDocEvents();
+
+        annotationsOptions[index] = annotation.options;
+    },
+
+    /**
+     * Drag and drop event. All basic annotations should share this
+     * capability as well as the extended ones.
+     *
+     * @param {Object} e event
+     */
+    onDrag: function (e) {
+        if (
+            this.chart.isInsidePlot(
+                e.chartX - this.chart.plotLeft,
+                e.chartY - this.chart.plotTop
+            )
+        ) {
+            var translation = this.mouseMoveToTranslation(e);
+
+            if (this.options.draggable === 'x') {
+                translation.y = 0;
+            }
+
+            if (this.options.draggable === 'y') {
+                translation.x = 0;
+            }
+
+            if (this.points.length) {
+                this.translate(translation.x, translation.y);
+            } else {
+                this.shapes.forEach(function (shape) {
+                    shape.translate(translation.x, translation.y);
+                });
+                this.labels.forEach(function (label) {
+                    label.translate(translation.x, translation.y);
+                });
+            }
+
+            this.redraw(false);
+        }
+    },
+
+    /**
+     * Map mouse move event to the radians.
+     *
+     * @param {Object} e event
+     * @param {number} cx center x
+     * @param {number} cy center y
+     */
+    mouseMoveToRadians: function (e, cx, cy) {
+        var prevDy = e.prevChartY - cy,
+            prevDx = e.prevChartX - cx,
+            dy = e.chartY - cy,
+            dx = e.chartX - cx,
+            temp;
+
+        if (this.chart.inverted) {
+            temp = prevDx;
+            prevDx = prevDy;
+            prevDy = temp;
+
+            temp = dx;
+            dx = dy;
+            dy = temp;
+        }
+
+        return Math.atan2(dy, dx) - Math.atan2(prevDy, prevDx);
+    },
+
+    /**
+     * Map mouse move event to the distance between two following events.
+     *
+     * @param {Object} e event
+     */
+    mouseMoveToTranslation: function (e) {
+        var dx = e.chartX - e.prevChartX,
+            dy = e.chartY - e.prevChartY,
+            temp;
+
+        if (this.chart.inverted) {
+            temp = dy;
+            dy = dx;
+            dx = temp;
+        }
+
+        return {
+            x: dx,
+            y: dy
+        };
+    },
+
+    /**
+     * Map mouse move to the scale factors.
+     *
+     * @param {Object} e event
+     * @param {number} cx center x
+     * @param {number} cy center y
+     **/
+    mouseMoveToScale: function (e, cx, cy) {
+        var prevDx = e.prevChartX - cx,
+            prevDy = e.prevChartY - cy,
+            dx = e.chartX - cx,
+            dy = e.chartY - cy,
+            sx = (dx || 1) / (prevDx || 1),
+            sy = (dy || 1) / (prevDy || 1),
+            temp;
+
+        if (this.chart.inverted) {
+            temp = sy;
+            sy = sx;
+            sx = temp;
+        }
+
+        return {
+            x: sx,
+            y: sy
+        };
+    },
+
+    /**
+     * Destroy the event emitter.
+     */
+    destroy: function () {
+        this.removeDocEvents();
+
+        H.removeEvent(this);
+
+        this.hcEvents = null;
+    }
+};
+
+export default eventEmitterMixin;

+ 1397 - 0
app/public/js/Highstock-8.0.0/code/es-modules/annotations/navigationBindings.js

@@ -0,0 +1,1397 @@
+/* *
+ *
+ *  (c) 2009-2017 Highsoft, Black Label
+ *
+ *  License: www.highcharts.com/license
+ *
+ * */
+'use strict';
+import H from '../parts/Globals.js';
+
+import U from '../parts/Utilities.js';
+var attr = U.attr,
+    extend = U.extend,
+    isArray = U.isArray,
+    isNumber = U.isNumber,
+    isObject = U.isObject,
+    objectEach = U.objectEach,
+    pick = U.pick;
+
+import chartNavigationMixin from '../mixins/navigation.js';
+
+var doc = H.doc,
+    win = H.win,
+    addEvent = H.addEvent,
+    merge = H.merge,
+    fireEvent = H.fireEvent,
+    PREFIX = 'highcharts-';
+
+// IE 9-11 polyfill for Element.closest():
+function closestPolyfill(el, s) {
+    var ElementProto = win.Element.prototype,
+        elementMatches =
+            ElementProto.matches ||
+            ElementProto.msMatchesSelector ||
+            ElementProto.webkitMatchesSelector,
+        ret = null;
+
+    if (ElementProto.closest) {
+        ret = ElementProto.closest.call(el, s);
+    } else {
+        do {
+            if (elementMatches.call(el, s)) {
+                return el;
+            }
+            el = el.parentElement || el.parentNode;
+
+        } while (el !== null && el.nodeType === 1);
+    }
+    return ret;
+}
+
+
+/**
+ * @private
+ * @interface bindingsUtils
+ */
+var bindingsUtils = {
+    /**
+     * Update size of background (rect) in some annotations: Measure, Simple
+     * Rect.
+     *
+     * @private
+     * @function bindingsUtils.updateRectSize
+     *
+     * @param {global.Event} event
+     *        Normalized browser event
+     *
+     * @param {Highcharts.Annotation} annotation
+     *        Annotation to be updated
+     */
+    updateRectSize: function (event, annotation) {
+        var chart = annotation.chart,
+            options = annotation.options.typeOptions,
+            coords = chart.pointer.getCoordinates(event),
+            width = coords.xAxis[0].value - options.point.x,
+            height = options.point.y - coords.yAxis[0].value;
+
+        annotation.update({
+            typeOptions: {
+                background: {
+                    width: chart.inverted ? height : width,
+                    height: chart.inverted ? width : height
+                }
+            }
+        });
+    },
+
+    /**
+     * Get field type according to value
+     *
+     * @private
+     * @function bindingsUtils.getFieldType
+     *
+     * @param {*} value
+     *        Atomic type (one of: string, number, boolean)
+     *
+     * @return {string}
+     *         Field type (one of: text, number, checkbox)
+     */
+    getFieldType: function (value) {
+        return {
+            'string': 'text',
+            'number': 'number',
+            'boolean': 'checkbox'
+        }[typeof value];
+    }
+};
+
+H.NavigationBindings = function (chart, options) {
+    this.chart = chart;
+    this.options = options;
+    this.eventsToUnbind = [];
+    this.container = doc.getElementsByClassName(
+        this.options.bindingsClassName
+    );
+};
+
+// Define which options from annotations should show up in edit box:
+H.NavigationBindings.annotationsEditable = {
+    // `typeOptions` are always available
+    // Nested and shared options:
+    nestedOptions: {
+        labelOptions: ['style', 'format', 'backgroundColor'],
+        labels: ['style'],
+        label: ['style'],
+        style: ['fontSize', 'color'],
+        background: ['fill', 'strokeWidth', 'stroke'],
+        innerBackground: ['fill', 'strokeWidth', 'stroke'],
+        outerBackground: ['fill', 'strokeWidth', 'stroke'],
+        shapeOptions: ['fill', 'strokeWidth', 'stroke'],
+        shapes: ['fill', 'strokeWidth', 'stroke'],
+        line: ['strokeWidth', 'stroke'],
+        backgroundColors: [true],
+        connector: ['fill', 'strokeWidth', 'stroke'],
+        crosshairX: ['strokeWidth', 'stroke'],
+        crosshairY: ['strokeWidth', 'stroke']
+    },
+    // Simple shapes:
+    circle: ['shapes'],
+    verticalLine: [],
+    label: ['labelOptions'],
+    // Measure
+    measure: ['background', 'crosshairY', 'crosshairX'],
+    // Others:
+    fibonacci: [],
+    tunnel: ['background', 'line', 'height'],
+    pitchfork: ['innerBackground', 'outerBackground'],
+    rect: ['shapes'],
+    // Crooked lines, elliots, arrows etc:
+    crookedLine: []
+};
+
+// Define non editable fields per annotation, for example Rectangle inherits
+// options from Measure, but crosshairs are not available
+H.NavigationBindings.annotationsNonEditable = {
+    rectangle: ['crosshairX', 'crosshairY', 'label']
+};
+
+extend(H.NavigationBindings.prototype, {
+    // Private properties added by bindings:
+
+    // Active (selected) annotation that is editted through popup/forms
+    // activeAnnotation: Annotation
+
+    // Holder for current step, used on mouse move to update bound object
+    // mouseMoveEvent: function () {}
+
+    // Next event in `step` array to be called on chart's click
+    // nextEvent: function () {}
+
+    // Index in the `step` array of the current event
+    // stepIndex: 0
+
+    // Flag to determine if current binding has steps
+    // steps: true|false
+
+    // Bindings holder for all events
+    // selectedButton: {}
+
+    // Holder for user options, returned from `start` event, and passed on to
+    // `step`'s' and `end`.
+    // currentUserDetails: {}
+    /**
+     * Initi all events conencted to NavigationBindings.
+     *
+     * @private
+     * @function Highcharts.NavigationBindings#initEvents
+     */
+    initEvents: function () {
+        var navigation = this,
+            chart = navigation.chart,
+            bindingsContainer = navigation.container,
+            options = navigation.options;
+
+        // Shorthand object for getting events for buttons:
+        navigation.boundClassNames = {};
+
+        objectEach(options.bindings, function (value) {
+            navigation.boundClassNames[value.className] = value;
+        });
+
+        // Handle multiple containers with the same class names:
+        [].forEach.call(bindingsContainer, function (subContainer) {
+            navigation.eventsToUnbind.push(
+                addEvent(
+                    subContainer,
+                    'click',
+                    function (event) {
+                        var bindings = navigation.getButtonEvents(
+                            bindingsContainer,
+                            event
+                        );
+
+                        if (bindings) {
+                            navigation.bindingsButtonClick(
+                                bindings.button,
+                                bindings.events,
+                                event
+                            );
+                        }
+                    }
+                )
+            );
+        });
+
+        objectEach(options.events || {}, function (callback, eventName) {
+            if (H.isFunction(callback)) {
+                navigation.eventsToUnbind.push(
+                    addEvent(
+                        navigation,
+                        eventName,
+                        callback
+                    )
+                );
+            }
+        });
+
+        navigation.eventsToUnbind.push(
+            addEvent(chart.container, 'click', function (e) {
+                if (
+                    !chart.cancelClick &&
+                    chart.isInsidePlot(
+                        e.chartX - chart.plotLeft,
+                        e.chartY - chart.plotTop
+                    )
+                ) {
+                    navigation.bindingsChartClick(this, e);
+                }
+            })
+        );
+        navigation.eventsToUnbind.push(
+            addEvent(chart.container, 'mousemove', function (e) {
+                navigation.bindingsContainerMouseMove(this, e);
+            })
+        );
+    },
+
+    /**
+     * Common chart.update() delegation, shared between bindings and exporting.
+     *
+     * @private
+     * @function Highcharts.NavigationBindings#initUpdate
+     */
+    initUpdate: function () {
+        var navigation = this;
+
+        chartNavigationMixin.addUpdate(
+            function (options) {
+                navigation.update(options);
+            },
+            this.chart
+        );
+    },
+
+    /**
+     * Hook for click on a button, method selcts/unselects buttons,
+     * then calls `bindings.init` callback.
+     *
+     * @private
+     * @function Highcharts.NavigationBindings#bindingsButtonClick
+     *
+     * @param {Highcharts.HTMLDOMElement} [button]
+     *        Clicked button
+     *
+     * @param {object} [events]
+     *        Events passed down from bindings (`init`, `start`, `step`, `end`)
+     *
+     * @param {global.Event} [clickEvent]
+     *        Browser's click event
+     */
+    bindingsButtonClick: function (button, events, clickEvent) {
+        var navigation = this,
+            chart = navigation.chart;
+
+        if (navigation.selectedButtonElement) {
+            fireEvent(
+                navigation,
+                'deselectButton',
+                { button: navigation.selectedButtonElement }
+            );
+
+            if (navigation.nextEvent) {
+                // Remove in-progress annotations adders:
+                if (
+                    navigation.currentUserDetails &&
+                    navigation.currentUserDetails.coll === 'annotations'
+                ) {
+                    chart.removeAnnotation(navigation.currentUserDetails);
+                }
+                navigation.mouseMoveEvent = navigation.nextEvent = false;
+            }
+        }
+
+        navigation.selectedButton = events;
+        navigation.selectedButtonElement = button;
+
+        fireEvent(navigation, 'selectButton', { button: button });
+
+        // Call "init" event, for example to open modal window
+        if (events.init) {
+            events.init.call(navigation, button, clickEvent);
+        }
+
+        if (events.start || events.steps) {
+            chart.renderer.boxWrapper.addClass(PREFIX + 'draw-mode');
+        }
+    },
+    /**
+     * Hook for click on a chart, first click on a chart calls `start` event,
+     * then on all subsequent clicks iterate over `steps` array.
+     * When finished, calls `end` event.
+     *
+     * @private
+     * @function Highcharts.NavigationBindings#bindingsChartClick
+     *
+     * @param {Highcharts.Chart} chart
+     *        Chart that click was performed on.
+     *
+     * @param {global.Event} clickEvent
+     *        Browser's click event.
+     */
+    bindingsChartClick: function (chartContainer, clickEvent) {
+        var navigation = this,
+            chart = navigation.chart,
+            selectedButton = navigation.selectedButton,
+            svgContainer = chart.renderer.boxWrapper;
+
+        // Click outside popups, should close them and deselect the annotation
+        if (
+            navigation.activeAnnotation &&
+            !clickEvent.activeAnnotation &&
+            // Element could be removed in the child action, e.g. button
+            clickEvent.target.parentNode &&
+            // TO DO: Polyfill for IE11?
+            !closestPolyfill(clickEvent.target, '.' + PREFIX + 'popup')
+        ) {
+            fireEvent(navigation, 'closePopup');
+            navigation.deselectAnnotation();
+        }
+
+        if (!selectedButton || !selectedButton.start) {
+            return;
+        }
+
+
+        if (!navigation.nextEvent) {
+            // Call init method:
+            navigation.currentUserDetails = selectedButton.start.call(
+                navigation,
+                clickEvent
+            );
+
+            // If steps exists (e.g. Annotations), bind them:
+            if (selectedButton.steps) {
+                navigation.stepIndex = 0;
+                navigation.steps = true;
+                navigation.mouseMoveEvent = navigation.nextEvent =
+                    selectedButton.steps[navigation.stepIndex];
+            } else {
+
+                fireEvent(
+                    navigation,
+                    'deselectButton',
+                    { button: navigation.selectedButtonElement }
+                );
+                svgContainer.removeClass(PREFIX + 'draw-mode');
+                navigation.steps = false;
+                navigation.selectedButton = null;
+                // First click is also the last one:
+                if (selectedButton.end) {
+                    selectedButton.end.call(
+                        navigation,
+                        clickEvent,
+                        navigation.currentUserDetails
+                    );
+
+                }
+            }
+        } else {
+
+            navigation.nextEvent(
+                clickEvent,
+                navigation.currentUserDetails
+            );
+
+            if (navigation.steps) {
+
+                navigation.stepIndex++;
+
+                if (selectedButton.steps[navigation.stepIndex]) {
+                    // If we have more steps, bind them one by one:
+                    navigation.mouseMoveEvent = navigation.nextEvent =
+                        selectedButton.steps[navigation.stepIndex];
+                } else {
+                    fireEvent(
+                        navigation,
+                        'deselectButton',
+                        { button: navigation.selectedButtonElement }
+                    );
+                    svgContainer.removeClass(PREFIX + 'draw-mode');
+                    // That was the last step, call end():
+                    if (selectedButton.end) {
+                        selectedButton.end.call(
+                            navigation,
+                            clickEvent,
+                            navigation.currentUserDetails
+                        );
+                    }
+                    navigation.nextEvent = false;
+                    navigation.mouseMoveEvent = false;
+                    navigation.selectedButton = null;
+                }
+            }
+        }
+    },
+    /**
+     * Hook for mouse move on a chart's container. It calls current step.
+     *
+     * @private
+     * @function Highcharts.NavigationBindings#bindingsContainerMouseMove
+     *
+     * @param {Highcharts.HTMLDOMElement} container
+     *        Chart's container.
+     *
+     * @param {global.Event} moveEvent
+     *        Browser's move event.
+     */
+    bindingsContainerMouseMove: function (container, moveEvent) {
+        if (this.mouseMoveEvent) {
+            this.mouseMoveEvent(
+                moveEvent,
+                this.currentUserDetails
+            );
+        }
+    },
+    /**
+     * Translate fields (e.g. `params.period` or `marker.styles.color`) to
+     * Highcharts options object (e.g. `{ params: { period } }`).
+     *
+     * @private
+     * @function Highcharts.NavigationBindings#fieldsToOptions
+     *
+     * @param {object} fields
+     *        Fields from popup form.
+     *
+     * @param {object} config
+     *        Default config to be modified.
+     *
+     * @return {object}
+     *         Modified config
+     */
+    fieldsToOptions: function (fields, config) {
+        objectEach(fields, function (value, field) {
+            var parsedValue = parseFloat(value),
+                path = field.split('.'),
+                parent = config,
+                pathLength = path.length - 1;
+
+            // If it's a number (not "forma" options), parse it:
+            if (
+                isNumber(parsedValue) &&
+                !value.match(/px/g) &&
+                !field.match(/format/g)
+            ) {
+                value = parsedValue;
+            }
+
+            // Remove empty strings or values like 0
+            if (value !== '' && value !== 'undefined') {
+                path.forEach(function (name, index) {
+                    var nextName = pick(path[index + 1], '');
+
+                    if (pathLength === index) {
+                        // Last index, put value:
+                        parent[name] = value;
+                    } else if (!parent[name]) {
+                        // Create middle property:
+                        parent[name] = nextName.match(/\d/g) ? [] : {};
+                        parent = parent[name];
+                    } else {
+                        // Jump into next property
+                        parent = parent[name];
+                    }
+                });
+            }
+        });
+        return config;
+    },
+    /**
+     * Shorthand method to deselect an annotation.
+     *
+     * @function Highcharts.NavigationBindings#deselectAnnotation
+     */
+    deselectAnnotation: function () {
+        if (this.activeAnnotation) {
+            this.activeAnnotation.setControlPointsVisibility(false);
+            this.activeAnnotation = false;
+        }
+    },
+    /**
+     * Generates API config for popup in the same format as options for
+     * Annotation object.
+     *
+     * @function Highcharts.NavigationBindings#annotationToFields
+     *
+     * @param {Highcharts.Annotation} annotation
+     *        Annotations object
+     *
+     * @return {object}
+     *         Annotation options to be displayed in popup box
+     */
+    annotationToFields: function (annotation) {
+        var options = annotation.options,
+            editables = H.NavigationBindings.annotationsEditable,
+            nestedEditables = editables.nestedOptions,
+            getFieldType = this.utils.getFieldType,
+            type = pick(
+                options.type,
+                options.shapes && options.shapes[0] &&
+                    options.shapes[0].type,
+                options.labels && options.labels[0] &&
+                    options.labels[0].itemType,
+                'label'
+            ),
+            nonEditables = H.NavigationBindings
+                .annotationsNonEditable[options.langKey] || [],
+            visualOptions = {
+                langKey: options.langKey,
+                type: type
+            };
+
+        /**
+         * Nested options traversing. Method goes down to the options and copies
+         * allowed options (with values) to new object, which is last parameter:
+         * "parent".
+         *
+         * @private
+         * @function Highcharts.NavigationBindings#annotationToFields.traverse
+         *
+         * @param {*} option
+         *        Atomic type or object/array
+         *
+         * @param {string} key
+         *        Option name, for example "visible" or "x", "y"
+         *
+         * @param {object} allowed
+         *        Editables from H.NavigationBindings.annotationsEditable
+         *
+         * @param {object} parent
+         *        Where new options will be assigned
+         */
+        function traverse(option, key, parentEditables, parent) {
+            var nextParent;
+
+            if (
+                parentEditables &&
+                nonEditables.indexOf(key) === -1 &&
+                (
+                    (
+                        parentEditables.indexOf &&
+                        parentEditables.indexOf(key)
+                    ) >= 0 ||
+                    parentEditables[key] || // nested array
+                    parentEditables === true // simple array
+                )
+            ) {
+                // Roots:
+                if (isArray(option)) {
+                    parent[key] = [];
+
+                    option.forEach(function (arrayOption, i) {
+                        if (!isObject(arrayOption)) {
+                            // Simple arrays, e.g. [String, Number, Boolean]
+                            traverse(
+                                arrayOption,
+                                0,
+                                nestedEditables[key],
+                                parent[key]
+                            );
+                        } else {
+                            // Advanced arrays, e.g. [Object, Object]
+                            parent[key][i] = {};
+                            objectEach(
+                                arrayOption,
+                                function (nestedOption, nestedKey) {
+                                    traverse(
+                                        nestedOption,
+                                        nestedKey,
+                                        nestedEditables[key],
+                                        parent[key][i]
+                                    );
+                                }
+                            );
+                        }
+                    });
+                } else if (isObject(option)) {
+                    nextParent = {};
+                    if (isArray(parent)) {
+                        parent.push(nextParent);
+                        nextParent[key] = {};
+                        nextParent = nextParent[key];
+                    } else {
+                        parent[key] = nextParent;
+                    }
+                    objectEach(option, function (nestedOption, nestedKey) {
+                        traverse(
+                            nestedOption,
+                            nestedKey,
+                            key === 0 ? parentEditables : nestedEditables[key],
+                            nextParent
+                        );
+                    });
+                } else {
+                    // Leaf:
+                    if (key === 'format') {
+                        parent[key] = [
+                            H.format(
+                                option,
+                                annotation.labels[0].points[0]
+                            ).toString(),
+                            'text'
+                        ];
+                    } else if (isArray(parent)) {
+                        parent.push([option, getFieldType(option)]);
+                    } else {
+                        parent[key] = [option, getFieldType(option)];
+                    }
+                }
+            }
+        }
+
+        objectEach(options, function (option, key) {
+            if (key === 'typeOptions') {
+                visualOptions[key] = {};
+                objectEach(options[key], function (typeOption, typeKey) {
+                    traverse(
+                        typeOption,
+                        typeKey,
+                        nestedEditables,
+                        visualOptions[key],
+                        true
+                    );
+                });
+            } else {
+                traverse(option, key, editables[type], visualOptions);
+            }
+        });
+
+        return visualOptions;
+    },
+
+    /**
+     * Get all class names for all parents in the element. Iterates until finds
+     * main container.
+     *
+     * @function Highcharts.NavigationBindings#getClickedClassNames
+     *
+     * @param {Highcharts.HTMLDOMElement}
+     *        Container that event is bound to.
+     *
+     * @param {global.Event} event
+     *        Browser's event.
+     *
+     * @return {Array<string>}
+     *         Array of class names with corresponding elements
+     */
+    getClickedClassNames: function (container, event) {
+        var element = event.target,
+            classNames = [],
+            elemClassName;
+
+        while (element) {
+            elemClassName = attr(element, 'class');
+            if (elemClassName) {
+                classNames = classNames.concat(
+                    elemClassName.split(' ').map(
+                        function (name) { // eslint-disable-line no-loop-func
+                            return [
+                                name,
+                                element
+                            ];
+                        }
+                    )
+                );
+            }
+            element = element.parentNode;
+
+            if (element === container) {
+                return classNames;
+            }
+        }
+
+        return classNames;
+
+    },
+    /**
+     * Get events bound to a button. It's a custom event delegation to find all
+     * events connected to the element.
+     *
+     * @function Highcharts.NavigationBindings#getButtonEvents
+     *
+     * @param {Highcharts.HTMLDOMElement}
+     *        Container that event is bound to.
+     *
+     * @param {global.Event} event
+     *        Browser's event.
+     *
+     * @return {object}
+     *         Oject with events (init, start, steps, and end)
+     */
+    getButtonEvents: function (container, event) {
+        var navigation = this,
+            classNames = this.getClickedClassNames(container, event),
+            bindings;
+
+
+        classNames.forEach(function (className) {
+            if (navigation.boundClassNames[className[0]] && !bindings) {
+                bindings = {
+                    events: navigation.boundClassNames[className[0]],
+                    button: className[1]
+                };
+            }
+        });
+
+        return bindings;
+    },
+    /**
+     * Bindings are just events, so the whole update process is simply
+     * removing old events and adding new ones.
+     *
+     * @private
+     * @function Highcharts.NavigationBindings#update
+     */
+    update: function (options) {
+        this.options = merge(true, this.options, options);
+        this.removeEvents();
+        this.initEvents();
+    },
+    /**
+     * Remove all events created in the navigation.
+     *
+     * @private
+     * @function Highcharts.NavigationBindings#removeEvents
+     */
+    removeEvents: function () {
+        this.eventsToUnbind.forEach(function (unbinder) {
+            unbinder();
+        });
+    },
+    destroy: function () {
+        this.removeEvents();
+    },
+    /**
+     * General utils for bindings
+     *
+     * @private
+     * @name Highcharts.NavigationBindings#utils
+     * @type {bindingsUtils}
+     */
+    utils: bindingsUtils
+});
+
+H.Chart.prototype.initNavigationBindings = function () {
+    var chart = this,
+        options = chart.options;
+
+    if (options && options.navigation && options.navigation.bindings) {
+        chart.navigationBindings = new H.NavigationBindings(
+            chart,
+            options.navigation
+        );
+        chart.navigationBindings.initEvents();
+        chart.navigationBindings.initUpdate();
+    }
+};
+
+addEvent(H.Chart, 'load', function () {
+    this.initNavigationBindings();
+});
+
+addEvent(H.Chart, 'destroy', function () {
+    if (this.navigationBindings) {
+        this.navigationBindings.destroy();
+    }
+});
+
+addEvent(H.NavigationBindings, 'deselectButton', function () {
+    this.selectedButtonElement = null;
+});
+
+addEvent(H.Annotation, 'remove', function () {
+    if (this.chart.navigationBindings) {
+        this.chart.navigationBindings.deselectAnnotation();
+    }
+});
+
+
+// Show edit-annotation form:
+function selectableAnnotation(annotationType) {
+    var originalClick = annotationType.prototype.defaultOptions.events &&
+            annotationType.prototype.defaultOptions.events.click;
+
+    function selectAndshowPopup(event) {
+        var annotation = this,
+            navigation = annotation.chart.navigationBindings,
+            prevAnnotation = navigation.activeAnnotation;
+
+        if (originalClick) {
+            originalClick.click.call(annotation, event);
+        }
+
+        if (prevAnnotation !== annotation) {
+            // Select current:
+            navigation.deselectAnnotation();
+
+            navigation.activeAnnotation = annotation;
+            annotation.setControlPointsVisibility(true);
+
+            fireEvent(
+                navigation,
+                'showPopup',
+                {
+                    annotation: annotation,
+                    formType: 'annotation-toolbar',
+                    options: navigation.annotationToFields(annotation),
+                    onSubmit: function (data) {
+
+                        var config = {},
+                            typeOptions;
+
+                        if (data.actionType === 'remove') {
+                            navigation.activeAnnotation = false;
+                            navigation.chart.removeAnnotation(annotation);
+                        } else {
+                            navigation.fieldsToOptions(data.fields, config);
+                            navigation.deselectAnnotation();
+
+                            typeOptions = config.typeOptions;
+
+                            if (annotation.options.type === 'measure') {
+                                // Manually disable crooshars according to
+                                // stroke width of the shape:
+                                typeOptions.crosshairY.enabled =
+                                    typeOptions.crosshairY.strokeWidth !== 0;
+                                typeOptions.crosshairX.enabled =
+                                    typeOptions.crosshairX.strokeWidth !== 0;
+                            }
+
+                            annotation.update(config);
+                        }
+                    }
+                }
+            );
+        } else {
+            // Deselect current:
+            navigation.deselectAnnotation();
+            fireEvent(navigation, 'closePopup');
+        }
+        // Let bubble event to chart.click:
+        event.activeAnnotation = true;
+    }
+
+    H.merge(
+        true,
+        annotationType.prototype.defaultOptions.events,
+        {
+            click: selectAndshowPopup
+        }
+    );
+}
+
+if (H.Annotation) {
+    // Basic shapes:
+    selectableAnnotation(H.Annotation);
+
+    // Advanced annotations:
+    objectEach(H.Annotation.types, function (annotationType) {
+        selectableAnnotation(annotationType);
+    });
+}
+
+H.setOptions({
+    /**
+     * @optionparent lang
+     */
+    lang: {
+        /**
+         * Configure the Popup strings in the chart. Requires the
+         * `annotations.js` or `annotations-advanced.src.js` module to be
+         * loaded.
+         *
+         * @since           7.0.0
+         * @type            {Object}
+         * @product         highcharts highstock
+         */
+        navigation: {
+            /**
+             * Translations for all field names used in popup.
+             *
+             * @product         highcharts highstock
+             * @type            {Object}
+             */
+            popup: {
+                simpleShapes: 'Simple shapes',
+                lines: 'Lines',
+                circle: 'Circle',
+                rectangle: 'Rectangle',
+                label: 'Label',
+                shapeOptions: 'Shape options',
+                typeOptions: 'Details',
+                fill: 'Fill',
+                format: 'Text',
+                strokeWidth: 'Line width',
+                stroke: 'Line color',
+                title: 'Title',
+                name: 'Name',
+                labelOptions: 'Label options',
+                labels: 'Labels',
+                backgroundColor: 'Background color',
+                backgroundColors: 'Background colors',
+                borderColor: 'Border color',
+                borderRadius: 'Border radius',
+                borderWidth: 'Border width',
+                style: 'Style',
+                padding: 'Padding',
+                fontSize: 'Font size',
+                color: 'Color',
+                height: 'Height',
+                shapes: 'Shape options'
+            }
+        }
+    },
+    /**
+     * @optionparent navigation
+     * @product      highcharts highstock
+     */
+    navigation: {
+        /**
+         * A CSS class name where all bindings will be attached to. Multiple
+         * charts on the same page should have separate class names to prevent
+         * duplicating events.
+         *
+         * Default value of versions < 7.0.4 `highcharts-bindings-wrapper`
+         *
+         * @since     7.0.0
+         * @type      {string}
+         */
+        bindingsClassName: 'highcharts-bindings-container',
+        /**
+         * Bindings definitions for custom HTML buttons. Each binding implements
+         * simple event-driven interface:
+         *
+         * - `className`: classname used to bind event to
+         *
+         * - `init`: initial event, fired on button click
+         *
+         * - `start`: fired on first click on a chart
+         *
+         * - `steps`: array of sequential events fired one after another on each
+         *   of users clicks
+         *
+         * - `end`: last event to be called after last step event
+         *
+         * @type         {Highcharts.Dictionary<Highcharts.StockToolsBindingsObject>|*}
+         * @sample       stock/stocktools/stocktools-thresholds
+         *               Custom bindings in Highstock
+         * @since        7.0.0
+         * @product      highcharts highstock
+         */
+        bindings: {
+            /**
+             * A circle annotation bindings. Includes `start` and one event in
+             * `steps` array.
+             *
+             * @type    {Highcharts.StockToolsBindingsObject}
+             * @default {"className": "highcharts-circle-annotation", "start": function() {}, "steps": [function() {}], "annotationsOptions": {}}
+             */
+            circleAnnotation: {
+                /** @ignore */
+                className: 'highcharts-circle-annotation',
+                /** @ignore */
+                start: function (e) {
+                    var coords = this.chart.pointer.getCoordinates(e),
+                        navigation = this.chart.options.navigation,
+                        controlPoints = [{
+                            positioner: function (target) {
+                                var xy = H.Annotation.MockPoint
+                                        .pointToPixels(
+                                            target.points[0]
+                                        ),
+                                    r = target.options.r;
+
+                                return {
+                                    x: xy.x + r * Math.cos(Math.PI / 4) -
+                                        this.graphic.width / 2,
+                                    y: xy.y + r * Math.sin(Math.PI / 4) -
+                                        this.graphic.height / 2
+                                };
+                            },
+                            events: {
+                                // TRANSFORM RADIUS ACCORDING TO Y
+                                // TRANSLATION
+                                drag: function (e, target) {
+                                    var annotation = target.annotation,
+                                        position = this
+                                            .mouseMoveToTranslation(e);
+
+                                    target.setRadius(
+                                        Math.max(
+                                            target.options.r +
+                                                position.y /
+                                                Math.sin(Math.PI / 4),
+                                            5
+                                        )
+                                    );
+
+                                    annotation.options.shapes[0] =
+                                        annotation.userOptions.shapes[0] =
+                                        target.options;
+
+                                    target.redraw(false);
+                                }
+                            }
+                        }];
+
+                    return this.chart.addAnnotation(
+                        merge(
+                            {
+                                langKey: 'circle',
+                                shapes: [{
+                                    type: 'circle',
+                                    point: {
+                                        xAxis: 0,
+                                        yAxis: 0,
+                                        x: coords.xAxis[0].value,
+                                        y: coords.yAxis[0].value
+                                    },
+                                    r: 5,
+                                    controlPoints: controlPoints
+                                }]
+                            },
+                            navigation
+                                .annotationsOptions,
+                            navigation
+                                .bindings
+                                .circleAnnotation
+                                .annotationsOptions
+                        )
+                    );
+                },
+                /** @ignore */
+                steps: [
+                    function (e, annotation) {
+                        var point = annotation.options.shapes[0].point,
+                            x = this.chart.xAxis[0].toPixels(point.x),
+                            y = this.chart.yAxis[0].toPixels(point.y),
+                            inverted = this.chart.inverted,
+                            distance = Math.max(
+                                Math.sqrt(
+                                    Math.pow(
+                                        inverted ? y - e.chartX : x - e.chartX,
+                                        2
+                                    ) +
+                                    Math.pow(
+                                        inverted ? x - e.chartY : y - e.chartY,
+                                        2
+                                    )
+                                ),
+                                5
+                            );
+
+                        annotation.update({
+                            shapes: [{
+                                r: distance
+                            }]
+                        });
+                    }
+                ]
+            },
+            /**
+             * A rectangle annotation bindings. Includes `start` and one event
+             * in `steps` array.
+             *
+             * @type    {Highcharts.StockToolsBindingsObject}
+             * @default {"className": "highcharts-rectangle-annotation", "start": function() {}, "steps": [function() {}], "annotationsOptions": {}}
+             */
+            rectangleAnnotation: {
+                /** @ignore */
+                className: 'highcharts-rectangle-annotation',
+                /** @ignore */
+                start: function (e) {
+                    var coords = this.chart.pointer.getCoordinates(e),
+                        navigation = this.chart.options.navigation,
+                        x = coords.xAxis[0].value,
+                        y = coords.yAxis[0].value,
+                        controlPoints = [{
+                            positioner: function (annotation) {
+                                var xy = H.Annotation.MockPoint
+                                    .pointToPixels(
+                                        annotation.shapes[0].points[2]
+                                    );
+
+                                return {
+                                    x: xy.x - 4,
+                                    y: xy.y - 4
+                                };
+                            },
+                            events: {
+                                drag: function (e, target) {
+                                    var coords = this.chart.pointer
+                                            .getCoordinates(e),
+                                        x = coords.xAxis[0].value,
+                                        y = coords.yAxis[0].value,
+                                        shape = target.options.shapes[0],
+                                        points = shape.points;
+
+                                    // Top right point
+                                    points[1].x = x;
+                                    // Bottom right point (cursor position)
+                                    points[2].x = x;
+                                    points[2].y = y;
+                                    // Bottom left
+                                    points[3].y = y;
+
+                                    target.options.shapes[0].points = points;
+
+                                    target.redraw(false);
+                                }
+                            }
+                        }];
+
+                    return this.chart.addAnnotation(
+                        merge(
+                            {
+                                langKey: 'rectangle',
+                                shapes: [{
+                                    type: 'path',
+                                    points: [{
+                                        xAxis: 0,
+                                        yAxis: 0,
+                                        x: x,
+                                        y: y
+                                    }, {
+                                        xAxis: 0,
+                                        yAxis: 0,
+                                        x: x,
+                                        y: y
+                                    }, {
+                                        xAxis: 0,
+                                        yAxis: 0,
+                                        x: x,
+                                        y: y
+                                    }, {
+                                        xAxis: 0,
+                                        yAxis: 0,
+                                        x: x,
+                                        y: y
+                                    }]
+                                }],
+                                controlPoints: controlPoints
+                            },
+                            navigation
+                                .annotationsOptions,
+                            navigation
+                                .bindings
+                                .rectangleAnnotation
+                                .annotationsOptions
+                        )
+                    );
+                },
+                /** @ignore */
+                steps: [
+                    function (e, annotation) {
+                        var points = annotation.options.shapes[0].points,
+                            coords = this.chart.pointer.getCoordinates(e),
+                            x = coords.xAxis[0].value,
+                            y = coords.yAxis[0].value;
+
+                        // Top right point
+                        points[1].x = x;
+                        // Bottom right point (cursor position)
+                        points[2].x = x;
+                        points[2].y = y;
+                        // Bottom left
+                        points[3].y = y;
+
+                        annotation.update({
+                            shapes: [{
+                                points: points
+                            }]
+                        });
+                    }
+                ]
+            },
+            /**
+             * A label annotation bindings. Includes `start` event only.
+             *
+             * @type    {Highcharts.StockToolsBindingsObject}
+             * @default {"className": "highcharts-label-annotation", "start": function() {}, "steps": [function() {}], "annotationsOptions": {}}
+             */
+            labelAnnotation: {
+                /** @ignore */
+                className: 'highcharts-label-annotation',
+                /** @ignore */
+                start: function (e) {
+                    var coords = this.chart.pointer.getCoordinates(e),
+                        navigation = this.chart.options.navigation,
+                        controlPoints = [{
+                            symbol: 'triangle-down',
+                            positioner: function (target) {
+                                if (!target.graphic.placed) {
+                                    return {
+                                        x: 0,
+                                        y: -9e7
+                                    };
+                                }
+
+                                var xy = H.Annotation.MockPoint
+                                    .pointToPixels(
+                                        target.points[0]
+                                    );
+
+                                return {
+                                    x: xy.x - this.graphic.width / 2,
+                                    y: xy.y - this.graphic.height / 2
+                                };
+                            },
+
+                            // TRANSLATE POINT/ANCHOR
+                            events: {
+                                drag: function (e, target) {
+                                    var xy = this.mouseMoveToTranslation(e);
+
+                                    target.translatePoint(xy.x, xy.y);
+
+                                    target.annotation.labels[0].options =
+                                        target.options;
+
+                                    target.redraw(false);
+                                }
+                            }
+                        }, {
+                            symbol: 'square',
+                            positioner: function (target) {
+                                if (!target.graphic.placed) {
+                                    return {
+                                        x: 0,
+                                        y: -9e7
+                                    };
+                                }
+
+                                return {
+                                    x: target.graphic.alignAttr.x -
+                                        this.graphic.width / 2,
+                                    y: target.graphic.alignAttr.y -
+                                        this.graphic.height / 2
+                                };
+                            },
+
+                            // TRANSLATE POSITION WITHOUT CHANGING THE
+                            // ANCHOR
+                            events: {
+                                drag: function (e, target) {
+                                    var xy = this.mouseMoveToTranslation(e);
+
+                                    target.translate(xy.x, xy.y);
+
+                                    target.annotation.labels[0].options =
+                                        target.options;
+
+                                    target.redraw(false);
+                                }
+                            }
+                        }];
+
+                    return this.chart.addAnnotation(
+                        merge(
+                            {
+                                langKey: 'label',
+                                labelOptions: {
+                                    format: '{y:.2f}'
+                                },
+                                labels: [{
+                                    point: {
+                                        xAxis: 0,
+                                        yAxis: 0,
+                                        x: coords.xAxis[0].value,
+                                        y: coords.yAxis[0].value
+                                    },
+                                    overflow: 'none',
+                                    crop: true,
+                                    controlPoints: controlPoints
+                                }]
+                            },
+                            navigation
+                                .annotationsOptions,
+                            navigation
+                                .bindings
+                                .labelAnnotation
+                                .annotationsOptions
+                        )
+                    );
+                }
+            }
+        },
+        /**
+         * Path where Highcharts will look for icons. Change this to use icons
+         * from a different server.
+         *
+         * @type      {string}
+         * @default   https://code.highcharts.com/8.0.0/gfx/stock-icons/
+         * @since     7.1.3
+         * @apioption navigation.iconsURL
+         */
+
+        /**
+         * A `showPopup` event. Fired when selecting for example an annotation.
+         *
+         * @type      {Function}
+         * @apioption navigation.events.showPopup
+         */
+
+        /**
+         * A `closePopup` event. Fired when Popup should be hidden, for example
+         * when clicking on an annotation again.
+         *
+         * @type      {Function}
+         * @apioption navigation.events.closePopup
+         */
+
+        /**
+         * Event fired on a button click.
+         *
+         * @type      {Function}
+         * @sample    highcharts/annotations/gui/
+         *            Change icon in a dropddown on event
+         * @sample    highcharts/annotations/gui-buttons/
+         *            Change button class on event
+         * @apioption navigation.events.selectButton
+         */
+
+        /**
+         * Event fired when button state should change, for example after
+         * adding an annotation.
+         *
+         * @type      {Function}
+         * @sample    highcharts/annotations/gui/
+         *            Change icon in a dropddown on event
+         * @sample    highcharts/annotations/gui-buttons/
+         *            Change button class on event
+         * @apioption navigation.events.deselectButton
+         */
+
+        /**
+         * Events to communicate between Stock Tools and custom GUI.
+         *
+         * @since        7.0.0
+         * @product      highcharts highstock
+         * @optionparent navigation.events
+         */
+        events: {},
+        /**
+         * Additional options to be merged into all annotations.
+         *
+         * @sample stock/stocktools/navigation-annotation-options
+         *         Set red color of all line annotations
+         *
+         * @type      {Highcharts.AnnotationsOptions}
+         * @extends   annotations
+         * @exclude   crookedLine, elliottWave, fibonacci, infinityLine,
+         *            measure, pitchfork, tunnel, verticalLine
+         * @apioption navigation.annotationsOptions
+         */
+        annotationsOptions: {}
+    }
+});

+ 1082 - 0
app/public/js/Highstock-8.0.0/code/es-modules/annotations/popup.js

@@ -0,0 +1,1082 @@
+/* *
+ *
+ *  Popup generator for Stock tools
+ *
+ *  (c) 2009-2017 Sebastian Bochan
+ *
+ *  License: www.highcharts.com/license
+ *
+ * */
+'use strict';
+import H from '../parts/Globals.js';
+
+import U from '../parts/Utilities.js';
+var defined = U.defined,
+    isArray = U.isArray,
+    isObject = U.isObject,
+    isString = U.isString,
+    objectEach = U.objectEach,
+    pick = U.pick,
+    wrap = U.wrap;
+
+var addEvent = H.addEvent,
+    createElement = H.createElement,
+    indexFilter = /\d/g,
+    PREFIX = 'highcharts-',
+    DIV = 'div',
+    INPUT = 'input',
+    LABEL = 'label',
+    BUTTON = 'button',
+    SELECT = 'select',
+    OPTION = 'option',
+    SPAN = 'span',
+    UL = 'ul',
+    LI = 'li',
+    H3 = 'h3';
+
+// onContainerMouseDown blocks internal popup events, due to e.preventDefault.
+// Related issue #4606
+
+wrap(H.Pointer.prototype, 'onContainerMouseDown', function (proceed, e) {
+
+    var popupClass = e.target && e.target.className;
+
+    // elements is not in popup
+    if (!(isString(popupClass) &&
+        popupClass.indexOf(PREFIX + 'popup-field') >= 0)
+    ) {
+        proceed.apply(this, Array.prototype.slice.call(arguments, 1));
+    }
+});
+
+H.Popup = function (parentDiv, iconsURL) {
+    this.init(parentDiv, iconsURL);
+};
+
+H.Popup.prototype = {
+    /**
+     * Initialize the popup. Create base div and add close button.
+     * @private
+     * @param {HTMLDOMElement} - container where popup should be placed
+     * @param {Object} - user options
+     * @return {HTMLDOMElement} - return created popup's div
+     */
+    init: function (parentDiv, iconsURL) {
+
+        // create popup div
+        this.container = createElement(DIV, {
+            className: PREFIX + 'popup'
+        }, null, parentDiv);
+
+        this.lang = this.getLangpack();
+        this.iconsURL = iconsURL;
+
+        // add close button
+        this.addCloseBtn();
+    },
+    /**
+     * Create HTML element and attach click event (close popup).
+     * @private
+     */
+    addCloseBtn: function () {
+        var _self = this,
+            closeBtn;
+
+        // create close popup btn
+        closeBtn = createElement(DIV, {
+            className: PREFIX + 'popup-close'
+        }, null, this.container);
+
+        closeBtn.style['background-image'] = 'url(' +
+                this.iconsURL + 'close.svg)';
+
+        ['click', 'touchstart'].forEach(function (eventName) {
+            addEvent(closeBtn, eventName, function () {
+                _self.closePopup();
+            });
+        });
+    },
+    /**
+     * Create two columns (divs) in HTML.
+     * @private
+     * @param {HTMLDOMElement} - container of columns
+     * @return {Object} - reference to two HTML columns
+     */
+    addColsContainer: function (container) {
+        var rhsCol,
+            lhsCol;
+
+        // left column
+        lhsCol = createElement(DIV, {
+            className: PREFIX + 'popup-lhs-col'
+        }, null, container);
+
+        // right column
+        rhsCol = createElement(DIV, {
+            className: PREFIX + 'popup-rhs-col'
+        }, null, container);
+
+        // wrapper content
+        createElement(DIV, {
+            className: PREFIX + 'popup-rhs-col-wrapper'
+        }, null, rhsCol);
+
+        return {
+            lhsCol: lhsCol,
+            rhsCol: rhsCol
+        };
+    },
+    /**
+     * Create input with label.
+     * @private
+     * @param {String} - chain of fields i.e params.styles.fontSize
+     * @param {String} - indicator type
+     * @param {HTMLDOMElement} - container where elements should be added
+     * @param {String} - dafault value of input i.e period value is 14,
+     * extracted from defaultOptions (ADD mode) or series options (EDIT mode)
+     */
+    addInput: function (option, type, parentDiv, value) {
+        var optionParamList = option.split('.'),
+            optionName = optionParamList[optionParamList.length - 1],
+            lang = this.lang,
+            inputName = PREFIX + type + '-' + optionName;
+
+        if (!inputName.match(indexFilter)) {
+            // add label
+            createElement(
+                LABEL, {
+                    innerHTML: lang[optionName] || optionName,
+                    htmlFor: inputName
+                },
+                null,
+                parentDiv
+            );
+        }
+
+        // add input
+        createElement(
+            INPUT,
+            {
+                name: inputName,
+                value: value[0],
+                type: value[1],
+                className: PREFIX + 'popup-field'
+            },
+            null,
+            parentDiv
+        ).setAttribute(PREFIX + 'data-name', option);
+    },
+    /**
+     * Create button.
+     * @private
+     * @param {HTMLDOMElement} - container where elements should be added
+     * @param {String} - text placed as button label
+     * @param {String} - add | edit | remove
+     * @param {Function} - on click callback
+     * @param {HTMLDOMElement} - container where inputs are generated
+     * @return {HTMLDOMElement} - html button
+     */
+    addButton: function (parentDiv, label, type, callback, fieldsDiv) {
+        var _self = this,
+            closePopup = this.closePopup,
+            getFields = this.getFields,
+            button;
+
+        button = createElement(BUTTON, {
+            innerHTML: label
+        }, null, parentDiv);
+
+        ['click', 'touchstart'].forEach(function (eventName) {
+            addEvent(button, eventName, function () {
+                closePopup.call(_self);
+
+                return callback(
+                    getFields(fieldsDiv, type)
+                );
+            });
+        });
+
+        return button;
+    },
+    /**
+     * Get values from all inputs and create JSON.
+     * @private
+     * @param {HTMLDOMElement} - container where inputs are created
+     * @param {String} - add | edit | remove
+     * @return {Object} - fields
+     */
+    getFields: function (parentDiv, type) {
+
+        var inputList = parentDiv.querySelectorAll('input'),
+            optionSeries = '#' + PREFIX + 'select-series > option:checked',
+            optionVolume = '#' + PREFIX + 'select-volume > option:checked',
+            linkedTo = parentDiv.querySelectorAll(optionSeries)[0],
+            volumeTo = parentDiv.querySelectorAll(optionVolume)[0],
+            seriesId,
+            param,
+            fieldsOutput;
+
+        fieldsOutput = {
+            actionType: type,
+            linkedTo: linkedTo && linkedTo.getAttribute('value'),
+            fields: { }
+        };
+
+        [].forEach.call(inputList, function (input) {
+            param = input.getAttribute(PREFIX + 'data-name');
+            seriesId = input.getAttribute(PREFIX + 'data-series-id');
+
+            // params
+            if (seriesId) {
+                fieldsOutput.seriesId = input.value;
+            } else if (param) {
+                fieldsOutput.fields[param] = input.value;
+            } else {
+                // type like sma / ema
+                fieldsOutput.type = input.value;
+            }
+        });
+
+        if (volumeTo) {
+            fieldsOutput.fields['params.volumeSeriesID'] = volumeTo
+                .getAttribute('value');
+        }
+
+        return fieldsOutput;
+    },
+    /**
+     * Reset content of the current popup and show.
+     * @private
+     * @param {Chart} - chart
+     * @param {Function} - on click callback
+     * @return {Object} - fields
+     */
+    showPopup: function () {
+
+        var popupDiv = this.container,
+            toolbarClass = PREFIX + 'annotation-toolbar',
+            popupCloseBtn = popupDiv
+                .querySelectorAll('.' + PREFIX + 'popup-close')[0];
+
+        // reset content
+        popupDiv.innerHTML = '';
+
+        // reset toolbar styles if exists
+        if (popupDiv.className.indexOf(toolbarClass) >= 0) {
+            popupDiv.classList.remove(toolbarClass);
+
+            // reset toolbar inline styles
+            popupDiv.removeAttribute('style');
+        }
+
+        // add close button
+        popupDiv.appendChild(popupCloseBtn);
+        popupDiv.style.display = 'block';
+    },
+    /**
+     * Hide popup.
+     * @private
+     */
+    closePopup: function () {
+        this.popup.container.style.display = 'none';
+    },
+    /**
+     * Create content and show popup.
+     * @private
+     * @param {String} - type of popup i.e indicators
+     * @param {Chart} - chart
+     * @param {Object} - options
+     * @param {Function} - on click callback
+     */
+    showForm: function (type, chart, options, callback) {
+
+        this.popup = chart.navigationBindings.popup;
+
+        // show blank popup
+        this.showPopup();
+
+        // indicator form
+        if (type === 'indicators') {
+            this.indicators.addForm.call(this, chart, options, callback);
+        }
+
+        // annotation small toolbar
+        if (type === 'annotation-toolbar') {
+            this.annotations.addToolbar.call(this, chart, options, callback);
+        }
+
+        // annotation edit form
+        if (type === 'annotation-edit') {
+            this.annotations.addForm.call(this, chart, options, callback);
+        }
+
+        // flags form - add / edit
+        if (type === 'flag') {
+            this.annotations.addForm.call(this, chart, options, callback, true);
+        }
+    },
+    /**
+     * Return lang definitions for popup.
+     * @private
+     * @return {Object} - elements translations.
+     */
+    getLangpack: function () {
+        return H.getOptions().lang.navigation.popup;
+    },
+    annotations: {
+        /**
+         * Create annotation simple form. It contains two buttons
+         * (edit / remove) and text label.
+         * @private
+         * @param {Chart} - chart
+         * @param {Object} - options
+         * @param {Function} - on click callback
+         */
+        addToolbar: function (chart, options, callback) {
+            var _self = this,
+                lang = this.lang,
+                popupDiv = this.popup.container,
+                showForm = this.showForm,
+                toolbarClass = PREFIX + 'annotation-toolbar',
+                button;
+
+            // set small size
+            if (popupDiv.className.indexOf(toolbarClass) === -1) {
+                popupDiv.className += ' ' + toolbarClass;
+            }
+
+            // set position
+            popupDiv.style.top = chart.plotTop + 10 + 'px';
+
+            // create label
+            createElement(SPAN, {
+                innerHTML: pick(
+                    // Advanced annotations:
+                    lang[options.langKey] || options.langKey,
+                    // Basic shapes:
+                    options.shapes && options.shapes[0].type
+                )
+            }, null, popupDiv);
+
+            // add buttons
+            button = this.addButton(
+                popupDiv,
+                lang.removeButton || 'remove',
+                'remove',
+                callback,
+                popupDiv
+            );
+
+            button.className += ' ' + PREFIX + 'annotation-remove-button';
+            button.style['background-image'] = 'url(' +
+                this.iconsURL + 'destroy.svg)';
+
+            button = this.addButton(
+                popupDiv,
+                lang.editButton || 'edit',
+                'edit',
+                function () {
+                    showForm.call(
+                        _self,
+                        'annotation-edit',
+                        chart,
+                        options,
+                        callback
+                    );
+                },
+                popupDiv
+            );
+
+            button.className += ' ' + PREFIX + 'annotation-edit-button';
+            button.style['background-image'] = 'url(' +
+                this.iconsURL + 'edit.svg)';
+
+        },
+        /**
+         * Create annotation simple form.
+         * It contains fields with param names.
+         * @private
+         * @param {Chart} - chart
+         * @param {Object} - options
+         * @param {Function} - on click callback
+         * @param {Boolean} - if it is a form declared for init annotation
+         */
+        addForm: function (chart, options, callback, isInit) {
+            var popupDiv = this.popup.container,
+                lang = this.lang,
+                bottomRow,
+                lhsCol;
+
+            // create title of annotations
+            lhsCol = createElement('h2', {
+                innerHTML: lang[options.langKey] || options.langKey,
+                className: PREFIX + 'popup-main-title'
+            }, null, popupDiv);
+
+            // left column
+            lhsCol = createElement(DIV, {
+                className: PREFIX + 'popup-lhs-col ' + PREFIX + 'popup-lhs-full'
+            }, null, popupDiv);
+
+            bottomRow = createElement(DIV, {
+                className: PREFIX + 'popup-bottom-row'
+            }, null, popupDiv);
+
+            this.annotations.addFormFields.call(
+                this,
+                lhsCol,
+                chart,
+                '',
+                options,
+                [],
+                true
+            );
+
+            this.addButton(
+                bottomRow,
+                isInit ?
+                    (lang.addButton || 'add') :
+                    (lang.saveButton || 'save'),
+                isInit ? 'add' : 'save',
+                callback,
+                popupDiv
+            );
+        },
+        /**
+         * Create annotation's form fields.
+         * @private
+         * @param {HTMLDOMElement} - div where inputs are placed
+         * @param {Chart} - chart
+         * @param {String} - name of parent to create chain of names
+         * @param {Object} - options
+         * @param {Array} - storage - array where all items are stored
+         * @param {Boolean} - isRoot - recursive flag for root
+         */
+        addFormFields: function (
+            parentDiv,
+            chart,
+            parentNode,
+            options,
+            storage,
+            isRoot
+        ) {
+            var _self = this,
+                addFormFields = this.annotations.addFormFields,
+                addInput = this.addInput,
+                lang = this.lang,
+                parentFullName,
+                titleName;
+
+            objectEach(options, function (value, option) {
+
+                // create name like params.styles.fontSize
+                parentFullName = parentNode !== '' ?
+                    parentNode + '.' + option : option;
+
+                if (isObject(value)) {
+                    if (
+                        // value is object of options
+                        !isArray(value) ||
+                        // array of objects with params. i.e labels in Fibonacci
+                        (isArray(value) && isObject(value[0]))
+                    ) {
+                        titleName = lang[option] || option;
+
+                        if (!titleName.match(indexFilter)) {
+                            storage.push([
+                                true,
+                                titleName,
+                                parentDiv
+                            ]);
+                        }
+
+                        addFormFields.call(
+                            _self,
+                            parentDiv,
+                            chart,
+                            parentFullName,
+                            value,
+                            storage,
+                            false
+                        );
+                    } else {
+                        storage.push([
+                            _self,
+                            parentFullName,
+                            'annotation',
+                            parentDiv,
+                            value
+                        ]);
+                    }
+                }
+            });
+
+            if (isRoot) {
+                storage = storage.sort(function (a) {
+                    return a[1].match(/format/g) ? -1 : 1;
+                });
+
+                storage.forEach(function (genInput) {
+                    if (genInput[0] === true) {
+                        createElement(SPAN, {
+                            className: PREFIX + 'annotation-title',
+                            innerHTML: genInput[1]
+                        }, null, genInput[2]);
+                    } else {
+                        addInput.apply(genInput[0], genInput.splice(1));
+                    }
+                });
+            }
+        }
+    },
+    indicators: {
+        /**
+         * Create indicator's form. It contains two tabs (ADD and EDIT) with
+         * content.
+         * @private
+         * @param {Chart} - chart
+         * @param {Object} - options
+         * @param {Function} - on click callback
+         */
+        addForm: function (chart, options, callback) {
+
+            var tabsContainers,
+                indicators = this.indicators,
+                lang = this.lang,
+                buttonParentDiv;
+
+            // add tabs
+            this.tabs.init.call(this, chart);
+
+            // get all tabs content divs
+            tabsContainers = this.popup.container
+                .querySelectorAll('.' + PREFIX + 'tab-item-content');
+
+            // ADD tab
+            this.addColsContainer(tabsContainers[0]);
+            indicators.addIndicatorList.call(
+                this,
+                chart,
+                tabsContainers[0],
+                'add'
+            );
+
+            buttonParentDiv = tabsContainers[0]
+                .querySelectorAll('.' + PREFIX + 'popup-rhs-col')[0];
+
+            this.addButton(
+                buttonParentDiv,
+                lang.addButton || 'add',
+                'add',
+                callback,
+                buttonParentDiv
+            );
+
+            // EDIT tab
+            this.addColsContainer(tabsContainers[1]);
+            indicators.addIndicatorList.call(
+                this,
+                chart,
+                tabsContainers[1],
+                'edit'
+            );
+
+            buttonParentDiv = tabsContainers[1]
+                .querySelectorAll('.' + PREFIX + 'popup-rhs-col')[0];
+
+            this.addButton(
+                buttonParentDiv,
+                lang.saveButton || 'save',
+                'edit',
+                callback,
+                buttonParentDiv
+            );
+            this.addButton(
+                buttonParentDiv,
+                lang.removeButton || 'remove',
+                'remove',
+                callback,
+                buttonParentDiv
+            );
+        },
+        /**
+         * Create HTML list of all indicators (ADD mode) or added indicators
+         * (EDIT mode).
+         * @private
+         * @param {Chart} - chart
+         * @param {HTMLDOMElement} - container where list is added
+         * @param {String} - 'edit' or 'add' mode
+         */
+        addIndicatorList: function (chart, parentDiv, listType) {
+            var _self = this,
+                lhsCol = parentDiv
+                    .querySelectorAll('.' + PREFIX + 'popup-lhs-col')[0],
+                rhsCol = parentDiv
+                    .querySelectorAll('.' + PREFIX + 'popup-rhs-col')[0],
+                isEdit = listType === 'edit',
+                series = isEdit ? chart.series : // EDIT mode
+                    chart.options.plotOptions, // ADD mode
+                addFormFields = this.indicators.addFormFields,
+                rhsColWrapper,
+                indicatorList,
+                item;
+
+            // create wrapper for list
+            indicatorList = createElement(UL, {
+                className: PREFIX + 'indicator-list'
+            }, null, lhsCol);
+
+            rhsColWrapper = rhsCol
+                .querySelectorAll('.' + PREFIX + 'popup-rhs-col-wrapper')[0];
+
+            objectEach(series, function (serie, value) {
+                var seriesOptions = serie.options;
+
+                if (
+                    serie.params ||
+                    seriesOptions && seriesOptions.params
+                ) {
+
+                    var indicatorNameType = _self.indicators
+                            .getNameType(serie, value),
+                        indicatorType = indicatorNameType.type;
+
+                    item = createElement(LI, {
+                        className: PREFIX + 'indicator-list',
+                        innerHTML: indicatorNameType.name
+                    }, null, indicatorList);
+
+                    ['click', 'touchstart'].forEach(function (eventName) {
+                        addEvent(item, eventName, function () {
+
+                            addFormFields.call(
+                                _self,
+                                chart,
+                                isEdit ? serie : series[indicatorType],
+                                indicatorNameType.type,
+                                rhsColWrapper
+                            );
+
+                            // add hidden input with series.id
+                            if (isEdit && serie.options) {
+                                createElement(INPUT, {
+                                    type: 'hidden',
+                                    name: PREFIX + 'id-' + indicatorType,
+                                    value: serie.options.id
+                                }, null, rhsColWrapper)
+                                    .setAttribute(
+                                        PREFIX + 'data-series-id',
+                                        serie.options.id
+                                    );
+                            }
+                        });
+                    });
+                }
+            });
+
+            // select first item from the list
+            if (indicatorList.childNodes.length > 0) {
+                indicatorList.childNodes[0].click();
+            }
+        },
+        /**
+         * Extract full name and type of requested indicator.
+         * @private
+         * @param {Series} - series which name is needed.
+         * (EDIT mode - defaultOptions.series, ADD mode - indicator series).
+         * @param {String} - indicator type like: sma, ema, etc.
+         * @return {Object} - series name and type like: sma, ema, etc.
+         */
+        getNameType: function (series, type) {
+            var options = series.options,
+                seriesTypes = H.seriesTypes,
+                // add mode
+                seriesName = seriesTypes[type] &&
+                    seriesTypes[type].prototype.nameBase || type.toUpperCase(),
+                seriesType = type;
+
+            // edit
+            if (options && options.type) {
+                seriesType = series.options.type;
+                seriesName = series.name;
+            }
+
+            return {
+                name: seriesName,
+                type: seriesType
+            };
+        },
+        /**
+         * List all series with unique ID. Its mandatory for indicators to set
+         * correct linking.
+         * @private
+         * @param {String} - indicator type like: sma, ema, etc.
+         * @param {String} - type of select i.e series or volume.
+         * @param {Chart} - chart
+         * @param {HTMLDOMElement} - element where created HTML list is added
+         * @param {String} selectedOption
+         *         optional param for default value in dropdown
+         */
+        listAllSeries: function (
+            type,
+            optionName,
+            chart,
+            parentDiv,
+            selectedOption
+        ) {
+            var selectName = PREFIX + optionName + '-type-' + type,
+                lang = this.lang,
+                selectBox,
+                seriesOptions;
+
+            createElement(
+                LABEL, {
+                    innerHTML: lang[optionName] || optionName,
+                    htmlFor: selectName
+                },
+                null,
+                parentDiv
+            );
+
+            // select type
+            selectBox = createElement(
+                SELECT,
+                {
+                    name: selectName,
+                    className: PREFIX + 'popup-field'
+                },
+                null,
+                parentDiv
+            );
+
+            selectBox.setAttribute('id', PREFIX + 'select-' + optionName);
+
+            // list all series which have id - mandatory for creating indicator
+            chart.series.forEach(function (serie) {
+
+                seriesOptions = serie.options;
+
+                if (
+                    !seriesOptions.params &&
+                    seriesOptions.id &&
+                    seriesOptions.id !== PREFIX + 'navigator-series'
+                ) {
+                    createElement(
+                        OPTION,
+                        {
+                            innerHTML: seriesOptions.name || seriesOptions.id,
+                            value: seriesOptions.id
+                        },
+                        null,
+                        selectBox
+                    );
+                }
+            });
+
+            if (defined(selectedOption)) {
+                selectBox.value = selectedOption;
+            }
+        },
+        /**
+         * Create typical inputs for chosen indicator. Fields are extracted from
+         * defaultOptions (ADD mode) or current indicator (ADD mode). Two extra
+         * fields are added:
+         * - hidden input - contains indicator type (required for callback)
+         * - select - list of series which can be linked with indicator
+         * @private
+         * @param {Chart} - chart
+         * @param {Series} - indicator
+         * @param {String} - indicator type like: sma, ema, etc.
+         * @param {HTMLDOMElement} - element where created HTML list is added
+         */
+        addFormFields: function (chart, series, seriesType, rhsColWrapper) {
+            var fields = series.params || series.options.params,
+                getNameType = this.indicators.getNameType;
+
+            // reset current content
+            rhsColWrapper.innerHTML = '';
+
+            // create title (indicator name in the right column)
+            createElement(
+                H3,
+                {
+                    className: PREFIX + 'indicator-title',
+                    innerHTML: getNameType(series, seriesType).name
+                },
+                null,
+                rhsColWrapper
+            );
+
+            // input type
+            createElement(
+                INPUT,
+                {
+                    type: 'hidden',
+                    name: PREFIX + 'type-' + seriesType,
+                    value: seriesType
+                },
+                null,
+                rhsColWrapper
+            );
+
+            // list all series with id
+            this.indicators.listAllSeries.call(
+                this,
+                seriesType,
+                'series',
+                chart,
+                rhsColWrapper,
+                series.linkedParent && fields.volumeSeriesID
+            );
+
+            if (fields.volumeSeriesID) {
+                this.indicators.listAllSeries.call(
+                    this,
+                    seriesType,
+                    'volume',
+                    chart,
+                    rhsColWrapper,
+                    series.linkedParent && series.linkedParent.options.id
+                );
+            }
+
+            // add param fields
+            this.indicators.addParamInputs.call(
+                this,
+                chart,
+                'params',
+                fields,
+                seriesType,
+                rhsColWrapper
+            );
+        },
+        /**
+         * Recurent function which lists all fields, from params object and
+         * create them as inputs. Each input has unique `data-name` attribute,
+         * which keeps chain of fields i.e params.styles.fontSize.
+         * @private
+         * @param {Chart} - chart
+         * @param {String} - name of parent to create chain of names
+         * @param {Series} - fields - params which are based for input create
+         * @param {String} - indicator type like: sma, ema, etc.
+         * @param {HTMLDOMElement} - element where created HTML list is added
+         */
+        addParamInputs: function (chart, parentNode, fields, type, parentDiv) {
+            var _self = this,
+                addParamInputs = this.indicators.addParamInputs,
+                addInput = this.addInput,
+                parentFullName;
+
+            objectEach(fields, function (value, fieldName) {
+                // create name like params.styles.fontSize
+                parentFullName = parentNode + '.' + fieldName;
+
+                if (isObject(value)) {
+                    addParamInputs.call(
+                        _self,
+                        chart,
+                        parentFullName,
+                        value,
+                        type,
+                        parentDiv
+                    );
+                } else if (
+                // skip volume field which is created by addFormFields
+                    parentFullName !== 'params.volumeSeriesID'
+                ) {
+                    addInput.call(
+                        _self,
+                        parentFullName,
+                        type,
+                        parentDiv,
+                        [value, 'text'] // all inputs are text type
+                    );
+                }
+            });
+        },
+        /**
+         * Get amount of indicators added to chart.
+         * @private
+         * @return {Number} - Amount of indicators
+         */
+        getAmount: function () {
+            var series = this.series,
+                counter = 0;
+
+            objectEach(series, function (serie) {
+                var seriesOptions = serie.options;
+
+                if (
+                    serie.params ||
+                    seriesOptions && seriesOptions.params
+                ) {
+                    counter++;
+                }
+            });
+
+            return counter;
+        }
+    },
+    tabs: {
+        /**
+         * Init tabs. Create tab menu items, tabs containers
+         * @private
+         * @param {Chart} - reference to current chart
+         */
+        init: function (chart) {
+            var tabs = this.tabs,
+                indicatorsCount = this.indicators.getAmount.call(chart),
+                firstTab; // run by default
+
+            // create menu items
+            firstTab = tabs.addMenuItem.call(this, 'add');
+            tabs.addMenuItem.call(this, 'edit', indicatorsCount);
+
+            // create tabs containers
+            tabs.addContentItem.call(this, 'add');
+            tabs.addContentItem.call(this, 'edit');
+
+            tabs.switchTabs.call(this, indicatorsCount);
+
+            // activate first tab
+            tabs.selectTab.call(this, firstTab, 0);
+        },
+        /**
+         * Create tab menu item
+         * @private
+         * @param {String} - `add` or `edit`
+         * @param {Number} - Disable tab when 0
+         * @return {HTMLDOMElement} - created HTML tab-menu element
+         */
+        addMenuItem: function (tabName, disableTab) {
+            var popupDiv = this.popup.container,
+                className = PREFIX + 'tab-item',
+                lang = this.lang,
+                menuItem;
+
+            if (disableTab === 0) {
+                className += ' ' + PREFIX + 'tab-disabled';
+            }
+
+            // tab 1
+            menuItem = createElement(
+                SPAN,
+                {
+                    innerHTML: lang[tabName + 'Button'] || tabName,
+                    className: className
+                },
+                null,
+                popupDiv
+            );
+
+            menuItem.setAttribute(PREFIX + 'data-tab-type', tabName);
+
+            return menuItem;
+        },
+        /**
+         * Create tab content
+         * @private
+         * @return {HTMLDOMElement} - created HTML tab-content element
+         */
+        addContentItem: function () {
+            var popupDiv = this.popup.container;
+
+            return createElement(
+                DIV,
+                {
+                    className: PREFIX + 'tab-item-content'
+                },
+                null,
+                popupDiv
+            );
+        },
+        /**
+         * Add click event to each tab
+         * @private
+         * @param {Number} - Disable tab when 0
+         */
+        switchTabs: function (disableTab) {
+            var _self = this,
+                popupDiv = this.popup.container,
+                tabs = popupDiv.querySelectorAll('.' + PREFIX + 'tab-item'),
+                dataParam;
+
+            tabs.forEach(function (tab, i) {
+
+                dataParam = tab.getAttribute(PREFIX + 'data-tab-type');
+
+                if (dataParam === 'edit' && disableTab === 0) {
+                    return;
+                }
+
+                ['click', 'touchstart'].forEach(function (eventName) {
+                    addEvent(tab, eventName, function () {
+
+                        // reset class on other elements
+                        _self.tabs.deselectAll.call(_self);
+                        _self.tabs.selectTab.call(_self, this, i);
+                    });
+                });
+            });
+        },
+        /**
+         * Set tab as visible
+         * @private
+         * @param {HTMLDOMElement} - current tab
+         * @param {Number} - Index of tab in menu
+         */
+        selectTab: function (tab, index) {
+            var allTabs = this.popup.container
+                .querySelectorAll('.' + PREFIX + 'tab-item-content');
+
+            tab.className += ' ' + PREFIX + 'tab-item-active';
+            allTabs[index].className += ' ' + PREFIX + 'tab-item-show';
+        },
+        /**
+         * Set all tabs as invisible.
+         * @private
+         */
+        deselectAll: function () {
+            var popupDiv = this.popup.container,
+                tabs = popupDiv
+                    .querySelectorAll('.' + PREFIX + 'tab-item'),
+                tabsContent = popupDiv
+                    .querySelectorAll('.' + PREFIX + 'tab-item-content'),
+                i;
+
+            for (i = 0; i < tabs.length; i++) {
+                tabs[i].classList.remove(PREFIX + 'tab-item-active');
+                tabsContent[i].classList.remove(PREFIX + 'tab-item-show');
+            }
+        }
+    }
+};
+
+addEvent(H.NavigationBindings, 'showPopup', function (config) {
+    if (!this.popup) {
+        // Add popup to main container
+        this.popup = new H.Popup(
+            this.chart.container, (
+                this.chart.options.navigation.iconsURL ||
+                (
+                    this.chart.options.stockTools &&
+                    this.chart.options.stockTools.gui.iconsURL
+                ) ||
+                'https://code.highcharts.com/8.0.0/gfx/stock-icons/'
+            )
+        );
+    }
+
+    this.popup.showForm(
+        config.formType,
+        this.chart,
+        config.options,
+        config.onSubmit
+    );
+});
+
+addEvent(H.NavigationBindings, 'closePopup', function () {
+    if (this.popup) {
+        this.popup.closePopup();
+    }
+});

+ 203 - 0
app/public/js/Highstock-8.0.0/code/es-modules/annotations/types/CrookedLine.js

@@ -0,0 +1,203 @@
+'use strict';
+import H from '../../parts/Globals.js';
+import '../../parts/Utilities.js';
+
+var Annotation = H.Annotation,
+    MockPoint = Annotation.MockPoint,
+    ControlPoint = Annotation.ControlPoint;
+
+/**
+ * @class
+ * @extends Annotation
+ * @memberOf Annotation
+ */
+function CrookedLine() {
+    Annotation.apply(this, arguments);
+}
+
+H.extendAnnotation(
+    CrookedLine,
+    null,
+    /** @lends Annotation.CrookedLine# */
+    {
+        /**
+         * Overrides default setter to get axes from typeOptions.
+         */
+        setClipAxes: function () {
+            this.clipXAxis = this.chart.xAxis[this.options.typeOptions.xAxis];
+            this.clipYAxis = this.chart.yAxis[this.options.typeOptions.yAxis];
+        },
+        getPointsOptions: function () {
+            var typeOptions = this.options.typeOptions;
+
+            return typeOptions.points.map(function (pointOptions) {
+                pointOptions.xAxis = typeOptions.xAxis;
+                pointOptions.yAxis = typeOptions.yAxis;
+
+                return pointOptions;
+            });
+        },
+
+        getControlPointsOptions: function () {
+            return this.getPointsOptions();
+        },
+
+        addControlPoints: function () {
+            this.getControlPointsOptions().forEach(
+                function (pointOptions, i) {
+                    var controlPoint = new ControlPoint(
+                        this.chart,
+                        this,
+                        H.merge(
+                            this.options.controlPointOptions,
+                            pointOptions.controlPoint
+                        ),
+                        i
+                    );
+
+                    this.controlPoints.push(controlPoint);
+
+                    pointOptions.controlPoint = controlPoint.options;
+                },
+                this
+            );
+        },
+
+        addShapes: function () {
+            var typeOptions = this.options.typeOptions,
+                shape = this.initShape(
+                    H.merge(typeOptions.line, {
+                        type: 'path',
+                        points: this.points.map(function (point, i) {
+                            return function (target) {
+                                return target.annotation.points[i];
+                            };
+                        })
+                    }),
+                    false
+                );
+
+            typeOptions.line = shape.options;
+        }
+    },
+
+    /**
+     * A crooked line annotation.
+     *
+     * @sample highcharts/annotations-advanced/crooked-line/
+     *         Crooked line
+     *
+     * @product      highstock
+     * @optionparent annotations.crookedLine
+     */
+    {
+
+        /**
+         * @extends   annotations.labelOptions
+         * @apioption annotations.crookedLine.labelOptions
+         */
+
+        /**
+         * @extends   annotations.shapeOptions
+         * @apioption annotations.crookedLine.shapeOptions
+         */
+
+        /**
+         * Additional options for an annotation with the type.
+         */
+        typeOptions: {
+            /**
+             * This number defines which xAxis the point is connected to.
+             * It refers to either the axis id or the index of the axis
+             * in the xAxis array.
+             */
+            xAxis: 0,
+            /**
+             * This number defines which yAxis the point is connected to.
+             * It refers to either the axis id or the index of the axis
+             * in the xAxis array.
+             */
+            yAxis: 0,
+
+            /**
+             * @type      {Array<*>}
+             * @apioption annotations.crookedLine.typeOptions.points
+             */
+
+            /**
+             * The x position of the point.
+             *
+             * @type      {number}
+             * @apioption annotations.crookedLine.typeOptions.points.x
+             */
+
+            /**
+             * The y position of the point.
+             *
+             * @type      {number}
+             * @apioption annotations.crookedLine.typeOptions.points.y
+             */
+
+            /**
+             * @type      {number}
+             * @excluding positioner, events
+             * @apioption annotations.crookedLine.typeOptions.points.controlPoint
+             */
+
+            /**
+             * Line options.
+             *
+             * @excluding height, point, points, r, type, width
+             */
+            line: {
+                fill: 'none'
+            }
+        },
+
+        /**
+         * @excluding positioner, events
+         */
+        controlPointOptions: {
+            positioner: function (target) {
+                var graphic = this.graphic,
+                    xy = MockPoint.pointToPixels(target.points[this.index]);
+
+                return {
+                    x: xy.x - graphic.width / 2,
+                    y: xy.y - graphic.height / 2
+                };
+            },
+
+            events: {
+                drag: function (e, target) {
+                    if (
+                        target.chart.isInsidePlot(
+                            e.chartX - target.chart.plotLeft,
+                            e.chartY - target.chart.plotTop
+                        )
+                    ) {
+                        var translation = this.mouseMoveToTranslation(e);
+
+                        target.translatePoint(
+                            translation.x,
+                            translation.y,
+                            this.index
+                        );
+
+                        // Update options:
+                        target.options.typeOptions.points[this.index].x =
+                            target.points[this.index].x;
+                        target.options.typeOptions.points[this.index].y =
+                            target.points[this.index].y;
+
+                        target.redraw(false);
+                    }
+                }
+            }
+        }
+    }
+);
+
+Annotation.types.crookedLine = CrookedLine;
+
+export default CrookedLine;

+ 77 - 0
app/public/js/Highstock-8.0.0/code/es-modules/annotations/types/ElliottWave.js

@@ -0,0 +1,77 @@
+'use strict';
+import H from '../../parts/Globals.js';
+import '../../parts/Utilities.js';
+
+var Annotation = H.Annotation,
+    CrookedLine = Annotation.types.crookedLine;
+
+/**
+ * @class
+ * @extends Annotation.CrookedLine
+ * @memberOf Annotation
+ */
+function ElliottWave() {
+    CrookedLine.apply(this, arguments);
+}
+
+H.extendAnnotation(ElliottWave, CrookedLine,
+    /** Annotation.CrookedLine# */
+    {
+        addLabels: function () {
+            this.getPointsOptions().forEach(function (point, i) {
+                var label = this.initLabel(H.merge(
+                    point.label, {
+                        text: this.options.typeOptions.labels[i],
+                        point: function (target) {
+                            return target.annotation.points[i];
+                        }
+                    }
+                ), false);
+
+                point.label = label.options;
+            }, this);
+        }
+    },
+
+    /**
+     * An elliott wave annotation.
+     *
+     * @sample highcharts/annotations-advanced/elliott-wave/
+     *         Elliott wave
+     *
+     * @extends      annotations.crookedLine
+     * @product      highstock
+     * @optionparent annotations.elliottWave
+     */
+    {
+        typeOptions: {
+
+            /**
+             * @extends   annotations.crookedLine.labelOptions
+             * @apioption annotations.elliottWave.typeOptions.points.label
+             */
+
+            /**
+             * @ignore-options
+             */
+            labels: ['(0)', '(A)', '(B)', '(C)', '(D)', '(E)'],
+            line: {
+                strokeWidth: 1
+            }
+        },
+
+        labelOptions: {
+            align: 'center',
+            allowOverlap: true,
+            crop: true,
+            overflow: 'none',
+            type: 'rect',
+            backgroundColor: 'none',
+            borderWidth: 0,
+            y: -5
+        }
+    });
+
+Annotation.types.elliottWave = ElliottWave;
+
+export default ElliottWave;

+ 247 - 0
app/public/js/Highstock-8.0.0/code/es-modules/annotations/types/Fibonacci.js

@@ -0,0 +1,247 @@
+'use strict';
+import H from '../../parts/Globals.js';
+import '../../parts/Utilities.js';
+
+var Annotation = H.Annotation,
+    MockPoint = Annotation.MockPoint,
+    Tunnel = Annotation.types.tunnel;
+
+var createPathDGenerator = function (retracementIndex, isBackground) {
+    return function () {
+        var annotation = this.annotation,
+            leftTop = this.anchor(
+                annotation.startRetracements[retracementIndex]
+            ).absolutePosition,
+            rightTop = this.anchor(
+                annotation.endRetracements[retracementIndex]
+            ).absolutePosition,
+            d = [
+                'M',
+                Math.round(leftTop.x),
+                Math.round(leftTop.y),
+                'L',
+                Math.round(rightTop.x),
+                Math.round(rightTop.y)
+            ],
+            rightBottom,
+            leftBottom;
+
+        if (isBackground) {
+            rightBottom = this.anchor(
+                annotation.endRetracements[retracementIndex - 1]
+            ).absolutePosition;
+
+            leftBottom = this.anchor(
+                annotation.startRetracements[retracementIndex - 1]
+            ).absolutePosition;
+
+            d.push(
+                'L',
+                Math.round(rightBottom.x),
+                Math.round(rightBottom.y),
+                'L',
+                Math.round(leftBottom.x),
+                Math.round(leftBottom.y)
+            );
+        }
+
+        return d;
+    };
+};
+
+/**
+ * @class
+ * @extends Annotation.Tunnel
+ * @memberOf Annotation
+ **/
+function Fibonacci() {
+    this.startRetracements = [];
+    this.endRetracements = [];
+
+    Tunnel.apply(this, arguments);
+}
+
+Fibonacci.levels = [0, 0.236, 0.382, 0.5, 0.618, 0.786, 1];
+
+H.extendAnnotation(Fibonacci, Tunnel,
+    /** @lends Annotation.Fibonacci# */
+    {
+        linkPoints: function () {
+            Tunnel.prototype.linkPoints.call(this);
+
+            this.linkRetracementsPoints();
+        },
+
+        linkRetracementsPoints: function () {
+            var points = this.points,
+                startDiff = points[0].y - points[3].y,
+                endDiff = points[1].y - points[2].y,
+                startX = points[0].x,
+                endX = points[1].x;
+
+            Fibonacci.levels.forEach(function (level, i) {
+                var startRetracement = points[0].y - startDiff * level,
+                    endRetracement = points[1].y - endDiff * level;
+
+                this.linkRetracementPoint(
+                    i,
+                    startX,
+                    startRetracement,
+                    this.startRetracements
+                );
+
+                this.linkRetracementPoint(
+                    i,
+                    endX,
+                    endRetracement,
+                    this.endRetracements
+                );
+            }, this);
+        },
+
+        linkRetracementPoint: function (
+            pointIndex,
+            x,
+            y,
+            retracements
+        ) {
+            var point = retracements[pointIndex],
+                typeOptions = this.options.typeOptions;
+
+            if (!point) {
+                retracements[pointIndex] = new MockPoint(
+                    this.chart,
+                    this,
+                    {
+                        x: x,
+                        y: y,
+                        xAxis: typeOptions.xAxis,
+                        yAxis: typeOptions.yAxis
+                    }
+                );
+            } else {
+                point.options.x = x;
+                point.options.y = y;
+
+                point.refresh();
+            }
+        },
+
+        addShapes: function () {
+            Fibonacci.levels.forEach(function (level, i) {
+                this.initShape({
+                    type: 'path',
+                    d: createPathDGenerator(i)
+                }, false);
+
+                if (i > 0) {
+                    this.initShape({
+                        type: 'path',
+                        fill: this.options.typeOptions.backgroundColors[i - 1],
+                        strokeWidth: 0,
+                        d: createPathDGenerator(i, true)
+                    });
+                }
+            }, this);
+        },
+
+        addLabels: function () {
+            Fibonacci.levels.forEach(function (level, i) {
+                var options = this.options.typeOptions,
+                    label = this.initLabel(
+                        H.merge(options.labels[i], {
+                            point: function (target) {
+                                var point = MockPoint.pointToOptions(
+                                    target.annotation.startRetracements[i]
+                                );
+
+                                return point;
+                            },
+                            text: level.toString()
+                        })
+                    );
+
+                options.labels[i] = label.options;
+            }, this);
+        }
+    },
+
+    /**
+     * A fibonacci annotation.
+     *
+     * @sample highcharts/annotations-advanced/fibonacci/
+     *         Fibonacci
+     *
+     * @extends      annotations.crookedLine
+     * @product      highstock
+     * @optionparent annotations.fibonacci
+     */
+    {
+        typeOptions: {
+            /**
+             * The height of the fibonacci in terms of yAxis.
+             */
+            height: 2,
+
+            /**
+             * An array of background colors:
+             * Default to:
+             * ```
+             * [
+             * 'rgba(130, 170, 255, 0.4)',
+             * 'rgba(139, 191, 216, 0.4)',
+             * 'rgba(150, 216, 192, 0.4)',
+             * 'rgba(156, 229, 161, 0.4)',
+             * 'rgba(162, 241, 130, 0.4)',
+             * 'rgba(169, 255, 101, 0.4)'
+             * ]
+             * ```
+             */
+            backgroundColors: [
+                'rgba(130, 170, 255, 0.4)',
+                'rgba(139, 191, 216, 0.4)',
+                'rgba(150, 216, 192, 0.4)',
+                'rgba(156, 229, 161, 0.4)',
+                'rgba(162, 241, 130, 0.4)',
+                'rgba(169, 255, 101, 0.4)'
+            ],
+
+            /**
+             * The color of line.
+             */
+            lineColor: 'grey',
+
+            /**
+             * An array of colors for the lines.
+             */
+            lineColors: [],
+
+            /**
+             * An array with options for the labels.
+             *
+             * @type      {Array<object>}
+             * @extends   annotations.crookedLine.labelOptions
+             * @apioption annotations.fibonacci.typeOptions.labels
+             */
+            labels: []
+        },
+
+        labelOptions: {
+            allowOverlap: true,
+            align: 'right',
+            backgroundColor: 'none',
+            borderWidth: 0,
+            crop: false,
+            overflow: 'none',
+            shape: 'rect',
+            style: {
+                color: 'grey'
+            },
+            verticalAlign: 'middle',
+            y: 0
+        }
+    });
+
+Annotation.types.fibonacci = Fibonacci;
+
+export default Fibonacci;

+ 185 - 0
app/public/js/Highstock-8.0.0/code/es-modules/annotations/types/InfinityLine.js

@@ -0,0 +1,185 @@
+'use strict';
+import H from '../../parts/Globals.js';
+import '../../parts/Utilities.js';
+
+var Annotation = H.Annotation,
+    MockPoint = Annotation.MockPoint,
+    CrookedLine = Annotation.types.crookedLine;
+
+/**
+ * @class
+ * @extends Annotation.CrookedLine
+ * @memberOf Annotation
+ */
+function InfinityLine() {
+    CrookedLine.apply(this, arguments);
+}
+
+InfinityLine.findEdgeCoordinate = function (
+    firstPoint,
+    secondPoint,
+    xOrY,
+    edgePointFirstCoordinate
+) {
+    var xOrYOpposite = xOrY === 'x' ? 'y' : 'x';
+
+    // solves equation for x or y
+    // y - y1 = (y2 - y1) / (x2 - x1) * (x - x1)
+    return (
+        (secondPoint[xOrY] - firstPoint[xOrY]) *
+        (edgePointFirstCoordinate - firstPoint[xOrYOpposite]) /
+        (secondPoint[xOrYOpposite] - firstPoint[xOrYOpposite]) +
+        firstPoint[xOrY]
+    );
+};
+
+InfinityLine.findEdgePoint = function (firstPoint, secondPoint) {
+    var xAxis = firstPoint.series.xAxis,
+        yAxis = secondPoint.series.yAxis,
+        firstPointPixels = MockPoint.pointToPixels(firstPoint),
+        secondPointPixels = MockPoint.pointToPixels(secondPoint),
+        deltaX = secondPointPixels.x - firstPointPixels.x,
+        deltaY = secondPointPixels.y - firstPointPixels.y,
+        xAxisMin = xAxis.left,
+        xAxisMax = xAxisMin + xAxis.width,
+        yAxisMin = yAxis.top,
+        yAxisMax = yAxisMin + yAxis.height,
+        xLimit = deltaX < 0 ? xAxisMin : xAxisMax,
+        yLimit = deltaY < 0 ? yAxisMin : yAxisMax,
+        edgePoint = {
+            x: deltaX === 0 ? firstPointPixels.x : xLimit,
+            y: deltaY === 0 ? firstPointPixels.y : yLimit
+        },
+        edgePointX,
+        edgePointY,
+        swap;
+
+    if (deltaX !== 0 && deltaY !== 0) {
+        edgePointY = InfinityLine.findEdgeCoordinate(
+            firstPointPixels,
+            secondPointPixels,
+            'y',
+            xLimit
+        );
+
+        edgePointX = InfinityLine.findEdgeCoordinate(
+            firstPointPixels,
+            secondPointPixels,
+            'x',
+            yLimit
+        );
+
+        if (edgePointY >= yAxisMin && edgePointY <= yAxisMax) {
+            edgePoint.x = xLimit;
+            edgePoint.y = edgePointY;
+        } else {
+            edgePoint.x = edgePointX;
+            edgePoint.y = yLimit;
+        }
+    }
+
+    edgePoint.x -= xAxisMin;
+    edgePoint.y -= yAxisMin;
+
+    if (firstPoint.series.chart.inverted) {
+        swap = edgePoint.x;
+        edgePoint.x = edgePoint.y;
+        edgePoint.y = swap;
+    }
+
+    return edgePoint;
+};
+
+var edgePoint = function (startIndex, endIndex) {
+    return function (target) {
+        var annotation = target.annotation,
+            points = annotation.points,
+            type = annotation.options.typeOptions.type;
+
+        if (type === 'horizontalLine') {
+            // Horizontal line has only one point,
+            // make a copy of it:
+            points = [
+                points[0],
+                new MockPoint(
+                    annotation.chart,
+                    points[0].target,
+                    {
+                        x: points[0].x + 1,
+                        y: points[0].y,
+                        xAxis: points[0].options.xAxis,
+                        yAxis: points[0].options.yAxis
+                    }
+                )
+            ];
+        } else if (type === 'verticalLine') {
+            // The same for verticalLine type:
+            points = [
+                points[0],
+                new MockPoint(
+                    annotation.chart,
+                    points[0].target,
+                    {
+                        x: points[0].x,
+                        y: points[0].y + 1,
+                        xAxis: points[0].options.xAxis,
+                        yAxis: points[0].options.yAxis
+                    }
+                )
+            ];
+        }
+
+        return InfinityLine.findEdgePoint(
+            points[startIndex],
+            points[endIndex]
+        );
+    };
+};
+
+InfinityLine.endEdgePoint = edgePoint(0, 1);
+InfinityLine.startEdgePoint = edgePoint(1, 0);
+
+H.extendAnnotation(
+    InfinityLine,
+    CrookedLine,
+    /** @lends Annotation.InfinityLine# */
+    {
+        addShapes: function () {
+            var typeOptions = this.options.typeOptions,
+                points = [
+                    this.points[0],
+                    InfinityLine.endEdgePoint
+                ];
+
+            if (typeOptions.type.match(/Line/g)) {
+                points[0] = InfinityLine.startEdgePoint;
+            }
+
+            var line = this.initShape(
+                H.merge(typeOptions.line, {
+                    type: 'path',
+                    points: points
+                }),
+                false
+            );
+
+            typeOptions.line = line.options;
+        }
+
+    }
+);
+
+/**
+ * An infinity line annotation.
+ *
+ * @sample highcharts/annotations-advanced/infinity-line/
+ *         Infinity Line
+ *
+ * @extends   annotations.crookedLine
+ * @product   highstock
+ * @apioption annotations.infinityLine
+ */
+
+Annotation.types.infinityLine = InfinityLine;
+
+export default InfinityLine;

+ 939 - 0
app/public/js/Highstock-8.0.0/code/es-modules/annotations/types/Measure.js

@@ -0,0 +1,939 @@
+'use strict';
+import H from '../../parts/Globals.js';
+
+import U from '../../parts/Utilities.js';
+var extend = U.extend,
+    isNumber = U.isNumber;
+
+var Annotation = H.Annotation,
+    ControlPoint = Annotation.ControlPoint,
+    merge = H.merge;
+
+/**
+ * @class
+ * @extends Annotation
+ * @memberOf Annotation
+ */
+function Measure() {
+    Annotation.apply(this, arguments);
+}
+
+Annotation.types.measure = Measure;
+
+H.extendAnnotation(Measure, null,
+    /** @lends Annotation.Measure# */
+    {
+        /**
+         * Init annotation object.
+         */
+        init: function () {
+            Annotation.prototype.init.apply(this, arguments);
+
+            this.offsetX = 0;
+            this.offsetY = 0;
+            this.resizeX = 0;
+            this.resizeY = 0;
+
+            this.calculations.init.call(this);
+            this.addValues();
+            this.addShapes();
+        },
+
+        /**
+         * Overrides default setter to get axes from typeOptions.
+         */
+        setClipAxes: function () {
+            this.clipXAxis = this.chart.xAxis[this.options.typeOptions.xAxis];
+            this.clipYAxis = this.chart.yAxis[this.options.typeOptions.yAxis];
+        },
+
+        /**
+         * Get measure points configuration objects.
+         *
+         * @return {Array<Highcharts.MockPointOptions>}
+         */
+        pointsOptions: function () {
+            return this.options.options.points;
+        },
+
+        /**
+         * Get points configuration objects for shapes.
+         *
+         * @return {Array<Highcharts.MockPointOptions>}
+         */
+        shapePointsOptions: function () {
+
+            var options = this.options.typeOptions,
+                xAxis = options.xAxis,
+                yAxis = options.yAxis;
+
+            return [
+                {
+                    x: this.xAxisMin,
+                    y: this.yAxisMin,
+                    xAxis: xAxis,
+                    yAxis: yAxis
+                },
+                {
+                    x: this.xAxisMax,
+                    y: this.yAxisMin,
+                    xAxis: xAxis,
+                    yAxis: yAxis
+                },
+                {
+                    x: this.xAxisMax,
+                    y: this.yAxisMax,
+                    xAxis: xAxis,
+                    yAxis: yAxis
+                },
+                {
+                    x: this.xAxisMin,
+                    y: this.yAxisMax,
+                    xAxis: xAxis,
+                    yAxis: yAxis
+                }
+            ];
+        },
+
+        addControlPoints: function () {
+            var selectType = this.options.typeOptions.selectType,
+                controlPoint;
+
+            controlPoint = new ControlPoint(
+                this.chart,
+                this,
+                this.options.controlPointOptions,
+                0
+            );
+
+            this.controlPoints.push(controlPoint);
+
+            // add extra controlPoint for horizontal and vertical range
+            if (selectType !== 'xy') {
+                controlPoint = new ControlPoint(
+                    this.chart,
+                    this,
+                    this.options.controlPointOptions,
+                    1
+                );
+
+                this.controlPoints.push(controlPoint);
+            }
+        },
+        /**
+         * Add label with calculated values (min, max, average, bins).
+         *
+         * @param {boolean} resize - the flag for resize shape
+         */
+        addValues: function (resize) {
+            var typeOptions = this.options.typeOptions,
+                formatter = typeOptions.label.formatter;
+
+            // set xAxisMin, xAxisMax, yAxisMin, yAxisMax
+            this.calculations.recalculate.call(this, resize);
+
+            if (!typeOptions.label.enabled) {
+                return;
+            }
+
+            if (this.labels.length > 0) {
+                this.labels[0].text = (formatter && formatter.call(this)) ||
+                            this.calculations.defaultFormatter.call(this);
+
+            } else {
+                this.initLabel(extend({
+                    shape: 'rect',
+                    backgroundColor: 'none',
+                    color: 'black',
+                    borderWidth: 0,
+                    dashStyle: 'dash',
+                    overflow: 'none',
+                    align: 'left',
+                    vertical: 'top',
+                    crop: true,
+                    point: function (target) {
+                        var annotation = target.annotation,
+                            chart = annotation.chart,
+                            inverted = chart.inverted,
+                            xAxis = chart.xAxis[typeOptions.xAxis],
+                            yAxis = chart.yAxis[typeOptions.yAxis],
+                            top = chart.plotTop,
+                            left = chart.plotLeft;
+
+                        return {
+                            x: (inverted ? top : 10) +
+                                xAxis.toPixels(annotation.xAxisMin, !inverted),
+                            y: (inverted ? -left + 10 : top) +
+                                yAxis.toPixels(annotation.yAxisMin)
+                        };
+                    },
+                    text: (formatter && formatter.call(this)) ||
+                        this.calculations.defaultFormatter.call(this)
+                }, typeOptions.label));
+            }
+        },
+        /**
+         * Crosshair, background (rect)
+         */
+        addShapes: function () {
+            this.addCrosshairs();
+            this.addBackground();
+        },
+
+        /**
+         * Add background shape.
+         */
+        addBackground: function () {
+            var shapePoints = this.shapePointsOptions();
+
+            if (typeof shapePoints[0].x === 'undefined') {
+                return;
+            }
+
+            this.initShape(extend({
+                type: 'path',
+                points: this.shapePointsOptions()
+            }, this.options.typeOptions.background), false);
+        },
+
+        /**
+         * Add internal crosshair shapes (on top and bottom)
+         */
+        addCrosshairs: function () {
+            var chart = this.chart,
+                options = this.options.typeOptions,
+                point = this.options.typeOptions.point,
+                xAxis = chart.xAxis[options.xAxis],
+                yAxis = chart.yAxis[options.yAxis],
+                inverted = chart.inverted,
+                xAxisMin = xAxis.toPixels(this.xAxisMin),
+                xAxisMax = xAxis.toPixels(this.xAxisMax),
+                yAxisMin = yAxis.toPixels(this.yAxisMin),
+                yAxisMax = yAxis.toPixels(this.yAxisMax),
+                defaultOptions = {
+                    point: point,
+                    type: 'path'
+                },
+                pathH = [],
+                pathV = [],
+                crosshairOptionsX,
+                crosshairOptionsY,
+                temp;
+
+            if (inverted) {
+                temp = xAxisMin;
+                xAxisMin = yAxisMin;
+                yAxisMin = temp;
+
+                temp = xAxisMax;
+                xAxisMax = yAxisMax;
+                yAxisMax = temp;
+            }
+            // horizontal line
+            if (options.crosshairX.enabled) {
+                pathH = [
+                    'M',
+                    xAxisMin,
+                    yAxisMin + ((yAxisMax - yAxisMin) / 2),
+                    'L',
+                    xAxisMax,
+                    yAxisMin + ((yAxisMax - yAxisMin) / 2)
+                ];
+            }
+
+            // vertical line
+            if (options.crosshairY.enabled) {
+                pathV = [
+                    'M',
+                    xAxisMin + ((xAxisMax - xAxisMin) / 2),
+                    yAxisMin,
+                    'L',
+                    xAxisMin + ((xAxisMax - xAxisMin) / 2),
+                    yAxisMax
+                ];
+            }
+
+            // Update existed crosshair
+            if (this.shapes.length > 0) {
+
+                this.shapes[0].options.d = pathH;
+                this.shapes[1].options.d = pathV;
+
+            } else {
+
+                // Add new crosshairs
+                crosshairOptionsX = merge(defaultOptions, options.crosshairX);
+                crosshairOptionsY = merge(defaultOptions, options.crosshairY);
+
+                this.initShape(extend({
+                    d: pathH
+                }, crosshairOptionsX), false);
+
+                this.initShape(extend({
+                    d: pathV
+                }, crosshairOptionsY), false);
+
+            }
+        },
+
+        onDrag: function (e) {
+            var translation = this.mouseMoveToTranslation(e),
+                selectType = this.options.typeOptions.selectType,
+                x = selectType === 'y' ? 0 : translation.x,
+                y = selectType === 'x' ? 0 : translation.y;
+
+            this.translate(x, y);
+
+            this.offsetX += x;
+            this.offsetY += y;
+
+            // animation, resize, setStartPoints
+            this.redraw(false, false, true);
+        },
+
+        /**
+         * Translate start or end ("left" or "right") side of the measure.
+         * Update start points (startXMin, startXMax, startYMin, startYMax)
+         *
+         * @param {number} dx - the amount of x translation
+         * @param {number} dy - the amount of y translation
+         * @param {number} cpIndex - index of control point
+         * @param {number} selectType - x / y / xy
+         */
+        resize: function (dx, dy, cpIndex, selectType) {
+
+            // background shape
+            var bckShape = this.shapes[2];
+
+            if (selectType === 'x') {
+                if (cpIndex === 0) {
+                    bckShape.translatePoint(dx, 0, 0);
+                    bckShape.translatePoint(dx, dy, 3);
+                } else {
+                    bckShape.translatePoint(dx, 0, 1);
+                    bckShape.translatePoint(dx, dy, 2);
+                }
+            } else if (selectType === 'y') {
+                if (cpIndex === 0) {
+                    bckShape.translatePoint(0, dy, 0);
+                    bckShape.translatePoint(0, dy, 1);
+                } else {
+                    bckShape.translatePoint(0, dy, 2);
+                    bckShape.translatePoint(0, dy, 3);
+                }
+            } else {
+                bckShape.translatePoint(dx, 0, 1);
+                bckShape.translatePoint(dx, dy, 2);
+                bckShape.translatePoint(0, dy, 3);
+            }
+
+            this.calculations.updateStartPoints
+                .call(this, false, true, cpIndex, dx, dy);
+
+            this.options.typeOptions.background.height = Math.abs(
+                this.startYMax - this.startYMin
+            );
+
+            this.options.typeOptions.background.width = Math.abs(
+                this.startXMax - this.startXMin
+            );
+        },
+        /**
+         * Redraw event which render elements and update start points
+         * if needed
+         *
+         * @param {Boolean} animation
+         * @param {Boolean} resize - flag if resized
+         * @param {Boolean} setStartPoints - update position of start points
+         */
+        redraw: function (animation, resize, setStartPoints) {
+
+            this.linkPoints();
+
+            if (!this.graphic) {
+                this.render();
+            }
+
+            if (setStartPoints) {
+                this.calculations.updateStartPoints.call(this, true, false);
+            }
+
+            // #11174 - clipBox was not recalculate during resize / redraw
+            if (this.clipRect) {
+                this.clipRect.animate(this.getClipBox());
+            }
+
+            this.addValues(resize);
+            this.addCrosshairs();
+            this.redrawItems(this.shapes, animation);
+            this.redrawItems(this.labels, animation);
+
+            // redraw control point to run positioner
+            this.controlPoints.forEach(function (controlPoint) {
+                controlPoint.redraw();
+            });
+        },
+        translate: function (dx, dy) {
+            this.shapes.forEach(function (item) {
+                item.translate(dx, dy);
+            });
+
+            this.options.typeOptions.point.x = this.startXMin;
+            this.options.typeOptions.point.y = this.startYMin;
+        },
+        calculations: {
+            /**
+             * Set starting points
+             * @private
+             */
+            init: function () {
+                var options = this.options.typeOptions,
+                    chart = this.chart,
+                    getPointPos = this.calculations.getPointPos,
+                    inverted = chart.inverted,
+                    xAxis = chart.xAxis[options.xAxis],
+                    yAxis = chart.yAxis[options.yAxis],
+                    bck = options.background,
+                    width = inverted ? bck.height : bck.width,
+                    height = inverted ? bck.width : bck.height,
+                    selectType = options.selectType,
+                    top = inverted ? chart.plotLeft : chart.plotTop,
+                    left = inverted ? chart.plotTop : chart.plotLeft;
+
+                this.startXMin = options.point.x;
+                this.startYMin = options.point.y;
+
+                if (isNumber(width)) {
+                    this.startXMax = this.startXMin + width;
+                } else {
+                    this.startXMax = getPointPos(
+                        xAxis,
+                        this.startXMin,
+                        parseFloat(width)
+                    );
+                }
+
+                if (isNumber(height)) {
+                    this.startYMax = this.startYMin - height;
+                } else {
+                    this.startYMax = getPointPos(
+                        yAxis,
+                        this.startYMin,
+                        parseFloat(height)
+                    );
+                }
+
+                // x / y selection type
+                if (selectType === 'x') {
+                    this.startYMin = yAxis.toValue(top);
+                    this.startYMax = yAxis.toValue(top + yAxis.len);
+                } else if (selectType === 'y') {
+                    this.startXMin = xAxis.toValue(left);
+                    this.startXMax = xAxis.toValue(left + xAxis.len);
+                }
+
+            },
+            /**
+             * Set current xAxisMin, xAxisMax, yAxisMin, yAxisMax.
+             * Calculations of measure values (min, max, average, bins).
+             * @private
+             * @param {Boolean} resize - flag if shape is resized
+             */
+            recalculate: function (resize) {
+                var calc = this.calculations,
+                    options = this.options.typeOptions,
+                    xAxis = this.chart.xAxis[options.xAxis],
+                    yAxis = this.chart.yAxis[options.yAxis],
+                    getPointPos = this.calculations.getPointPos,
+                    offsetX = this.offsetX,
+                    offsetY = this.offsetY;
+
+                this.xAxisMin = getPointPos(xAxis, this.startXMin, offsetX);
+                this.xAxisMax = getPointPos(xAxis, this.startXMax, offsetX);
+                this.yAxisMin = getPointPos(yAxis, this.startYMin, offsetY);
+                this.yAxisMax = getPointPos(yAxis, this.startYMax, offsetY);
+
+                this.min = calc.min.call(this);
+                this.max = calc.max.call(this);
+                this.average = calc.average.call(this);
+                this.bins = calc.bins.call(this);
+
+                if (resize) {
+                    this.resize(0, 0);
+                }
+
+            },
+            /**
+             * Set current xAxisMin, xAxisMax, yAxisMin, yAxisMax.
+             * Calculations of measure values (min, max, average, bins).
+             * @private
+             * @param {Object} axis - x or y axis reference
+             * @param {Number} value - point's value (x or y)
+             * @param {Number} offset - amount of pixels
+             */
+            getPointPos: function (axis, value, offset) {
+                return axis.toValue(
+                    axis.toPixels(value) + offset
+                );
+            },
+            /**
+             * Update position of start points
+             * (startXMin, startXMax, startYMin, startYMax)
+             * @private
+             * @param {Boolean} redraw - flag if shape is redraw
+             * @param {Boolean} resize - flag if shape is resized
+             * @param {Boolean} cpIndex - index of controlPoint
+             */
+            updateStartPoints: function (redraw, resize, cpIndex, dx, dy) {
+                var options = this.options.typeOptions,
+                    selectType = options.selectType,
+                    xAxis = this.chart.xAxis[options.xAxis],
+                    yAxis = this.chart.yAxis[options.yAxis],
+                    getPointPos = this.calculations.getPointPos,
+                    startXMin = this.startXMin,
+                    startXMax = this.startXMax,
+                    startYMin = this.startYMin,
+                    startYMax = this.startYMax,
+                    offsetX = this.offsetX,
+                    offsetY = this.offsetY;
+
+                if (resize) {
+                    if (selectType === 'x') {
+                        if (cpIndex === 0) {
+                            this.startXMin = getPointPos(xAxis, startXMin, dx);
+                        } else {
+                            this.startXMax = getPointPos(xAxis, startXMax, dx);
+                        }
+                    } else if (selectType === 'y') {
+                        if (cpIndex === 0) {
+                            this.startYMin = getPointPos(yAxis, startYMin, dy);
+                        } else {
+                            this.startYMax = getPointPos(yAxis, startYMax, dy);
+                        }
+                    } else {
+                        this.startXMax = getPointPos(xAxis, startXMax, dx);
+                        this.startYMax = getPointPos(yAxis, startYMax, dy);
+                    }
+                }
+
+                if (redraw) {
+                    this.startXMin = getPointPos(xAxis, startXMin, offsetX);
+                    this.startXMax = getPointPos(xAxis, startXMax, offsetX);
+                    this.startYMin = getPointPos(yAxis, startYMin, offsetY);
+                    this.startYMax = getPointPos(yAxis, startYMax, offsetY);
+
+                    this.offsetX = 0;
+                    this.offsetY = 0;
+                }
+            },
+            /**
+             * Default formatter of label's content
+             * @private
+             */
+            defaultFormatter: function () {
+                return 'Min: ' + this.min +
+                    '<br>Max: ' + this.max +
+                    '<br>Average: ' + this.average +
+                    '<br>Bins: ' + this.bins;
+            },
+            /**
+             * Set values for xAxisMin, xAxisMax, yAxisMin, yAxisMax, also
+             * when chart is inverted
+             * @private
+             */
+            getExtremes: function (xAxisMin, xAxisMax, yAxisMin, yAxisMax) {
+                return {
+                    xAxisMin: Math.min(xAxisMax, xAxisMin),
+                    xAxisMax: Math.max(xAxisMax, xAxisMin),
+                    yAxisMin: Math.min(yAxisMax, yAxisMin),
+                    yAxisMax: Math.max(yAxisMax, yAxisMin)
+                };
+            },
+            /**
+             * Definitions of calculations (min, max, average, bins)
+             * @private
+             */
+            min: function () {
+                var min = Infinity,
+                    series = this.chart.series,
+                    ext = this.calculations.getExtremes(
+                        this.xAxisMin,
+                        this.xAxisMax,
+                        this.yAxisMin,
+                        this.yAxisMax
+                    ),
+                    isCalculated = false; // to avoid Infinity in formatter
+
+                series.forEach(function (serie) {
+                    if (
+                        serie.visible &&
+                        serie.options.id !== 'highcharts-navigator-series'
+                    ) {
+                        serie.points.forEach(function (point) {
+                            if (
+                                !point.isNull &&
+                                point.y < min &&
+                                point.x > ext.xAxisMin &&
+                                point.x <= ext.xAxisMax &&
+                                point.y > ext.yAxisMin &&
+                                point.y <= ext.yAxisMax
+                            ) {
+                                min = point.y;
+                                isCalculated = true;
+                            }
+                        });
+                    }
+                });
+
+                if (!isCalculated) {
+                    min = '';
+                }
+
+                return min;
+            },
+            max: function () {
+                var max = -Infinity,
+                    series = this.chart.series,
+                    ext = this.calculations.getExtremes(
+                        this.xAxisMin,
+                        this.xAxisMax,
+                        this.yAxisMin,
+                        this.yAxisMax
+                    ),
+                    isCalculated = false; // to avoid Infinity in formatter
+
+                series.forEach(function (serie) {
+                    if (
+                        serie.visible &&
+                        serie.options.id !== 'highcharts-navigator-series'
+                    ) {
+                        serie.points.forEach(function (point) {
+                            if (
+                                !point.isNull &&
+                                point.y > max &&
+                                point.x > ext.xAxisMin &&
+                                point.x <= ext.xAxisMax &&
+                                point.y > ext.yAxisMin &&
+                                point.y <= ext.yAxisMax
+                            ) {
+                                max = point.y;
+                                isCalculated = true;
+                            }
+                        });
+                    }
+                });
+
+                if (!isCalculated) {
+                    max = '';
+                }
+
+                return max;
+            },
+            average: function () {
+                var average = '';
+
+                if (this.max !== '' && this.min !== '') {
+                    average = (this.max + this.min) / 2;
+                }
+
+                return average;
+            },
+            bins: function () {
+                var bins = 0,
+                    series = this.chart.series,
+                    ext = this.calculations.getExtremes(
+                        this.xAxisMin,
+                        this.xAxisMax,
+                        this.yAxisMin,
+                        this.yAxisMax
+                    ),
+                    isCalculated = false; // to avoid Infinity in formatter
+
+                series.forEach(function (serie) {
+                    if (
+                        serie.visible &&
+                        serie.options.id !== 'highcharts-navigator-series'
+                    ) {
+                        serie.points.forEach(function (point) {
+                            if (
+                                !point.isNull &&
+                                point.x > ext.xAxisMin &&
+                                point.x <= ext.xAxisMax &&
+                                point.y > ext.yAxisMin &&
+                                point.y <= ext.yAxisMax
+                            ) {
+                                bins++;
+                                isCalculated = true;
+                            }
+                        });
+                    }
+                });
+
+                if (!isCalculated) {
+                    bins = '';
+                }
+
+                return bins;
+            }
+        }
+    },
+    /**
+     * A measure annotation.
+     *
+     * @extends annotations.crookedLine
+     * @excluding labels, labelOptions, shapes, shapeOptions
+     * @sample highcharts/annotations-advanced/measure/
+     *         Measure
+     * @product highstock
+     * @optionparent annotations.measure
+     */
+    {
+        typeOptions: {
+            /**
+             * Decides in what dimensions the user can resize by dragging the
+             * mouse. Can be one of x, y or xy.
+             */
+            selectType: 'xy',
+            /**
+             * This number defines which xAxis the point is connected to.
+             * It refers to either the axis id or the index of the axis
+             * in the xAxis array.
+             */
+            xAxis: 0,
+            /**
+             * This number defines which yAxis the point is connected to.
+             * It refers to either the axis id or the index of the axis
+             * in the yAxis array.
+             */
+            yAxis: 0,
+            background: {
+                /**
+                 * The color of the rectangle.
+                 */
+                fill: 'rgba(130, 170, 255, 0.4)',
+                /**
+                 * The width of border.
+                 */
+                strokeWidth: 0,
+                /**
+                 * The color of border.
+                 */
+                stroke: void 0
+            },
+            /**
+             * Configure a crosshair that is horizontally placed in middle of
+             * rectangle.
+             *
+             */
+            crosshairX: {
+                /**
+                 * Enable or disable the horizontal crosshair.
+                 *
+                 */
+                enabled: true,
+                /**
+                 * The Z index of the crosshair in annotation.
+                 */
+                zIndex: 6,
+                /**
+                 * The dash or dot style of the crosshair's line. For possible
+                 * values, see
+                 * [this demonstration](https://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/plotoptions/series-dashstyle-all/).
+                 *
+                 * @type    {Highcharts.DashStyleValue}
+                 * @default Dash
+                 */
+                dashStyle: 'Dash',
+                /**
+                 * The marker-end defines the arrowhead that will be drawn
+                 * at the final vertex of the given crosshair's path.
+                 *
+                 * @type       {string}
+                 * @default    arrow
+                 */
+                markerEnd: 'arrow'
+            },
+            /**
+             * Configure a crosshair that is vertically placed in middle of
+             * rectangle.
+             */
+            crosshairY: {
+                /**
+                 * Enable or disable the vertical crosshair.
+                 *
+                 */
+                enabled: true,
+                /**
+                 * The Z index of the crosshair in annotation.
+                 */
+                zIndex: 6,
+                /**
+                 * The dash or dot style of the crosshair's line. For possible
+                 * values, see [this demonstration](https://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/plotoptions/series-dashstyle-all/).
+                 *
+                 * @type      {Highcharts.DashStyleValue}
+                 * @default   Dash
+                 * @apioption annotations.measure.typeOptions.crosshairY.dashStyle
+                 *
+                 */
+                dashStyle: 'Dash',
+                /**
+                 * The marker-end defines the arrowhead that will be drawn
+                 * at the final vertex of the given crosshair's path.
+                 *
+                 * @type       {string}
+                 * @default    arrow
+                 * @validvalue ["none", "arrow"]
+                 *
+                 */
+                markerEnd: 'arrow'
+            },
+            label: {
+                /**
+                 * Enable or disable the label text (min, max, average,
+                 * bins values).
+                 *
+                 * Defaults to true.
+                 */
+                enabled: true,
+                /**
+                 * CSS styles for the measure label.
+                 *
+                 * @type    {Highcharts.CSSObject}
+                 * @default {"color": "#666666", "fontSize": "11px"}
+                 */
+                style: {
+                    fontSize: '11px',
+                    color: '#666666'
+                },
+                /**
+                 * Formatter function for the label text.
+                 *
+                 * Available data are:
+                 *
+                 * <table>
+                 *
+                 * <tbody>
+                 *
+                 * <tr>
+                 *
+                 * <td>`this.min`</td>
+                 *
+                 * <td>The mininimum value of the points in the selected
+                 * range.</td>
+                 *
+                 * </tr>
+                 *
+                 * <tr>
+                 *
+                 * <td>`this.max`</td>
+                 *
+                 * <td>The maximum value of the points in the selected
+                 * range.</td>
+                 *
+                 * </tr>
+                 *
+                 * <tr>
+                 *
+                 * <td>`this.average`</td>
+                 *
+                 * <td>The average value of the points in the selected
+                 * range.</td>
+                 *
+                 * </tr>
+                 *
+                 * <tr>
+                 *
+                 * <td>`this.bins`</td>
+                 *
+                 * <td>The amount of the points in the selected range.</td>
+                 *
+                 * </tr>
+                 *
+                 * </table>
+                 *
+                 * @type      {function}
+                 *
+                 */
+                formatter: void 0
+            }
+        },
+        controlPointOptions: {
+            positioner: function (target) {
+                var cpIndex = this.index,
+                    chart = target.chart,
+                    options = target.options,
+                    typeOptions = options.typeOptions,
+                    selectType = typeOptions.selectType,
+                    controlPointOptions = options.controlPointOptions,
+                    inverted = chart.inverted,
+                    xAxis = chart.xAxis[typeOptions.xAxis],
+                    yAxis = chart.yAxis[typeOptions.yAxis],
+                    targetX = target.xAxisMax,
+                    targetY = target.yAxisMax,
+                    ext = target.calculations.getExtremes(
+                        target.xAxisMin,
+                        target.xAxisMax,
+                        target.yAxisMin,
+                        target.yAxisMax
+                    ),
+                    x, y;
+
+                if (selectType === 'x') {
+                    targetY = (ext.yAxisMax - ext.yAxisMin) / 2;
+
+                    // first control point
+                    if (cpIndex === 0) {
+                        targetX = target.xAxisMin;
+                    }
+                }
+
+                if (selectType === 'y') {
+                    targetX = ext.xAxisMin +
+                                        ((ext.xAxisMax - ext.xAxisMin) / 2);
+
+                    // first control point
+                    if (cpIndex === 0) {
+                        targetY = target.yAxisMin;
+                    }
+                }
+
+                if (inverted) {
+                    x = yAxis.toPixels(targetY);
+                    y = xAxis.toPixels(targetX);
+                } else {
+                    x = xAxis.toPixels(targetX);
+                    y = yAxis.toPixels(targetY);
+                }
+
+                return {
+                    x: x - (controlPointOptions.width / 2),
+                    y: y - (controlPointOptions.height / 2)
+                };
+            },
+            events: {
+                drag: function (e, target) {
+                    var translation = this.mouseMoveToTranslation(e),
+                        selectType = target.options.typeOptions.selectType,
+                        index = this.index,
+                        x = selectType === 'y' ? 0 : translation.x,
+                        y = selectType === 'x' ? 0 : translation.y;
+
+                    target.resize(
+                        x,
+                        y,
+                        index,
+                        selectType
+                    );
+
+                    target.resizeX += x;
+                    target.resizeY += y;
+                    target.redraw(false, true);
+                }
+            }
+        }
+    });
+
+Annotation.types.measure = Measure;
+
+export default Measure;

+ 204 - 0
app/public/js/Highstock-8.0.0/code/es-modules/annotations/types/Pitchfork.js

@@ -0,0 +1,204 @@
+'use strict';
+import H from '../../parts/Globals.js';
+import '../../parts/Utilities.js';
+
+var Annotation = H.Annotation,
+    MockPoint = Annotation.MockPoint,
+    InfinityLine = Annotation.types.infinityLine;
+
+/**
+ * @class
+ * @extends Highcharts.InfinityLine
+ * @memberOf Highcharts
+ **/
+function Pitchfork() {
+    InfinityLine.apply(this, arguments);
+}
+
+Pitchfork.findEdgePoint = function (
+    point,
+    firstAnglePoint,
+    secondAnglePoint
+) {
+    var angle = Math.atan2(
+            secondAnglePoint.plotY - firstAnglePoint.plotY,
+            secondAnglePoint.plotX - firstAnglePoint.plotX
+        ),
+        distance = 1e7;
+
+    return {
+        x: point.plotX + distance * Math.cos(angle),
+        y: point.plotY + distance * Math.sin(angle)
+    };
+};
+
+Pitchfork.middleLineEdgePoint = function (target) {
+    var annotation = target.annotation,
+        points = annotation.points;
+
+    return InfinityLine.findEdgePoint(
+        points[0],
+        new MockPoint(
+            annotation.chart,
+            target,
+            annotation.midPointOptions()
+        )
+    );
+};
+
+var outerLineEdgePoint = function (firstPointIndex) {
+    return function (target) {
+        var annotation = target.annotation,
+            points = annotation.points;
+
+        return Pitchfork.findEdgePoint(
+            points[firstPointIndex],
+            points[0],
+            new MockPoint(
+                annotation.chart,
+                target,
+                annotation.midPointOptions()
+            )
+        );
+    };
+};
+
+Pitchfork.topLineEdgePoint = outerLineEdgePoint(1);
+Pitchfork.bottomLineEdgePoint = outerLineEdgePoint(0);
+
+H.extendAnnotation(Pitchfork, InfinityLine,
+    {
+        midPointOptions: function () {
+            var points = this.points;
+
+            return {
+                x: (points[1].x + points[2].x) / 2,
+                y: (points[1].y + points[2].y) / 2,
+                xAxis: points[0].series.xAxis,
+                yAxis: points[0].series.yAxis
+            };
+        },
+
+        addShapes: function () {
+            this.addLines();
+            this.addBackgrounds();
+        },
+
+        addLines: function () {
+            this.initShape({
+                type: 'path',
+                points: [
+                    this.points[0],
+                    Pitchfork.middleLineEdgePoint
+                ]
+            }, false);
+
+            this.initShape({
+                type: 'path',
+                points: [
+                    this.points[1],
+                    Pitchfork.topLineEdgePoint
+                ]
+            }, false);
+
+            this.initShape({
+                type: 'path',
+                points: [
+                    this.points[2],
+                    Pitchfork.bottomLineEdgePoint
+                ]
+            }, false);
+        },
+
+        addBackgrounds: function () {
+            var shapes = this.shapes,
+                typeOptions = this.options.typeOptions;
+
+            var innerBackground = this.initShape(
+                H.merge(typeOptions.innerBackground, {
+                    type: 'path',
+                    points: [
+                        function (target) {
+                            var annotation = target.annotation,
+                                points = annotation.points,
+                                midPointOptions = annotation.midPointOptions();
+
+                            return {
+                                x: (points[1].x + midPointOptions.x) / 2,
+                                y: (points[1].y + midPointOptions.y) / 2,
+                                xAxis: midPointOptions.xAxis,
+                                yAxis: midPointOptions.yAxis
+                            };
+                        },
+                        shapes[1].points[1],
+                        shapes[2].points[1],
+                        function (target) {
+                            var annotation = target.annotation,
+                                points = annotation.points,
+                                midPointOptions = annotation.midPointOptions();
+
+                            return {
+                                x: (midPointOptions.x + points[2].x) / 2,
+                                y: (midPointOptions.y + points[2].y) / 2,
+                                xAxis: midPointOptions.xAxis,
+                                yAxis: midPointOptions.yAxis
+                            };
+                        }
+                    ]
+                })
+            );
+
+            var outerBackground = this.initShape(
+                H.merge(typeOptions.outerBackground, {
+                    type: 'path',
+                    points: [
+                        this.points[1],
+                        shapes[1].points[1],
+                        shapes[2].points[1],
+                        this.points[2]
+                    ]
+                })
+            );
+
+            typeOptions.innerBackground = innerBackground.options;
+            typeOptions.outerBackground = outerBackground.options;
+        }
+    },
+    /**
+     * A pitchfork annotation.
+     *
+     * @sample highcharts/annotations-advanced/pitchfork/
+     *         Pitchfork
+     *
+     * @extends      annotations.infinityLine
+     * @product      highstock
+     * @optionparent annotations.pitchfork
+     */
+    {
+        typeOptions: {
+            /**
+             * Inner background options.
+             *
+             * @extends   annotations.crookedLine.shapeOptions
+             * @excluding height, r, type, width
+             */
+            innerBackground: {
+                fill: 'rgba(130, 170, 255, 0.4)',
+                strokeWidth: 0
+            },
+            /**
+             * Outer background options.
+             *
+             * @extends   annotations.crookedLine.shapeOptions
+             * @excluding height, r, type, width
+             */
+            outerBackground: {
+                fill: 'rgba(156, 229, 161, 0.4)',
+                strokeWidth: 0
+            }
+        }
+    });
+
+Annotation.types.pitchfork = Pitchfork;
+
+export default Pitchfork;

+ 242 - 0
app/public/js/Highstock-8.0.0/code/es-modules/annotations/types/Tunnel.js

@@ -0,0 +1,242 @@
+'use strict';
+import H from '../../parts/Globals.js';
+import '../../parts/Utilities.js';
+
+var Annotation = H.Annotation,
+    CrookedLine = Annotation.types.crookedLine,
+    ControlPoint = Annotation.ControlPoint,
+    MockPoint = Annotation.MockPoint;
+
+function getSecondCoordinate(p1, p2, x) {
+    return (p2.y - p1.y) / (p2.x - p1.x) * (x - p1.x) + p1.y;
+}
+
+/**
+ * @class
+ * @extends Annotation.CrookedLine
+ * @memberOf Annotation
+ **/
+function Tunnel() {
+    CrookedLine.apply(this, arguments);
+}
+
+H.extendAnnotation(
+    Tunnel,
+    CrookedLine,
+    /** @lends Annotation.Tunnel# */
+    {
+        getPointsOptions: function () {
+            var pointsOptions =
+                CrookedLine.prototype.getPointsOptions.call(this);
+
+            pointsOptions[2] = this.heightPointOptions(pointsOptions[1]);
+            pointsOptions[3] = this.heightPointOptions(pointsOptions[0]);
+
+            return pointsOptions;
+        },
+
+        getControlPointsOptions: function () {
+            return this.getPointsOptions().slice(0, 2);
+        },
+
+        heightPointOptions: function (pointOptions) {
+            var heightPointOptions = H.merge(pointOptions);
+
+            heightPointOptions.y += this.options.typeOptions.height;
+
+            return heightPointOptions;
+        },
+
+        addControlPoints: function () {
+            CrookedLine.prototype.addControlPoints.call(this);
+
+            var options = this.options,
+                controlPoint = new ControlPoint(
+                    this.chart,
+                    this,
+                    H.merge(
+                        options.controlPointOptions,
+                        options.typeOptions.heightControlPoint
+                    ),
+                    2
+                );
+
+            this.controlPoints.push(controlPoint);
+
+            options.typeOptions.heightControlPoint = controlPoint.options;
+        },
+
+        addShapes: function () {
+            this.addLine();
+            this.addBackground();
+        },
+
+        addLine: function () {
+            var line = this.initShape(
+                H.merge(this.options.typeOptions.line, {
+                    type: 'path',
+                    points: [
+                        this.points[0],
+                        this.points[1],
+                        function (target) {
+                            var pointOptions = MockPoint.pointToOptions(
+                                target.annotation.points[2]
+                            );
+
+                            pointOptions.command = 'M';
+
+                            return pointOptions;
+                        },
+                        this.points[3]
+                    ]
+                }),
+                false
+            );
+
+            this.options.typeOptions.line = line.options;
+        },
+
+        addBackground: function () {
+            var background = this.initShape(H.merge(
+                this.options.typeOptions.background,
+                {
+                    type: 'path',
+                    points: this.points.slice()
+                }
+            ));
+
+            this.options.typeOptions.background = background.options;
+        },
+
+        /**
+         * Translate start or end ("left" or "right") side of the tunnel.
+         *
+         * @param {number} dx - the amount of x translation
+         * @param {number} dy - the amount of y translation
+         * @param {boolean} [end] - whether to translate start or end side
+         */
+        translateSide: function (dx, dy, end) {
+            var topIndex = Number(end),
+                bottomIndex = topIndex === 0 ? 3 : 2;
+
+            this.translatePoint(dx, dy, topIndex);
+            this.translatePoint(dx, dy, bottomIndex);
+        },
+
+        /**
+         * Translate height of the tunnel.
+         *
+         * @param {number} dh - the amount of height translation
+         */
+        translateHeight: function (dh) {
+            this.translatePoint(0, dh, 2);
+            this.translatePoint(0, dh, 3);
+
+            this.options.typeOptions.height =
+                this.points[3].y - this.points[0].y;
+        }
+    },
+
+    /**
+     * A tunnel annotation.
+     *
+     * @extends annotations.crookedLine
+     * @sample highcharts/annotations-advanced/tunnel/
+     *         Tunnel
+     * @product highstock
+     * @optionparent annotations.tunnel
+     */
+    {
+        typeOptions: {
+            xAxis: 0,
+            yAxis: 0,
+            /**
+             * Background options.
+             *
+             * @type {Object}
+             * @excluding height, point, points, r, type, width, markerEnd,
+             *            markerStart
+             */
+            background: {
+                fill: 'rgba(130, 170, 255, 0.4)',
+                strokeWidth: 0
+            },
+            line: {
+                strokeWidth: 1
+            },
+            /**
+             * The height of the annotation in terms of yAxis.
+             */
+            height: -2,
+
+
+            /**
+             * Options for the control point which controls
+             * the annotation's height.
+             *
+             * @extends annotations.crookedLine.controlPointOptions
+             * @excluding positioner, events
+             */
+            heightControlPoint: {
+                positioner: function (target) {
+                    var startXY = MockPoint.pointToPixels(target.points[2]),
+                        endXY = MockPoint.pointToPixels(target.points[3]),
+                        x = (startXY.x + endXY.x) / 2;
+
+                    return {
+                        x: x - this.graphic.width / 2,
+                        y: getSecondCoordinate(startXY, endXY, x) -
+                        this.graphic.height / 2
+                    };
+                },
+                events: {
+                    drag: function (e, target) {
+                        if (
+                            target.chart.isInsidePlot(
+                                e.chartX - target.chart.plotLeft,
+                                e.chartY - target.chart.plotTop
+                            )
+                        ) {
+                            target.translateHeight(
+                                this.mouseMoveToTranslation(e).y
+                            );
+
+                            target.redraw(false);
+                        }
+                    }
+                }
+            }
+        },
+
+        /**
+         * @extends annotations.crookedLine.controlPointOptions
+         * @excluding positioner, events
+         */
+        controlPointOptions: {
+            events: {
+                drag: function (e, target) {
+                    if (
+                        target.chart.isInsidePlot(
+                            e.chartX - target.chart.plotLeft,
+                            e.chartY - target.chart.plotTop
+                        )
+                    ) {
+                        var translation = this.mouseMoveToTranslation(e);
+
+                        target.translateSide(
+                            translation.x,
+                            translation.y,
+                            this.index
+                        );
+
+                        target.redraw(false);
+                    }
+                }
+            }
+        }
+    }
+);
+
+Annotation.types.tunnel = Tunnel;
+
+export default Tunnel;

+ 158 - 0
app/public/js/Highstock-8.0.0/code/es-modules/annotations/types/VerticalLine.js

@@ -0,0 +1,158 @@
+'use strict';
+import H from '../../parts/Globals.js';
+import '../../parts/Utilities.js';
+
+var Annotation = H.Annotation,
+    MockPoint = Annotation.MockPoint;
+
+/**
+ * @class
+ * @extends Annotation
+ * @memberOf Highcharts
+ */
+function VerticalLine() {
+    H.Annotation.apply(this, arguments);
+}
+
+VerticalLine.connectorFirstPoint = function (target) {
+    var annotation = target.annotation,
+        point = annotation.points[0],
+        xy = MockPoint.pointToPixels(point, true),
+        y = xy.y,
+        offset = annotation.options.typeOptions.label.offset;
+
+    if (annotation.chart.inverted) {
+        y = xy.x;
+    }
+
+    return {
+        x: point.x,
+        xAxis: point.series.xAxis,
+        y: y + offset
+    };
+};
+
+VerticalLine.connectorSecondPoint = function (target) {
+    var annotation = target.annotation,
+        typeOptions = annotation.options.typeOptions,
+        point = annotation.points[0],
+        yOffset = typeOptions.yOffset,
+        xy = MockPoint.pointToPixels(point, true),
+        y = xy[annotation.chart.inverted ? 'x' : 'y'];
+
+    if (typeOptions.label.offset < 0) {
+        yOffset *= -1;
+    }
+
+    return {
+        x: point.x,
+        xAxis: point.series.xAxis,
+        y: y + yOffset
+    };
+};
+
+H.extendAnnotation(VerticalLine, null,
+
+    /** @lends Annotation.VerticalLine# */
+    {
+        getPointsOptions: function () {
+            return [this.options.typeOptions.point];
+        },
+
+        addShapes: function () {
+            var typeOptions = this.options.typeOptions,
+                connector = this.initShape(
+                    H.merge(typeOptions.connector, {
+                        type: 'path',
+                        points: [
+                            VerticalLine.connectorFirstPoint,
+                            VerticalLine.connectorSecondPoint
+                        ]
+                    }),
+                    false
+                );
+
+            typeOptions.connector = connector.options;
+        },
+
+        addLabels: function () {
+            var typeOptions = this.options.typeOptions,
+                labelOptions = typeOptions.label,
+                x = 0,
+                y = labelOptions.offset,
+                verticalAlign = labelOptions.offset < 0 ? 'bottom' : 'top',
+                align = 'center';
+
+            if (this.chart.inverted) {
+                x = labelOptions.offset;
+                y = 0;
+                verticalAlign = 'middle';
+                align = labelOptions.offset < 0 ? 'right' : 'left';
+            }
+
+            var label = this.initLabel(
+                H.merge(labelOptions, {
+                    verticalAlign: verticalAlign,
+                    align: align,
+                    x: x,
+                    y: y
+                })
+            );
+
+            typeOptions.label = label.options;
+        }
+    },
+
+    /**
+     * A vertical line annotation.
+     *
+     * @sample highcharts/annotations-advanced/vertical-line/
+     *         Vertical line
+     *
+     * @extends      annotations.crookedLine
+     * @excluding    labels, shapes, controlPointOptions
+     * @product      highstock
+     * @optionparent annotations.verticalLine
+     */
+    {
+        typeOptions: {
+            /**
+             * @ignore
+             */
+            yOffset: 10,
+
+            /**
+             * Label options.
+             *
+             * @extends annotations.crookedLine.labelOptions
+             */
+            label: {
+                offset: -40,
+                point: function (target) {
+                    return target.annotation.points[0];
+                },
+                allowOverlap: true,
+                backgroundColor: 'none',
+                borderWidth: 0,
+                crop: true,
+                overflow: 'none',
+                shape: 'rect',
+                text: '{y:.2f}'
+            },
+
+            /**
+             * Connector options.
+             *
+             * @extends   annotations.crookedLine.shapeOptions
+             * @excluding height, r, type, width
+             */
+            connector: {
+                strokeWidth: 1,
+                markerEnd: 'arrow'
+            }
+        }
+    });
+
+Annotation.types.verticalLine = VerticalLine;
+
+export default VerticalLine;

+ 133 - 0
app/public/js/Highstock-8.0.0/code/es-modules/error-messages.js

@@ -0,0 +1,133 @@
+/* eslint-disable */
+/* *
+ * Error information for the debugger module
+ * (c) 2010-2019 Torstein Honsi
+ * License: www.highcharts.com/license
+ */
+
+// DO NOT EDIT!
+// Automatically generated by ./tools/error-messages.js
+// Sources can be found in ./errors/*/*.md
+
+'use strict';
+
+import H from './parts/Globals.js';
+
+H.errorMessages = {
+    "10": {
+        "title": "Can't plot zero or subzero values on a logarithmic axis",
+        "text": "<h1>Can't plot zero or subzero values on a logarithmic axis</h1><p>This error occurs in the following situations: </p><ul><li>If a zero or subzero data value is added to a logarithmic axis</li><li>If the minimum of a logarithimic axis is set to 0 or less</li><li>If the threshold is set to 0 or less</li></ul><p>Note: As of Highcharts 5.0.8 it's possible to bypass this error message by setting <code>Axis.prototype.allowNegativeLog</code> to true, and add custom conversion functions. <a href=\"https://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/samples/highcharts/yaxis/type-log-negative/\">View live demo</a>. It is also possible to use a similar workaround for colorAxis. <a href=\"https://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/samples/highcharts/coloraxis/logarithmic-with-emulate-negative-values/\">View live demo</a>.</p>",
+        "enduser": "<h1>Can't plot zero or subzero values on a logarithmic axis</h1><p>This error occurs in the following situations:</p><ul><li>If a zero or subzero data value is added to a logarithmic axis</li><li>If the minimum of a logarithimic axis is set to 0 or less</li><li>If the threshold is set to 0 or less</li></ul><p>As of Highcharts 5.0.8 it's possible to bypass this error message by setting <code>Axis.prototype.allowNegativeLog</code> to <code>true</code> and add custom conversion functions. <a href=\"http://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/samples/highcharts/yaxis/type-log-negative/\">\">View Live Demo</a>. It is also possible to use a similar workaround for colorAxis. <a href=\"https://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/samples/highcharts/coloraxis/logarithmic-with-emulate-negative-values/\">View live demo</a>.</p>"
+    },
+    "11": {
+        "title": "Can't link axes of different type",
+        "text": "<h1>Can't link axes of different type</h1><p>This error occurs when using the <code>linkedTo</code> option to link two axes of different types, for example a logarithmic axis to a linear axis. Highcharts can't link these because the calculation of ticks, extremes, padding etc. is different.</p>"
+    },
+    "12": {
+        "title": "Highcharts expects point configuration to be numbers or arrays in turbo mode",
+        "text": "<h1>Highcharts expects point configuration to be numbers or arrays in turbo mode</h1><p>This error occurs if the <code>series.data</code> option contains object configurations and the number of points exceeds the turboThreshold. It can be fixed by either setting <code>turboThreshold</code> to a higher value, or changing the point configurations to numbers or arrays.</p><p>In boost mode, turbo mode is always on, which means only array of numbers or two dimensional arrays are allowed.</p><p>See <a href=\"https://api.highcharts.com/highcharts#plotOptions.series.turboThreshold\">plotOptions.series.turboThreshold</a></p>"
+    },
+    "13": {
+        "title": "Rendering div not found",
+        "text": "<h1>Rendering div not found</h1><p>This error occurs if the <a href=\"https://api.highcharts.com/highcharts#chart.renderTo\">chart.renderTo</a> option is misconfigured so that Highcharts is unable to find the HTML element to render the chart in.</p><p>If using a DOM ID when creating the chart, make sure a node with the same ID exists somewhere in the DOM.</p>"
+    },
+    "14": {
+        "title": "String value sent to series.data, expected Number",
+        "text": "<h1>String value sent to series.data, expected Number</h1><p>This happens if using a string as a data point, for example in a setup like this: </p><pre>series: [{\n    data: [&quot;3&quot;, &quot;5&quot;, &quot;1&quot;, &quot;6&quot;]\n}]</pre><p>Highcharts expects numerical data values.</p><p>The most common reason for this error this is that data is parsed from CSV or from a XML source, and the implementer forgot to run <code>parseFloat</code> on the parsed value.</p><p>Note: For performance reasons internal type casting is not performed, and only the first value is checked (since 2.3).</p>"
+    },
+    "15": {
+        "title": "Highcharts expects data to be sorted",
+        "text": "<h1>Highcharts expects data to be sorted</h1><p>This happens when creating a line series or a stock chart where the data is not sorted in ascending X order.</p><p>For performance reasons, Highcharts does not sort the data, instead it requires that the implementer pre-sorts the data.</p>"
+    },
+    "16": {
+        "title": "Highcharts already defined in the page",
+        "text": "<h1>Highcharts already defined in the page</h1><p>This error happens if the <code>Highcharts</code> namespace already exists when loading Highcharts or Highstock.</p><p>This is caused by including Highcharts or Highstock more than once.</p><p>Keep in mind that the <code>Highcharts.Chart</code> constructor and all features of Highcharts are included in Highstock, so if using the <code>Chart</code> and <code>StockChart</code> constructors in combination, only the <code>highstock.js</code> file is required.</p>"
+    },
+    "17": {
+        "title": "The requested series type does not exist",
+        "text": "<h1>The requested series type does not exist</h1><p>This error happens when setting <code>chart.type</code> or <code>series.type</code> to a series type that isn't defined in Highcharts. A typical reason may be that the module or extension where the series type is defined isn't included.</p><p>For example in order to create an <code>arearange</code> series, the <code>highcharts-more.js</code> file must be loaded.</p>"
+    },
+    "18": {
+        "title": "The requested axis does not exist",
+        "text": "<h1>The requested axis does not exist</h1><p>This error happens when setting a series' <code>xAxis</code> or <code>yAxis</code> property to point to an axis that does not exist.</p>"
+    },
+    "19": {
+        "title": "Too many ticks",
+        "text": "<h1>Too many ticks</h1><p>This error happens when applying too many ticks to an axis, specifically when adding more ticks than the axis pixel length.</p><p>With default value this won't happen, but there are edge cases, for example when setting axis categories and <code>xAxis.labels.step</code> in combination with a long data range, when the axis is instructed to create a great number of ticks.</p>"
+    },
+    "20": {
+        "title": "Can't add object point configuration to a long data series",
+        "text": "<h1>Can't add object point configuration to a long data series</h1><p>In Highstock, when trying to add a point using the object literal configuration syntax, it will only work when the number of data points is below the series' <a href=\"https://api.highcharts.com/highstock#plotOptions.series.turboThreshold\">turboThreshold</a>. Instead of the object syntax, use the Array syntax.</p>"
+    },
+    "21": {
+        "title": "Can't find Proj4js library",
+        "text": "<h1>Can't find Proj4js library</h1><p>Using latitude/longitude functionality in Highmaps requires the <a href=\"http://proj4js.org\">Proj4js</a> library to be loaded.</p>"
+    },
+    "22": {
+        "title": "Map does not support latitude/longitude",
+        "text": "<h1>Map does not support latitude/longitude</h1><p>The loaded map does not support latitude/longitude functionality. This is only supported with maps from the <a href=\"https://code.highcharts.com/mapdata\">official Highmaps map collection</a> from version 1.1.0 onwards. If you are using a custom map, consider using the <a href=\"https://proj4js.org\">Proj4js</a> library to convert between projections.</p>"
+    },
+    "23": {
+        "title": "Unsupported color format used for color interpolation",
+        "text": "<h1>Unsupported color format used for color interpolation</h1><p>Highcharts supports three color formats primarily: hex (<code>#FFFFFF</code>), rgb (<code>rgba(255,255,255)</code>) and rgba (<code>rgba(255,255,255,1)</code>). If any other format, like 3-digit colors (<code>#FFF</code>), named colors (<code>white</code>) or gradient structures are used in for example a heatmap, Highcharts will fail to interpolate and will instead use the end-color with no interpolation applied.</p><p>We've chosen to preserve this limitation in order to keep the weight of the implementation at a minimum.</p>"
+    },
+    "24": {
+        "title": "Cannot run Point.update on a grouped point",
+        "text": "<h1>Cannot run Point.update on a grouped point</h1><p>Running <code>Point.update</code> in Highstock when a point is grouped by data grouping is not supported.</p><p>This is not supported because when data grouping is enabled, there won't be any references to the raw points, which is required by the <code>Point.update</code> function.</p>"
+    },
+    "25": {
+        "title": "Can't find Moment.js library",
+        "text": "<h1>Can't find Moment.js library</h1><p>Using the global.timezone option requires the <a href=\"https://momentjs.com/\">Moment.js</a> library to be loaded.</p>"
+    },
+    "26": {
+        "title": "WebGL not supported, and no fallback module included",
+        "text": "<h1>WebGL not supported, and no fallback module included</h1><p>This happens when the browser doesn't support WebGL,<b>and</b> the canvas fallback module (<code>boost-canvas.js</code>) hasn't been included OR if the fallback module was included<b>after</b> the boost module.</p><p>If a fallback is required, make sure to include <code>boost-canvas.js</code>, and that it's included before <code>boost.js</code>.</p><p>Please note that the fallback module is not intended as a fully-featured one. Rather, it's a minimal implementation of the WebGL counterpart.</p>"
+    },
+    "27": {
+        "title": "This browser does not support SVG",
+        "text": "<h1>This browser does not support SVG</h1><p>This happens in old IE when the <code>oldie.js</code> module isn't loaded.</p><p>If compatibility with IE versions 6, 7 and 8 is required, add the module after loading <code>highcharts.js</code>. In a website context, it's a good idea to load it in a conditional comment to avoid traffic overhead and dead code in modern browsers: </p><pre>&lt;!--[if lt IE 9]&gt;\n    &lt;script src='https://code.highcharts.com/modules/oldie.js'&gt;&lt;/script&gt;\n&lt;![endif]--&gt;</pre>"
+    },
+    "28": {
+        "title": "Fallback to export server disabled",
+        "text": "<h1>Fallback to export server disabled</h1><p>This happens when the offline export module encounters a chart that it can't export successfully, and the fallback to the online export server is disabled. The offline exporting module will fail for certain browsers, and certain features (e.g. <a href=\"https://api.highcharts.com/highcharts/exporting.allowHTML\">exporting.allowHTML</a> ), depending on the type of image exporting to. For a compatibility overview, see <a href=\"https://www.highcharts.com/docs/export-module/client-side-export\">Client Side Export</a>.</p><p>For very complex charts, it's possible that exporting fail in browsers that don't support Blob objects, due to data URL length limits. It's always recommended to define the <a href=\"https://api.highcharts.com/highcharts/exporting.error\">exporting.error</a> callback when disabling the fallback, so that details can be provided to the end-user if offline export isn't working for them.</p>"
+    },
+    "29": {
+        "title": "Browser does not support WebAudio",
+        "text": "<h1>Browser does not support WebAudio</h1><p>This happens when you attempt to use the sonification module on a chart in a browser or environment that does not support the WebAudio API. This API is supported on all modern browsers, including Microsoft Edge, Google Chrome and Mozilla Firefox.</p>"
+    },
+    "30": {
+        "title": "Invalid instrument",
+        "text": "<h1>Invalid instrument</h1><p>This happens when you try to use a sonification instrument that is not valid. If you are using a predefined instrument, make sure your spelling is correct.</p>"
+    },
+    "31": {
+        "title": "Non-unique point or node id",
+        "text": "<h1>Non-unique point or node id</h1><p>This error occurs when using the same <code>id</code> for two or more points or nodes.</p>"
+    },
+    "meta": {
+        "files": [
+            "errors/10/readme.md",
+            "errors/10/enduser.md",
+            "errors/11/readme.md",
+            "errors/12/readme.md",
+            "errors/13/readme.md",
+            "errors/14/readme.md",
+            "errors/15/readme.md",
+            "errors/16/readme.md",
+            "errors/17/readme.md",
+            "errors/18/readme.md",
+            "errors/19/readme.md",
+            "errors/20/readme.md",
+            "errors/21/readme.md",
+            "errors/22/readme.md",
+            "errors/23/readme.md",
+            "errors/24/readme.md",
+            "errors/25/readme.md",
+            "errors/26/readme.md",
+            "errors/27/readme.md",
+            "errors/28/readme.md",
+            "errors/29/readme.md",
+            "errors/30/readme.md",
+            "errors/31/readme.md"
+        ]
+    }
+};

+ 1 - 0
app/public/js/Highstock-8.0.0/code/es-modules/error.js

@@ -0,0 +1 @@
+console.error('code.highcharts.local has moved to the /code folder'); // eslint-disable-line no-console

+ 183 - 0
app/public/js/Highstock-8.0.0/code/es-modules/indicators/acceleration-bands.src.js

@@ -0,0 +1,183 @@
+/* *
+ *
+ *  License: www.highcharts.com/license
+ *
+ *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
+ *
+ * */
+'use strict';
+import H from '../parts/Globals.js';
+import U from '../parts/Utilities.js';
+var correctFloat = U.correctFloat;
+import multipleLinesMixin from '../mixins/multipe-lines.js';
+var SMA = H.seriesTypes.sma, merge = H.merge;
+/* eslint-disable valid-jsdoc */
+/**
+ * @private
+ */
+function getBaseForBand(low, high, factor) {
+    return (((correctFloat(high - low)) /
+        ((correctFloat(high + low)) / 2)) * 1000) * factor;
+}
+/**
+ * @private
+ */
+function getPointUB(high, base) {
+    return high * (correctFloat(1 + 2 * base));
+}
+/**
+ * @private
+ */
+function getPointLB(low, base) {
+    return low * (correctFloat(1 - 2 * base));
+}
+/* eslint-enable valid-jsdoc */
+/**
+ * The ABands series type
+ *
+ * @private
+ * @class
+ * @name Highcharts.seriesTypes.abands
+ *
+ * @augments Highcharts.Series
+ */
+H.seriesType('abands', 'sma', 
+/**
+ * Acceleration bands (ABANDS). This series requires the `linkedTo` option
+ * to be set and should be loaded after the
+ * `stock/indicators/indicators.js`.
+ *
+ * @sample {highstock} stock/indicators/acceleration-bands
+ *         Acceleration Bands
+ *
+ * @extends      plotOptions.sma
+ * @mixes        Highcharts.MultipleLinesMixin
+ * @since        7.0.0
+ * @product      highstock
+ * @excluding    allAreas, colorAxis, compare, compareBase, joinBy, keys,
+ *               navigatorOptions, pointInterval, pointIntervalUnit,
+ *               pointPlacement, pointRange, pointStart, showInNavigator,
+ *               stacking,
+ * @requires     stock/indicators/indicators
+ * @requires     stock/indicators/acceleration-bands
+ * @optionparent plotOptions.abands
+ */
+{
+    params: {
+        period: 20,
+        /**
+         * The algorithms factor value used to calculate bands.
+         *
+         * @product highstock
+         */
+        factor: 0.001,
+        index: 3
+    },
+    lineWidth: 1,
+    topLine: {
+        styles: {
+            /**
+             * Pixel width of the line.
+             */
+            lineWidth: 1
+        }
+    },
+    bottomLine: {
+        styles: {
+            /**
+             * Pixel width of the line.
+             */
+            lineWidth: 1
+        }
+    },
+    dataGrouping: {
+        approximation: 'averages'
+    }
+}, 
+/**
+ * @lends Highcharts.Series#
+ */
+merge(multipleLinesMixin, {
+    pointArrayMap: ['top', 'middle', 'bottom'],
+    pointValKey: 'middle',
+    nameBase: 'Acceleration Bands',
+    nameComponents: ['period', 'factor'],
+    linesApiNames: ['topLine', 'bottomLine'],
+    getValues: function (series, params) {
+        var period = params.period, factor = params.factor, index = params.index, xVal = series.xData, yVal = series.yData, yValLen = yVal ? yVal.length : 0, 
+        // Upperbands
+        UB = [], 
+        // Lowerbands
+        LB = [], 
+        // ABANDS array structure:
+        // 0-date, 1-top line, 2-middle line, 3-bottom line
+        ABANDS = [], 
+        // middle line, top line and bottom line
+        ML, TL, BL, date, bandBase, pointSMA, ubSMA, lbSMA, low = 2, high = 1, xData = [], yData = [], slicedX, slicedY, i;
+        if (yValLen < period) {
+            return;
+        }
+        for (i = 0; i <= yValLen; i++) {
+            // Get UB and LB values of every point. This condition
+            // is necessary, because there is a need to calculate current
+            // UB nad LB values simultaneously with given period SMA
+            // in one for loop.
+            if (i < yValLen) {
+                bandBase = getBaseForBand(yVal[i][low], yVal[i][high], factor);
+                UB.push(getPointUB(yVal[i][high], bandBase));
+                LB.push(getPointLB(yVal[i][low], bandBase));
+            }
+            if (i >= period) {
+                slicedX = xVal.slice(i - period, i);
+                slicedY = yVal.slice(i - period, i);
+                ubSMA = SMA.prototype.getValues.call(this, {
+                    xData: slicedX,
+                    yData: UB.slice(i - period, i)
+                }, {
+                    period: period
+                });
+                lbSMA = SMA.prototype.getValues.call(this, {
+                    xData: slicedX,
+                    yData: LB.slice(i - period, i)
+                }, {
+                    period: period
+                });
+                pointSMA = SMA.prototype.getValues.call(this, {
+                    xData: slicedX,
+                    yData: slicedY
+                }, {
+                    period: period,
+                    index: index
+                });
+                date = pointSMA.xData[0];
+                TL = ubSMA.yData[0];
+                BL = lbSMA.yData[0];
+                ML = pointSMA.yData[0];
+                ABANDS.push([date, TL, ML, BL]);
+                xData.push(date);
+                yData.push([TL, ML, BL]);
+            }
+        }
+        return {
+            values: ABANDS,
+            xData: xData,
+            yData: yData
+        };
+    }
+}));
+/**
+ * An Acceleration bands indicator. If the [type](#series.abands.type) option is not
+ * specified, it is inherited from [chart.type](#chart.type).
+ *
+ * @extends   series,plotOptions.abands
+ * @since     7.0.0
+ * @product   highstock
+ * @excluding allAreas, colorAxis, compare, compareBase, dataParser, dataURL,
+ *            joinBy, keys, navigatorOptions, pointInterval,
+ *            pointIntervalUnit, pointPlacement, pointRange, pointStart,
+ *            stacking, showInNavigator,
+ * @requires  stock/indicators/indicators
+ * @requires  stock/indicators/acceleration-bands
+ * @apioption series.abands
+ */
+''; // to include the above in jsdoc

+ 109 - 0
app/public/js/Highstock-8.0.0/code/es-modules/indicators/accumulation-distribution.src.js

@@ -0,0 +1,109 @@
+/* *
+ *
+ *  License: www.highcharts.com/license
+ *
+ *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
+ * */
+'use strict';
+import H from '../parts/Globals.js';
+import '../parts/Utilities.js';
+var seriesType = H.seriesType;
+/* eslint-disable valid-jsdoc */
+// Utils:
+/**
+ * @private
+ */
+function populateAverage(xVal, yVal, yValVolume, i) {
+    var high = yVal[i][1], low = yVal[i][2], close = yVal[i][3], volume = yValVolume[i], adY = close === high && close === low || high === low ?
+        0 :
+        ((2 * close - low - high) / (high - low)) * volume, adX = xVal[i];
+    return [adX, adY];
+}
+/* eslint-enable valid-jsdoc */
+/**
+ * The AD series type.
+ *
+ * @private
+ * @class
+ * @name Highcharts.seriesTypes.ad
+ *
+ * @augments Highcharts.Series
+ */
+seriesType('ad', 'sma', 
+/**
+ * Accumulation Distribution (AD). This series requires `linkedTo` option to
+ * be set.
+ *
+ * @sample stock/indicators/accumulation-distribution
+ *         Accumulation/Distribution indicator
+ *
+ * @extends      plotOptions.sma
+ * @since        6.0.0
+ * @product      highstock
+ * @requires     stock/indicators/indicators
+ * @requires     stock/indicators/accumulation-distribution
+ * @optionparent plotOptions.ad
+ */
+{
+    params: {
+        /**
+         * The id of volume series which is mandatory.
+         * For example using OHLC data, volumeSeriesID='volume' means
+         * the indicator will be calculated using OHLC and volume values.
+         *
+         * @since 6.0.0
+         */
+        volumeSeriesID: 'volume'
+    }
+}, 
+/**
+ * @lends Highcharts.Series#
+ */
+{
+    nameComponents: false,
+    nameBase: 'Accumulation/Distribution',
+    getValues: function (series, params) {
+        var period = params.period, xVal = series.xData, yVal = series.yData, volumeSeriesID = params.volumeSeriesID, volumeSeries = series.chart.get(volumeSeriesID), yValVolume = volumeSeries && volumeSeries.yData, yValLen = yVal ? yVal.length : 0, AD = [], xData = [], yData = [], len, i, ADPoint;
+        if (xVal.length <= period &&
+            yValLen &&
+            yVal[0].length !== 4) {
+            return;
+        }
+        if (!volumeSeries) {
+            H.error('Series ' +
+                volumeSeriesID +
+                ' not found! Check `volumeSeriesID`.', true, series.chart);
+            return;
+        }
+        // i = period <-- skip first N-points
+        // Calculate value one-by-one for each period in visible data
+        for (i = period; i < yValLen; i++) {
+            len = AD.length;
+            ADPoint = populateAverage(xVal, yVal, yValVolume, i, period);
+            if (len > 0) {
+                ADPoint[1] += AD[len - 1][1];
+            }
+            AD.push(ADPoint);
+            xData.push(ADPoint[0]);
+            yData.push(ADPoint[1]);
+        }
+        return {
+            values: AD,
+            xData: xData,
+            yData: yData
+        };
+    }
+});
+/**
+ * A `AD` series. If the [type](#series.ad.type) option is not
+ * specified, it is inherited from [chart.type](#chart.type).
+ *
+ * @extends   series,plotOptions.ad
+ * @since     6.0.0
+ * @excluding dataParser, dataURL
+ * @product   highstock
+ * @requires  stock/indicators/indicators
+ * @requires  stock/indicators/accumulation-distribution
+ * @apioption series.ad
+ */
+''; // add doclet above to transpiled file

+ 162 - 0
app/public/js/Highstock-8.0.0/code/es-modules/indicators/ao.src.js

@@ -0,0 +1,162 @@
+/* *
+ *
+ *  License: www.highcharts.com/license
+ *
+ *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
+ *
+ * */
+'use strict';
+import H from '../parts/Globals.js';
+import U from '../parts/Utilities.js';
+var correctFloat = U.correctFloat, isArray = U.isArray;
+var noop = H.noop;
+/**
+ * The AO series type
+ *
+ * @private
+ * @class
+ * @name Highcharts.seriesTypes.ao
+ *
+ * @augments Highcharts.Series
+ */
+H.seriesType('ao', 'sma', 
+/**
+ * Awesome Oscillator. This series requires the `linkedTo` option to
+ * be set and should be loaded after the `stock/indicators/indicators.js`
+ *
+ * @sample {highstock} stock/indicators/ao
+ *         Awesome
+ *
+ * @extends      plotOptions.sma
+ * @since        7.0.0
+ * @product      highstock
+ * @excluding    allAreas, colorAxis, joinBy, keys, navigatorOptions,
+ *               params, pointInterval, pointIntervalUnit, pointPlacement,
+ *               pointRange, pointStart, showInNavigator, stacking
+ * @requires     stock/indicators/indicators
+ * @requires     stock/indicators/ao
+ * @optionparent plotOptions.ao
+ */
+{
+    /**
+     * Color of the Awesome oscillator series bar that is greater than the
+     * previous one. Note that if a `color` is defined, the `color`
+     * takes precedence and the `greaterBarColor` is ignored.
+     *
+     * @sample {highstock} stock/indicators/ao/
+     *         greaterBarColor
+     *
+     * @type  {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
+     * @since 7.0.0
+     */
+    greaterBarColor: '#06B535',
+    /**
+     * Color of the Awesome oscillator series bar that is lower than the
+     * previous one. Note that if a `color` is defined, the `color`
+     * takes precedence and the `lowerBarColor` is ignored.
+     *
+     * @sample {highstock} stock/indicators/ao/
+     *         lowerBarColor
+     *
+     * @type  {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
+     * @since 7.0.0
+     */
+    lowerBarColor: '#F21313',
+    threshold: 0,
+    groupPadding: 0.2,
+    pointPadding: 0.2,
+    states: {
+        hover: {
+            halo: {
+                size: 0
+            }
+        }
+    }
+}, 
+/**
+ * @lends Highcharts.Series#
+ */
+{
+    nameBase: 'AO',
+    nameComponents: false,
+    // Columns support:
+    markerAttribs: noop,
+    getColumnMetrics: H.seriesTypes.column.prototype.getColumnMetrics,
+    crispCol: H.seriesTypes.column.prototype.crispCol,
+    translate: H.seriesTypes.column.prototype.translate,
+    drawPoints: H.seriesTypes.column.prototype.drawPoints,
+    drawGraph: function () {
+        var indicator = this, options = indicator.options, points = indicator.points, userColor = indicator.userOptions.color, positiveColor = options.greaterBarColor, negativeColor = options.lowerBarColor, firstPoint = points[0], i;
+        if (!userColor && firstPoint) {
+            firstPoint.color = positiveColor;
+            for (i = 1; i < points.length; i++) {
+                if (points[i].y > points[i - 1].y) {
+                    points[i].color = positiveColor;
+                }
+                else if (points[i].y < points[i - 1].y) {
+                    points[i].color = negativeColor;
+                }
+                else {
+                    points[i].color = points[i - 1].color;
+                }
+            }
+        }
+    },
+    getValues: function (series) {
+        var shortPeriod = 5, longPeriod = 34, xVal = series.xData || [], yVal = series.yData || [], yValLen = yVal.length, AO = [], // 0- date, 1- Awesome Oscillator
+        xData = [], yData = [], high = 1, low = 2, shortSum = 0, longSum = 0, shortSMA, // Shorter Period SMA
+        longSMA, // Longer Period SMA
+        awesome, shortLastIndex, longLastIndex, price, i, j;
+        if (xVal.length <= longPeriod ||
+            !isArray(yVal[0]) ||
+            yVal[0].length !== 4) {
+            return;
+        }
+        for (i = 0; i < longPeriod - 1; i++) {
+            price = (yVal[i][high] + yVal[i][low]) / 2;
+            if (i >= longPeriod - shortPeriod) {
+                shortSum = correctFloat(shortSum + price);
+            }
+            longSum = correctFloat(longSum + price);
+        }
+        for (j = longPeriod - 1; j < yValLen; j++) {
+            price = (yVal[j][high] + yVal[j][low]) / 2;
+            shortSum = correctFloat(shortSum + price);
+            longSum = correctFloat(longSum + price);
+            shortSMA = shortSum / shortPeriod;
+            longSMA = longSum / longPeriod;
+            awesome = correctFloat(shortSMA - longSMA);
+            AO.push([xVal[j], awesome]);
+            xData.push(xVal[j]);
+            yData.push(awesome);
+            shortLastIndex = j + 1 - shortPeriod;
+            longLastIndex = j + 1 - longPeriod;
+            shortSum = correctFloat(shortSum -
+                (yVal[shortLastIndex][high] +
+                    yVal[shortLastIndex][low]) / 2);
+            longSum = correctFloat(longSum -
+                (yVal[longLastIndex][high] +
+                    yVal[longLastIndex][low]) / 2);
+        }
+        return {
+            values: AO,
+            xData: xData,
+            yData: yData
+        };
+    }
+});
+/**
+ * An `AO` series. If the [type](#series.ao.type)
+ * option is not specified, it is inherited from [chart.type](#chart.type).
+ *
+ * @extends   series,plotOptions.ao
+ * @since     7.0.0
+ * @product   highstock
+ * @excluding allAreas, colorAxis, dataParser, dataURL, joinBy, keys,
+ *            navigatorOptions, pointInterval, pointIntervalUnit,
+ *            pointPlacement, pointRange, pointStart, showInNavigator, stacking
+ * @requires  stock/indicators/indicators
+ * @requires  stock/indicators/ao
+ * @apioption series.ao
+ */
+''; // for including the above in the doclets

+ 129 - 0
app/public/js/Highstock-8.0.0/code/es-modules/indicators/apo.src.js

@@ -0,0 +1,129 @@
+/* *
+ *
+ *  License: www.highcharts.com/license
+ *
+ *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
+ *
+ * */
+'use strict';
+import H from '../parts/Globals.js';
+import '../parts/Utilities.js';
+import requiredIndicatorMixin from '../mixins/indicator-required.js';
+var EMA = H.seriesTypes.ema, error = H.error, requiredIndicator = requiredIndicatorMixin;
+/**
+ * The APO series type.
+ *
+ * @private
+ * @class
+ * @name Highcharts.seriesTypes.apo
+ *
+ * @augments Highcharts.Series
+ */
+H.seriesType('apo', 'ema', 
+/**
+ * Absolute Price Oscillator. This series requires the `linkedTo` option to
+ * be set and should be loaded after the `stock/indicators/indicators.js`
+ * and `stock/indicators/ema.js`.
+ *
+ * @sample {highstock} stock/indicators/apo
+ *         Absolute Price Oscillator
+ *
+ * @extends      plotOptions.ema
+ * @since        7.0.0
+ * @product      highstock
+ * @excluding    allAreas, colorAxis, joinBy, keys, navigatorOptions,
+ *               pointInterval, pointIntervalUnit, pointPlacement,
+ *               pointRange, pointStart, showInNavigator, stacking
+ * @requires     stock/indicators/indicators
+ * @requires     stock/indicators/ema
+ * @requires     stock/indicators/apo
+ * @optionparent plotOptions.apo
+ */
+{
+    /**
+     * Paramters used in calculation of Absolute Price Oscillator
+     * series points.
+     *
+     * @excluding period
+     */
+    params: {
+        /**
+         * Periods for Absolute Price Oscillator calculations.
+         *
+         * @type    {Array<number>}
+         * @default [10, 20]
+         * @since   7.0.0
+         */
+        periods: [10, 20]
+    }
+}, 
+/**
+ * @lends Highcharts.Series.prototype
+ */
+{
+    nameBase: 'APO',
+    nameComponents: ['periods'],
+    init: function () {
+        var args = arguments, ctx = this;
+        requiredIndicator.isParentLoaded(EMA, 'ema', ctx.type, function (indicator) {
+            indicator.prototype.init.apply(ctx, args);
+            return;
+        });
+    },
+    getValues: function (series, params) {
+        var periods = params.periods, index = params.index, 
+        // 0- date, 1- Absolute price oscillator
+        APO = [], xData = [], yData = [], periodsOffset, 
+        // Shorter Period EMA
+        SPE, 
+        // Longer Period EMA
+        LPE, oscillator, i;
+        // Check if periods are correct
+        if (periods.length !== 2 || periods[1] <= periods[0]) {
+            error('Error: "APO requires two periods. Notice, first period ' +
+                'should be lower than the second one."');
+            return;
+        }
+        SPE = EMA.prototype.getValues.call(this, series, {
+            index: index,
+            period: periods[0]
+        });
+        LPE = EMA.prototype.getValues.call(this, series, {
+            index: index,
+            period: periods[1]
+        });
+        // Check if ema is calculated properly, if not skip
+        if (!SPE || !LPE) {
+            return;
+        }
+        periodsOffset = periods[1] - periods[0];
+        for (i = 0; i < LPE.yData.length; i++) {
+            oscillator = (SPE.yData[i + periodsOffset] -
+                LPE.yData[i]);
+            APO.push([LPE.xData[i], oscillator]);
+            xData.push(LPE.xData[i]);
+            yData.push(oscillator);
+        }
+        return {
+            values: APO,
+            xData: xData,
+            yData: yData
+        };
+    }
+});
+/**
+ * An `Absolute Price Oscillator` series. If the [type](#series.apo.type) option
+ * is not specified, it is inherited from [chart.type](#chart.type).
+ *
+ * @extends   series,plotOptions.apo
+ * @since     7.0.0
+ * @product   highstock
+ * @excluding allAreas, colorAxis, dataParser, dataURL, joinBy, keys,
+ *            navigatorOptions, pointInterval, pointIntervalUnit,
+ *            pointPlacement, pointRange, pointStart, showInNavigator, stacking
+ * @requires  stock/indicators/indicators
+ * @requires  stock/indicators/ema
+ * @requires  stock/indicators/apo
+ * @apioption series.apo
+ */
+''; // to include the above in the js output

+ 112 - 0
app/public/js/Highstock-8.0.0/code/es-modules/indicators/aroon-oscillator.src.js

@@ -0,0 +1,112 @@
+/* *
+ *
+ *  License: www.highcharts.com/license
+ *
+ *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
+ *
+ * */
+'use strict';
+import H from '../parts/Globals.js';
+import multipleLinesMixin from '../mixins/multipe-lines.js';
+import requiredIndicatorMixin from '../mixins/indicator-required.js';
+var AROON = H.seriesTypes.aroon, requiredIndicator = requiredIndicatorMixin;
+/**
+ * The Aroon Oscillator series type.
+ *
+ * @private
+ * @class
+ * @name Highcharts.seriesTypes.aroonoscillator
+ *
+ * @augments Highcharts.Series
+ */
+H.seriesType('aroonoscillator', 'aroon', 
+/**
+ * Aroon Oscillator. This series requires the `linkedTo` option to be set
+ * and should be loaded after the `stock/indicators/indicators.js` and
+ * `stock/indicators/aroon.js`.
+ *
+ * @sample {highstock} stock/indicators/aroon-oscillator
+ *         Aroon Oscillator
+ *
+ * @extends      plotOptions.aroon
+ * @since        7.0.0
+ * @product      highstock
+ * @excluding    allAreas, aroonDown, colorAxis, compare, compareBase,
+ *               joinBy, keys, navigatorOptions, pointInterval,
+ *               pointIntervalUnit, pointPlacement, pointRange, pointStart,
+ *               showInNavigator, stacking
+ * @requires     stock/indicators/indicators
+ * @requires     stock/indicators/aroon
+ * @requires     stock/indicators/aroon-oscillator
+ * @optionparent plotOptions.aroonoscillator
+ */
+{
+    /**
+     * Paramters used in calculation of aroon oscillator series points.
+     *
+     * @excluding periods, index
+     */
+    params: {
+        /**
+         * Period for Aroon Oscillator
+         *
+         * @since   7.0.0
+         * @product highstock
+         */
+        period: 25
+    },
+    tooltip: {
+        pointFormat: '<span style="color:{point.color}">\u25CF</span><b> {series.name}</b>: {point.y}'
+    }
+}, 
+/**
+ * @lends Highcharts.Series#
+ */
+H.merge(multipleLinesMixin, {
+    nameBase: 'Aroon Oscillator',
+    pointArrayMap: ['y'],
+    pointValKey: 'y',
+    linesApiNames: [],
+    init: function () {
+        var args = arguments, ctx = this;
+        requiredIndicator.isParentLoaded(AROON, 'aroon', ctx.type, function (indicator) {
+            indicator.prototype.init.apply(ctx, args);
+            return;
+        });
+    },
+    getValues: function (series, params) {
+        // 0- date, 1- Aroon Oscillator
+        var ARO = [], xData = [], yData = [], aroon, aroonUp, aroonDown, oscillator, i;
+        aroon = AROON.prototype.getValues.call(this, series, params);
+        for (i = 0; i < aroon.yData.length; i++) {
+            aroonUp = aroon.yData[i][0];
+            aroonDown = aroon.yData[i][1];
+            oscillator = aroonUp - aroonDown;
+            ARO.push([aroon.xData[i], oscillator]);
+            xData.push(aroon.xData[i]);
+            yData.push(oscillator);
+        }
+        return {
+            values: ARO,
+            xData: xData,
+            yData: yData
+        };
+    }
+}));
+/**
+ * An `Aroon Oscillator` series. If the [type](#series.aroonoscillator.type)
+ * option is not specified, it is inherited from [chart.type](#chart.type).
+ *
+ * @extends   series,plotOptions.aroonoscillator
+ * @since     7.0.0
+ * @product   highstock
+ * @excluding allAreas, aroonDown, colorAxis, compare, compareBase, dataParser,
+ *            dataURL, joinBy, keys, navigatorOptions, pointInterval,
+ *            pointIntervalUnit, pointPlacement, pointRange, pointStart,
+ *            showInNavigator, stacking
+ * @requires  stock/indicators/indicators
+ * @requires  stock/indicators/aroon
+ * @requires  stock/indicators/aroon-oscillator
+ * @apioption series.aroonoscillator
+ */
+''; // adds doclet above to the transpiled file

+ 154 - 0
app/public/js/Highstock-8.0.0/code/es-modules/indicators/aroon.src.js

@@ -0,0 +1,154 @@
+/* *
+ *
+ *  License: www.highcharts.com/license
+ *
+ *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
+ *
+ * */
+'use strict';
+import H from '../parts/Globals.js';
+import U from '../parts/Utilities.js';
+var pick = U.pick;
+import multipleLinesMixin from '../mixins/multipe-lines.js';
+/* eslint-disable valid-jsdoc */
+// Utils
+// Index of element with extreme value from array (min or max)
+/**
+ * @private
+ */
+function getExtremeIndexInArray(arr, extreme) {
+    var extremeValue = arr[0], valueIndex = 0, i;
+    for (i = 1; i < arr.length; i++) {
+        if (extreme === 'max' && arr[i] >= extremeValue ||
+            extreme === 'min' && arr[i] <= extremeValue) {
+            extremeValue = arr[i];
+            valueIndex = i;
+        }
+    }
+    return valueIndex;
+}
+/* eslint-enable valid-jsdoc */
+/**
+ * The Aroon series type.
+ *
+ * @private
+ * @class
+ * @name Highcharts.seriesTypes.aroon
+ *
+ * @augments Highcharts.Series
+ */
+H.seriesType('aroon', 'sma', 
+/**
+ * Aroon. This series requires the `linkedTo` option to be
+ * set and should be loaded after the `stock/indicators/indicators.js`.
+ *
+ * @sample {highstock} stock/indicators/aroon
+ *         Aroon
+ *
+ * @extends      plotOptions.sma
+ * @since        7.0.0
+ * @product      highstock
+ * @excluding    allAreas, colorAxis, compare, compareBase, joinBy, keys,
+ *               navigatorOptions, pointInterval, pointIntervalUnit,
+ *               pointPlacement, pointRange, pointStart, showInNavigator,
+ *               stacking
+ * @requires     stock/indicators/indicators
+ * @requires     stock/indicators/aroon
+ * @optionparent plotOptions.aroon
+ */
+{
+    /**
+     * Paramters used in calculation of aroon series points.
+     *
+     * @excluding periods, index
+     */
+    params: {
+        /**
+         * Period for Aroon indicator
+         */
+        period: 25
+    },
+    marker: {
+        enabled: false
+    },
+    tooltip: {
+        pointFormat: '<span style="color:{point.color}">\u25CF</span><b> {series.name}</b><br/>Aroon Up: {point.y}<br/>Aroon Down: {point.aroonDown}<br/>'
+    },
+    /**
+     * aroonDown line options.
+     */
+    aroonDown: {
+        /**
+         * Styles for an aroonDown line.
+         */
+        styles: {
+            /**
+             * Pixel width of the line.
+             */
+            lineWidth: 1,
+            /**
+             * Color of the line. If not set, it's inherited from
+             * [plotOptions.aroon.color](#plotOptions.aroon.color).
+             *
+             * @type {Highcharts.ColorString}
+             */
+            lineColor: void 0
+        }
+    },
+    dataGrouping: {
+        approximation: 'averages'
+    }
+}, 
+/**
+ * @lends Highcharts.Series#
+ */
+H.merge(multipleLinesMixin, {
+    nameBase: 'Aroon',
+    pointArrayMap: ['y', 'aroonDown'],
+    pointValKey: 'y',
+    linesApiNames: ['aroonDown'],
+    getValues: function (series, params) {
+        var period = params.period, xVal = series.xData, yVal = series.yData, yValLen = yVal ? yVal.length : 0, 
+        // 0- date, 1- Aroon Up, 2- Aroon Down
+        AR = [], xData = [], yData = [], slicedY, low = 2, high = 1, aroonUp, aroonDown, xLow, xHigh, i;
+        // For a N-period, we start from N-1 point, to calculate Nth point
+        // That is why we later need to comprehend slice() elements list
+        // with (+1)
+        for (i = period - 1; i < yValLen; i++) {
+            slicedY = yVal.slice(i - period + 1, i + 2);
+            xLow = getExtremeIndexInArray(slicedY.map(function (elem) {
+                return pick(elem[low], elem);
+            }), 'min');
+            xHigh = getExtremeIndexInArray(slicedY.map(function (elem) {
+                return pick(elem[high], elem);
+            }), 'max');
+            aroonUp = (xHigh / period) * 100;
+            aroonDown = (xLow / period) * 100;
+            if (xVal[i + 1]) {
+                AR.push([xVal[i + 1], aroonUp, aroonDown]);
+                xData.push(xVal[i + 1]);
+                yData.push([aroonUp, aroonDown]);
+            }
+        }
+        return {
+            values: AR,
+            xData: xData,
+            yData: yData
+        };
+    }
+}));
+/**
+ * A Aroon indicator. If the [type](#series.aroon.type) option is not
+ * specified, it is inherited from [chart.type](#chart.type).
+ *
+ * @extends   series,plotOptions.aroon
+ * @since     7.0.0
+ * @product   highstock
+ * @excluding allAreas, colorAxis, compare, compareBase, dataParser, dataURL,
+ *            joinBy, keys, navigatorOptions, pointInterval, pointIntervalUnit,
+ *            pointPlacement, pointRange, pointStart, showInNavigator, stacking
+ * @requires  stock/indicators/indicators
+ * @requires  stock/indicators/aroon
+ * @apioption series.aroon
+ */
+''; // to avoid removal of the above jsdoc

+ 119 - 0
app/public/js/Highstock-8.0.0/code/es-modules/indicators/atr.src.js

@@ -0,0 +1,119 @@
+/* *
+ *
+ *  License: www.highcharts.com/license
+ *
+ *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
+ *
+ * */
+'use strict';
+import H from '../parts/Globals.js';
+import U from '../parts/Utilities.js';
+var isArray = U.isArray;
+var seriesType = H.seriesType, UNDEFINED;
+/* eslint-disable valid-jsdoc */
+// Utils:
+/**
+ * @private
+ */
+function accumulateAverage(points, xVal, yVal, i) {
+    var xValue = xVal[i], yValue = yVal[i];
+    points.push([xValue, yValue]);
+}
+/**
+ * @private
+ */
+function getTR(currentPoint, prevPoint) {
+    var pointY = currentPoint, prevY = prevPoint, HL = pointY[1] - pointY[2], HCp = prevY === UNDEFINED ? 0 : Math.abs(pointY[1] - prevY[3]), LCp = prevY === UNDEFINED ? 0 : Math.abs(pointY[2] - prevY[3]), TR = Math.max(HL, HCp, LCp);
+    return TR;
+}
+/**
+ * @private
+ */
+function populateAverage(points, xVal, yVal, i, period, prevATR) {
+    var x = xVal[i - 1], TR = getTR(yVal[i - 1], yVal[i - 2]), y;
+    y = (((prevATR * (period - 1)) + TR) / period);
+    return [x, y];
+}
+/* eslint-enable valid-jsdoc */
+/**
+ * The ATR series type.
+ *
+ * @private
+ * @class
+ * @name Highcharts.seriesTypes.atr
+ *
+ * @augments Highcharts.Series
+ */
+seriesType('atr', 'sma', 
+/**
+ * Average true range indicator (ATR). This series requires `linkedTo`
+ * option to be set.
+ *
+ * @sample stock/indicators/atr
+ *         ATR indicator
+ *
+ * @extends      plotOptions.sma
+ * @since        6.0.0
+ * @product      highstock
+ * @requires     stock/indicators/indicators
+ * @requires     stock/indicators/atr
+ * @optionparent plotOptions.atr
+ */
+{
+    params: {
+        period: 14
+    }
+}, 
+/**
+ * @lends Highcharts.Series#
+ */
+{
+    getValues: function (series, params) {
+        var period = params.period, xVal = series.xData, yVal = series.yData, yValLen = yVal ? yVal.length : 0, xValue = xVal[0], yValue = yVal[0], range = 1, prevATR = 0, TR = 0, ATR = [], xData = [], yData = [], point, i, points;
+        points = [[xValue, yValue]];
+        if ((xVal.length <= period) ||
+            !isArray(yVal[0]) ||
+            yVal[0].length !== 4) {
+            return;
+        }
+        for (i = 1; i <= yValLen; i++) {
+            accumulateAverage(points, xVal, yVal, i);
+            if (period < range) {
+                point = populateAverage(points, xVal, yVal, i, period, prevATR);
+                prevATR = point[1];
+                ATR.push(point);
+                xData.push(point[0]);
+                yData.push(point[1]);
+            }
+            else if (period === range) {
+                prevATR = TR / (i - 1);
+                ATR.push([xVal[i - 1], prevATR]);
+                xData.push(xVal[i - 1]);
+                yData.push(prevATR);
+                range++;
+            }
+            else {
+                TR += getTR(yVal[i - 1], yVal[i - 2]);
+                range++;
+            }
+        }
+        return {
+            values: ATR,
+            xData: xData,
+            yData: yData
+        };
+    }
+});
+/**
+ * A `ATR` series. If the [type](#series.atr.type) option is not specified, it
+ * is inherited from [chart.type](#chart.type).
+ *
+ * @extends   series,plotOptions.atr
+ * @since     6.0.0
+ * @product   highstock
+ * @excluding dataParser, dataURL
+ * @requires  stock/indicators/indicators
+ * @requires  stock/indicators/atr
+ * @apioption series.atr
+ */
+''; // to include the above in the js output

+ 177 - 0
app/public/js/Highstock-8.0.0/code/es-modules/indicators/bollinger-bands.src.js

@@ -0,0 +1,177 @@
+/**
+ *
+ *  License: www.highcharts.com/license
+ *
+ *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
+ *
+ * */
+'use strict';
+import H from '../parts/Globals.js';
+import U from '../parts/Utilities.js';
+var isArray = U.isArray;
+import multipleLinesMixin from '../mixins/multipe-lines.js';
+var merge = H.merge, SMA = H.seriesTypes.sma;
+/* eslint-disable valid-jsdoc */
+// Utils:
+/**
+ * @private
+ */
+function getStandardDeviation(arr, index, isOHLC, mean) {
+    var variance = 0, arrLen = arr.length, std = 0, i = 0, value;
+    for (; i < arrLen; i++) {
+        value = (isOHLC ? arr[i][index] : arr[i]) - mean;
+        variance += value * value;
+    }
+    variance = variance / (arrLen - 1);
+    std = Math.sqrt(variance);
+    return std;
+}
+/* eslint-enable valid-jsdoc */
+/**
+ * Bollinger Bands series type.
+ *
+ * @private
+ * @class
+ * @name Highcharts.seriesTypes.bb
+ *
+ * @augments Highcharts.Series
+ */
+H.seriesType('bb', 'sma', 
+/**
+ * Bollinger bands (BB). This series requires the `linkedTo` option to be
+ * set and should be loaded after the `stock/indicators/indicators.js` file.
+ *
+ * @sample stock/indicators/bollinger-bands
+ *         Bollinger bands
+ *
+ * @extends      plotOptions.sma
+ * @since        6.0.0
+ * @product      highstock
+ * @requires     stock/indicators/indicators
+ * @requires     stock/indicators/bollinger-bands
+ * @optionparent plotOptions.bb
+ */
+{
+    params: {
+        period: 20,
+        /**
+         * Standard deviation for top and bottom bands.
+         */
+        standardDeviation: 2,
+        index: 3
+    },
+    /**
+     * Bottom line options.
+     */
+    bottomLine: {
+        /**
+         * Styles for a bottom line.
+         */
+        styles: {
+            /**
+             * Pixel width of the line.
+             */
+            lineWidth: 1,
+            /**
+             * Color of the line. If not set, it's inherited from
+             * [plotOptions.bb.color](#plotOptions.bb.color).
+             *
+             * @type  {Highcharts.ColorString}
+             */
+            lineColor: void 0
+        }
+    },
+    /**
+     * Top line options.
+     *
+     * @extends plotOptions.bb.bottomLine
+     */
+    topLine: {
+        styles: {
+            lineWidth: 1,
+            /**
+             * @type {Highcharts.ColorString}
+             */
+            lineColor: void 0
+        }
+    },
+    tooltip: {
+        pointFormat: '<span style="color:{point.color}">\u25CF</span><b> {series.name}</b><br/>Top: {point.top}<br/>Middle: {point.middle}<br/>Bottom: {point.bottom}<br/>'
+    },
+    marker: {
+        enabled: false
+    },
+    dataGrouping: {
+        approximation: 'averages'
+    }
+}, 
+/**
+ * @lends Highcharts.Series#
+ */
+H.merge(multipleLinesMixin, {
+    pointArrayMap: ['top', 'middle', 'bottom'],
+    pointValKey: 'middle',
+    nameComponents: ['period', 'standardDeviation'],
+    linesApiNames: ['topLine', 'bottomLine'],
+    init: function () {
+        SMA.prototype.init.apply(this, arguments);
+        // Set default color for lines:
+        this.options = merge({
+            topLine: {
+                styles: {
+                    lineColor: this.color
+                }
+            },
+            bottomLine: {
+                styles: {
+                    lineColor: this.color
+                }
+            }
+        }, this.options);
+    },
+    getValues: function (series, params) {
+        var period = params.period, standardDeviation = params.standardDeviation, xVal = series.xData, yVal = series.yData, yValLen = yVal ? yVal.length : 0, 
+        // 0- date, 1-middle line, 2-top line, 3-bottom line
+        BB = [], 
+        // middle line, top line and bottom line
+        ML, TL, BL, date, xData = [], yData = [], slicedX, slicedY, stdDev, isOHLC, point, i;
+        if (xVal.length < period) {
+            return;
+        }
+        isOHLC = isArray(yVal[0]);
+        for (i = period; i <= yValLen; i++) {
+            slicedX = xVal.slice(i - period, i);
+            slicedY = yVal.slice(i - period, i);
+            point = SMA.prototype.getValues.call(this, {
+                xData: slicedX,
+                yData: slicedY
+            }, params);
+            date = point.xData[0];
+            ML = point.yData[0];
+            stdDev = getStandardDeviation(slicedY, params.index, isOHLC, ML);
+            TL = ML + standardDeviation * stdDev;
+            BL = ML - standardDeviation * stdDev;
+            BB.push([date, TL, ML, BL]);
+            xData.push(date);
+            yData.push([TL, ML, BL]);
+        }
+        return {
+            values: BB,
+            xData: xData,
+            yData: yData
+        };
+    }
+}));
+/**
+ * A bollinger bands indicator. If the [type](#series.bb.type) option is not
+ * specified, it is inherited from [chart.type](#chart.type).
+ *
+ * @extends   series,plotOptions.bb
+ * @since     6.0.0
+ * @excluding dataParser, dataURL
+ * @product   highstock
+ * @requires  stock/indicators/indicators
+ * @requires  stock/indicators/bollinger-bands
+ * @apioption series.bb
+ */
+''; // to include the above in the js output

+ 111 - 0
app/public/js/Highstock-8.0.0/code/es-modules/indicators/cci.src.js

@@ -0,0 +1,111 @@
+/* *
+ *
+ *  License: www.highcharts.com/license
+ *
+ *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
+ * */
+'use strict';
+import H from '../parts/Globals.js';
+import U from '../parts/Utilities.js';
+var isArray = U.isArray;
+var seriesType = H.seriesType;
+/* eslint-disable valid-jsdoc */
+// Utils:
+/**
+ * @private
+ */
+function sumArray(array) {
+    return array.reduce(function (prev, cur) {
+        return prev + cur;
+    }, 0);
+}
+/**
+ * @private
+ */
+function meanDeviation(arr, sma) {
+    var len = arr.length, sum = 0, i;
+    for (i = 0; i < len; i++) {
+        sum += Math.abs(sma - (arr[i]));
+    }
+    return sum;
+}
+/* eslint-enable valid-jsdoc */
+/**
+ * The CCI series type.
+ *
+ * @private
+ * @class
+ * @name Highcharts.seriesTypes.cci
+ *
+ * @augments Highcharts.Series
+ */
+seriesType('cci', 'sma', 
+/**
+ * Commodity Channel Index (CCI). This series requires `linkedTo` option to
+ * be set.
+ *
+ * @sample stock/indicators/cci
+ *         CCI indicator
+ *
+ * @extends      plotOptions.sma
+ * @since        6.0.0
+ * @product      highstock
+ * @requires     stock/indicators/indicators
+ * @requires     stock/indicators/cci
+ * @optionparent plotOptions.cci
+ */
+{
+    params: {
+        period: 14
+    }
+}, 
+/**
+ * @lends Highcharts.Series#
+ */
+{
+    getValues: function (series, params) {
+        var period = params.period, xVal = series.xData, yVal = series.yData, yValLen = yVal ? yVal.length : 0, TP = [], periodTP = [], range = 1, CCI = [], xData = [], yData = [], CCIPoint, p, len, smaTP, TPtemp, meanDev, i;
+        // CCI requires close value
+        if (xVal.length <= period ||
+            !isArray(yVal[0]) ||
+            yVal[0].length !== 4) {
+            return;
+        }
+        // accumulate first N-points
+        while (range < period) {
+            p = yVal[range - 1];
+            TP.push((p[1] + p[2] + p[3]) / 3);
+            range++;
+        }
+        for (i = period; i <= yValLen; i++) {
+            p = yVal[i - 1];
+            TPtemp = (p[1] + p[2] + p[3]) / 3;
+            len = TP.push(TPtemp);
+            periodTP = TP.slice(len - period);
+            smaTP = sumArray(periodTP) / period;
+            meanDev = meanDeviation(periodTP, smaTP) / period;
+            CCIPoint = ((TPtemp - smaTP) / (0.015 * meanDev));
+            CCI.push([xVal[i - 1], CCIPoint]);
+            xData.push(xVal[i - 1]);
+            yData.push(CCIPoint);
+        }
+        return {
+            values: CCI,
+            xData: xData,
+            yData: yData
+        };
+    }
+});
+/**
+ * A `CCI` series. If the [type](#series.cci.type) option is not
+ * specified, it is inherited from [chart.type](#chart.type).
+ *
+ * @extends   series,plotOptions.cci
+ * @since     6.0.0
+ * @excluding dataParser, dataURL
+ * @product   highstock
+ * @requires  stock/indicators/indicators
+ * @requires  stock/indicators/cci
+ * @apioption series.cci
+ */
+''; // to include the above in the js output

+ 144 - 0
app/public/js/Highstock-8.0.0/code/es-modules/indicators/chaikin.src.js

@@ -0,0 +1,144 @@
+/* *
+ *
+ *  License: www.highcharts.com/license
+ *
+ *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
+ *
+ * */
+'use strict';
+import H from '../parts/Globals.js';
+import './accumulation-distribution.src.js';
+import U from '../parts/Utilities.js';
+var correctFloat = U.correctFloat;
+import requiredIndicatorMixin from '../mixins/indicator-required.js';
+var EMA = H.seriesTypes.ema, AD = H.seriesTypes.ad, error = H.error, requiredIndicator = requiredIndicatorMixin;
+/**
+ * The Chaikin series type.
+ *
+ * @private
+ * @class
+ * @name Highcharts.seriesTypes.chaikin
+ *
+ * @augments Highcharts.Series
+ */
+H.seriesType('chaikin', 'ema', 
+/**
+ * Chaikin Oscillator. This series requires the `linkedTo` option to
+ * be set and should be loaded after the `stock/indicators/indicators.js`
+ * and `stock/indicators/ema.js`.
+ *
+ * @sample {highstock} stock/indicators/chaikin
+ *         Chaikin Oscillator
+ *
+ * @extends      plotOptions.ema
+ * @since        7.0.0
+ * @product      highstock
+ * @excluding    allAreas, colorAxis, joinBy, keys, navigatorOptions,
+ *               pointInterval, pointIntervalUnit, pointPlacement,
+ *               pointRange, pointStart, showInNavigator, stacking
+ * @requires     stock/indicators/indicators
+ * @requires     stock/indicators/ema
+ * @requires     stock/indicators/chaikin
+ * @optionparent plotOptions.chaikin
+ */
+{
+    /**
+     * Paramters used in calculation of Chaikin Oscillator
+     * series points.
+     *
+     * @excluding index, period
+     */
+    params: {
+        /**
+         * The id of volume series which is mandatory.
+         * For example using OHLC data, volumeSeriesID='volume' means
+         * the indicator will be calculated using OHLC and volume values.
+         */
+        volumeSeriesID: 'volume',
+        /**
+         * Periods for Chaikin Oscillator calculations.
+         *
+         * @type    {Array<number>}
+         * @default [3, 10]
+         */
+        periods: [3, 10]
+    }
+}, 
+/**
+ * @lends Highcharts.Series#
+ */
+{
+    nameBase: 'Chaikin Osc',
+    nameComponents: ['periods'],
+    init: function () {
+        var args = arguments, ctx = this;
+        requiredIndicator.isParentLoaded(EMA, 'ema', ctx.type, function (indicator) {
+            indicator.prototype.init.apply(ctx, args);
+            return;
+        });
+    },
+    getValues: function (series, params) {
+        var periods = params.periods, period = params.period, 
+        // Accumulation Distribution Line data
+        ADL, 
+        // 0- date, 1- Chaikin Oscillator
+        CHA = [], xData = [], yData = [], periodsOffset, 
+        // Shorter Period EMA
+        SPE, 
+        // Longer Period EMA
+        LPE, oscillator, i;
+        // Check if periods are correct
+        if (periods.length !== 2 || periods[1] <= periods[0]) {
+            error('Error: "Chaikin requires two periods. Notice, first ' +
+                'period should be lower than the second one."');
+            return;
+        }
+        ADL = AD.prototype.getValues.call(this, series, {
+            volumeSeriesID: params.volumeSeriesID,
+            period: period
+        });
+        // Check if adl is calculated properly, if not skip
+        if (!ADL) {
+            return;
+        }
+        SPE = EMA.prototype.getValues.call(this, ADL, {
+            period: periods[0]
+        });
+        LPE = EMA.prototype.getValues.call(this, ADL, {
+            period: periods[1]
+        });
+        // Check if ema is calculated properly, if not skip
+        if (!SPE || !LPE) {
+            return;
+        }
+        periodsOffset = periods[1] - periods[0];
+        for (i = 0; i < LPE.yData.length; i++) {
+            oscillator = correctFloat(SPE.yData[i + periodsOffset] -
+                LPE.yData[i]);
+            CHA.push([LPE.xData[i], oscillator]);
+            xData.push(LPE.xData[i]);
+            yData.push(oscillator);
+        }
+        return {
+            values: CHA,
+            xData: xData,
+            yData: yData
+        };
+    }
+});
+/**
+ * A `Chaikin Oscillator` series. If the [type](#series.chaikin.type)
+ * option is not specified, it is inherited from [chart.type](#chart.type).
+ *
+ * @extends   series,plotOptions.chaikin
+ * @since     7.0.0
+ * @product   highstock
+ * @excluding allAreas, colorAxis, dataParser, dataURL, joinBy, keys,
+ *            navigatorOptions, pointInterval, pointIntervalUnit,
+ *            pointPlacement, pointRange, pointStart, stacking, showInNavigator
+ * @requires  stock/indicators/indicators
+ * @requires  stock/indicators/ema
+ * @requires  stock/indicators/chaikin
+ * @apioption series.chaikin
+ */
+''; // to include the above in the js output

+ 184 - 0
app/public/js/Highstock-8.0.0/code/es-modules/indicators/cmf.src.js

@@ -0,0 +1,184 @@
+/* *
+ *
+ *  (c) 2010-2019 Highsoft AS
+ *
+ *  Author: Sebastian Domas
+ *
+ *  Chaikin Money Flow indicator for Highstock
+ *
+ *  License: www.highcharts.com/license
+ *
+ *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
+ *
+ * */
+'use strict';
+import H from '../parts/Globals.js';
+/**
+ * The CMF series type.
+ *
+ * @private
+ * @class
+ * @name Highcharts.seriesTypes.cmf
+ *
+ * @augments Highcharts.Series
+ */
+H.seriesType('cmf', 'sma', 
+/**
+ * Chaikin Money Flow indicator (cmf).
+ *
+ * @sample stock/indicators/cmf/
+ *         Chaikin Money Flow indicator
+ *
+ * @extends      plotOptions.sma
+ * @since        6.0.0
+ * @excluding    animationLimit
+ * @product      highstock
+ * @requires     stock/indicators/indicators
+ * @requires     stock/indicators/cmf
+ * @optionparent plotOptions.cmf
+ */
+{
+    params: {
+        period: 14,
+        /**
+         * The id of another series to use its data as volume data for the
+         * indiator calculation.
+         */
+        volumeSeriesID: 'volume'
+    }
+}, 
+/**
+ * @lends Highcharts.Series#
+ */
+{
+    nameBase: 'Chaikin Money Flow',
+    /**
+     * Checks if the series and volumeSeries are accessible, number of
+     * points.x is longer than period, is series has OHLC data
+     * @private
+     * @param {Highcharts.CMFIndicator} this indicator to use.
+     * @return {boolean} True if series is valid and can be computed,
+     * otherwise false.
+     */
+    isValid: function () {
+        var chart = this.chart, options = this.options, series = this.linkedParent, volumeSeries = (this.volumeSeries ||
+            (this.volumeSeries =
+                chart.get(options.params.volumeSeriesID))), isSeriesOHLC = (series &&
+            series.yData &&
+            series.yData[0].length === 4);
+        /**
+         * @private
+         * @param {Highcharts.Series} serie to check length validity on.
+         * @return {boolean|undefined} true if length is valid.
+         */
+        function isLengthValid(serie) {
+            return serie.xData &&
+                serie.xData.length >= options.params.period;
+        }
+        return !!(series &&
+            volumeSeries &&
+            isLengthValid(series) &&
+            isLengthValid(volumeSeries) && isSeriesOHLC);
+    },
+    /**
+     * Returns indicator's data.
+     * @private
+     * @param {Highcharts.CMFIndicator} this indicator to use.
+     * @param {Highcharts.Series} series to calculate values from
+     * @param {Highcharts.CMFIndicatorParamsOptions} params to pass
+     * @return {boolean|Highcharts.IndicatorNullableValuesObject} Returns false if the
+     * indicator is not valid, otherwise returns Values object.
+     */
+    getValues: function (series, params) {
+        if (!this.isValid()) {
+            return;
+        }
+        return this.getMoneyFlow(series.xData, series.yData, this.volumeSeries.yData, params.period);
+    },
+    /**
+     * @private
+     * @param {Array<number>} xData - x timestamp values
+     * @param {Array<number>} seriesYData - yData of basic series
+     * @param {Array<number>} volumeSeriesYData - yData of volume series
+     * @param {number} period - indicator's param
+     * @return {Highcharts.IndicatorNullableValuesObject} object containing computed money
+     * flow data
+     */
+    getMoneyFlow: function (xData, seriesYData, volumeSeriesYData, period) {
+        var len = seriesYData.length, moneyFlowVolume = [], sumVolume = 0, sumMoneyFlowVolume = 0, moneyFlowXData = [], moneyFlowYData = [], values = [], i, point, nullIndex = -1;
+        /**
+         * Calculates money flow volume, changes i, nullIndex vars from
+         * upper scope!
+         * @private
+         * @param {Array<number>} ohlc - OHLC point
+         * @param {number} volume - Volume point's y value
+         * @return {number|null} - volume * moneyFlowMultiplier
+         **/
+        function getMoneyFlowVolume(ohlc, volume) {
+            var high = ohlc[1], low = ohlc[2], close = ohlc[3], isValid = volume !== null &&
+                high !== null &&
+                low !== null &&
+                close !== null &&
+                high !== low;
+            /**
+             * @private
+             * @param {number} h - High value
+             * @param {number} l - Low value
+             * @param {number} c - Close value
+             * @return {number} calculated multiplier for the point
+             **/
+            function getMoneyFlowMultiplier(h, l, c) {
+                return ((c - l) - (h - c)) / (h - l);
+            }
+            return isValid ?
+                getMoneyFlowMultiplier(high, low, close) * volume :
+                ((nullIndex = i), null);
+        }
+        if (period > 0 && period <= len) {
+            for (i = 0; i < period; i++) {
+                moneyFlowVolume[i] = getMoneyFlowVolume(seriesYData[i], volumeSeriesYData[i]);
+                sumVolume += volumeSeriesYData[i];
+                sumMoneyFlowVolume += moneyFlowVolume[i];
+            }
+            moneyFlowXData.push(xData[i - 1]);
+            moneyFlowYData.push(i - nullIndex >= period && sumVolume !== 0 ?
+                sumMoneyFlowVolume / sumVolume :
+                null);
+            values.push([moneyFlowXData[0], moneyFlowYData[0]]);
+            for (; i < len; i++) {
+                moneyFlowVolume[i] = getMoneyFlowVolume(seriesYData[i], volumeSeriesYData[i]);
+                sumVolume -= volumeSeriesYData[i - period];
+                sumVolume += volumeSeriesYData[i];
+                sumMoneyFlowVolume -= moneyFlowVolume[i - period];
+                sumMoneyFlowVolume += moneyFlowVolume[i];
+                point = [
+                    xData[i],
+                    i - nullIndex >= period ?
+                        sumMoneyFlowVolume / sumVolume :
+                        null
+                ];
+                moneyFlowXData.push(point[0]);
+                moneyFlowYData.push(point[1]);
+                values.push([point[0], point[1]]);
+            }
+        }
+        return {
+            values: values,
+            xData: moneyFlowXData,
+            yData: moneyFlowYData
+        };
+    }
+});
+/**
+ * A `CMF` series. If the [type](#series.cmf.type) option is not
+ * specified, it is inherited from [chart.type](#chart.type).
+ *
+ * @extends   series,plotOptions.cmf
+ * @since     6.0.0
+ * @product   highstock
+ * @excluding dataParser, dataURL
+ * @requires  stock/indicators/indicators
+ * @requires  stock/indicators/cmf
+ * @apioption series.cmf
+ */
+''; // adds doclet above to the transpiled file

+ 133 - 0
app/public/js/Highstock-8.0.0/code/es-modules/indicators/dema.src.js

@@ -0,0 +1,133 @@
+/* *
+ *
+ *  License: www.highcharts.com/license
+ *
+ *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
+ *
+ * */
+'use strict';
+import H from '../parts/Globals.js';
+import U from '../parts/Utilities.js';
+var correctFloat = U.correctFloat, isArray = U.isArray;
+import requiredIndicatorMixin from '../mixins/indicator-required.js';
+var EMAindicator = H.seriesTypes.ema, requiredIndicator = requiredIndicatorMixin;
+/**
+ * The DEMA series Type
+ *
+ * @private
+ * @class
+ * @name Highcharts.seriesTypes.dema
+ *
+ * @augments Highcharts.Series
+ */
+H.seriesType('dema', 'ema', 
+/**
+ * Double exponential moving average (DEMA) indicator. This series requires
+ * `linkedTo` option to be set and should be loaded after the
+ * `stock/indicators/indicators.js` and `stock/indicators/ema.js`.
+ *
+ * @sample {highstock} stock/indicators/dema
+ *         DEMA indicator
+ *
+ * @extends      plotOptions.ema
+ * @since        7.0.0
+ * @product      highstock
+ * @excluding    allAreas, colorAxis, compare, compareBase, joinBy, keys,
+ *               navigatorOptions, pointInterval, pointIntervalUnit,
+ *               pointPlacement, pointRange, pointStart, showInNavigator,
+ *               stacking
+ * @requires     stock/indicators/indicators
+ * @requires     stock/indicators/ema
+ * @requires     stock/indicators/dema
+ * @optionparent plotOptions.dema
+ */
+{}, 
+/**
+ * @lends Highcharts.Series#
+ */
+{
+    init: function () {
+        var args = arguments, ctx = this;
+        requiredIndicator.isParentLoaded(EMAindicator, 'ema', ctx.type, function (indicator) {
+            indicator.prototype.init.apply(ctx, args);
+            return;
+        });
+    },
+    getEMA: function (yVal, prevEMA, SMA, index, i, xVal) {
+        return EMAindicator.prototype.calculateEma(xVal || [], yVal, typeof i === 'undefined' ? 1 : i, this.chart.series[0].EMApercent, prevEMA, typeof index === 'undefined' ? -1 : index, SMA);
+    },
+    getValues: function (series, params) {
+        var period = params.period, doubledPeriod = 2 * period, xVal = series.xData, yVal = series.yData, yValLen = yVal ? yVal.length : 0, index = -1, accumulatePeriodPoints = 0, SMA = 0, DEMA = [], xDataDema = [], yDataDema = [], EMA = 0, 
+        // EMA(EMA)
+        EMAlevel2, 
+        // EMA of previous point
+        prevEMA, prevEMAlevel2, 
+        // EMA values array
+        EMAvalues = [], i, DEMAPoint;
+        series.EMApercent = (2 / (period + 1));
+        // Check period, if bigger than EMA points length, skip
+        if (yValLen < 2 * period - 1) {
+            return;
+        }
+        // Switch index for OHLC / Candlestick / Arearange
+        if (isArray(yVal[0])) {
+            index = params.index ? params.index : 0;
+        }
+        // Accumulate first N-points
+        accumulatePeriodPoints =
+            EMAindicator.prototype.accumulatePeriodPoints(period, index, yVal);
+        // first point
+        SMA = accumulatePeriodPoints / period;
+        accumulatePeriodPoints = 0;
+        // Calculate value one-by-one for each period in visible data
+        for (i = period; i < yValLen + 2; i++) {
+            if (i < yValLen + 1) {
+                EMA = this.getEMA(yVal, prevEMA, SMA, index, i)[1];
+                EMAvalues.push(EMA);
+            }
+            prevEMA = EMA;
+            // Summing first period points for EMA(EMA)
+            if (i < doubledPeriod) {
+                accumulatePeriodPoints += EMA;
+            }
+            else {
+                // Calculate DEMA
+                // First DEMA point
+                if (i === doubledPeriod) {
+                    SMA = accumulatePeriodPoints / period;
+                }
+                EMA = EMAvalues[i - period - 1];
+                EMAlevel2 = this.getEMA([EMA], prevEMAlevel2, SMA)[1];
+                DEMAPoint = [
+                    xVal[i - 2],
+                    correctFloat(2 * EMA - EMAlevel2)
+                ];
+                DEMA.push(DEMAPoint);
+                xDataDema.push(DEMAPoint[0]);
+                yDataDema.push(DEMAPoint[1]);
+                prevEMAlevel2 = EMAlevel2;
+            }
+        }
+        return {
+            values: DEMA,
+            xData: xDataDema,
+            yData: yDataDema
+        };
+    }
+});
+/**
+ * A `DEMA` series. If the [type](#series.ema.type) option is not
+ * specified, it is inherited from [chart.type](#chart.type).
+ *
+ * @extends   series,plotOptions.ema
+ * @since     7.0.0
+ * @product   highstock
+ * @excluding allAreas, colorAxis, compare, compareBase, dataParser, dataURL,
+ *            joinBy, keys, navigatorOptions, pointInterval, pointIntervalUnit,
+ *            pointPlacement, pointRange, pointStart, showInNavigator, stacking
+ * @requires  stock/indicators/indicators
+ * @requires  stock/indicators/ema
+ * @requires  stock/indicators/dema
+ * @apioption series.dema
+ */
+''; // adds doclet above to the transpiled file

+ 117 - 0
app/public/js/Highstock-8.0.0/code/es-modules/indicators/dpo.src.js

@@ -0,0 +1,117 @@
+/* *
+ *
+ *  License: www.highcharts.com/license
+ *
+ *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
+ *
+ * */
+'use strict';
+import H from '../parts/Globals.js';
+import U from '../parts/Utilities.js';
+var correctFloat = U.correctFloat, pick = U.pick;
+/* eslint-disable valid-jsdoc */
+// Utils
+/**
+ * @private
+ */
+function accumulatePoints(sum, yVal, i, index, subtract) {
+    var price = pick(yVal[i][index], yVal[i]);
+    if (subtract) {
+        return correctFloat(sum - price);
+    }
+    return correctFloat(sum + price);
+}
+/* eslint-enable valid-jsdoc */
+/**
+ * The DPO series type.
+ *
+ * @private
+ * @class
+ * @name Highcharts.seriesTypes.dpo
+ *
+ * @augments Highcharts.Series
+ */
+H.seriesType('dpo', 'sma', 
+/**
+ * Detrended Price Oscillator. This series requires the `linkedTo` option to
+ * be set and should be loaded after the `stock/indicators/indicators.js`.
+ *
+ * @sample {highstock} stock/indicators/dpo
+ *         Detrended Price Oscillator
+ *
+ * @extends      plotOptions.sma
+ * @since        7.0.0
+ * @product      highstock
+ * @excluding    allAreas, colorAxis, compare, compareBase, joinBy, keys,
+ *               navigatorOptions, pointInterval, pointIntervalUnit,
+ *               pointPlacement, pointRange, pointStart, showInNavigator,
+ *               stacking
+ * @requires     stock/indicators/indicators
+ * @requires     stock/indicators/dpo
+ * @optionparent plotOptions.dpo
+ */
+{
+    /**
+     * Parameters used in calculation of Detrended Price Oscillator series
+     * points.
+     */
+    params: {
+        /**
+         * Period for Detrended Price Oscillator
+         */
+        period: 21
+    }
+}, 
+/**
+ * @lends Highcharts.Series#
+ */
+{
+    nameBase: 'DPO',
+    getValues: function (series, params) {
+        var period = params.period, index = params.index, offset = Math.floor(period / 2 + 1), range = period + offset, xVal = series.xData || [], yVal = series.yData || [], yValLen = yVal.length, 
+        // 0- date, 1- Detrended Price Oscillator
+        DPO = [], xData = [], yData = [], sum = 0, oscillator, periodIndex, rangeIndex, price, i, j;
+        if (xVal.length <= range) {
+            return;
+        }
+        // Accumulate first N-points for SMA
+        for (i = 0; i < period - 1; i++) {
+            sum = accumulatePoints(sum, yVal, i, index);
+        }
+        // Detrended Price Oscillator formula:
+        // DPO = Price - Simple moving average [from (n / 2 + 1) days ago]
+        for (j = 0; j <= yValLen - range; j++) {
+            periodIndex = j + period - 1;
+            rangeIndex = j + range - 1;
+            // adding the last period point
+            sum = accumulatePoints(sum, yVal, periodIndex, index);
+            price = pick(yVal[rangeIndex][index], yVal[rangeIndex]);
+            oscillator = price - sum / period;
+            // substracting the first period point
+            sum = accumulatePoints(sum, yVal, j, index, true);
+            DPO.push([xVal[rangeIndex], oscillator]);
+            xData.push(xVal[rangeIndex]);
+            yData.push(oscillator);
+        }
+        return {
+            values: DPO,
+            xData: xData,
+            yData: yData
+        };
+    }
+});
+/**
+ * A Detrended Price Oscillator. If the [type](#series.dpo.type) option is not
+ * specified, it is inherited from [chart.type](#chart.type).
+ *
+ * @extends   series,plotOptions.dpo
+ * @since     7.0.0
+ * @product   highstock
+ * @excluding allAreas, colorAxis, compare, compareBase, dataParser, dataURL,
+ *            joinBy, keys, navigatorOptions, pointInterval, pointIntervalUnit,
+ *            pointPlacement, pointRange, pointStart, showInNavigator, stacking
+ * @requires  stock/indicators/indicators
+ * @requires  stock/indicators/dpo
+ * @apioption series.dpo
+ */
+''; // to include the above in the js output'

+ 115 - 0
app/public/js/Highstock-8.0.0/code/es-modules/indicators/ema.src.js

@@ -0,0 +1,115 @@
+/* *
+ *
+ *  License: www.highcharts.com/license
+ *
+ *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
+ *
+ * */
+'use strict';
+import H from '../parts/Globals.js';
+import U from '../parts/Utilities.js';
+var correctFloat = U.correctFloat, isArray = U.isArray;
+var seriesType = H.seriesType;
+/**
+ * The EMA series type.
+ *
+ * @private
+ * @class
+ * @name Highcharts.seriesTypes.ema
+ *
+ * @augments Highcharts.Series
+ */
+seriesType('ema', 'sma', 
+/**
+ * Exponential moving average indicator (EMA). This series requires the
+ * `linkedTo` option to be set.
+ *
+ * @sample stock/indicators/ema
+ *         Exponential moving average indicator
+ *
+ * @extends      plotOptions.sma
+ * @since        6.0.0
+ * @product      highstock
+ * @requires     stock/indicators/indicators
+ * @requires     stock/indicators/ema
+ * @optionparent plotOptions.ema
+ */
+{
+    params: {
+        /**
+         * The point index which indicator calculations will base. For
+         * example using OHLC data, index=2 means the indicator will be
+         * calculated using Low values.
+         *
+         * By default index value used to be set to 0. Since Highstock 7
+         * by default index is set to 3 which means that the ema
+         * indicator will be calculated using Close values.
+         */
+        index: 3,
+        period: 9 // @merge 14 in v6.2
+    }
+}, 
+/**
+ * @lends Highcharts.Series#
+ */
+{
+    accumulatePeriodPoints: function (period, index, yVal) {
+        var sum = 0, i = 0, y = 0;
+        while (i < period) {
+            y = index < 0 ? yVal[i] : yVal[i][index];
+            sum = sum + y;
+            i++;
+        }
+        return sum;
+    },
+    calculateEma: function (xVal, yVal, i, EMApercent, calEMA, index, SMA) {
+        var x = xVal[i - 1], yValue = index < 0 ?
+            yVal[i - 1] :
+            yVal[i - 1][index], y;
+        y = typeof calEMA === 'undefined' ?
+            SMA : correctFloat((yValue * EMApercent) +
+            (calEMA * (1 - EMApercent)));
+        return [x, y];
+    },
+    getValues: function (series, params) {
+        var period = params.period, xVal = series.xData, yVal = series.yData, yValLen = yVal ? yVal.length : 0, EMApercent = 2 / (period + 1), sum = 0, EMA = [], xData = [], yData = [], index = -1, SMA = 0, calEMA, EMAPoint, i;
+        // Check period, if bigger than points length, skip
+        if (yValLen < period) {
+            return;
+        }
+        // Switch index for OHLC / Candlestick / Arearange
+        if (isArray(yVal[0])) {
+            index = params.index ? params.index : 0;
+        }
+        // Accumulate first N-points
+        sum = this.accumulatePeriodPoints(period, index, yVal);
+        // first point
+        SMA = sum / period;
+        // Calculate value one-by-one for each period in visible data
+        for (i = period; i < yValLen + 1; i++) {
+            EMAPoint = this.calculateEma(xVal, yVal, i, EMApercent, calEMA, index, SMA);
+            EMA.push(EMAPoint);
+            xData.push(EMAPoint[0]);
+            yData.push(EMAPoint[1]);
+            calEMA = EMAPoint[1];
+        }
+        return {
+            values: EMA,
+            xData: xData,
+            yData: yData
+        };
+    }
+});
+/**
+ * A `EMA` series. If the [type](#series.ema.type) option is not
+ * specified, it is inherited from [chart.type](#chart.type).
+ *
+ * @extends   series,plotOptions.ema
+ * @since     6.0.0
+ * @product   highstock
+ * @excluding dataParser, dataURL
+ * @requires  stock/indicators/indicators
+ * @requires  stock/indicators/ema
+ * @apioption series.ema
+ */
+''; // adds doclet above to the transpiled file

+ 639 - 0
app/public/js/Highstock-8.0.0/code/es-modules/indicators/ichimoku-kinko-hyo.src.js

@@ -0,0 +1,639 @@
+/* *
+ *
+ *  License: www.highcharts.com/license
+ *
+ *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
+ *
+ * */
+'use strict';
+import H from '../parts/Globals.js';
+/* eslint-enable @typescript-eslint/interface-name-prefix */
+import U from '../parts/Utilities.js';
+var defined = U.defined, isArray = U.isArray, objectEach = U.objectEach;
+var UNDEFINED, seriesType = H.seriesType, merge = H.merge, color = H.color, SMA = H.seriesTypes.sma;
+/* eslint-disable require-jsdoc */
+// Utils:
+function maxHigh(arr) {
+    return arr.reduce(function (max, res) {
+        return Math.max(max, res[1]);
+    }, -Infinity);
+}
+function minLow(arr) {
+    return arr.reduce(function (min, res) {
+        return Math.min(min, res[2]);
+    }, Infinity);
+}
+function highlowLevel(arr) {
+    return {
+        high: maxHigh(arr),
+        low: minLow(arr)
+    };
+}
+function getClosestPointRange(axis) {
+    var closestDataRange, loopLength, distance, xData, i;
+    axis.series.forEach(function (series) {
+        if (series.xData) {
+            xData = series.xData;
+            loopLength = series.xIncrement ? 1 : xData.length - 1;
+            for (i = loopLength; i > 0; i--) {
+                distance = xData[i] - xData[i - 1];
+                if (closestDataRange === UNDEFINED ||
+                    distance < closestDataRange) {
+                    closestDataRange = distance;
+                }
+            }
+        }
+    });
+    return closestDataRange;
+}
+// Check two lines intersection (line a1-a2 and b1-b2)
+// Source: https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection
+function checkLineIntersection(a1, a2, b1, b2) {
+    if (a1 && a2 && b1 && b2) {
+        var saX = a2.plotX - a1.plotX, // Auxiliary section a2-a1 X
+        saY = a2.plotY - a1.plotY, // Auxiliary section a2-a1 Y
+        sbX = b2.plotX - b1.plotX, // Auxiliary section b2-b1 X
+        sbY = b2.plotY - b1.plotY, // Auxiliary section b2-b1 Y
+        sabX = a1.plotX - b1.plotX, // Auxiliary section a1-b1 X
+        sabY = a1.plotY - b1.plotY, // Auxiliary section a1-b1 Y
+        // First degree Bézier parameters
+        u, t;
+        u = (-saY * sabX + saX * sabY) / (-sbX * saY + saX * sbY);
+        t = (sbX * sabY - sbY * sabX) / (-sbX * saY + saX * sbY);
+        if (u >= 0 && u <= 1 && t >= 0 && t <= 1) {
+            return {
+                plotX: a1.plotX + (t * saX),
+                plotY: a1.plotY + (t * saY)
+            };
+        }
+    }
+    return false;
+}
+// Parameter opt (indicator options object) include indicator, points,
+// nextPoints, color, options, gappedExtend and graph properties
+function drawSenkouSpan(opt) {
+    var indicator = opt.indicator;
+    indicator.points = opt.points;
+    indicator.nextPoints = opt.nextPoints;
+    indicator.color = opt.color;
+    indicator.options = merge(opt.options.senkouSpan.styles, opt.gap);
+    indicator.graph = opt.graph;
+    indicator.fillGraph = true;
+    SMA.prototype.drawGraph.call(indicator);
+}
+// Data integrity in Ichimoku is different than default "averages":
+// Point: [undefined, value, value, ...] is correct
+// Point: [undefined, undefined, undefined, ...] is incorrect
+H.approximations['ichimoku-averages'] = function () {
+    var ret = [], isEmptyRange;
+    [].forEach.call(arguments, function (arr, i) {
+        ret.push(H.approximations.average(arr));
+        isEmptyRange = !isEmptyRange && typeof ret[i] === 'undefined';
+    });
+    // Return undefined when first elem. is undefined and let
+    // sum method handle null (#7377)
+    return isEmptyRange ? void 0 : ret;
+};
+/* eslint-enable require-jsdoc */
+/**
+ * The IKH series type.
+ *
+ * @private
+ * @class
+ * @name Highcharts.seriesTypes.ikh
+ *
+ * @augments Highcharts.Series
+ */
+seriesType('ikh', 'sma', 
+/**
+ * Ichimoku Kinko Hyo (IKH). This series requires `linkedTo` option to be
+ * set.
+ *
+ * @sample stock/indicators/ichimoku-kinko-hyo
+ *         Ichimoku Kinko Hyo indicator
+ *
+ * @extends      plotOptions.sma
+ * @since        6.0.0
+ * @excluding    allAreas, colorAxis, compare, compareBase, joinBy, keys,
+ *               navigatorOptions, pointInterval, pointIntervalUnit,
+ *               pointPlacement, pointRange, pointStart, showInNavigator,
+ *               stacking
+ * @product      highstock
+ * @requires     stock/indicators/indicators
+ * @requires     stock/indicators/ichimoku-kinko-hyo
+ * @optionparent plotOptions.ikh
+ */
+{
+    params: {
+        period: 26,
+        /**
+         * The base period for Tenkan calculations.
+         */
+        periodTenkan: 9,
+        /**
+         * The base period for Senkou Span B calculations
+         */
+        periodSenkouSpanB: 52
+    },
+    marker: {
+        enabled: false
+    },
+    tooltip: {
+        pointFormat: '<span style="color:{point.color}">\u25CF</span> <b> {series.name}</b><br/>' +
+            'TENKAN SEN: {point.tenkanSen:.3f}<br/>' +
+            'KIJUN SEN: {point.kijunSen:.3f}<br/>' +
+            'CHIKOU SPAN: {point.chikouSpan:.3f}<br/>' +
+            'SENKOU SPAN A: {point.senkouSpanA:.3f}<br/>' +
+            'SENKOU SPAN B: {point.senkouSpanB:.3f}<br/>'
+    },
+    /**
+     * The styles for Tenkan line
+     */
+    tenkanLine: {
+        styles: {
+            /**
+             * Pixel width of the line.
+             */
+            lineWidth: 1,
+            /**
+             * Color of the line.
+             *
+             * @type {Highcharts.ColorString}
+             */
+            lineColor: void 0
+        }
+    },
+    /**
+     * The styles for Kijun line
+     */
+    kijunLine: {
+        styles: {
+            /**
+             * Pixel width of the line.
+             */
+            lineWidth: 1,
+            /**
+             * Color of the line.
+             *
+             * @type {Highcharts.ColorString}
+             */
+            lineColor: void 0
+        }
+    },
+    /**
+     * The styles for Chikou line
+     */
+    chikouLine: {
+        styles: {
+            /**
+             * Pixel width of the line.
+             */
+            lineWidth: 1,
+            /**
+             * Color of the line.
+             *
+             * @type {Highcharts.ColorString}
+             */
+            lineColor: void 0
+        }
+    },
+    /**
+     * The styles for Senkou Span A line
+     */
+    senkouSpanA: {
+        styles: {
+            /**
+             * Pixel width of the line.
+             */
+            lineWidth: 1,
+            /**
+             * Color of the line.
+             *
+             * @type {Highcharts.ColorString}
+             */
+            lineColor: void 0
+        }
+    },
+    /**
+     * The styles for Senkou Span B line
+     */
+    senkouSpanB: {
+        styles: {
+            /**
+             * Pixel width of the line.
+             */
+            lineWidth: 1,
+            /**
+             * Color of the line.
+             *
+             * @type {Highcharts.ColorString}
+             */
+            lineColor: void 0
+        }
+    },
+    /**
+     * The styles for area between Senkou Span A and B.
+     */
+    senkouSpan: {
+        /**
+        * Color of the area between Senkou Span A and B,
+        * when Senkou Span A is above Senkou Span B. Note that if
+        * a `style.fill` is defined, the `color` takes precedence and
+        * the `style.fill` is ignored.
+        *
+        * @see [senkouSpan.styles.fill](#series.ikh.senkouSpan.styles.fill)
+        *
+        * @sample stock/indicators/ichimoku-kinko-hyo
+        *         Ichimoku Kinko Hyo color
+        *
+        * @type      {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
+        * @since     7.0.0
+        * @apioption plotOptions.ikh.senkouSpan.color
+        */
+        /**
+        * Color of the area between Senkou Span A and B,
+        * when Senkou Span A is under Senkou Span B.
+        *
+        * @sample stock/indicators/ikh-negative-color
+        *         Ichimoku Kinko Hyo negativeColor
+        *
+        * @type      {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
+        * @since     7.0.0
+        * @apioption plotOptions.ikh.senkouSpan.negativeColor
+        */
+        styles: {
+            /**
+             * Color of the area between Senkou Span A and B.
+             *
+             * @deprecated
+             * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
+             */
+            fill: 'rgba(255, 0, 0, 0.5)'
+        }
+    },
+    dataGrouping: {
+        approximation: 'ichimoku-averages'
+    }
+}, 
+/**
+ * @lends Highcharts.Series#
+ */
+{
+    pointArrayMap: [
+        'tenkanSen',
+        'kijunSen',
+        'chikouSpan',
+        'senkouSpanA',
+        'senkouSpanB'
+    ],
+    pointValKey: 'tenkanSen',
+    nameComponents: ['periodSenkouSpanB', 'period', 'periodTenkan'],
+    init: function () {
+        SMA.prototype.init.apply(this, arguments);
+        // Set default color for lines:
+        this.options = merge({
+            tenkanLine: {
+                styles: {
+                    lineColor: this.color
+                }
+            },
+            kijunLine: {
+                styles: {
+                    lineColor: this.color
+                }
+            },
+            chikouLine: {
+                styles: {
+                    lineColor: this.color
+                }
+            },
+            senkouSpanA: {
+                styles: {
+                    lineColor: this.color,
+                    fill: color(this.color).setOpacity(0.5).get()
+                }
+            },
+            senkouSpanB: {
+                styles: {
+                    lineColor: this.color,
+                    fill: color(this.color).setOpacity(0.5).get()
+                }
+            },
+            senkouSpan: {
+                styles: {
+                    fill: color(this.color).setOpacity(0.2).get()
+                }
+            }
+        }, this.options);
+    },
+    toYData: function (point) {
+        return [
+            point.tenkanSen,
+            point.kijunSen,
+            point.chikouSpan,
+            point.senkouSpanA,
+            point.senkouSpanB
+        ];
+    },
+    translate: function () {
+        var indicator = this;
+        SMA.prototype.translate.apply(indicator);
+        indicator.points.forEach(function (point) {
+            indicator.pointArrayMap.forEach(function (value) {
+                if (defined(point[value])) {
+                    point['plot' + value] =
+                        indicator.yAxis.toPixels(point[value], true);
+                    // Add extra parameters for support tooltip in moved
+                    // lines
+                    point.plotY = point['plot' + value];
+                    point.tooltipPos = [
+                        point.plotX,
+                        point['plot' + value]
+                    ];
+                    point.isNull = false;
+                }
+            });
+        });
+    },
+    // One does not simply
+    // Render five linesZ
+    // And an arearange
+    // In just one series..
+    drawGraph: function () {
+        var indicator = this, mainLinePoints = (indicator.points), pointsLength = mainLinePoints.length, mainLineOptions = (indicator.options), mainLinePath = (indicator.graph), mainColor = indicator.color, gappedExtend = {
+            options: {
+                gapSize: mainLineOptions.gapSize
+            }
+        }, pointArrayMapLength = indicator.pointArrayMap.length, allIchimokuPoints = [[], [], [], [], [], []], ikhMap = {
+            tenkanLine: allIchimokuPoints[0],
+            kijunLine: allIchimokuPoints[1],
+            chikouLine: allIchimokuPoints[2],
+            senkouSpanA: allIchimokuPoints[3],
+            senkouSpanB: allIchimokuPoints[4],
+            senkouSpan: allIchimokuPoints[5]
+        }, intersectIndexColl = [], senkouSpanOptions = indicator.options.senkouSpan, color = (senkouSpanOptions.color ||
+            senkouSpanOptions.styles.fill), negativeColor = (senkouSpanOptions.negativeColor), 
+        // Points to create color and negativeColor senkouSpan
+        points = [
+            [],
+            [] // Points negative color
+        ], 
+        // For span, we need an access to the next points, used in
+        // getGraphPath()
+        nextPoints = [
+            [],
+            [] // NextPoints negative color
+        ], lineIndex = 0, position, point, i, startIntersect, endIntersect, sectionPoints, sectionNextPoints, pointsPlotYSum, nextPointsPlotYSum, senkouSpanTempColor, concatArrIndex, j, k;
+        indicator.ikhMap = ikhMap;
+        // Generate points for all lines and spans lines:
+        while (pointsLength--) {
+            point = mainLinePoints[pointsLength];
+            for (i = 0; i < pointArrayMapLength; i++) {
+                position = indicator.pointArrayMap[i];
+                if (defined(point[position])) {
+                    allIchimokuPoints[i].push({
+                        plotX: point.plotX,
+                        plotY: point['plot' + position],
+                        isNull: false
+                    });
+                }
+            }
+            if (negativeColor &&
+                pointsLength !== mainLinePoints.length - 1) {
+                // Check if lines intersect
+                var index = ikhMap.senkouSpanB.length - 1, intersect = checkLineIntersection(ikhMap.senkouSpanA[index - 1], ikhMap.senkouSpanA[index], ikhMap.senkouSpanB[index - 1], ikhMap.senkouSpanB[index]), intersectPointObj = {
+                    plotX: intersect.plotX,
+                    plotY: intersect.plotY,
+                    isNull: false,
+                    intersectPoint: true
+                };
+                if (intersect) {
+                    // Add intersect point to ichimoku points collection
+                    // Create senkouSpan sections
+                    ikhMap.senkouSpanA.splice(index, 0, intersectPointObj);
+                    ikhMap.senkouSpanB.splice(index, 0, intersectPointObj);
+                    intersectIndexColl.push(index);
+                }
+            }
+        }
+        // Modify options and generate lines:
+        objectEach(ikhMap, function (values, lineName) {
+            if (mainLineOptions[lineName] &&
+                lineName !== 'senkouSpan') {
+                // First line is rendered by default option
+                indicator.points = allIchimokuPoints[lineIndex];
+                indicator.options = merge(mainLineOptions[lineName].styles, gappedExtend);
+                indicator.graph = indicator['graph' + lineName];
+                indicator.fillGraph = false;
+                indicator.color = mainColor;
+                SMA.prototype.drawGraph.call(indicator);
+                // Now save line
+                indicator['graph' + lineName] = indicator.graph;
+            }
+            lineIndex++;
+        });
+        // Generate senkouSpan area:
+        // If graphColection exist then remove svg
+        // element and indicator property
+        if (indicator.graphCollection) {
+            indicator.graphCollection.forEach(function (graphName) {
+                indicator[graphName].destroy();
+                delete indicator[graphName];
+            });
+        }
+        // Clean grapCollection or initialize it
+        indicator.graphCollection = [];
+        // When user set negativeColor property
+        if (negativeColor &&
+            ikhMap.senkouSpanA[0] &&
+            ikhMap.senkouSpanB[0]) {
+            // Add first and last point to senkouSpan area sections
+            intersectIndexColl.unshift(0);
+            intersectIndexColl.push(ikhMap.senkouSpanA.length - 1);
+            // Populate points and nextPoints arrays
+            for (j = 0; j < intersectIndexColl.length - 1; j++) {
+                startIntersect = intersectIndexColl[j];
+                endIntersect = intersectIndexColl[j + 1];
+                sectionPoints = ikhMap.senkouSpanB.slice(startIntersect, endIntersect + 1);
+                sectionNextPoints = ikhMap.senkouSpanA.slice(startIntersect, endIntersect + 1);
+                // Add points to color or negativeColor arrays
+                // Check the middle point (if exist)
+                if (Math.floor(sectionPoints.length / 2) >= 1) {
+                    var x = Math.floor(sectionPoints.length / 2);
+                    // When middle points has equal values
+                    // Compare all ponints plotY value sum
+                    if (sectionPoints[x].plotY ===
+                        sectionNextPoints[x].plotY) {
+                        pointsPlotYSum = 0;
+                        nextPointsPlotYSum = 0;
+                        for (k = 0; k < sectionPoints.length; k++) {
+                            pointsPlotYSum +=
+                                sectionPoints[k].plotY;
+                            nextPointsPlotYSum +=
+                                sectionNextPoints[k].plotY;
+                        }
+                        concatArrIndex = (pointsPlotYSum > nextPointsPlotYSum ? 0 : 1);
+                        points[concatArrIndex] = (points[concatArrIndex].concat(sectionPoints));
+                        nextPoints[concatArrIndex] = (nextPoints[concatArrIndex].concat(sectionNextPoints));
+                    }
+                    else {
+                        // Compare middle point of the section
+                        concatArrIndex = (sectionPoints[x].plotY >
+                            sectionNextPoints[x].plotY ?
+                            0 : 1);
+                        points[concatArrIndex] = (points[concatArrIndex].concat(sectionPoints));
+                        nextPoints[concatArrIndex] = (nextPoints[concatArrIndex].concat(sectionNextPoints));
+                    }
+                }
+                else {
+                    // Compare first point of the section
+                    concatArrIndex = (sectionPoints[0].plotY >
+                        sectionNextPoints[0].plotY ?
+                        0 : 1);
+                    points[concatArrIndex] = (points[concatArrIndex].concat(sectionPoints));
+                    nextPoints[concatArrIndex] = (nextPoints[concatArrIndex].concat(sectionNextPoints));
+                }
+            }
+            // Render color and negativeColor paths
+            [
+                'graphsenkouSpanColor', 'graphsenkouSpanNegativeColor'
+            ].forEach(function (areaName, i) {
+                if (points[i].length && nextPoints[i].length) {
+                    senkouSpanTempColor = (i === 0) ?
+                        color : negativeColor;
+                    drawSenkouSpan({
+                        indicator: indicator,
+                        points: points[i],
+                        nextPoints: nextPoints[i],
+                        color: senkouSpanTempColor,
+                        options: mainLineOptions,
+                        gap: gappedExtend,
+                        graph: indicator[areaName]
+                    });
+                    // Now save line
+                    indicator[areaName] = indicator.graph;
+                    indicator.graphCollection.push(areaName);
+                }
+            });
+        }
+        else {
+            // When user set only senkouSpan style.fill property
+            drawSenkouSpan({
+                indicator: indicator,
+                points: ikhMap.senkouSpanB,
+                nextPoints: ikhMap.senkouSpanA,
+                color: color,
+                options: mainLineOptions,
+                gap: gappedExtend,
+                graph: indicator.graphsenkouSpan
+            });
+            // Now save line
+            indicator.graphsenkouSpan = indicator.graph;
+        }
+        // Clean temporary properties:
+        delete indicator.nextPoints;
+        delete indicator.fillGraph;
+        // Restore options and draw the Tenkan line:
+        indicator.points = mainLinePoints;
+        indicator.options = mainLineOptions;
+        indicator.graph = mainLinePath;
+    },
+    getGraphPath: function (points) {
+        var indicator = this, path = [], spanA, fillArray = [], spanAarr = [];
+        points = points || this.points;
+        // Render Senkou Span
+        if (indicator.fillGraph && indicator.nextPoints) {
+            spanA = SMA.prototype.getGraphPath.call(indicator, 
+            // Reverse points, so Senkou Span A will start from the end:
+            indicator.nextPoints);
+            spanA[0] = 'L';
+            path = SMA.prototype.getGraphPath.call(indicator, points);
+            spanAarr = spanA.slice(0, path.length);
+            for (var i = (spanAarr.length - 1); i > 0; i -= 3) {
+                fillArray.push(spanAarr[i - 2], spanAarr[i - 1], spanAarr[i]);
+            }
+            path = path.concat(fillArray);
+        }
+        else {
+            path = SMA.prototype.getGraphPath.apply(indicator, arguments);
+        }
+        return path;
+    },
+    getValues: function (series, params) {
+        var period = params.period, periodTenkan = params.periodTenkan, periodSenkouSpanB = params.periodSenkouSpanB, xVal = series.xData, yVal = series.yData, xAxis = series.xAxis, yValLen = (yVal && yVal.length) || 0, closestPointRange = getClosestPointRange(xAxis), IKH = [], xData = [], dateStart, date, slicedTSY, slicedKSY, slicedSSBY, pointTS, pointKS, pointSSB, i, TS, KS, CS, SSA, SSB;
+        // Ikh requires close value
+        if (xVal.length <= period ||
+            !isArray(yVal[0]) ||
+            yVal[0].length !== 4) {
+            return;
+        }
+        // Add timestamps at the beginning
+        dateStart = xVal[0] - (period * closestPointRange);
+        for (i = 0; i < period; i++) {
+            xData.push(dateStart + i * closestPointRange);
+        }
+        for (i = 0; i < yValLen; i++) {
+            // Tenkan Sen
+            if (i >= periodTenkan) {
+                slicedTSY = yVal.slice(i - periodTenkan, i);
+                pointTS = highlowLevel(slicedTSY);
+                TS = (pointTS.high + pointTS.low) / 2;
+            }
+            if (i >= period) {
+                slicedKSY = yVal.slice(i - period, i);
+                pointKS = highlowLevel(slicedKSY);
+                KS = (pointKS.high + pointKS.low) / 2;
+                SSA = (TS + KS) / 2;
+            }
+            if (i >= periodSenkouSpanB) {
+                slicedSSBY = yVal.slice(i - periodSenkouSpanB, i);
+                pointSSB = highlowLevel(slicedSSBY);
+                SSB = (pointSSB.high + pointSSB.low) / 2;
+            }
+            CS = yVal[i][3];
+            date = xVal[i];
+            if (IKH[i] === UNDEFINED) {
+                IKH[i] = [];
+            }
+            if (IKH[i + period] === UNDEFINED) {
+                IKH[i + period] = [];
+            }
+            IKH[i + period][0] = TS;
+            IKH[i + period][1] = KS;
+            IKH[i + period][2] = UNDEFINED;
+            IKH[i][2] = CS;
+            if (i <= period) {
+                IKH[i + period][3] = UNDEFINED;
+                IKH[i + period][4] = UNDEFINED;
+            }
+            if (IKH[i + 2 * period] === UNDEFINED) {
+                IKH[i + 2 * period] = [];
+            }
+            IKH[i + 2 * period][3] = SSA;
+            IKH[i + 2 * period][4] = SSB;
+            xData.push(date);
+        }
+        // Add timestamps for further points
+        for (i = 1; i <= period; i++) {
+            xData.push(date + i * closestPointRange);
+        }
+        return {
+            values: IKH,
+            xData: xData,
+            yData: IKH
+        };
+    }
+});
+/**
+ * A `IKH` series. If the [type](#series.ikh.type) option is not
+ * specified, it is inherited from [chart.type](#chart.type).
+ *
+ * @extends   series,plotOptions.ikh
+ * @since     6.0.0
+ * @product   highstock
+ * @excluding dataParser, dataURL
+ * @requires  stock/indicators/indicators
+ * @requires  stock/indicators/ichimoku-kinko-hyo
+ * @apioption series.ikh
+ */
+''; // add doclet above to transpiled file

+ 317 - 0
app/public/js/Highstock-8.0.0/code/es-modules/indicators/indicators.src.js

@@ -0,0 +1,317 @@
+/* *
+ *
+ *  License: www.highcharts.com/license
+ *
+ *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
+ *
+ * */
+'use strict';
+import H from '../parts/Globals.js';
+import U from '../parts/Utilities.js';
+var extend = U.extend, isArray = U.isArray, pick = U.pick, splat = U.splat;
+import requiredIndicatorMixin from '../mixins/indicator-required.js';
+var error = H.error, Series = H.Series, addEvent = H.addEvent, seriesType = H.seriesType, seriesTypes = H.seriesTypes, ohlcProto = H.seriesTypes.ohlc.prototype, generateMessage = requiredIndicatorMixin.generateMessage;
+/**
+ * The parameter allows setting line series type and use OHLC indicators. Data
+ * in OHLC format is required.
+ *
+ * @sample {highstock} stock/indicators/use-ohlc-data
+ *         Plot line on Y axis
+ *
+ * @type      {boolean}
+ * @product   highstock
+ * @apioption plotOptions.line.useOhlcData
+ */
+/* eslint-disable no-invalid-this */
+addEvent(H.Series, 'init', function (eventOptions) {
+    var series = this, options = eventOptions.options;
+    if (options.useOhlcData &&
+        options.id !== 'highcharts-navigator-series') {
+        extend(series, {
+            pointValKey: ohlcProto.pointValKey,
+            keys: ohlcProto.keys,
+            pointArrayMap: ohlcProto.pointArrayMap,
+            toYData: ohlcProto.toYData
+        });
+    }
+});
+addEvent(Series, 'afterSetOptions', function (e) {
+    var options = e.options, dataGrouping = options.dataGrouping;
+    if (dataGrouping &&
+        options.useOhlcData &&
+        options.id !== 'highcharts-navigator-series') {
+        dataGrouping.approximation = 'ohlc';
+    }
+});
+/* eslint-enable no-invalid-this */
+/**
+ * The SMA series type.
+ *
+ * @private
+ * @class
+ * @name Highcharts.seriesTypes.sma
+ *
+ * @augments Highcharts.Series
+ */
+seriesType('sma', 'line', 
+/**
+ * Simple moving average indicator (SMA). This series requires `linkedTo`
+ * option to be set.
+ *
+ * @sample stock/indicators/sma
+ *         Simple moving average indicator
+ *
+ * @extends      plotOptions.line
+ * @since        6.0.0
+ * @excluding    allAreas, colorAxis, dragDrop, joinBy, keys,
+ *               navigatorOptions, pointInterval, pointIntervalUnit,
+ *               pointPlacement, pointRange, pointStart, showInNavigator,
+ *               stacking, useOhlcData
+ * @product      highstock
+ * @requires     stock/indicators/indicators
+ * @optionparent plotOptions.sma
+ */
+{
+    /**
+     * The name of the series as shown in the legend, tooltip etc. If not
+     * set, it will be based on a technical indicator type and default
+     * params.
+     *
+     * @type {string}
+     */
+    name: void 0,
+    tooltip: {
+        /**
+         * Number of decimals in indicator series.
+         */
+        valueDecimals: 4
+    },
+    /**
+     * The main series ID that indicator will be based on. Required for this
+     * indicator.
+     *
+     * @type {string}
+     */
+    linkedTo: void 0,
+    /**
+     * Whether to compare indicator to the main series values
+     * or indicator values.
+     *
+     * @sample {highstock} stock/plotoptions/series-comparetomain/
+     *         Difference between comparing SMA values to the main series
+     *         and its own values.
+     *
+     * @type {boolean}
+     */
+    compareToMain: false,
+    /**
+     * Paramters used in calculation of regression series' points.
+     */
+    params: {
+        /**
+         * The point index which indicator calculations will base. For
+         * example using OHLC data, index=2 means the indicator will be
+         * calculated using Low values.
+         */
+        index: 0,
+        /**
+         * The base period for indicator calculations. This is the number of
+         * data points which are taken into account for the indicator
+         * calculations.
+         */
+        period: 14
+    }
+}, 
+/**
+ * @lends Highcharts.Series.prototype
+ */
+{
+    processData: function () {
+        var series = this, compareToMain = series.options.compareToMain, linkedParent = series.linkedParent;
+        Series.prototype.processData.apply(series, arguments);
+        if (linkedParent && linkedParent.compareValue && compareToMain) {
+            series.compareValue = linkedParent.compareValue;
+        }
+        return;
+    },
+    bindTo: {
+        series: true,
+        eventName: 'updatedData'
+    },
+    hasDerivedData: true,
+    useCommonDataGrouping: true,
+    nameComponents: ['period'],
+    nameSuffixes: [],
+    calculateOn: 'init',
+    // Defines on which other indicators is this indicator based on.
+    requiredIndicators: [],
+    requireIndicators: function () {
+        var obj = {
+            allLoaded: true
+        };
+        // Check whether all required indicators are loaded, else return
+        // the object with missing indicator's name.
+        this.requiredIndicators.forEach(function (indicator) {
+            if (seriesTypes[indicator]) {
+                seriesTypes[indicator].prototype.requireIndicators();
+            }
+            else {
+                obj.allLoaded = false;
+                obj.needed = indicator;
+            }
+        });
+        return obj;
+    },
+    init: function (chart, options) {
+        var indicator = this, requiredIndicators = indicator.requireIndicators();
+        // Check whether all required indicators are loaded.
+        if (!requiredIndicators.allLoaded) {
+            return error(generateMessage(indicator.type, requiredIndicators.needed));
+        }
+        Series.prototype.init.call(indicator, chart, options);
+        // Make sure we find series which is a base for an indicator
+        chart.linkSeries();
+        indicator.dataEventsToUnbind = [];
+        /**
+         * @private
+         * @return {void}
+         */
+        function recalculateValues() {
+            var oldData = indicator.points || [], oldDataLength = (indicator.xData || []).length, processedData = indicator.getValues(indicator.linkedParent, indicator.options.params) || {
+                values: [],
+                xData: [],
+                yData: []
+            }, croppedDataValues = [], overwriteData = true, oldFirstPointIndex, oldLastPointIndex, croppedData, min, max, i;
+            // We need to update points to reflect changes in all,
+            // x and y's, values. However, do it only for non-grouped
+            // data - grouping does it for us (#8572)
+            if (oldDataLength &&
+                !indicator.hasGroupedData &&
+                indicator.visible &&
+                indicator.points) {
+                // When data is cropped update only avaliable points (#9493)
+                if (indicator.cropped) {
+                    if (indicator.xAxis) {
+                        min = indicator.xAxis.min;
+                        max = indicator.xAxis.max;
+                    }
+                    croppedData = indicator.cropData(processedData.xData, processedData.yData, min, max);
+                    for (i = 0; i < croppedData.xData.length; i++) {
+                        // (#10774)
+                        croppedDataValues.push([
+                            croppedData.xData[i]
+                        ].concat(splat(croppedData.yData[i])));
+                    }
+                    oldFirstPointIndex = processedData.xData.indexOf(indicator.xData[0]);
+                    oldLastPointIndex = processedData.xData.indexOf(indicator.xData[indicator.xData.length - 1]);
+                    // Check if indicator points should be shifted (#8572)
+                    if (oldFirstPointIndex === -1 &&
+                        oldLastPointIndex === processedData.xData.length - 2) {
+                        if (croppedDataValues[0][0] === oldData[0].x) {
+                            croppedDataValues.shift();
+                        }
+                    }
+                    indicator.updateData(croppedDataValues);
+                    // Omit addPoint() and removePoint() cases
+                }
+                else if (processedData.xData.length !== oldDataLength - 1 &&
+                    processedData.xData.length !== oldDataLength + 1) {
+                    overwriteData = false;
+                    indicator.updateData(processedData.values);
+                }
+            }
+            if (overwriteData) {
+                indicator.xData = processedData.xData;
+                indicator.yData = processedData.yData;
+                indicator.options.data = processedData.values;
+            }
+            // Removal of processedXData property is required because on
+            // first translate processedXData array is empty
+            if (indicator.bindTo.series === false) {
+                delete indicator.processedXData;
+                indicator.isDirty = true;
+                indicator.redraw();
+            }
+            indicator.isDirtyData = false;
+        }
+        if (!indicator.linkedParent) {
+            return error('Series ' +
+                indicator.options.linkedTo +
+                ' not found! Check `linkedTo`.', false, chart);
+        }
+        indicator.dataEventsToUnbind.push(addEvent(indicator.bindTo.series ?
+            indicator.linkedParent : indicator.linkedParent.xAxis, indicator.bindTo.eventName, recalculateValues));
+        if (indicator.calculateOn === 'init') {
+            recalculateValues();
+        }
+        else {
+            var unbinder = addEvent(indicator.chart, indicator.calculateOn, function () {
+                recalculateValues();
+                // Call this just once, on init
+                unbinder();
+            });
+        }
+        return indicator;
+    },
+    getName: function () {
+        var name = this.name, params = [];
+        if (!name) {
+            (this.nameComponents || []).forEach(function (component, index) {
+                params.push(this.options.params[component] +
+                    pick(this.nameSuffixes[index], ''));
+            }, this);
+            name = (this.nameBase || this.type.toUpperCase()) +
+                (this.nameComponents ? ' (' + params.join(', ') + ')' : '');
+        }
+        return name;
+    },
+    getValues: function (series, params) {
+        var period = params.period, xVal = series.xData, yVal = series.yData, yValLen = yVal.length, range = 0, sum = 0, SMA = [], xData = [], yData = [], index = -1, i, SMAPoint;
+        if (xVal.length < period) {
+            return;
+        }
+        // Switch index for OHLC / Candlestick / Arearange
+        if (isArray(yVal[0])) {
+            index = params.index ? params.index : 0;
+        }
+        // Accumulate first N-points
+        while (range < period - 1) {
+            sum += index < 0 ? yVal[range] : yVal[range][index];
+            range++;
+        }
+        // Calculate value one-by-one for each period in visible data
+        for (i = range; i < yValLen; i++) {
+            sum += index < 0 ? yVal[i] : yVal[i][index];
+            SMAPoint = [xVal[i], sum / period];
+            SMA.push(SMAPoint);
+            xData.push(SMAPoint[0]);
+            yData.push(SMAPoint[1]);
+            sum -= (index < 0 ?
+                yVal[i - range] :
+                yVal[i - range][index]);
+        }
+        return {
+            values: SMA,
+            xData: xData,
+            yData: yData
+        };
+    },
+    destroy: function () {
+        this.dataEventsToUnbind.forEach(function (unbinder) {
+            unbinder();
+        });
+        Series.prototype.destroy.apply(this, arguments);
+    }
+});
+/**
+ * A `SMA` series. If the [type](#series.sma.type) option is not specified, it
+ * is inherited from [chart.type](#chart.type).
+ *
+ * @extends   series,plotOptions.sma
+ * @since     6.0.0
+ * @product   highstock
+ * @excluding dataParser, dataURL, useOhlcData
+ * @requires  stock/indicators/indicators
+ * @apioption series.sma
+ */
+''; // adds doclet above to the transpiled file

+ 172 - 0
app/public/js/Highstock-8.0.0/code/es-modules/indicators/keltner-channels.src.js

@@ -0,0 +1,172 @@
+/* *
+ *
+ *  License: www.highcharts.com/license
+ *
+ *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
+ *
+ * */
+'use strict';
+import H from '../parts/Globals.js';
+import U from '../parts/Utilities.js';
+var correctFloat = U.correctFloat;
+import multipleLinesMixin from '../mixins/multipe-lines.js';
+var SMA = H.seriesTypes.sma, EMA = H.seriesTypes.ema, ATR = H.seriesTypes.atr, merge = H.merge;
+/**
+ * The Keltner Channels series type.
+ *
+ * @private
+ * @class
+ * @name Highcharts.seriesTypes.keltnerchannels
+ *
+ * @augments Highcharts.Series
+ */
+H.seriesType('keltnerchannels', 'sma', 
+/**
+ * Keltner Channels. This series requires the `linkedTo` option to be set
+ * and should be loaded after the `stock/indicators/indicators.js`,
+ * `stock/indicators/atr.js`, and `stock/ema/.js`.
+ *
+ * @sample {highstock} stock/indicators/keltner-channels
+ *         Keltner Channels
+ *
+ * @extends      plotOptions.sma
+ * @since        7.0.0
+ * @product      highstock
+ * @excluding    allAreas, colorAxis, compare, compareBase, joinBy, keys,
+ *               navigatorOptions, pointInterval, pointIntervalUnit,
+ *               pointPlacement, pointRange, pointStart,showInNavigator,
+ *               stacking
+ * @requires     stock/indicators/indicators
+ * @requires     stock/indicators/keltner-channels
+ * @optionparent plotOptions.keltnerchannels
+ */
+{
+    params: {
+        period: 20,
+        /**
+         * The ATR period.
+         */
+        periodATR: 10,
+        /**
+         * The ATR multiplier.
+         */
+        multiplierATR: 2
+    },
+    /**
+     * Bottom line options.
+     *
+     */
+    bottomLine: {
+        /**
+         * Styles for a bottom line.
+         *
+         */
+        styles: {
+            /**
+             * Pixel width of the line.
+             */
+            lineWidth: 1,
+            /**
+             * Color of the line. If not set, it's inherited from
+             * `plotOptions.keltnerchannels.color`
+             */
+            lineColor: void 0
+        }
+    },
+    /**
+     * Top line options.
+     *
+     * @extends plotOptions.keltnerchannels.bottomLine
+     */
+    topLine: {
+        styles: {
+            lineWidth: 1,
+            lineColor: void 0
+        }
+    },
+    tooltip: {
+        pointFormat: '<span style="color:{point.color}">\u25CF</span><b> {series.name}</b><br/>Upper Channel: {point.top}<br/>EMA({series.options.params.period}): {point.middle}<br/>Lower Channel: {point.bottom}<br/>'
+    },
+    marker: {
+        enabled: false
+    },
+    dataGrouping: {
+        approximation: 'averages'
+    },
+    lineWidth: 1
+}, 
+/**
+ * @lends Highcharts.Series#
+ */
+merge(multipleLinesMixin, {
+    pointArrayMap: ['top', 'middle', 'bottom'],
+    pointValKey: 'middle',
+    nameBase: 'Keltner Channels',
+    nameComponents: ['period', 'periodATR', 'multiplierATR'],
+    linesApiNames: ['topLine', 'bottomLine'],
+    requiredIndicators: ['ema', 'atr'],
+    init: function () {
+        SMA.prototype.init.apply(this, arguments);
+        // Set default color for lines:
+        this.options = merge({
+            topLine: {
+                styles: {
+                    lineColor: this.color
+                }
+            },
+            bottomLine: {
+                styles: {
+                    lineColor: this.color
+                }
+            }
+        }, this.options);
+    },
+    getValues: function (series, params) {
+        var period = params.period, periodATR = params.periodATR, multiplierATR = params.multiplierATR, index = params.index, yVal = series.yData, yValLen = yVal ? yVal.length : 0, 
+        // Keltner Channels array structure:
+        // 0-date, 1-top line, 2-middle line, 3-bottom line
+        KC = [], 
+        // middle line, top line and bottom lineI
+        ML, TL, BL, date, seriesEMA = EMA.prototype.getValues(series, {
+            period: period,
+            index: index
+        }), seriesATR = ATR.prototype.getValues(series, {
+            period: periodATR
+        }), pointEMA, pointATR, xData = [], yData = [], i;
+        if (yValLen < period) {
+            return;
+        }
+        for (i = period; i <= yValLen; i++) {
+            pointEMA = seriesEMA.values[i - period];
+            pointATR = seriesATR.values[i - periodATR];
+            date = pointEMA[0];
+            TL = correctFloat(pointEMA[1] + (multiplierATR * pointATR[1]));
+            BL = correctFloat(pointEMA[1] - (multiplierATR * pointATR[1]));
+            ML = pointEMA[1];
+            KC.push([date, TL, ML, BL]);
+            xData.push(date);
+            yData.push([TL, ML, BL]);
+        }
+        return {
+            values: KC,
+            xData: xData,
+            yData: yData
+        };
+    }
+}));
+/**
+ * A Keltner Channels indicator. If the [type](#series.keltnerchannels.type)
+ * option is not specified, it is inherited from[chart.type](#chart.type).
+ *
+ * @extends      series,plotOptions.keltnerchannels
+ * @since        7.0.0
+ * @product      highstock
+ * @excluding    allAreas, colorAxis, compare, compareBase, dataParser, dataURL,
+ *               joinBy, keys, navigatorOptions, pointInterval,
+ *               pointIntervalUnit, pointPlacement, pointRange, pointStart,
+ *               stacking, showInNavigator
+ * @requires     stock/indicators/indicators
+ * @requires     stock/indicators/keltner-channels
+ * @apioption    series.keltnerchannels
+ */
+''; // to include the above in the js output

+ 348 - 0
app/public/js/Highstock-8.0.0/code/es-modules/indicators/macd.src.js

@@ -0,0 +1,348 @@
+/* *
+ *
+ *  License: www.highcharts.com/license
+ *
+ *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
+ *
+ * */
+'use strict';
+import H from '../parts/Globals.js';
+import U from '../parts/Utilities.js';
+var correctFloat = U.correctFloat, defined = U.defined;
+var seriesType = H.seriesType, noop = H.noop, merge = H.merge, SMA = H.seriesTypes.sma, EMA = H.seriesTypes.ema;
+/**
+ * The MACD series type.
+ *
+ * @private
+ * @class
+ * @name Highcharts.seriesTypes.macd
+ *
+ * @augments Highcharts.Series
+ */
+seriesType('macd', 'sma', 
+/**
+ * Moving Average Convergence Divergence (MACD). This series requires
+ * `linkedTo` option to be set and should be loaded after the
+ * `stock/indicators/indicators.js` and `stock/indicators/ema.js`.
+ *
+ * @sample stock/indicators/macd
+ *         MACD indicator
+ *
+ * @extends      plotOptions.sma
+ * @since        6.0.0
+ * @product      highstock
+ * @requires     stock/indicators/indicators
+ * @requires     stock/indicators/macd
+ * @optionparent plotOptions.macd
+ */
+{
+    params: {
+        /**
+         * The short period for indicator calculations.
+         */
+        shortPeriod: 12,
+        /**
+         * The long period for indicator calculations.
+         */
+        longPeriod: 26,
+        /**
+         * The base period for signal calculations.
+         */
+        signalPeriod: 9,
+        period: 26
+    },
+    /**
+     * The styles for signal line
+     */
+    signalLine: {
+        /**
+         * @sample stock/indicators/macd-zones
+         *         Zones in MACD
+         *
+         * @extends plotOptions.macd.zones
+         */
+        zones: [],
+        styles: {
+            /**
+             * Pixel width of the line.
+             */
+            lineWidth: 1,
+            /**
+             * Color of the line.
+             *
+             * @type  {Highcharts.ColorString}
+             */
+            lineColor: void 0
+        }
+    },
+    /**
+     * The styles for macd line
+     */
+    macdLine: {
+        /**
+         * @sample stock/indicators/macd-zones
+         *         Zones in MACD
+         *
+         * @extends plotOptions.macd.zones
+         */
+        zones: [],
+        styles: {
+            /**
+             * Pixel width of the line.
+             */
+            lineWidth: 1,
+            /**
+             * Color of the line.
+             *
+             * @type  {Highcharts.ColorString}
+             */
+            lineColor: void 0
+        }
+    },
+    threshold: 0,
+    groupPadding: 0.1,
+    pointPadding: 0.1,
+    states: {
+        hover: {
+            halo: {
+                size: 0
+            }
+        }
+    },
+    tooltip: {
+        pointFormat: '<span style="color:{point.color}">\u25CF</span> <b> {series.name}</b><br/>' +
+            'Value: {point.MACD}<br/>' +
+            'Signal: {point.signal}<br/>' +
+            'Histogram: {point.y}<br/>'
+    },
+    dataGrouping: {
+        approximation: 'averages'
+    },
+    minPointLength: 0
+}, 
+/**
+ * @lends Highcharts.Series#
+ */
+{
+    nameComponents: ['longPeriod', 'shortPeriod', 'signalPeriod'],
+    requiredIndicators: ['ema'],
+    // "y" value is treated as Histogram data
+    pointArrayMap: ['y', 'signal', 'MACD'],
+    parallelArrays: ['x', 'y', 'signal', 'MACD'],
+    pointValKey: 'y',
+    // Columns support:
+    markerAttribs: noop,
+    getColumnMetrics: H.seriesTypes.column.prototype.getColumnMetrics,
+    crispCol: H.seriesTypes.column.prototype.crispCol,
+    // Colors and lines:
+    init: function () {
+        SMA.prototype.init.apply(this, arguments);
+        // Check whether series is initialized. It may be not initialized,
+        // when any of required indicators is missing.
+        if (this.options) {
+            // Set default color for a signal line and the histogram:
+            this.options = merge({
+                signalLine: {
+                    styles: {
+                        lineColor: this.color
+                    }
+                },
+                macdLine: {
+                    styles: {
+                        color: this.color
+                    }
+                }
+            }, this.options);
+            // Zones have indexes automatically calculated, we need to
+            // translate them to support multiple lines within one indicator
+            this.macdZones = {
+                zones: this.options.macdLine.zones,
+                startIndex: 0
+            };
+            this.signalZones = {
+                zones: this.macdZones.zones.concat(this.options.signalLine.zones),
+                startIndex: this.macdZones.zones.length
+            };
+            this.resetZones = true;
+        }
+    },
+    toYData: function (point) {
+        return [point.y, point.signal, point.MACD];
+    },
+    translate: function () {
+        var indicator = this, plotNames = ['plotSignal', 'plotMACD'];
+        H.seriesTypes.column.prototype.translate.apply(indicator);
+        indicator.points.forEach(function (point) {
+            [point.signal, point.MACD].forEach(function (value, i) {
+                if (value !== null) {
+                    point[plotNames[i]] =
+                        indicator.yAxis.toPixels(value, true);
+                }
+            });
+        });
+    },
+    destroy: function () {
+        // this.graph is null due to removing two times the same SVG element
+        this.graph = null;
+        this.graphmacd = this.graphmacd && this.graphmacd.destroy();
+        this.graphsignal = this.graphsignal && this.graphsignal.destroy();
+        SMA.prototype.destroy.apply(this, arguments);
+    },
+    drawPoints: H.seriesTypes.column.prototype.drawPoints,
+    drawGraph: function () {
+        var indicator = this, mainLinePoints = indicator.points, pointsLength = mainLinePoints.length, mainLineOptions = indicator.options, histogramZones = indicator.zones, gappedExtend = {
+            options: {
+                gapSize: mainLineOptions.gapSize
+            }
+        }, otherSignals = [[], []], point;
+        // Generate points for top and bottom lines:
+        while (pointsLength--) {
+            point = mainLinePoints[pointsLength];
+            if (defined(point.plotMACD)) {
+                otherSignals[0].push({
+                    plotX: point.plotX,
+                    plotY: point.plotMACD,
+                    isNull: !defined(point.plotMACD)
+                });
+            }
+            if (defined(point.plotSignal)) {
+                otherSignals[1].push({
+                    plotX: point.plotX,
+                    plotY: point.plotSignal,
+                    isNull: !defined(point.plotMACD)
+                });
+            }
+        }
+        // Modify options and generate smoothing line:
+        ['macd', 'signal'].forEach(function (lineName, i) {
+            indicator.points = otherSignals[i];
+            indicator.options = merge(mainLineOptions[lineName + 'Line'].styles, gappedExtend);
+            indicator.graph = indicator['graph' + lineName];
+            // Zones extension:
+            indicator.currentLineZone = lineName + 'Zones';
+            indicator.zones =
+                indicator[indicator.currentLineZone].zones;
+            SMA.prototype.drawGraph.call(indicator);
+            indicator['graph' + lineName] = indicator.graph;
+        });
+        // Restore options:
+        indicator.points = mainLinePoints;
+        indicator.options = mainLineOptions;
+        indicator.zones = histogramZones;
+        indicator.currentLineZone = null;
+        // indicator.graph = null;
+    },
+    getZonesGraphs: function (props) {
+        var allZones = SMA.prototype.getZonesGraphs.call(this, props), currentZones = allZones;
+        if (this.currentLineZone) {
+            currentZones = allZones.splice(this[this.currentLineZone].startIndex + 1);
+            if (!currentZones.length) {
+                // Line has no zones, return basic graph "zone"
+                currentZones = [props[0]];
+            }
+            else {
+                // Add back basic prop:
+                currentZones.splice(0, 0, props[0]);
+            }
+        }
+        return currentZones;
+    },
+    applyZones: function () {
+        // Histogram zones are handled by drawPoints method
+        // Here we need to apply zones for all lines
+        var histogramZones = this.zones;
+        // signalZones.zones contains all zones:
+        this.zones = this.signalZones.zones;
+        SMA.prototype.applyZones.call(this);
+        // applyZones hides only main series.graph, hide macd line manually
+        if (this.graphmacd && this.options.macdLine.zones.length) {
+            this.graphmacd.hide();
+        }
+        this.zones = histogramZones;
+    },
+    getValues: function (series, params) {
+        var j = 0, MACD = [], xMACD = [], yMACD = [], signalLine = [], shortEMA, longEMA, i;
+        if (series.xData.length <
+            params.longPeriod + params.signalPeriod) {
+            return;
+        }
+        // Calculating the short and long EMA used when calculating the MACD
+        shortEMA = EMA.prototype.getValues(series, {
+            period: params.shortPeriod
+        });
+        longEMA = EMA.prototype.getValues(series, {
+            period: params.longPeriod
+        });
+        shortEMA = shortEMA.values;
+        longEMA = longEMA.values;
+        // Subtract each Y value from the EMA's and create the new dataset
+        // (MACD)
+        for (i = 1; i <= shortEMA.length; i++) {
+            if (defined(longEMA[i - 1]) &&
+                defined(longEMA[i - 1][1]) &&
+                defined(shortEMA[i + params.shortPeriod + 1]) &&
+                defined(shortEMA[i + params.shortPeriod + 1][0])) {
+                MACD.push([
+                    shortEMA[i + params.shortPeriod + 1][0],
+                    0,
+                    null,
+                    shortEMA[i + params.shortPeriod + 1][1] -
+                        longEMA[i - 1][1]
+                ]);
+            }
+        }
+        // Set the Y and X data of the MACD. This is used in calculating the
+        // signal line.
+        for (i = 0; i < MACD.length; i++) {
+            xMACD.push(MACD[i][0]);
+            yMACD.push([0, null, MACD[i][3]]);
+        }
+        // Setting the signalline (Signal Line: X-day EMA of MACD line).
+        signalLine = EMA.prototype.getValues({
+            xData: xMACD,
+            yData: yMACD
+        }, {
+            period: params.signalPeriod,
+            index: 2
+        });
+        signalLine = signalLine.values;
+        // Setting the MACD Histogram. In comparison to the loop with pure
+        // MACD this loop uses MACD x value not xData.
+        for (i = 0; i < MACD.length; i++) {
+            // detect the first point
+            if (MACD[i][0] >= signalLine[0][0]) {
+                MACD[i][2] = signalLine[j][1];
+                yMACD[i] = [0, signalLine[j][1], MACD[i][3]];
+                if (MACD[i][3] === null) {
+                    MACD[i][1] = 0;
+                    yMACD[i][0] = 0;
+                }
+                else {
+                    MACD[i][1] = correctFloat(MACD[i][3] -
+                        signalLine[j][1]);
+                    yMACD[i][0] = correctFloat(MACD[i][3] -
+                        signalLine[j][1]);
+                }
+                j++;
+            }
+        }
+        return {
+            values: MACD,
+            xData: xMACD,
+            yData: yMACD
+        };
+    }
+});
+/**
+ * A `MACD` series. If the [type](#series.macd.type) option is not
+ * specified, it is inherited from [chart.type](#chart.type).
+ *
+ * @extends   series,plotOptions.macd
+ * @since     6.0.0
+ * @product   highstock
+ * @excluding dataParser, dataURL
+ * @requires  stock/indicators/indicators
+ * @requires  stock/indicators/macd
+ * @apioption series.macd
+ */
+''; // to include the above in the js output

+ 155 - 0
app/public/js/Highstock-8.0.0/code/es-modules/indicators/mfi.src.js

@@ -0,0 +1,155 @@
+/* *
+ *
+ *  Money Flow Index indicator for Highstock
+ *
+ *  (c) 2010-2019 Grzegorz Blachliński
+ *
+ *  License: www.highcharts.com/license
+ *
+ *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
+ *
+ * */
+'use strict';
+import H from '../parts/Globals.js';
+import U from '../parts/Utilities.js';
+var isArray = U.isArray;
+/* eslint-disable require-jsdoc */
+// Utils:
+function sumArray(array) {
+    return array.reduce(function (prev, cur) {
+        return prev + cur;
+    });
+}
+function toFixed(a, n) {
+    return parseFloat(a.toFixed(n));
+}
+function calculateTypicalPrice(point) {
+    return (point[1] + point[2] + point[3]) / 3;
+}
+function calculateRawMoneyFlow(typicalPrice, volume) {
+    return typicalPrice * volume;
+}
+/* eslint-enable require-jsdoc */
+/**
+ * The MFI series type.
+ *
+ * @private
+ * @class
+ * @name Highcharts.seriesTypes.mfi
+ *
+ * @augments Highcharts.Series
+ */
+H.seriesType('mfi', 'sma', 
+/**
+ * Money Flow Index. This series requires `linkedTo` option to be set and
+ * should be loaded after the `stock/indicators/indicators.js` file.
+ *
+ * @sample stock/indicators/mfi
+ *         Money Flow Index Indicator
+ *
+ * @extends      plotOptions.sma
+ * @since        6.0.0
+ * @product      highstock
+ * @requires     stock/indicators/indicators
+ * @requires     stock/indicators/mfi
+ * @optionparent plotOptions.mfi
+ */
+{
+    /**
+     * @excluding index
+     */
+    params: {
+        period: 14,
+        /**
+         * The id of volume series which is mandatory.
+         * For example using OHLC data, volumeSeriesID='volume' means
+         * the indicator will be calculated using OHLC and volume values.
+         */
+        volumeSeriesID: 'volume',
+        /**
+         * Number of maximum decimals that are used in MFI calculations.
+         */
+        decimals: 4
+    }
+}, 
+/**
+ * @lends Highcharts.Series#
+ */
+{
+    nameBase: 'Money Flow Index',
+    getValues: function (series, params) {
+        var period = params.period, xVal = series.xData, yVal = series.yData, yValLen = yVal ? yVal.length : 0, decimals = params.decimals, 
+        // MFI starts calculations from the second point
+        // Cause we need to calculate change between two points
+        range = 1, volumeSeries = series.chart.get(params.volumeSeriesID), yValVolume = (volumeSeries && volumeSeries.yData), MFI = [], isUp = false, xData = [], yData = [], positiveMoneyFlow = [], negativeMoneyFlow = [], newTypicalPrice, oldTypicalPrice, rawMoneyFlow, negativeMoneyFlowSum, positiveMoneyFlowSum, moneyFlowRatio, MFIPoint, i;
+        if (!volumeSeries) {
+            H.error('Series ' +
+                params.volumeSeriesID +
+                ' not found! Check `volumeSeriesID`.', true, series.chart);
+            return;
+        }
+        // MFI requires high low and close values
+        if ((xVal.length <= period) || !isArray(yVal[0]) ||
+            yVal[0].length !== 4 ||
+            !yValVolume) {
+            return;
+        }
+        // Calculate first typical price
+        newTypicalPrice = calculateTypicalPrice(yVal[range]);
+        // Accumulate first N-points
+        while (range < period + 1) {
+            // Calculate if up or down
+            oldTypicalPrice = newTypicalPrice;
+            newTypicalPrice = calculateTypicalPrice(yVal[range]);
+            isUp = newTypicalPrice >= oldTypicalPrice;
+            // Calculate raw money flow
+            rawMoneyFlow = calculateRawMoneyFlow(newTypicalPrice, yValVolume[range]);
+            // Add to array
+            positiveMoneyFlow.push(isUp ? rawMoneyFlow : 0);
+            negativeMoneyFlow.push(isUp ? 0 : rawMoneyFlow);
+            range++;
+        }
+        for (i = range - 1; i < yValLen; i++) {
+            if (i > range - 1) {
+                // Remove first point from array
+                positiveMoneyFlow.shift();
+                negativeMoneyFlow.shift();
+                // Calculate if up or down
+                oldTypicalPrice = newTypicalPrice;
+                newTypicalPrice = calculateTypicalPrice(yVal[i]);
+                isUp = newTypicalPrice > oldTypicalPrice;
+                // Calculate raw money flow
+                rawMoneyFlow = calculateRawMoneyFlow(newTypicalPrice, yValVolume[i]);
+                // Add to array
+                positiveMoneyFlow.push(isUp ? rawMoneyFlow : 0);
+                negativeMoneyFlow.push(isUp ? 0 : rawMoneyFlow);
+            }
+            // Calculate sum of negative and positive money flow:
+            negativeMoneyFlowSum = sumArray(negativeMoneyFlow);
+            positiveMoneyFlowSum = sumArray(positiveMoneyFlow);
+            moneyFlowRatio = positiveMoneyFlowSum / negativeMoneyFlowSum;
+            MFIPoint = toFixed(100 - (100 / (1 + moneyFlowRatio)), decimals);
+            MFI.push([xVal[i], MFIPoint]);
+            xData.push(xVal[i]);
+            yData.push(MFIPoint);
+        }
+        return {
+            values: MFI,
+            xData: xData,
+            yData: yData
+        };
+    }
+});
+/**
+ * A `MFI` series. If the [type](#series.mfi.type) option is not specified, it
+ * is inherited from [chart.type](#chart.type).
+ *
+ * @extends   series,plotOptions.mfi
+ * @since     6.0.0
+ * @excluding dataParser, dataURL
+ * @product   highstock
+ * @requires  stock/indicators/indicators
+ * @requires  stock/indicators/mfi
+ * @apioption series.mfi
+ */
+''; // to include the above in the js output

+ 99 - 0
app/public/js/Highstock-8.0.0/code/es-modules/indicators/momentum.src.js

@@ -0,0 +1,99 @@
+/* *
+ *
+ *  License: www.highcharts.com/license
+ *
+ *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
+ *
+ * */
+'use strict';
+import H from '../parts/Globals.js';
+import U from '../parts/Utilities.js';
+var isArray = U.isArray;
+var seriesType = H.seriesType;
+/* eslint-disable require-jsdoc */
+function populateAverage(points, xVal, yVal, i, period) {
+    var mmY = yVal[i - 1][3] - yVal[i - period - 1][3], mmX = xVal[i - 1];
+    points.shift(); // remove point until range < period
+    return [mmX, mmY];
+}
+/* eslint-enable require-jsdoc */
+/**
+ * The Momentum series type.
+ *
+ * @private
+ * @class
+ * @name Highcharts.seriesTypes.momentum
+ *
+ * @augments Highcharts.Series
+ */
+seriesType('momentum', 'sma', 
+/**
+ * Momentum. This series requires `linkedTo` option to be set.
+ *
+ * @sample stock/indicators/momentum
+ *         Momentum indicator
+ *
+ * @extends      plotOptions.sma
+ * @since        6.0.0
+ * @product      highstock
+ * @requires     stock/indicators/indicators
+ * @requires     stock/indicators/momentum
+ * @optionparent plotOptions.momentum
+ */
+{
+    params: {
+        period: 14
+    }
+}, 
+/**
+ * @lends Highcharts.Series#
+ */
+{
+    nameBase: 'Momentum',
+    getValues: function (series, params) {
+        var period = params.period, xVal = series.xData, yVal = series.yData, yValLen = yVal ? yVal.length : 0, xValue = xVal[0], yValue = yVal[0], MM = [], xData = [], yData = [], index, i, points, MMPoint;
+        if (xVal.length <= period) {
+            return;
+        }
+        // Switch index for OHLC / Candlestick / Arearange
+        if (isArray(yVal[0])) {
+            yValue = yVal[0][3];
+        }
+        else {
+            return;
+        }
+        // Starting point
+        points = [
+            [xValue, yValue]
+        ];
+        // Calculate value one-by-one for each period in visible data
+        for (i = (period + 1); i < yValLen; i++) {
+            MMPoint = populateAverage(points, xVal, yVal, i, period, index);
+            MM.push(MMPoint);
+            xData.push(MMPoint[0]);
+            yData.push(MMPoint[1]);
+        }
+        MMPoint = populateAverage(points, xVal, yVal, i, period, index);
+        MM.push(MMPoint);
+        xData.push(MMPoint[0]);
+        yData.push(MMPoint[1]);
+        return {
+            values: MM,
+            xData: xData,
+            yData: yData
+        };
+    }
+});
+/**
+ * A `Momentum` series. If the [type](#series.momentum.type) option is not
+ * specified, it is inherited from [chart.type](#chart.type).
+ *
+ * @extends   series,plotOptions.momentum
+ * @since     6.0.0
+ * @excluding dataParser, dataURL
+ * @product   highstock
+ * @requires  stock/indicators/indicators
+ * @requires  stock/indicators/momentum
+ * @apioption series.momentum
+ */
+''; // to include the above in the js output

+ 72 - 0
app/public/js/Highstock-8.0.0/code/es-modules/indicators/natr.src.js

@@ -0,0 +1,72 @@
+/* *
+ *
+ *  License: www.highcharts.com/license
+ *
+ *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
+ *
+ * */
+'use strict';
+import H from '../parts/Globals.js';
+import '../parts/Utilities.js';
+var ATR = H.seriesTypes.atr;
+/**
+ * The NATR series type.
+ *
+ * @private
+ * @class
+ * @name Highcharts.seriesTypes.natr
+ *
+ * @augments Highcharts.Series
+ */
+H.seriesType('natr', 'sma', 
+/**
+ * Normalized average true range indicator (NATR). This series requires
+ * `linkedTo` option to be set and should be loaded after the
+ * `stock/indicators/indicators.js` and `stock/indicators/atr.js`.
+ *
+ * @sample {highstock} stock/indicators/natr
+ *         NATR indicator
+ *
+ * @extends      plotOptions.atr
+ * @since        7.0.0
+ * @product      highstock
+ * @requires     stock/indicators/indicators
+ * @requires     stock/indicators/natr
+ * @optionparent plotOptions.natr
+ */
+{
+    tooltip: {
+        valueSuffix: '%'
+    }
+}, 
+/**
+ * @lends Highcharts.Series#
+ */
+{
+    requiredIndicators: ['atr'],
+    getValues: function (series, params) {
+        var atrData = (ATR.prototype.getValues.apply(this, arguments)), atrLength = atrData.values.length, period = params.period - 1, yVal = series.yData, i = 0;
+        if (!atrData) {
+            return;
+        }
+        for (; i < atrLength; i++) {
+            atrData.yData[i] = (atrData.values[i][1] / yVal[period][3] * 100);
+            atrData.values[i][1] = atrData.yData[i];
+            period++;
+        }
+        return atrData;
+    }
+});
+/**
+ * A `NATR` series. If the [type](#series.natr.type) option is not specified, it
+ * is inherited from [chart.type](#chart.type).
+ *
+ * @extends   series,plotOptions.natr
+ * @since     7.0.0
+ * @product   highstock
+ * @excluding dataParser, dataURL
+ * @requires  stock/indicators/indicators
+ * @requires  stock/indicators/natr
+ * @apioption series.natr
+ */
+''; // to include the above in the js output'

+ 288 - 0
app/public/js/Highstock-8.0.0/code/es-modules/indicators/pivot-points.src.js

@@ -0,0 +1,288 @@
+/* *
+ *
+ *  License: www.highcharts.com/license
+ *
+ *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
+ *
+ * */
+'use strict';
+import H from '../parts/Globals.js';
+import U from '../parts/Utilities.js';
+var defined = U.defined, isArray = U.isArray;
+var SMA = H.seriesTypes.sma;
+/* eslint-disable valid-jsdoc */
+/**
+ * @private
+ */
+function destroyExtraLabels(point, functionName) {
+    var props = point.series.pointArrayMap, prop, i = props.length;
+    SMA.prototype.pointClass.prototype[functionName].call(point);
+    while (i--) {
+        prop = 'dataLabel' + props[i];
+        // S4 dataLabel could be removed by parent method:
+        if (point[prop] && point[prop].element) {
+            point[prop].destroy();
+        }
+        point[prop] = null;
+    }
+}
+/* eslint-enable valid-jsdoc */
+/**
+ * The Pivot Points series type.
+ *
+ * @private
+ * @class
+ * @name Highcharts.seriesTypes.pivotpoints
+ *
+ * @augments Highcharts.Series
+ */
+H.seriesType('pivotpoints', 'sma', 
+/**
+ * Pivot points indicator. This series requires the `linkedTo` option to be
+ * set and should be loaded after `stock/indicators/indicators.js` file.
+ *
+ * @sample stock/indicators/pivot-points
+ *         Pivot points
+ *
+ * @extends      plotOptions.sma
+ * @since        6.0.0
+ * @product      highstock
+ * @requires     stock/indicators/indicators
+ * @requires     stock/indicators/pivotpoints
+ * @optionparent plotOptions.pivotpoints
+ */
+{
+    /**
+     * @excluding index
+     */
+    params: {
+        period: 28,
+        /**
+         * Algorithm used to calculate ressistance and support lines based
+         * on pivot points. Implemented algorithms: `'standard'`,
+         * `'fibonacci'` and `'camarilla'`
+         */
+        algorithm: 'standard'
+    },
+    marker: {
+        enabled: false
+    },
+    enableMouseTracking: false,
+    dataLabels: {
+        enabled: true,
+        format: '{point.pivotLine}'
+    },
+    dataGrouping: {
+        approximation: 'averages'
+    }
+}, 
+/**
+ * @lends Highcharts.Series#
+ */
+{
+    nameBase: 'Pivot Points',
+    pointArrayMap: ['R4', 'R3', 'R2', 'R1', 'P', 'S1', 'S2', 'S3', 'S4'],
+    pointValKey: 'P',
+    toYData: function (point) {
+        return [point.P]; // The rest should not affect extremes
+    },
+    translate: function () {
+        var indicator = this;
+        SMA.prototype.translate.apply(indicator);
+        indicator.points.forEach(function (point) {
+            indicator.pointArrayMap.forEach(function (value) {
+                if (defined(point[value])) {
+                    point['plot' + value] = (indicator.yAxis.toPixels(point[value], true));
+                }
+            });
+        });
+        // Pivot points are rendered as horizontal lines
+        // And last point start not from the next one (as it's the last one)
+        // But from the approximated last position in a given range
+        indicator.plotEndPoint = indicator.xAxis.toPixels(indicator.endPoint, true);
+    },
+    getGraphPath: function (points) {
+        var indicator = this, pointsLength = points.length, allPivotPoints = ([[], [], [], [], [], [], [], [], []]), path = [], endPoint = indicator.plotEndPoint, pointArrayMapLength = indicator.pointArrayMap.length, position, point, i;
+        while (pointsLength--) {
+            point = points[pointsLength];
+            for (i = 0; i < pointArrayMapLength; i++) {
+                position = indicator.pointArrayMap[i];
+                if (defined(point[position])) {
+                    allPivotPoints[i].push({
+                        // Start left:
+                        plotX: point.plotX,
+                        plotY: point['plot' + position],
+                        isNull: false
+                    }, {
+                        // Go to right:
+                        plotX: endPoint,
+                        plotY: point['plot' + position],
+                        isNull: false
+                    }, {
+                        // And add null points in path to generate breaks:
+                        plotX: endPoint,
+                        plotY: null,
+                        isNull: true
+                    });
+                }
+            }
+            endPoint = point.plotX;
+        }
+        allPivotPoints.forEach(function (pivotPoints) {
+            path = path.concat(SMA.prototype.getGraphPath.call(indicator, pivotPoints));
+        });
+        return path;
+    },
+    // TODO: Rewrite this logic to use multiple datalabels
+    drawDataLabels: function () {
+        var indicator = this, pointMapping = indicator.pointArrayMap, currentLabel, pointsLength, point, i;
+        if (indicator.options.dataLabels.enabled) {
+            pointsLength = indicator.points.length;
+            // For every Ressitance/Support group we need to render labels.
+            // Add one more item, which will just store dataLabels from
+            // previous iteration
+            pointMapping.concat([false]).forEach(function (position, k) {
+                i = pointsLength;
+                while (i--) {
+                    point = indicator.points[i];
+                    if (!position) {
+                        // Store S4 dataLabel too:
+                        point['dataLabel' + pointMapping[k - 1]] =
+                            point.dataLabel;
+                    }
+                    else {
+                        point.y = point[position];
+                        point.pivotLine = position;
+                        point.plotY = point['plot' + position];
+                        currentLabel = point['dataLabel' + position];
+                        // Store previous label
+                        if (k) {
+                            point['dataLabel' + pointMapping[k - 1]] = point.dataLabel;
+                        }
+                        if (!point.dataLabels) {
+                            point.dataLabels = [];
+                        }
+                        point.dataLabels[0] = point.dataLabel =
+                            currentLabel =
+                                currentLabel && currentLabel.element ?
+                                    currentLabel :
+                                    null;
+                    }
+                }
+                SMA.prototype.drawDataLabels.apply(indicator, arguments);
+            });
+        }
+    },
+    getValues: function (series, params) {
+        var period = params.period, xVal = series.xData, yVal = series.yData, yValLen = yVal ? yVal.length : 0, placement = this[params.algorithm + 'Placement'], 
+        // 0- from, 1- to, 2- R1, 3- R2, 4- pivot, 5- S1 etc.
+        PP = [], endTimestamp, xData = [], yData = [], slicedXLen, slicedX, slicedY, lastPP, pivot, avg, i;
+        // Pivot Points requires high, low and close values
+        if (xVal.length < period ||
+            !isArray(yVal[0]) ||
+            yVal[0].length !== 4) {
+            return;
+        }
+        for (i = period + 1; i <= yValLen + period; i += period) {
+            slicedX = xVal.slice(i - period - 1, i);
+            slicedY = yVal.slice(i - period - 1, i);
+            slicedXLen = slicedX.length;
+            endTimestamp = slicedX[slicedXLen - 1];
+            pivot = this.getPivotAndHLC(slicedY);
+            avg = placement(pivot);
+            lastPP = PP.push([endTimestamp]
+                .concat(avg));
+            xData.push(endTimestamp);
+            yData.push(PP[lastPP - 1].slice(1));
+        }
+        // We don't know exact position in ordinal axis
+        // So we use simple logic:
+        // Get first point in last range, calculate visible average range
+        // and multiply by period
+        this.endPoint = slicedX[0] + ((endTimestamp - slicedX[0]) /
+            slicedXLen) * period;
+        return {
+            values: PP,
+            xData: xData,
+            yData: yData
+        };
+    },
+    getPivotAndHLC: function (values) {
+        var high = -Infinity, low = Infinity, close = values[values.length - 1][3], pivot;
+        values.forEach(function (p) {
+            high = Math.max(high, p[1]);
+            low = Math.min(low, p[2]);
+        });
+        pivot = (high + low + close) / 3;
+        return [pivot, high, low, close];
+    },
+    standardPlacement: function (values) {
+        var diff = values[1] - values[2], avg = [
+            null,
+            null,
+            values[0] + diff,
+            values[0] * 2 - values[2],
+            values[0],
+            values[0] * 2 - values[1],
+            values[0] - diff,
+            null,
+            null
+        ];
+        return avg;
+    },
+    camarillaPlacement: function (values) {
+        var diff = values[1] - values[2], avg = [
+            values[3] + diff * 1.5,
+            values[3] + diff * 1.25,
+            values[3] + diff * 1.1666,
+            values[3] + diff * 1.0833,
+            values[0],
+            values[3] - diff * 1.0833,
+            values[3] - diff * 1.1666,
+            values[3] - diff * 1.25,
+            values[3] - diff * 1.5
+        ];
+        return avg;
+    },
+    fibonacciPlacement: function (values) {
+        var diff = values[1] - values[2], avg = [
+            null,
+            values[0] + diff,
+            values[0] + diff * 0.618,
+            values[0] + diff * 0.382,
+            values[0],
+            values[0] - diff * 0.382,
+            values[0] - diff * 0.618,
+            values[0] - diff,
+            null
+        ];
+        return avg;
+    }
+}, 
+/**
+ * @lends Highcharts.Point#
+ */
+{
+    // Destroy labels:
+    // This method is called when cropping data:
+    destroyElements: function () {
+        destroyExtraLabels(this, 'destroyElements');
+    },
+    // This method is called when removing points, e.g. series.update()
+    destroy: function () {
+        destroyExtraLabels(this, 'destroyElements');
+    }
+});
+/**
+ * A pivot points indicator. If the [type](#series.pivotpoints.type) option is
+ * not specified, it is inherited from [chart.type](#chart.type).
+ *
+ * @extends   series,plotOptions.pivotpoints
+ * @since     6.0.0
+ * @product   highstock
+ * @excluding dataParser, dataURL
+ * @requires  stock/indicators/indicators
+ * @requires  stock/indicators/pivotpoints
+ * @apioption series.pivotpoints
+ */
+''; // to include the above in the js output'

+ 131 - 0
app/public/js/Highstock-8.0.0/code/es-modules/indicators/ppo.src.js

@@ -0,0 +1,131 @@
+/* *
+ *
+ *  License: www.highcharts.com/license
+ *
+ *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
+ *
+ * */
+'use strict';
+import H from '../parts/Globals.js';
+import U from '../parts/Utilities.js';
+var correctFloat = U.correctFloat;
+import requiredIndicatorMixin from '../mixins/indicator-required.js';
+var EMA = H.seriesTypes.ema, error = H.error, requiredIndicator = requiredIndicatorMixin;
+/**
+ * The PPO series type.
+ *
+ * @private
+ * @class
+ * @name Highcharts.seriesTypes.ppo
+ *
+ * @augments Highcharts.Series
+ */
+H.seriesType('ppo', 'ema', 
+/**
+ * Percentage Price Oscillator. This series requires the
+ * `linkedTo` option to be set and should be loaded after the
+ * `stock/indicators/indicators.js` and `stock/indicators/ema.js`.
+ *
+ * @sample {highstock} stock/indicators/ppo
+ *         Percentage Price Oscillator
+ *
+ * @extends      plotOptions.ema
+ * @since        7.0.0
+ * @product      highstock
+ * @excluding    allAreas, colorAxis, joinBy, keys, navigatorOptions,
+ *               pointInterval, pointIntervalUnit, pointPlacement,
+ *               pointRange, pointStart, showInNavigator, stacking
+ * @requires     stock/indicators/indicators
+ * @requires     stock/indicators/ema
+ * @requires     stock/indicators/ppo
+ * @optionparent plotOptions.ppo
+ */
+{
+    /**
+     * Paramters used in calculation of Percentage Price Oscillator series
+     * points.
+     *
+     * @excluding period
+     */
+    params: {
+        /**
+         * Periods for Percentage Price Oscillator calculations.
+         *
+         * @type    {Array<number>}
+         * @default [12, 26]
+         */
+        periods: [12, 26]
+    }
+}, 
+/**
+ * @lends Highcharts.Series.prototype
+ */
+{
+    nameBase: 'PPO',
+    nameComponents: ['periods'],
+    init: function () {
+        var args = arguments, ctx = this;
+        requiredIndicator.isParentLoaded(EMA, 'ema', ctx.type, function (indicator) {
+            indicator.prototype.init.apply(ctx, args);
+            return;
+        });
+    },
+    getValues: function (series, params) {
+        var periods = params.periods, index = params.index, 
+        // 0- date, 1- Percentage Price Oscillator
+        PPO = [], xData = [], yData = [], periodsOffset, 
+        // Shorter Period EMA
+        SPE, 
+        // Longer Period EMA
+        LPE, oscillator, i;
+        // Check if periods are correct
+        if (periods.length !== 2 || periods[1] <= periods[0]) {
+            error('Error: "PPO requires two periods. Notice, first period ' +
+                'should be lower than the second one."');
+            return;
+        }
+        SPE = EMA.prototype.getValues.call(this, series, {
+            index: index,
+            period: periods[0]
+        });
+        LPE = EMA.prototype.getValues.call(this, series, {
+            index: index,
+            period: periods[1]
+        });
+        // Check if ema is calculated properly, if not skip
+        if (!SPE || !LPE) {
+            return;
+        }
+        periodsOffset = periods[1] - periods[0];
+        for (i = 0; i < LPE.yData.length; i++) {
+            oscillator = correctFloat((SPE.yData[i + periodsOffset] -
+                LPE.yData[i]) /
+                LPE.yData[i] *
+                100);
+            PPO.push([LPE.xData[i], oscillator]);
+            xData.push(LPE.xData[i]);
+            yData.push(oscillator);
+        }
+        return {
+            values: PPO,
+            xData: xData,
+            yData: yData
+        };
+    }
+});
+/**
+ * A `Percentage Price Oscillator` series. If the [type](#series.ppo.type)
+ * option is not specified, it is inherited from [chart.type](#chart.type).
+ *
+ * @extends   series,plotOptions.ppo
+ * @since     7.0.0
+ * @product   highstock
+ * @excluding allAreas, colorAxis, dataParser, dataURL, joinBy, keys,
+ *            navigatorOptions, pointInterval, pointIntervalUnit,
+ *            pointPlacement, pointRange, pointStart, showInNavigator, stacking
+ * @requires  stock/indicators/indicators
+ * @requires  stock/indicators/ema
+ * @requires  stock/indicators/ppo
+ * @apioption series.ppo
+ */
+''; // to include the above in the js output

+ 135 - 0
app/public/js/Highstock-8.0.0/code/es-modules/indicators/price-channel.src.js

@@ -0,0 +1,135 @@
+/* *
+ *
+ *  License: www.highcharts.com/license
+ *
+ *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
+ *
+ * */
+'use strict';
+import H from '../parts/Globals.js';
+import '../parts/Utilities.js';
+import reduceArrayMixin from '../mixins/reduce-array.js';
+import multipleLinesMixin from '../mixins/multipe-lines.js';
+var getArrayExtremes = reduceArrayMixin.getArrayExtremes, merge = H.merge;
+/**
+ * The Price Channel series type.
+ *
+ * @private
+ * @class
+ * @name Highcharts.seriesTypes.pc
+ *
+ * @augments Highcharts.Series
+ */
+H.seriesType('pc', 'sma', 
+/**
+ * Price channel (PC). This series requires the `linkedTo` option to be
+ * set and should be loaded after the `stock/indicators/indicators.js`.
+ *
+ * @sample {highstock} stock/indicators/price-channel
+ *         Price Channel
+ *
+ * @extends      plotOptions.sma
+ * @since        7.0.0
+ * @product      highstock
+ * @excluding    allAreas, colorAxis, compare, compareBase, joinBy, keys,
+ *               navigatorOptions, pointInterval, pointIntervalUnit,
+ *               pointPlacement, pointRange, pointStart, showInNavigator,
+ *               stacking
+ * @requires     stock/indicators/indicators
+ * @requires     stock/indicators/price-channel
+ * @optionparent plotOptions.pc
+ */
+{
+    /**
+     * @excluding index
+     */
+    params: {
+        period: 20
+    },
+    lineWidth: 1,
+    topLine: {
+        styles: {
+            /**
+             * Color of the top line. If not set, it's inherited from
+             * [plotOptions.pc.color](#plotOptions.pc.color).
+             *
+             * @type {Highcharts.ColorString}
+             */
+            lineColor: '#7cb5ec #434348 #90ed7d #f7a35c #8085e9 #f15c80 #e4d354 #2b908f #f45b5b #91e8e1'.split(' ')[2],
+            /**
+             * Pixel width of the line.
+             */
+            lineWidth: 1
+        }
+    },
+    bottomLine: {
+        styles: {
+            /**
+             * Color of the bottom line. If not set, it's inherited from
+             * [plotOptions.pc.color](#plotOptions.pc.color).
+             *
+             * @type {Highcharts.ColorString}
+             */
+            lineColor: '#7cb5ec #434348 #90ed7d #f7a35c #8085e9 #f15c80 #e4d354 #2b908f #f45b5b #91e8e1'.split(' ')[8],
+            /**
+             * Pixel width of the line.
+             */
+            lineWidth: 1
+        }
+    },
+    dataGrouping: {
+        approximation: 'averages'
+    }
+}, 
+/**
+ * @lends Highcharts.Series#
+ */
+merge(multipleLinesMixin, {
+    pointArrayMap: ['top', 'middle', 'bottom'],
+    pointValKey: 'middle',
+    nameBase: 'Price Channel',
+    nameComponents: ['period'],
+    linesApiNames: ['topLine', 'bottomLine'],
+    getValues: function (series, params) {
+        var period = params.period, xVal = series.xData, yVal = series.yData, yValLen = yVal ? yVal.length : 0, 
+        // 0- date, 1-top line, 2-middle line, 3-bottom line
+        PC = [], 
+        // middle line, top line and bottom line
+        ML, TL, BL, date, low = 2, high = 1, xData = [], yData = [], slicedY, extremes, i;
+        if (yValLen < period) {
+            return;
+        }
+        for (i = period; i <= yValLen; i++) {
+            date = xVal[i - 1];
+            slicedY = yVal.slice(i - period, i);
+            extremes = getArrayExtremes(slicedY, low, high);
+            TL = extremes[1];
+            BL = extremes[0];
+            ML = (TL + BL) / 2;
+            PC.push([date, TL, ML, BL]);
+            xData.push(date);
+            yData.push([TL, ML, BL]);
+        }
+        return {
+            values: PC,
+            xData: xData,
+            yData: yData
+        };
+    }
+}));
+/**
+ * A Price channel indicator. If the [type](#series.pc.type) option is not
+ * specified, it is inherited from [chart.type](#chart.type).
+ *
+ * @extends      series,plotOptions.pc
+ * @since        7.0.0
+ * @product      highstock
+ * @excluding    allAreas, colorAxis, compare, compareBase, dataParser, dataURL,
+ *               joinBy, keys, navigatorOptions, pointInterval,
+ *               pointIntervalUnit, pointPlacement, pointRange, pointStart,
+ *               showInNavigator, stacking
+ * @requires     stock/indicators/indicators
+ * @requires     stock/indicators/price-channel
+ * @apioption    series.pc
+ */
+''; // to include the above in the js output

+ 213 - 0
app/public/js/Highstock-8.0.0/code/es-modules/indicators/price-envelopes.src.js

@@ -0,0 +1,213 @@
+/* *
+ *
+ *  License: www.highcharts.com/license
+ *
+ *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
+ *
+ * */
+'use strict';
+import H from '../parts/Globals.js';
+import U from '../parts/Utilities.js';
+var isArray = U.isArray;
+var merge = H.merge, SMA = H.seriesTypes.sma;
+/**
+ * The Price Envelopes series type.
+ *
+ * @private
+ * @class
+ * @name Highcharts.seriesTypes.priceenvelopes
+ *
+ * @augments Highcharts.Series
+ */
+H.seriesType('priceenvelopes', 'sma', 
+/**
+ * Price envelopes indicator based on [SMA](#plotOptions.sma) calculations.
+ * This series requires the `linkedTo` option to be set and should be loaded
+ * after the `stock/indicators/indicators.js` file.
+ *
+ * @sample stock/indicators/price-envelopes
+ *         Price envelopes
+ *
+ * @extends      plotOptions.sma
+ * @since        6.0.0
+ * @product      highstock
+ * @requires     stock/indicators/indicators
+ * @requires     stock/indicators/price-envelopes
+ * @optionparent plotOptions.priceenvelopes
+ */
+{
+    marker: {
+        enabled: false
+    },
+    tooltip: {
+        pointFormat: '<span style="color:{point.color}">\u25CF</span><b> {series.name}</b><br/>Top: {point.top}<br/>Middle: {point.middle}<br/>Bottom: {point.bottom}<br/>'
+    },
+    params: {
+        period: 20,
+        /**
+         * Percentage above the moving average that should be displayed.
+         * 0.1 means 110%. Relative to the calculated value.
+         */
+        topBand: 0.1,
+        /**
+         * Percentage below the moving average that should be displayed.
+         * 0.1 means 90%. Relative to the calculated value.
+         */
+        bottomBand: 0.1
+    },
+    /**
+     * Bottom line options.
+     */
+    bottomLine: {
+        styles: {
+            /**
+             * Pixel width of the line.
+             */
+            lineWidth: 1,
+            /**
+             * Color of the line. If not set, it's inherited from
+             * [plotOptions.priceenvelopes.color](
+             * #plotOptions.priceenvelopes.color).
+             *
+             * @type {Highcharts.ColorString}
+             */
+            lineColor: void 0
+        }
+    },
+    /**
+     * Top line options.
+     *
+     * @extends plotOptions.priceenvelopes.bottomLine
+     */
+    topLine: {
+        styles: {
+            lineWidth: 1
+        }
+    },
+    dataGrouping: {
+        approximation: 'averages'
+    }
+}, 
+/**
+ * @lends Highcharts.Series#
+ */
+{
+    nameComponents: ['period', 'topBand', 'bottomBand'],
+    nameBase: 'Price envelopes',
+    pointArrayMap: ['top', 'middle', 'bottom'],
+    parallelArrays: ['x', 'y', 'top', 'bottom'],
+    pointValKey: 'middle',
+    init: function () {
+        SMA.prototype.init.apply(this, arguments);
+        // Set default color for lines:
+        this.options = merge({
+            topLine: {
+                styles: {
+                    lineColor: this.color
+                }
+            },
+            bottomLine: {
+                styles: {
+                    lineColor: this.color
+                }
+            }
+        }, this.options);
+    },
+    toYData: function (point) {
+        return [point.top, point.middle, point.bottom];
+    },
+    translate: function () {
+        var indicator = this, translatedEnvelopes = ['plotTop', 'plotMiddle', 'plotBottom'];
+        SMA.prototype.translate.apply(indicator);
+        indicator.points.forEach(function (point) {
+            [point.top, point.middle, point.bottom].forEach(function (value, i) {
+                if (value !== null) {
+                    point[translatedEnvelopes[i]] =
+                        indicator.yAxis.toPixels(value, true);
+                }
+            });
+        });
+    },
+    drawGraph: function () {
+        var indicator = this, middleLinePoints = indicator.points, pointsLength = middleLinePoints.length, middleLineOptions = (indicator.options), middleLinePath = indicator.graph, gappedExtend = {
+            options: {
+                gapSize: middleLineOptions.gapSize
+            }
+        }, deviations = [[], []], // top and bottom point place holders
+        point;
+        // Generate points for top and bottom lines:
+        while (pointsLength--) {
+            point = middleLinePoints[pointsLength];
+            deviations[0].push({
+                plotX: point.plotX,
+                plotY: point.plotTop,
+                isNull: point.isNull
+            });
+            deviations[1].push({
+                plotX: point.plotX,
+                plotY: point.plotBottom,
+                isNull: point.isNull
+            });
+        }
+        // Modify options and generate lines:
+        ['topLine', 'bottomLine'].forEach(function (lineName, i) {
+            indicator.points = deviations[i];
+            indicator.options = merge(middleLineOptions[lineName].styles, gappedExtend);
+            indicator.graph = indicator['graph' + lineName];
+            SMA.prototype.drawGraph.call(indicator);
+            // Now save lines:
+            indicator['graph' + lineName] = indicator.graph;
+        });
+        // Restore options and draw a middle line:
+        indicator.points = middleLinePoints;
+        indicator.options = middleLineOptions;
+        indicator.graph = middleLinePath;
+        SMA.prototype.drawGraph.call(indicator);
+    },
+    getValues: function (series, params) {
+        var period = params.period, topPercent = params.topBand, botPercent = params.bottomBand, xVal = series.xData, yVal = series.yData, yValLen = yVal ? yVal.length : 0, 
+        // 0- date, 1-top line, 2-middle line, 3-bottom line
+        PE = [], 
+        // middle line, top line and bottom line
+        ML, TL, BL, date, xData = [], yData = [], slicedX, slicedY, point, i;
+        // Price envelopes requires close value
+        if (xVal.length < period ||
+            !isArray(yVal[0]) ||
+            yVal[0].length !== 4) {
+            return;
+        }
+        for (i = period; i <= yValLen; i++) {
+            slicedX = xVal.slice(i - period, i);
+            slicedY = yVal.slice(i - period, i);
+            point = SMA.prototype.getValues.call(this, {
+                xData: slicedX,
+                yData: slicedY
+            }, params);
+            date = point.xData[0];
+            ML = point.yData[0];
+            TL = ML * (1 + topPercent);
+            BL = ML * (1 - botPercent);
+            PE.push([date, TL, ML, BL]);
+            xData.push(date);
+            yData.push([TL, ML, BL]);
+        }
+        return {
+            values: PE,
+            xData: xData,
+            yData: yData
+        };
+    }
+});
+/**
+ * A price envelopes indicator. If the [type](#series.priceenvelopes.type)
+ * option is not specified, it is inherited from [chart.type](#chart.type).
+ *
+ * @extends   series,plotOptions.priceenvelopes
+ * @since     6.0.0
+ * @excluding dataParser, dataURL
+ * @product   highstock
+ * @requires  stock/indicators/indicators
+ * @requires  stock/indicators/price-envelopes
+ * @apioption series.priceenvelopes
+ */
+''; // to include the above in the js output

+ 231 - 0
app/public/js/Highstock-8.0.0/code/es-modules/indicators/psar.src.js

@@ -0,0 +1,231 @@
+/* *
+ *
+ *  Parabolic SAR indicator for Highstock
+ *
+ *  (c) 2010-2019 Grzegorz Blachliński
+ *
+ *  License: www.highcharts.com/license
+ *
+ *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
+ *
+ * */
+'use strict';
+import H from '../parts/Globals.js';
+import '../parts/Utilities.js';
+/* eslint-disable require-jsdoc */
+// Utils:
+function toFixed(a, n) {
+    return parseFloat(a.toFixed(n));
+}
+function calculateDirection(previousDirection, low, high, PSAR) {
+    if ((previousDirection === 1 && low > PSAR) ||
+        (previousDirection === -1 && high > PSAR)) {
+        return 1;
+    }
+    return -1;
+}
+/* *
+ * Method for calculating acceleration factor
+ * dir - direction
+ * pDir - previous Direction
+ * eP - extreme point
+ * pEP - previous extreme point
+ * inc - increment for acceleration factor
+ * maxAcc - maximum acceleration factor
+ * initAcc - initial acceleration factor
+ */
+function getAccelerationFactor(dir, pDir, eP, pEP, pAcc, inc, maxAcc, initAcc) {
+    if (dir === pDir) {
+        if (dir === 1 && (eP > pEP)) {
+            return (pAcc === maxAcc) ? maxAcc : toFixed(pAcc + inc, 2);
+        }
+        if (dir === -1 && (eP < pEP)) {
+            return (pAcc === maxAcc) ? maxAcc : toFixed(pAcc + inc, 2);
+        }
+        return pAcc;
+    }
+    return initAcc;
+}
+function getExtremePoint(high, low, previousDirection, previousExtremePoint) {
+    if (previousDirection === 1) {
+        return (high > previousExtremePoint) ? high : previousExtremePoint;
+    }
+    return (low < previousExtremePoint) ? low : previousExtremePoint;
+}
+function getEPMinusPSAR(EP, PSAR) {
+    return EP - PSAR;
+}
+function getAccelerationFactorMultiply(accelerationFactor, EPMinusSAR) {
+    return accelerationFactor * EPMinusSAR;
+}
+/* *
+ * Method for calculating PSAR
+ * pdir - previous direction
+ * sDir - second previous Direction
+ * PSAR - previous PSAR
+ * pACCMultiply - previous acceleration factor multiply
+ * sLow - second previous low
+ * pLow - previous low
+ * sHigh - second previous high
+ * pHigh - previous high
+ * pEP - previous extreme point
+ */
+function getPSAR(pdir, sDir, PSAR, pACCMulti, sLow, pLow, pHigh, sHigh, pEP) {
+    if (pdir === sDir) {
+        if (pdir === 1) {
+            return (PSAR + pACCMulti < Math.min(sLow, pLow)) ?
+                PSAR + pACCMulti :
+                Math.min(sLow, pLow);
+        }
+        return (PSAR + pACCMulti > Math.max(sHigh, pHigh)) ?
+            PSAR + pACCMulti :
+            Math.max(sHigh, pHigh);
+    }
+    return pEP;
+}
+/* eslint-enable require-jsdoc */
+/**
+ * The Parabolic SAR series type.
+ *
+ * @private
+ * @class
+ * @name Highcharts.seriesTypes.psar
+ *
+ * @augments Highcharts.Series
+ */
+H.seriesType('psar', 'sma', 
+/**
+ * Parabolic SAR. This series requires `linkedTo`
+ * option to be set and should be loaded
+ * after `stock/indicators/indicators.js` file.
+ *
+ * @sample stock/indicators/psar
+ *         Parabolic SAR Indicator
+ *
+ * @extends      plotOptions.sma
+ * @since        6.0.0
+ * @product      highstock
+ * @requires     stock/indicators/indicators
+ * @requires     stock/indicators/psar
+ * @optionparent plotOptions.psar
+ */
+{
+    lineWidth: 0,
+    marker: {
+        enabled: true
+    },
+    states: {
+        hover: {
+            lineWidthPlus: 0
+        }
+    },
+    /**
+     * @excluding period
+     */
+    params: {
+        /**
+         * The initial value for acceleration factor.
+         * Acceleration factor is starting with this value
+         * and increases by specified increment each time
+         * the extreme point makes a new high.
+         * AF can reach a maximum of maxAccelerationFactor,
+         * no matter how long the uptrend extends.
+         */
+        initialAccelerationFactor: 0.02,
+        /**
+         * The Maximum value for acceleration factor.
+         * AF can reach a maximum of maxAccelerationFactor,
+         * no matter how long the uptrend extends.
+         */
+        maxAccelerationFactor: 0.2,
+        /**
+         * Acceleration factor increases by increment each time
+         * the extreme point makes a new high.
+         *
+         * @since 6.0.0
+         */
+        increment: 0.02,
+        /**
+         * Index from which PSAR is starting calculation
+         *
+         * @since 6.0.0
+         */
+        index: 2,
+        /**
+         * Number of maximum decimals that are used in PSAR calculations.
+         *
+         * @since 6.0.0
+         */
+        decimals: 4
+    }
+}, {
+    nameComponents: false,
+    getValues: function (series, params) {
+        var xVal = series.xData, yVal = series.yData, 
+        // Extreme point is the lowest low for falling and highest high
+        // for rising psar - and we are starting with falling
+        extremePoint = yVal[0][1], accelerationFactor = params.initialAccelerationFactor, maxAccelerationFactor = params.maxAccelerationFactor, increment = params.increment, 
+        // Set initial acc factor (for every new trend!)
+        initialAccelerationFactor = params.initialAccelerationFactor, PSAR = yVal[0][2], decimals = params.decimals, index = params.index, PSARArr = [], xData = [], yData = [], previousDirection = 1, direction, EPMinusPSAR, accelerationFactorMultiply, newDirection, prevLow, prevPrevLow, prevHigh, prevPrevHigh, newExtremePoint, high, low, ind;
+        if (index >= yVal.length) {
+            return;
+        }
+        for (ind = 0; ind < index; ind++) {
+            extremePoint = Math.max(yVal[ind][1], extremePoint);
+            PSAR = Math.min(yVal[ind][2], toFixed(PSAR, decimals));
+        }
+        direction = (yVal[ind][1] > PSAR) ? 1 : -1;
+        EPMinusPSAR = getEPMinusPSAR(extremePoint, PSAR);
+        accelerationFactor = params.initialAccelerationFactor;
+        accelerationFactorMultiply = getAccelerationFactorMultiply(accelerationFactor, EPMinusPSAR);
+        PSARArr.push([xVal[index], PSAR]);
+        xData.push(xVal[index]);
+        yData.push(toFixed(PSAR, decimals));
+        for (ind = index + 1; ind < yVal.length; ind++) {
+            prevLow = yVal[ind - 1][2];
+            prevPrevLow = yVal[ind - 2][2];
+            prevHigh = yVal[ind - 1][1];
+            prevPrevHigh = yVal[ind - 2][1];
+            high = yVal[ind][1];
+            low = yVal[ind][2];
+            // Null points break PSAR
+            if (prevPrevLow !== null &&
+                prevPrevHigh !== null &&
+                prevLow !== null &&
+                prevHigh !== null &&
+                high !== null &&
+                low !== null) {
+                PSAR = getPSAR(direction, previousDirection, PSAR, accelerationFactorMultiply, prevPrevLow, prevLow, prevHigh, prevPrevHigh, extremePoint);
+                newExtremePoint = getExtremePoint(high, low, direction, extremePoint);
+                newDirection = calculateDirection(previousDirection, low, high, PSAR);
+                accelerationFactor = getAccelerationFactor(newDirection, direction, newExtremePoint, extremePoint, accelerationFactor, increment, maxAccelerationFactor, initialAccelerationFactor);
+                EPMinusPSAR = getEPMinusPSAR(newExtremePoint, PSAR);
+                accelerationFactorMultiply = getAccelerationFactorMultiply(accelerationFactor, EPMinusPSAR);
+                PSARArr.push([xVal[ind], toFixed(PSAR, decimals)]);
+                xData.push(xVal[ind]);
+                yData.push(toFixed(PSAR, decimals));
+                previousDirection = direction;
+                direction = newDirection;
+                extremePoint = newExtremePoint;
+            }
+        }
+        return {
+            values: PSARArr,
+            xData: xData,
+            yData: yData
+        };
+    }
+});
+/**
+ * A `PSAR` series. If the [type](#series.psar.type) option is not specified, it
+ * is inherited from [chart.type](#chart.type).
+ *
+ * @extends   series,plotOptions.psar
+ * @since     6.0.0
+ * @product   highstock
+ * @excluding dataParser, dataURL
+ * @requires  stock/indicators/indicators
+ * @requires  stock/indicators/psar
+ * @apioption series.psar
+ */
+''; // to include the above in the js output

+ 377 - 0
app/public/js/Highstock-8.0.0/code/es-modules/indicators/regressions.src.js

@@ -0,0 +1,377 @@
+/**
+ *
+ *  (c) 2010-2019 Kamil Kulig
+ *
+ *  License: www.highcharts.com/license
+ *
+ *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
+ *
+ * */
+'use strict';
+import H from '../parts/Globals.js';
+import U from '../parts/Utilities.js';
+var isArray = U.isArray;
+var seriesType = H.seriesType;
+/**
+ * Linear regression series type.
+ *
+ * @private
+ * @class
+ * @name Highcharts.seriesTypes.linearregression
+ *
+ * @augments Highcharts.Series
+ */
+seriesType('linearRegression', 'sma', 
+/**
+ * Linear regression indicator. This series requires `linkedTo` option to be
+ * set.
+ *
+ * @sample {highstock} stock/indicators/linear-regression
+ *         Linear regression indicator
+ *
+ * @extends      plotOptions.sma
+ * @since        7.0.0
+ * @product      highstock
+ * @requires     stock/indicators/indicators
+ * @requires     stock/indicators/regressions
+ * @optionparent plotOptions.linearregression
+ */
+{
+    params: {
+        /**
+         * Unit (in milliseconds) for the x axis distances used to compute
+         * the regression line paramters (slope & intercept) for every
+         * range. In Highstock the x axis values are always represented in
+         * milliseconds which may cause that distances between points are
+         * "big" integer numbers.
+         *
+         * Highstock's linear regression algorithm (least squares method)
+         * will utilize these "big" integers for finding the slope and the
+         * intercept of the regression line for each period. In consequence,
+         * this value may be a very "small" decimal number that's hard to
+         * interpret by a human.
+         *
+         * For instance: `xAxisUnit` equealed to `86400000` ms (1 day)
+         * forces the algorithm to treat `86400000` as `1` while computing
+         * the slope and the intercept. This may enchance the legiblitity of
+         * the indicator's values.
+         *
+         * Default value is the closest distance between two data points.
+         *
+         * @sample {highstock} stock/plotoptions/linear-regression-xaxisunit
+         *         xAxisUnit set to 1 minute
+         *
+         * @example
+         * // In Liniear Regression Slope Indicator series `xAxisUnit` is
+         * // `86400000` (1 day) and period is `3`. There're 3 points in the
+         * // base series:
+         *
+         * data: [
+         *   [Date.UTC(2019, 0, 1), 1],
+         *   [Date.UTC(2019, 0, 2), 3],
+         *   [Date.UTC(2019, 0, 3), 5]
+         * ]
+         *
+         * // This will produce one point in the indicator series that has a
+         * // `y` value of `2` (slope of the regression line). If we change
+         * // the `xAxisUnit` to `1` (ms) the value of the indicator's point
+         * // will be `2.3148148148148148e-8` which is harder to interpert
+         * // for a human.
+         *
+         * @type    {number}
+         * @product highstock
+         */
+        xAxisUnit: void 0
+    },
+    tooltip: {
+        valueDecimals: 4
+    }
+}, 
+/**
+ * @lends Highcharts.Series#
+ */
+{
+    nameBase: 'Linear Regression Indicator',
+    /**
+     * Return the slope and intercept of a straight line function.
+     * @private
+     * @param {Highcharts.LinearRegressionIndicator} this indicator to use
+     * @param {Array<number>} xData -  list of all x coordinates in a period
+     * @param {Array<number>} yData - list of all y coordinates in a period
+     * @return {Highcharts.RegressionLineParametersObject}
+     *          object that contains the slope and the intercept
+     *          of a straight line function
+     */
+    getRegressionLineParameters: function (xData, yData) {
+        // least squares method
+        var yIndex = this.options.params.index, getSingleYValue = function (yValue, yIndex) {
+            return isArray(yValue) ? yValue[yIndex] : yValue;
+        }, xSum = xData.reduce(function (accX, val) {
+            return val + accX;
+        }, 0), ySum = yData.reduce(function (accY, val) {
+            return getSingleYValue(val, yIndex) + accY;
+        }, 0), xMean = xSum / xData.length, yMean = ySum / yData.length, xError, yError, formulaNumerator = 0, formulaDenominator = 0, i, slope;
+        for (i = 0; i < xData.length; i++) {
+            xError = xData[i] - xMean;
+            yError = getSingleYValue(yData[i], yIndex) - yMean;
+            formulaNumerator += xError * yError;
+            formulaDenominator += Math.pow(xError, 2);
+        }
+        slope = formulaDenominator ?
+            formulaNumerator / formulaDenominator : 0; // don't divide by 0
+        return {
+            slope: slope,
+            intercept: yMean - slope * xMean
+        };
+    },
+    /**
+     * Return the y value on a straight line.
+     * @private
+     * @param {Highcharts.RegressionLineParametersObject} lineParameters
+     *          object that contains the slope and the intercept
+     *          of a straight line function
+     * @param {number} endPointX - x coordinate of the point
+     * @return {number} - y value of the point that lies on the line
+     */
+    getEndPointY: function (lineParameters, endPointX) {
+        return lineParameters.slope * endPointX + lineParameters.intercept;
+    },
+    /**
+     * Transform the coordinate system so that x values start at 0 and
+     * apply xAxisUnit.
+     * @private
+     * @param {Array<number>} xData - list of all x coordinates in a period
+     * @param {number} xAxisUnit - option (see the API)
+     * @return {Array<number>} - array of transformed x data
+     */
+    transformXData: function (xData, xAxisUnit) {
+        var xOffset = xData[0];
+        return xData.map(function (xValue) {
+            return (xValue - xOffset) / xAxisUnit;
+        });
+    },
+    /**
+     * Find the closest distance between points in the base series.
+     * @private
+     * @param {Array<number>} xData
+                list of all x coordinates in the base series
+     * @return {number} - closest distance between points in the base series
+     */
+    findClosestDistance: function (xData) {
+        var distance, closestDistance, i;
+        for (i = 1; i < xData.length - 1; i++) {
+            distance = xData[i] - xData[i - 1];
+            if (distance > 0 &&
+                (typeof closestDistance === 'undefined' ||
+                    distance < closestDistance)) {
+                closestDistance = distance;
+            }
+        }
+        return closestDistance;
+    },
+    // Required to be implemented - starting point for indicator's logic
+    getValues: function (baseSeries, regressionSeriesParams) {
+        var xData = baseSeries.xData, yData = baseSeries.yData, period = regressionSeriesParams.period, lineParameters, i, periodStart, periodEnd, 
+        // format required to be returned
+        indicatorData = {
+            xData: [],
+            yData: [],
+            values: []
+        }, endPointX, endPointY, periodXData, periodYData, periodTransformedXData, xAxisUnit = this.options.params.xAxisUnit ||
+            this.findClosestDistance(xData);
+        // Iteration logic: x value of the last point within the period
+        // (end point) is used to represent the y value (regression)
+        // of the entire period.
+        for (i = period - 1; i <= xData.length - 1; i++) {
+            periodStart = i - period + 1; // adjusted for slice() function
+            periodEnd = i + 1; // (as above)
+            endPointX = xData[i];
+            periodXData = xData.slice(periodStart, periodEnd);
+            periodYData = yData.slice(periodStart, periodEnd);
+            periodTransformedXData = this.transformXData(periodXData, xAxisUnit);
+            lineParameters = this.getRegressionLineParameters(periodTransformedXData, periodYData);
+            endPointY = this.getEndPointY(lineParameters, periodTransformedXData[periodTransformedXData.length - 1]);
+            // @todo this is probably not used anywhere
+            indicatorData.values.push({
+                regressionLineParameters: lineParameters,
+                x: endPointX,
+                y: endPointY
+            });
+            indicatorData.xData.push(endPointX);
+            indicatorData.yData.push(endPointY);
+        }
+        return indicatorData;
+    }
+});
+/**
+ * A linear regression series. If the [type](#series.linearregression.type)
+ * option is not specified, it is inherited from [chart.type](#chart.type).
+ *
+ * @extends   series,plotOptions.linearregression
+ * @since     7.0.0
+ * @product   highstock
+ * @excluding dataParser,dataURL
+ * @requires  stock/indicators/indicators
+ * @requires  stock/indicators/regressions
+ * @apioption series.linearregression
+ */
+/* ************************************************************************** */
+/**
+ * The Linear Regression Slope series type.
+ *
+ * @private
+ * @class
+ * @name Highcharts.seriesTypes.linearRegressionSlope
+ *
+ * @augments Highcharts.Series
+ */
+seriesType('linearRegressionSlope', 'linearRegression', 
+/**
+ * Linear regression slope indicator. This series requires `linkedTo`
+ * option to be set.
+ *
+ * @sample {highstock} stock/indicators/linear-regression-slope
+ *         Linear regression slope indicator
+ *
+ * @extends      plotOptions.linearregression
+ * @since        7.0.0
+ * @product      highstock
+ * @requires     stock/indicators/indicators
+ * @requires     stock/indicators/regressions
+ * @optionparent plotOptions.linearregressionslope
+ */
+{}, 
+/**
+ * @lends Highcharts.Series#
+ */
+{
+    nameBase: 'Linear Regression Slope Indicator',
+    getEndPointY: function (lineParameters) {
+        return lineParameters.slope;
+    }
+});
+/**
+ * A linear regression slope series. If the
+ * [type](#series.linearregressionslope.type) option is not specified, it is
+ * inherited from [chart.type](#chart.type).
+ *
+ * @extends   series,plotOptions.linearregressionslope
+ * @since     7.0.0
+ * @product   highstock
+ * @excluding dataParser,dataURL
+ * @requires  stock/indicators/indicators
+ * @requires  stock/indicators/regressions
+ * @apioption series.linearregressionslope
+ */
+/* ************************************************************************** */
+/**
+ * The Linear Regression Intercept series type.
+ *
+ * @private
+ * @class
+ * @name Highcharts.seriesTypes.linearRegressionIntercept
+ *
+ * @augments Highcharts.Series
+ */
+seriesType('linearRegressionIntercept', 'linearRegression', 
+/**
+ * Linear regression intercept indicator. This series requires `linkedTo`
+ * option to be set.
+ *
+ * @sample {highstock} stock/indicators/linear-regression-intercept
+ *         Linear intercept slope indicator
+ *
+ * @extends      plotOptions.linearregression
+ * @since        7.0.0
+ * @product      highstock
+ * @requires     stock/indicators/indicators
+ * @requires     stock/indicators/regressions
+ * @optionparent plotOptions.linearregressionintercept
+ */
+{}, 
+/**
+ * @lends Highcharts.Series#
+ */
+{
+    nameBase: 'Linear Regression Intercept Indicator',
+    getEndPointY: function (lineParameters) {
+        return lineParameters.intercept;
+    }
+});
+/**
+ * A linear regression intercept series. If the
+ * [type](#series.linearregressionintercept.type) option is not specified, it is
+ * inherited from [chart.type](#chart.type).
+ *
+ * @extends   series,plotOptions.linearregressionintercept
+ * @since     7.0.0
+ * @product   highstock
+ * @excluding dataParser,dataURL
+ * @requires  stock/indicators/indicators
+ * @requires  stock/indicators/regressions
+ * @apioption series.linearregressionintercept
+ */
+/* ************************************************************************** */
+/**
+ * The Linear Regression Angle series type.
+ *
+ * @private
+ * @class
+ * @name Highcharts.seriesTypes.linearRegressionAngle
+ *
+ * @augments Highcharts.Series
+ */
+seriesType('linearRegressionAngle', 'linearRegression', 
+/**
+ * Linear regression angle indicator. This series requires `linkedTo`
+ * option to be set.
+ *
+ * @sample {highstock} stock/indicators/linear-regression-angle
+ *         Linear intercept angle indicator
+ *
+ * @extends      plotOptions.linearregression
+ * @since        7.0.0
+ * @product      highstock
+ * @requires     stock/indicators/indicators
+ * @requires     stock/indicators/regressions
+ * @optionparent plotOptions.linearregressionangle
+ */
+{
+    tooltip: {
+        pointFormat: '<span style="color:{point.color}">\u25CF</span>' +
+            '{series.name}: <b>{point.y}°</b><br/>'
+    }
+}, 
+/**
+ * @lends Highcharts.Series#
+ */
+{
+    nameBase: 'Linear Regression Angle Indicator',
+    /**
+    * Convert a slope of a line to angle (in degrees) between
+    * the line and x axis
+    * @private
+    * @param {number} slope of the straight line function
+    * @return {number} angle in degrees
+    */
+    slopeToAngle: function (slope) {
+        return Math.atan(slope) * (180 / Math.PI); // rad to deg
+    },
+    getEndPointY: function (lineParameters) {
+        return this.slopeToAngle(lineParameters.slope);
+    }
+});
+/**
+ * A linear regression intercept series. If the
+ * [type](#series.linearregressionangle.type) option is not specified, it is
+ * inherited from [chart.type](#chart.type).
+ *
+ * @extends   series,plotOptions.linearregressionangle
+ * @since     7.0.0
+ * @product   highstock
+ * @excluding dataParser,dataURL
+ * @requires  stock/indicators/indicators
+ * @requires  stock/indicators/regressions
+ * @apioption series.linearregressionangle
+ */
+''; // to include the above in the js output

+ 134 - 0
app/public/js/Highstock-8.0.0/code/es-modules/indicators/roc.src.js

@@ -0,0 +1,134 @@
+/* *
+ *
+ *  (c) 2010-2019 Kacper Madej
+ *
+ *  License: www.highcharts.com/license
+ *
+ *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
+ *
+ * */
+'use strict';
+import H from '../parts/Globals.js';
+import U from '../parts/Utilities.js';
+var isArray = U.isArray;
+var seriesType = H.seriesType;
+/* eslint-disable require-jsdoc */
+// Utils:
+function populateAverage(xVal, yVal, i, period, index) {
+    /* Calculated as:
+
+       (Closing Price [today] - Closing Price [n days ago]) /
+        Closing Price [n days ago] * 100
+
+       Return y as null when avoiding division by zero */
+    var nDaysAgoY, rocY;
+    if (index < 0) {
+        // y data given as an array of values
+        nDaysAgoY = yVal[i - period];
+        rocY = nDaysAgoY ?
+            (yVal[i] - nDaysAgoY) / nDaysAgoY * 100 :
+            null;
+    }
+    else {
+        // y data given as an array of arrays and the index should be used
+        nDaysAgoY = yVal[i - period][index];
+        rocY = nDaysAgoY ?
+            (yVal[i][index] - nDaysAgoY) / nDaysAgoY * 100 :
+            null;
+    }
+    return [xVal[i], rocY];
+}
+/* eslint-enable require-jsdoc */
+/**
+ * The ROC series type.
+ *
+ * @private
+ * @class
+ * @name Highcharts.seriesTypes.roc
+ *
+ * @augments Highcharts.Series
+ */
+seriesType('roc', 'sma', 
+/**
+ * Rate of change indicator (ROC). The indicator value for each point
+ * is defined as:
+ *
+ * `(C - Cn) / Cn * 100`
+ *
+ * where: `C` is the close value of the point of the same x in the
+ * linked series and `Cn` is the close value of the point `n` periods
+ * ago. `n` is set through [period](#plotOptions.roc.params.period).
+ *
+ * This series requires `linkedTo` option to be set.
+ *
+ * @sample stock/indicators/roc
+ *         Rate of change indicator
+ *
+ * @extends      plotOptions.sma
+ * @since        6.0.0
+ * @product      highstock
+ * @requires     stock/indicators/indicators
+ * @requires     stock/indicators/roc
+ * @optionparent plotOptions.roc
+ */
+{
+    params: {
+        index: 3,
+        period: 9
+    }
+}, 
+/**
+ * @lends Highcharts.Series#
+ */
+{
+    nameBase: 'Rate of Change',
+    getValues: function (series, params) {
+        var period = params.period, xVal = series.xData, yVal = series.yData, yValLen = yVal ? yVal.length : 0, ROC = [], xData = [], yData = [], i, index = -1, ROCPoint;
+        // Period is used as a number of time periods ago, so we need more
+        // (at least 1 more) data than the period value
+        if (xVal.length <= period) {
+            return;
+        }
+        // Switch index for OHLC / Candlestick / Arearange
+        if (isArray(yVal[0])) {
+            index = params.index;
+        }
+        // i = period <-- skip first N-points
+        // Calculate value one-by-one for each period in visible data
+        for (i = period; i < yValLen; i++) {
+            ROCPoint = populateAverage(xVal, yVal, i, period, index);
+            ROC.push(ROCPoint);
+            xData.push(ROCPoint[0]);
+            yData.push(ROCPoint[1]);
+        }
+        return {
+            values: ROC,
+            xData: xData,
+            yData: yData
+        };
+    }
+});
+/**
+ * A `ROC` series. If the [type](#series.wma.type) option is not
+ * specified, it is inherited from [chart.type](#chart.type).
+ *
+ * Rate of change indicator (ROC). The indicator value for each point
+ * is defined as:
+ *
+ * `(C - Cn) / Cn * 100`
+ *
+ * where: `C` is the close value of the point of the same x in the
+ * linked series and `Cn` is the close value of the point `n` periods
+ * ago. `n` is set through [period](#series.roc.params.period).
+ *
+ * This series requires `linkedTo` option to be set.
+ *
+ * @extends   series,plotOptions.roc
+ * @since     6.0.0
+ * @product   highstock
+ * @excluding dataParser, dataURL
+ * @requires  stock/indicators/indicators
+ * @requires  stock/indicators/roc
+ * @apioption series.roc
+ */
+''; // to include the above in the js output

+ 132 - 0
app/public/js/Highstock-8.0.0/code/es-modules/indicators/rsi.src.js

@@ -0,0 +1,132 @@
+/* *
+ *
+ *  License: www.highcharts.com/license
+ *
+ *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
+ *
+ * */
+'use strict';
+import H from '../parts/Globals.js';
+import U from '../parts/Utilities.js';
+var isArray = U.isArray;
+/* eslint-disable require-jsdoc */
+// Utils:
+function toFixed(a, n) {
+    return parseFloat(a.toFixed(n));
+}
+/* eslint-enable require-jsdoc */
+/**
+ * The RSI series type.
+ *
+ * @private
+ * @class
+ * @name Highcharts.seriesTypes.rsi
+ *
+ * @augments Highcharts.Series
+ */
+H.seriesType('rsi', 'sma', 
+/**
+ * Relative strength index (RSI) technical indicator. This series
+ * requires the `linkedTo` option to be set and should be loaded after
+ * the `stock/indicators/indicators.js` file.
+ *
+ * @sample stock/indicators/rsi
+ *         RSI indicator
+ *
+ * @extends      plotOptions.sma
+ * @since        6.0.0
+ * @product      highstock
+ * @requires     stock/indicators/indicators
+ * @requires     stock/indicators/rsi
+ * @optionparent plotOptions.rsi
+ */
+{
+    /**
+     * @excluding index
+     */
+    params: {
+        period: 14,
+        /**
+         * Number of maximum decimals that are used in RSI calculations.
+         */
+        decimals: 4
+    }
+}, 
+/**
+ * @lends Highcharts.Series#
+ */
+{
+    getValues: function (series, params) {
+        var period = params.period, xVal = series.xData, yVal = series.yData, yValLen = yVal ? yVal.length : 0, decimals = params.decimals, 
+        // RSI starts calculations from the second point
+        // Cause we need to calculate change between two points
+        range = 1, RSI = [], xData = [], yData = [], index = 3, gain = 0, loss = 0, RSIPoint, change, avgGain, avgLoss, i;
+        // RSI requires close value
+        if ((xVal.length < period) || !isArray(yVal[0]) ||
+            yVal[0].length !== 4) {
+            return;
+        }
+        // Calculate changes for first N points
+        while (range < period) {
+            change = toFixed(yVal[range][index] - yVal[range - 1][index], decimals);
+            if (change > 0) {
+                gain += change;
+            }
+            else {
+                loss += Math.abs(change);
+            }
+            range++;
+        }
+        // Average for first n-1 points:
+        avgGain = toFixed(gain / (period - 1), decimals);
+        avgLoss = toFixed(loss / (period - 1), decimals);
+        for (i = range; i < yValLen; i++) {
+            change = toFixed(yVal[i][index] - yVal[i - 1][index], decimals);
+            if (change > 0) {
+                gain = change;
+                loss = 0;
+            }
+            else {
+                gain = 0;
+                loss = Math.abs(change);
+            }
+            // Calculate smoothed averages, RS, RSI values:
+            avgGain = toFixed((avgGain * (period - 1) + gain) / period, decimals);
+            avgLoss = toFixed((avgLoss * (period - 1) + loss) / period, decimals);
+            // If average-loss is equal zero, then by definition RSI is set
+            // to 100:
+            if (avgLoss === 0) {
+                RSIPoint = 100;
+                // If average-gain is equal zero, then by definition RSI is set
+                // to 0:
+            }
+            else if (avgGain === 0) {
+                RSIPoint = 0;
+            }
+            else {
+                RSIPoint = toFixed(100 - (100 / (1 + (avgGain / avgLoss))), decimals);
+            }
+            RSI.push([xVal[i], RSIPoint]);
+            xData.push(xVal[i]);
+            yData.push(RSIPoint);
+        }
+        return {
+            values: RSI,
+            xData: xData,
+            yData: yData
+        };
+    }
+});
+/**
+ * A `RSI` series. If the [type](#series.rsi.type) option is not
+ * specified, it is inherited from [chart.type](#chart.type).
+ *
+ * @extends   series,plotOptions.rsi
+ * @since     6.0.0
+ * @product   highstock
+ * @excluding dataParser, dataURL
+ * @requires  stock/indicators/indicators
+ * @requires  stock/indicators/rsi
+ * @apioption series.rsi
+ */
+''; // to include the above in the js output

+ 112 - 0
app/public/js/Highstock-8.0.0/code/es-modules/indicators/slow-stochastic.src.js

@@ -0,0 +1,112 @@
+/* *
+ *
+ *  License: www.highcharts.com/license
+ *
+ *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
+ *
+ * */
+'use strict';
+import H from '../parts/Globals.js';
+import requiredIndicator from '../mixins/indicator-required.js';
+var seriesTypes = H.seriesTypes;
+/**
+ * The Slow Stochastic series type.
+ *
+ * @private
+ * @class
+ * @name Highcharts.seriesTypes.slowstochastic
+ *
+ * @augments Highcharts.Series
+ */
+H.seriesType('slowstochastic', 'stochastic', 
+/**
+ * Slow Stochastic oscillator. This series requires the `linkedTo` option
+ * to be set and should be loaded after `stock/indicators/indicators.js`
+ * and `stock/indicators/stochastic.js` files.
+ *
+ * @sample stock/indicators/slow-stochastic
+ *         Slow Stochastic oscillator
+ *
+ * @extends      plotOptions.stochastic
+ * @since        8.0.0
+ * @product      highstock
+ * @requires     stock/indicators/indicators
+ * @requires     stock/indicators/stochastic
+ * @requires     stock/indicators/slowstochastic
+ * @optionparent plotOptions.slowstochastic
+ */
+{
+    params: {
+        /**
+         * Periods for Slow Stochastic oscillator: [%K, %D, SMA(%D)].
+         *
+         * @type    {Array<number,number,number>}
+         * @default [14, 3, 3]
+         */
+        periods: [14, 3, 3]
+    }
+}, 
+/**
+ * @lends Highcharts.Series#
+ */
+{
+    nameBase: 'Slow Stochastic',
+    init: function () {
+        var args = arguments, ctx = this;
+        requiredIndicator.isParentLoaded(H.seriesTypes.stochastic, 'stochastic', ctx.type, function (indicator) {
+            indicator.prototype.init.apply(ctx, args);
+            return;
+        });
+    },
+    getValues: function (series, params) {
+        var periods = params.periods, fastValues = seriesTypes.stochastic.prototype.getValues.call(this, series, params), slowValues = {
+            values: [],
+            xData: [],
+            yData: []
+        };
+        var i = 0;
+        if (!fastValues) {
+            return;
+        }
+        slowValues.xData = fastValues.xData.slice(periods[1] - 1);
+        var fastYData = fastValues.yData.slice(periods[1] - 1);
+        // Get SMA(%D)
+        var smoothedValues = seriesTypes.sma.prototype.getValues.call(this, {
+            xData: slowValues.xData,
+            yData: fastYData
+        }, {
+            index: 1,
+            period: periods[2]
+        });
+        if (!smoothedValues) {
+            return;
+        }
+        var xDataLen = slowValues.xData.length;
+        // Format data
+        for (; i < xDataLen; i++) {
+            slowValues.yData[i] = [
+                fastYData[i][1],
+                smoothedValues.yData[i - periods[2] + 1] || null
+            ];
+            slowValues.values[i] = [
+                slowValues.xData[i],
+                fastYData[i][1],
+                smoothedValues.yData[i - periods[2] + 1] || null
+            ];
+        }
+        return slowValues;
+    }
+});
+/**
+ * A Slow Stochastic indicator. If the [type](#series.slowstochastic.type)
+ * option is not specified, it is inherited from [chart.type](#chart.type).
+ *
+ * @extends   series,plotOptions.slowstochastic
+ * @since     8.0.0
+ * @product   highstock
+ * @requires  stock/indicators/indicators
+ * @requires  stock/indicators/stochastic
+ * @requires  stock/indicators/slowstochastic
+ * @apioption series.slowstochastic
+ */
+''; // to include the above in the js output

+ 165 - 0
app/public/js/Highstock-8.0.0/code/es-modules/indicators/stochastic.src.js

@@ -0,0 +1,165 @@
+/* *
+ *
+ *  License: www.highcharts.com/license
+ *
+ *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
+ *
+ * */
+'use strict';
+import H from '../parts/Globals.js';
+import U from '../parts/Utilities.js';
+var isArray = U.isArray;
+import reduceArrayMixin from '../mixins/reduce-array.js';
+import multipleLinesMixin from '../mixins/multipe-lines.js';
+var merge = H.merge, SMA = H.seriesTypes.sma, getArrayExtremes = reduceArrayMixin.getArrayExtremes;
+/**
+ * The Stochastic series type.
+ *
+ * @private
+ * @class
+ * @name Highcharts.seriesTypes.stochastic
+ *
+ * @augments Highcharts.Series
+ */
+H.seriesType('stochastic', 'sma', 
+/**
+ * Stochastic oscillator. This series requires the `linkedTo` option to be
+ * set and should be loaded after the `stock/indicators/indicators.js` file.
+ *
+ * @sample stock/indicators/stochastic
+ *         Stochastic oscillator
+ *
+ * @extends      plotOptions.sma
+ * @since        6.0.0
+ * @product      highstock
+ * @excluding    allAreas, colorAxis, joinBy, keys, navigatorOptions,
+ *               pointInterval, pointIntervalUnit, pointPlacement,
+ *               pointRange, pointStart, showInNavigator, stacking
+ * @requires     stock/indicators/indicators
+ * @requires     stock/indicators/stochastic
+ * @optionparent plotOptions.stochastic
+ */
+{
+    /**
+     * @excluding index, period
+     */
+    params: {
+        /**
+         * Periods for Stochastic oscillator: [%K, %D].
+         *
+         * @type    {Array<number,number>}
+         * @default [14, 3]
+         */
+        periods: [14, 3]
+    },
+    marker: {
+        enabled: false
+    },
+    tooltip: {
+        pointFormat: '<span style="color:{point.color}">\u25CF</span><b> {series.name}</b><br/>%K: {point.y}<br/>%D: {point.smoothed}<br/>'
+    },
+    /**
+     * Smoothed line options.
+     */
+    smoothedLine: {
+        /**
+         * Styles for a smoothed line.
+         */
+        styles: {
+            /**
+             * Pixel width of the line.
+             */
+            lineWidth: 1,
+            /**
+             * Color of the line. If not set, it's inherited from
+             * [plotOptions.stochastic.color
+             * ](#plotOptions.stochastic.color).
+             *
+             * @type {Highcharts.ColorString}
+             */
+            lineColor: void 0
+        }
+    },
+    dataGrouping: {
+        approximation: 'averages'
+    }
+}, 
+/**
+ * @lends Highcharts.Series#
+ */
+H.merge(multipleLinesMixin, {
+    nameComponents: ['periods'],
+    nameBase: 'Stochastic',
+    pointArrayMap: ['y', 'smoothed'],
+    parallelArrays: ['x', 'y', 'smoothed'],
+    pointValKey: 'y',
+    linesApiNames: ['smoothedLine'],
+    init: function () {
+        SMA.prototype.init.apply(this, arguments);
+        // Set default color for lines:
+        this.options = merge({
+            smoothedLine: {
+                styles: {
+                    lineColor: this.color
+                }
+            }
+        }, this.options);
+    },
+    getValues: function (series, params) {
+        var periodK = params.periods[0], periodD = params.periods[1], xVal = series.xData, yVal = series.yData, yValLen = yVal ? yVal.length : 0, 
+        // 0- date, 1-%K, 2-%D
+        SO = [], xData = [], yData = [], slicedY, close = 3, low = 2, high = 1, CL, HL, LL, K, D = null, points, extremes, i;
+        // Stochastic requires close value
+        if (yValLen < periodK ||
+            !isArray(yVal[0]) ||
+            yVal[0].length !== 4) {
+            return;
+        }
+        // For a N-period, we start from N-1 point, to calculate Nth point
+        // That is why we later need to comprehend slice() elements list
+        // with (+1)
+        for (i = periodK - 1; i < yValLen; i++) {
+            slicedY = yVal.slice(i - periodK + 1, i + 1);
+            // Calculate %K
+            extremes = getArrayExtremes(slicedY, low, high);
+            LL = extremes[0]; // Lowest low in %K periods
+            CL = yVal[i][close] - LL;
+            HL = extremes[1] - LL;
+            K = CL / HL * 100;
+            xData.push(xVal[i]);
+            yData.push([K, null]);
+            // Calculate smoothed %D, which is SMA of %K
+            if (i >= (periodK - 1) + (periodD - 1)) {
+                points = SMA.prototype.getValues.call(this, {
+                    xData: xData.slice(-periodD),
+                    yData: yData.slice(-periodD)
+                }, {
+                    period: periodD
+                });
+                D = points.yData[0];
+            }
+            SO.push([xVal[i], K, D]);
+            yData[yData.length - 1][1] = D;
+        }
+        return {
+            values: SO,
+            xData: xData,
+            yData: yData
+        };
+    }
+}));
+/**
+ * A Stochastic indicator. If the [type](#series.stochastic.type) option is not
+ * specified, it is inherited from [chart.type](#chart.type).
+ *
+ * @extends   series,plotOptions.stochastic
+ * @since     6.0.0
+ * @product   highstock
+ * @excluding allAreas, colorAxis,  dataParser, dataURL, joinBy, keys,
+ *            navigatorOptions, pointInterval, pointIntervalUnit,
+ *            pointPlacement, pointRange, pointStart, showInNavigator, stacking
+ * @requires  stock/indicators/indicators
+ * @requires  stock/indicators/stochastic
+ * @apioption series.stochastic
+ */
+''; // to include the above in the js output

+ 431 - 0
app/public/js/Highstock-8.0.0/code/es-modules/indicators/supertrend.src.js

@@ -0,0 +1,431 @@
+/* *
+ *
+ *  License: www.highcharts.com/license
+ *
+ *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
+ *
+ * */
+'use strict';
+import H from '../parts/Globals.js';
+import U from '../parts/Utilities.js';
+var correctFloat = U.correctFloat;
+var isArray = U.isArray, objectEach = U.objectEach;
+var ATR = H.seriesTypes.atr, SMA = H.seriesTypes.sma, merge = H.merge;
+/* eslint-disable require-jsdoc */
+// Utils:
+function createPointObj(mainSeries, index, close) {
+    return {
+        index: index,
+        close: mainSeries.yData[index][close],
+        x: mainSeries.xData[index]
+    };
+}
+/* eslint-enable require-jsdoc */
+/**
+ * The Supertrend series type.
+ *
+ * @private
+ * @class
+ * @name Highcharts.seriesTypes.supertrend
+ *
+ * @augments Highcharts.Series
+ */
+H.seriesType('supertrend', 'sma', 
+/**
+ * Supertrend indicator. This series requires the `linkedTo` option to be
+ * set and should be loaded after the `stock/indicators/indicators.js` and
+ * `stock/indicators/sma.js`.
+ *
+ * @sample {highstock} stock/indicators/supertrend
+ *         Supertrend indicator
+ *
+ * @extends      plotOptions.sma
+ * @since        7.0.0
+ * @product      highstock
+ * @excluding    allAreas, cropThreshold, negativeColor, colorAxis, joinBy,
+ *               keys, navigatorOptions, pointInterval, pointIntervalUnit,
+ *               pointPlacement, pointRange, pointStart, showInNavigator,
+ *               stacking, threshold
+ * @requires     stock/indicators/indicators
+ * @requires     stock/indicators/supertrend
+ * @optionparent plotOptions.supertrend
+ */
+{
+    /**
+     * Paramters used in calculation of Supertrend indicator series points.
+     *
+     * @excluding index
+     */
+    params: {
+        /**
+         * Multiplier for Supertrend Indicator.
+         */
+        multiplier: 3,
+        /**
+         * The base period for indicator Supertrend Indicator calculations.
+         * This is the number of data points which are taken into account
+         * for the indicator calculations.
+         */
+        period: 10
+    },
+    /**
+     * Color of the Supertrend series line that is beneath the main series.
+     *
+     * @sample {highstock} stock/indicators/supertrend/
+     *         Example with risingTrendColor
+     *
+     * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
+     */
+    risingTrendColor: '#06B535',
+    /**
+     * Color of the Supertrend series line that is above the main series.
+     *
+     * @sample {highstock} stock/indicators/supertrend/
+     *         Example with fallingTrendColor
+     *
+     * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
+     */
+    fallingTrendColor: '#F21313',
+    /**
+     * The styles for the Supertrend line that intersect main series.
+     *
+     * @sample {highstock} stock/indicators/supertrend/
+     *         Example with changeTrendLine
+     */
+    changeTrendLine: {
+        styles: {
+            /**
+             * Pixel width of the line.
+             */
+            lineWidth: 1,
+            /**
+             * Color of the line.
+             *
+             * @type {Highcharts.ColorString}
+             */
+            lineColor: '#333333',
+            /**
+             * The dash or dot style of the grid lines. For possible
+             * values, see
+             * [this demonstration](https://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/plotoptions/series-dashstyle-all/).
+             *
+             * @sample {highcharts} highcharts/yaxis/gridlinedashstyle/
+             *         Long dashes
+             * @sample {highstock} stock/xaxis/gridlinedashstyle/
+             *         Long dashes
+             *
+             * @type  {Highcharts.DashStyleValue}
+             * @since 7.0.0
+             */
+            dashStyle: 'LongDash'
+        }
+    }
+}, 
+/**
+ * @lends Highcharts.Series.prototype
+ */
+{
+    nameBase: 'Supertrend',
+    nameComponents: ['multiplier', 'period'],
+    requiredIndicators: ['atr'],
+    init: function () {
+        var options, parentOptions;
+        SMA.prototype.init.apply(this, arguments);
+        options = this.options;
+        parentOptions = this.linkedParent.options;
+        // Indicator cropThreshold has to be equal linked series one
+        // reduced by period due to points comparison in drawGraph method
+        // (#9787)
+        options.cropThreshold = (parentOptions.cropThreshold -
+            (options.params.period - 1));
+    },
+    drawGraph: function () {
+        var indicator = this, indicOptions = indicator.options, 
+        // Series that indicator is linked to
+        mainSeries = indicator.linkedParent, mainLinePoints = (mainSeries ? mainSeries.points : []), indicPoints = indicator.points, indicPath = indicator.graph, indicPointsLen = indicPoints.length, 
+        // Points offset between lines
+        tempOffset = mainLinePoints.length - indicPointsLen, offset = tempOffset > 0 ? tempOffset : 0, 
+        // @todo: fix when ichi-moku indicator is merged to master.
+        gappedExtend = {
+            options: {
+                gapSize: indicOptions.gapSize
+            }
+        }, 
+        // Sorted supertrend points array
+        groupedPoitns = {
+            top: [],
+            bottom: [],
+            intersect: [] // Change trend line points
+        }, 
+        // Options for trend lines
+        supertrendLineOptions = {
+            top: {
+                styles: {
+                    lineWidth: indicOptions.lineWidth,
+                    lineColor: (indicOptions.fallingTrendColor ||
+                        indicOptions.color),
+                    dashStyle: indicOptions.dashStyle
+                }
+            },
+            bottom: {
+                styles: {
+                    lineWidth: indicOptions.lineWidth,
+                    lineColor: (indicOptions.risingTrendColor ||
+                        indicOptions.color),
+                    dashStyle: indicOptions.dashStyle
+                }
+            },
+            intersect: indicOptions.changeTrendLine
+        }, close = 3, 
+        // Supertrend line point
+        point, 
+        // Supertrend line next point (has smaller x pos than point)
+        nextPoint, 
+        // Main series points
+        mainPoint, nextMainPoint, 
+        // Used when supertrend and main points are shifted
+        // relative to each other
+        prevMainPoint, prevPrevMainPoint, 
+        // Used when particular point color is set
+        pointColor, 
+        // Temporary points that fill groupedPoitns array
+        newPoint, newNextPoint;
+        // Loop which sort supertrend points
+        while (indicPointsLen--) {
+            point = indicPoints[indicPointsLen];
+            nextPoint = indicPoints[indicPointsLen - 1];
+            mainPoint = mainLinePoints[indicPointsLen - 1 + offset];
+            nextMainPoint = mainLinePoints[indicPointsLen - 2 + offset];
+            prevMainPoint = mainLinePoints[indicPointsLen + offset];
+            prevPrevMainPoint = mainLinePoints[indicPointsLen + offset + 1];
+            pointColor = point.options.color;
+            newPoint = {
+                x: point.x,
+                plotX: point.plotX,
+                plotY: point.plotY,
+                isNull: false
+            };
+            // When mainPoint is the last one (left plot area edge)
+            // but supertrend has additional one
+            if (!nextMainPoint &&
+                mainPoint && mainSeries.yData[mainPoint.index - 1]) {
+                nextMainPoint = createPointObj(mainSeries, mainPoint.index - 1, close);
+            }
+            // When prevMainPoint is the last one (right plot area edge)
+            // but supertrend has additional one (and points are shifted)
+            if (!prevPrevMainPoint &&
+                prevMainPoint && mainSeries.yData[prevMainPoint.index + 1]) {
+                prevPrevMainPoint = createPointObj(mainSeries, prevMainPoint.index + 1, close);
+            }
+            // When points are shifted (right or left plot area edge)
+            if (!mainPoint &&
+                nextMainPoint && mainSeries.yData[nextMainPoint.index + 1]) {
+                mainPoint = createPointObj(mainSeries, nextMainPoint.index + 1, close);
+            }
+            else if (!mainPoint &&
+                prevMainPoint && mainSeries.yData[prevMainPoint.index - 1]) {
+                mainPoint = createPointObj(mainSeries, prevMainPoint.index - 1, close);
+            }
+            // Check if points are shifted relative to each other
+            if (point &&
+                mainPoint &&
+                prevMainPoint &&
+                nextMainPoint &&
+                point.x !== mainPoint.x) {
+                if (point.x === prevMainPoint.x) {
+                    nextMainPoint = mainPoint;
+                    mainPoint = prevMainPoint;
+                }
+                else if (point.x === nextMainPoint.x) {
+                    mainPoint = nextMainPoint;
+                    nextMainPoint = {
+                        close: mainSeries.yData[mainPoint.index - 1][close],
+                        x: mainSeries.xData[mainPoint.index - 1]
+                    };
+                }
+                else if (prevPrevMainPoint && point.x === prevPrevMainPoint.x) {
+                    mainPoint = prevPrevMainPoint;
+                    nextMainPoint = prevMainPoint;
+                }
+            }
+            if (nextPoint && nextMainPoint && mainPoint) {
+                newNextPoint = {
+                    x: nextPoint.x,
+                    plotX: nextPoint.plotX,
+                    plotY: nextPoint.plotY,
+                    isNull: false
+                };
+                if (point.y >= mainPoint.close &&
+                    nextPoint.y >= nextMainPoint.close) {
+                    point.color = (pointColor || indicOptions.fallingTrendColor ||
+                        indicOptions.color);
+                    groupedPoitns.top.push(newPoint);
+                }
+                else if (point.y < mainPoint.close &&
+                    nextPoint.y < nextMainPoint.close) {
+                    point.color = (pointColor || indicOptions.risingTrendColor ||
+                        indicOptions.color);
+                    groupedPoitns.bottom.push(newPoint);
+                }
+                else {
+                    groupedPoitns.intersect.push(newPoint);
+                    groupedPoitns.intersect.push(newNextPoint);
+                    // Additional null point to make a gap in line
+                    groupedPoitns.intersect.push(merge(newNextPoint, {
+                        isNull: true
+                    }));
+                    if (point.y >= mainPoint.close &&
+                        nextPoint.y < nextMainPoint.close) {
+                        point.color = (pointColor || indicOptions.fallingTrendColor ||
+                            indicOptions.color);
+                        nextPoint.color = (pointColor || indicOptions.risingTrendColor ||
+                            indicOptions.color);
+                        groupedPoitns.top.push(newPoint);
+                        groupedPoitns.top.push(merge(newNextPoint, {
+                            isNull: true
+                        }));
+                    }
+                    else if (point.y < mainPoint.close &&
+                        nextPoint.y >= nextMainPoint.close) {
+                        point.color = (pointColor || indicOptions.risingTrendColor ||
+                            indicOptions.color);
+                        nextPoint.color = (pointColor || indicOptions.fallingTrendColor ||
+                            indicOptions.color);
+                        groupedPoitns.bottom.push(newPoint);
+                        groupedPoitns.bottom.push(merge(newNextPoint, {
+                            isNull: true
+                        }));
+                    }
+                }
+            }
+            else if (mainPoint) {
+                if (point.y >= mainPoint.close) {
+                    point.color = (pointColor || indicOptions.fallingTrendColor ||
+                        indicOptions.color);
+                    groupedPoitns.top.push(newPoint);
+                }
+                else {
+                    point.color = (pointColor || indicOptions.risingTrendColor ||
+                        indicOptions.color);
+                    groupedPoitns.bottom.push(newPoint);
+                }
+            }
+        }
+        // Generate lines:
+        objectEach(groupedPoitns, function (values, lineName) {
+            indicator.points = values;
+            indicator.options = merge(supertrendLineOptions[lineName].styles, gappedExtend);
+            indicator.graph = indicator['graph' + lineName + 'Line'];
+            SMA.prototype.drawGraph.call(indicator);
+            // Now save line
+            indicator['graph' + lineName + 'Line'] = indicator.graph;
+        });
+        // Restore options:
+        indicator.points = indicPoints;
+        indicator.options = indicOptions;
+        indicator.graph = indicPath;
+    },
+    // Supertrend (Multiplier, Period) Formula:
+    // BASIC UPPERBAND = (HIGH + LOW) / 2 + Multiplier * ATR(Period)
+    // BASIC LOWERBAND = (HIGH + LOW) / 2 - Multiplier * ATR(Period)
+    // FINAL UPPERBAND =
+    //     IF(
+    //      Current BASICUPPERBAND  < Previous FINAL UPPERBAND AND
+    //      Previous Close > Previous FINAL UPPERBAND
+    //     ) THEN (Current BASIC UPPERBAND)
+    //     ELSE (Previous FINALUPPERBAND)
+    // FINAL LOWERBAND =
+    //     IF(
+    //      Current BASIC LOWERBAND  > Previous FINAL LOWERBAND AND
+    //      Previous Close < Previous FINAL LOWERBAND
+    //     ) THEN (Current BASIC LOWERBAND)
+    //     ELSE (Previous FINAL LOWERBAND)
+    // SUPERTREND =
+    //     IF(
+    //      Previous Supertrend == Previous FINAL UPPERBAND AND
+    //      Current Close < Current FINAL UPPERBAND
+    //     ) THAN Current FINAL UPPERBAND
+    //     ELSE IF(
+    //      Previous Supertrend == Previous FINAL LOWERBAND AND
+    //      Current Close < Current FINAL LOWERBAND
+    //     ) THAN Current FINAL UPPERBAND
+    //     ELSE IF(
+    //      Previous Supertrend == Previous FINAL UPPERBAND AND
+    //      Current Close > Current FINAL UPPERBAND
+    //     ) THAN Current FINAL LOWERBAND
+    //     ELSE IF(
+    //      Previous Supertrend == Previous FINAL LOWERBAND AND
+    //      Current Close > Current FINAL LOWERBAND
+    //     ) THAN Current FINAL LOWERBAND
+    getValues: function (series, params) {
+        var period = params.period, multiplier = params.multiplier, xVal = series.xData, yVal = series.yData, ATRData = [], 
+        // 0- date, 1- Supertrend indicator
+        ST = [], xData = [], yData = [], close = 3, low = 2, high = 1, periodsOffset = (period === 0) ? 0 : period - 1, basicUp, basicDown, finalUp = [], finalDown = [], supertrend, prevFinalUp, prevFinalDown, prevST, // previous Supertrend
+        prevY, y, i;
+        if ((xVal.length <= period) || !isArray(yVal[0]) ||
+            yVal[0].length !== 4 || period < 0) {
+            return;
+        }
+        ATRData = ATR.prototype.getValues.call(this, series, {
+            period: period
+        }).yData;
+        for (i = 0; i < ATRData.length; i++) {
+            y = yVal[periodsOffset + i];
+            prevY = yVal[periodsOffset + i - 1] || [];
+            prevFinalUp = finalUp[i - 1];
+            prevFinalDown = finalDown[i - 1];
+            prevST = yData[i - 1];
+            if (i === 0) {
+                prevFinalUp = prevFinalDown = prevST = 0;
+            }
+            basicUp = correctFloat((y[high] + y[low]) / 2 + multiplier * ATRData[i]);
+            basicDown = correctFloat((y[high] + y[low]) / 2 - multiplier * ATRData[i]);
+            if ((basicUp < prevFinalUp) ||
+                (prevY[close] > prevFinalUp)) {
+                finalUp[i] = basicUp;
+            }
+            else {
+                finalUp[i] = prevFinalUp;
+            }
+            if ((basicDown > prevFinalDown) ||
+                (prevY[close] < prevFinalDown)) {
+                finalDown[i] = basicDown;
+            }
+            else {
+                finalDown[i] = prevFinalDown;
+            }
+            if (prevST === prevFinalUp && y[close] < finalUp[i] ||
+                prevST === prevFinalDown && y[close] < finalDown[i]) {
+                supertrend = finalUp[i];
+            }
+            else if (prevST === prevFinalUp && y[close] > finalUp[i] ||
+                prevST === prevFinalDown && y[close] > finalDown[i]) {
+                supertrend = finalDown[i];
+            }
+            ST.push([xVal[periodsOffset + i], supertrend]);
+            xData.push(xVal[periodsOffset + i]);
+            yData.push(supertrend);
+        }
+        return {
+            values: ST,
+            xData: xData,
+            yData: yData
+        };
+    }
+});
+/**
+ * A `Supertrend indicator` series. If the [type](#series.supertrend.type)
+ * option is not specified, it is inherited from [chart.type](#chart.type).
+ *
+ * @extends   series,plotOptions.supertrend
+ * @since     7.0.0
+ * @product   highstock
+ * @excluding allAreas, colorAxis, cropThreshold, data, dataParser, dataURL,
+ *            joinBy, keys, navigatorOptions, negativeColor, pointInterval,
+ *            pointIntervalUnit, pointPlacement, pointRange, pointStart,
+ *            showInNavigator, stacking, threshold
+ * @requires  stock/indicators/indicators
+ * @requires  stock/indicators/supertrend
+ * @apioption series.supertrend
+ */
+''; // to include the above in the js output

+ 167 - 0
app/public/js/Highstock-8.0.0/code/es-modules/indicators/tema.src.js

@@ -0,0 +1,167 @@
+/* *
+ *
+ *  License: www.highcharts.com/license
+ *
+ *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
+ *
+ * */
+'use strict';
+import H from '../parts/Globals.js';
+import U from '../parts/Utilities.js';
+var correctFloat = U.correctFloat, isArray = U.isArray;
+import requiredIndicatorMixin from '../mixins/indicator-required.js';
+var EMAindicator = H.seriesTypes.ema, requiredIndicator = requiredIndicatorMixin;
+/**
+ * The TEMA series type.
+ *
+ * @private
+ * @class
+ * @name Highcharts.seriesTypes.tema
+ *
+ * @augments Highcharts.Series
+ */
+H.seriesType('tema', 'ema', 
+/**
+ * Triple exponential moving average (TEMA) indicator. This series requires
+ * `linkedTo` option to be set and should be loaded after the
+ * `stock/indicators/indicators.js` and `stock/indicators/ema.js`.
+ *
+ * @sample {highstock} stock/indicators/tema
+ *         TEMA indicator
+ *
+ * @extends      plotOptions.ema
+ * @since        7.0.0
+ * @product      highstock
+ * @excluding    allAreas, colorAxis, compare, compareBase, joinBy, keys,
+ *               navigatorOptions, pointInterval, pointIntervalUnit,
+ *               pointPlacement, pointRange, pointStart, showInNavigator,
+ *               stacking
+ * @requires     stock/indicators/indicators
+ * @requires     stock/indicators/ema
+ * @requires     stock/indicators/tema
+ * @optionparent plotOptions.tema
+ */
+{}, 
+/**
+ * @lends Highcharts.Series#
+ */
+{
+    init: function () {
+        var args = arguments, ctx = this;
+        requiredIndicator.isParentLoaded(EMAindicator, 'ema', ctx.type, function (indicator) {
+            indicator.prototype.init.apply(ctx, args);
+            return;
+        });
+    },
+    getEMA: function (yVal, prevEMA, SMA, index, i, xVal) {
+        return EMAindicator.prototype.calculateEma(xVal || [], yVal, typeof i === 'undefined' ? 1 : i, this.chart.series[0].EMApercent, prevEMA, typeof index === 'undefined' ? -1 : index, SMA);
+    },
+    getTemaPoint: function (xVal, tripledPeriod, EMAlevels, i) {
+        var TEMAPoint = [
+            xVal[i - 3],
+            correctFloat(3 * EMAlevels.level1 -
+                3 * EMAlevels.level2 + EMAlevels.level3)
+        ];
+        return TEMAPoint;
+    },
+    getValues: function (series, params) {
+        var period = params.period, doubledPeriod = 2 * period, tripledPeriod = 3 * period, xVal = series.xData, yVal = series.yData, yValLen = yVal ? yVal.length : 0, index = -1, accumulatePeriodPoints = 0, SMA = 0, TEMA = [], xDataTema = [], yDataTema = [], 
+        // EMA of previous point
+        prevEMA, prevEMAlevel2, 
+        // EMA values array
+        EMAvalues = [], EMAlevel2values = [], i, TEMAPoint, 
+        // This object contains all EMA EMAlevels calculated like below
+        // EMA = level1
+        // EMA(EMA) = level2,
+        // EMA(EMA(EMA)) = level3,
+        EMAlevels = {};
+        series.EMApercent = (2 / (period + 1));
+        // Check period, if bigger than EMA points length, skip
+        if (yValLen < 3 * period - 2) {
+            return;
+        }
+        // Switch index for OHLC / Candlestick / Arearange
+        if (isArray(yVal[0])) {
+            index = params.index ? params.index : 0;
+        }
+        // Accumulate first N-points
+        accumulatePeriodPoints =
+            EMAindicator.prototype.accumulatePeriodPoints(period, index, yVal);
+        // first point
+        SMA = accumulatePeriodPoints / period;
+        accumulatePeriodPoints = 0;
+        // Calculate value one-by-one for each period in visible data
+        for (i = period; i < yValLen + 3; i++) {
+            if (i < yValLen + 1) {
+                EMAlevels.level1 = this.getEMA(yVal, prevEMA, SMA, index, i)[1];
+                EMAvalues.push(EMAlevels.level1);
+            }
+            prevEMA = EMAlevels.level1;
+            // Summing first period points for ema(ema)
+            if (i < doubledPeriod) {
+                accumulatePeriodPoints += EMAlevels.level1;
+            }
+            else {
+                // Calculate dema
+                // First dema point
+                if (i === doubledPeriod) {
+                    SMA = accumulatePeriodPoints / period;
+                    accumulatePeriodPoints = 0;
+                }
+                EMAlevels.level1 = EMAvalues[i - period - 1];
+                EMAlevels.level2 = this.getEMA([EMAlevels.level1], prevEMAlevel2, SMA)[1];
+                EMAlevel2values.push(EMAlevels.level2);
+                prevEMAlevel2 = EMAlevels.level2;
+                // Summing first period points for ema(ema(ema))
+                if (i < tripledPeriod) {
+                    accumulatePeriodPoints += EMAlevels.level2;
+                }
+                else {
+                    // Calculate tema
+                    // First tema point
+                    if (i === tripledPeriod) {
+                        SMA = accumulatePeriodPoints / period;
+                    }
+                    if (i === yValLen + 1) {
+                        // Calculate the last ema and emaEMA points
+                        EMAlevels.level1 = EMAvalues[i - period - 1];
+                        EMAlevels.level2 = this.getEMA([EMAlevels.level1], prevEMAlevel2, SMA)[1];
+                        EMAlevel2values.push(EMAlevels.level2);
+                    }
+                    EMAlevels.level1 = EMAvalues[i - period - 2];
+                    EMAlevels.level2 = EMAlevel2values[i - 2 * period - 1];
+                    EMAlevels.level3 = this.getEMA([EMAlevels.level2], EMAlevels.prevLevel3, SMA)[1];
+                    TEMAPoint = this.getTemaPoint(xVal, tripledPeriod, EMAlevels, i);
+                    // Make sure that point exists (for TRIX oscillator)
+                    if (TEMAPoint) {
+                        TEMA.push(TEMAPoint);
+                        xDataTema.push(TEMAPoint[0]);
+                        yDataTema.push(TEMAPoint[1]);
+                    }
+                    EMAlevels.prevLevel3 = EMAlevels.level3;
+                }
+            }
+        }
+        return {
+            values: TEMA,
+            xData: xDataTema,
+            yData: yDataTema
+        };
+    }
+});
+/**
+ * A `TEMA` series. If the [type](#series.ema.type) option is not
+ * specified, it is inherited from [chart.type](#chart.type).
+ *
+ * @extends   series,plotOptions.ema
+ * @since     7.0.0
+ * @product   highstock
+ * @excluding allAreas, colorAxis, compare, compareBase, dataParser, dataURL,
+ *            joinBy, keys, navigatorOptions, pointInterval, pointIntervalUnit,
+ *            pointPlacement, pointRange, pointStart, showInNavigator, stacking
+ * @requires  stock/indicators/indicators
+ * @requires  stock/indicators/ema
+ * @requires  stock/indicators/tema
+ * @apioption series.tema
+ */
+''; // to include the above in the js output

+ 105 - 0
app/public/js/Highstock-8.0.0/code/es-modules/indicators/trendline.src.js

@@ -0,0 +1,105 @@
+/* *
+ *
+ *  License: www.highcharts.com/license
+ *
+ *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
+ *
+ * */
+'use strict';
+import H from '../parts/Globals.js';
+import U from '../parts/Utilities.js';
+var isArray = U.isArray;
+var seriesType = H.seriesType;
+/**
+ * The Trend line series type.
+ *
+ * @private
+ * @class
+ * @name Highcharts.seriesTypes.trendline
+ *
+ * @augments Highcharts.Series
+ */
+seriesType('trendline', 'sma', 
+/**
+ * Trendline (linear regression) fits a straight line to the selected data
+ * using a method called the Sum Of Least Squares. This series requires the
+ * `linkedTo` option to be set.
+ *
+ * @sample stock/indicators/trendline
+ *         Trendline indicator
+ *
+ * @extends      plotOptions.sma
+ * @since        7.1.3
+ * @product      highstock
+ * @requires     stock/indicators/indicators
+ * @requires     stock/indicators/trendline
+ * @optionparent plotOptions.trendline
+ */
+{
+    /**
+     * @excluding period
+     */
+    params: {
+        /**
+         * The point index which indicator calculations will base. For
+         * example using OHLC data, index=2 means the indicator will be
+         * calculated using Low values.
+         *
+         * @default 3
+         */
+        index: 3
+    }
+}, 
+/**
+ * @lends Highcharts.Series#
+ */
+{
+    nameBase: 'Trendline',
+    nameComponents: false,
+    getValues: function (series, params) {
+        var xVal = series.xData, yVal = series.yData, LR = [], xData = [], yData = [], sumX = 0, sumY = 0, sumXY = 0, sumX2 = 0, xValLength = xVal.length, index = params.index, alpha, beta, i, x, y;
+        // Get sums:
+        for (i = 0; i < xValLength; i++) {
+            x = xVal[i];
+            y = isArray(yVal[i]) ? yVal[i][index] : yVal[i];
+            sumX += x;
+            sumY += y;
+            sumXY += x * y;
+            sumX2 += x * x;
+        }
+        // Get slope and offset:
+        alpha = (xValLength * sumXY - sumX * sumY) /
+            (xValLength * sumX2 - sumX * sumX);
+        if (isNaN(alpha)) {
+            alpha = 0;
+        }
+        beta = (sumY - alpha * sumX) / xValLength;
+        // Calculate linear regression:
+        for (i = 0; i < xValLength; i++) {
+            x = xVal[i];
+            y = alpha * x + beta;
+            // Prepare arrays required for getValues() method
+            LR[i] = [x, y];
+            xData[i] = x;
+            yData[i] = y;
+        }
+        return {
+            xData: xData,
+            yData: yData,
+            values: LR
+        };
+    }
+});
+/**
+ * A `TrendLine` series. If the [type](#series.trendline.type) option is not
+ * specified, it is inherited from [chart.type](#chart.type).
+ *
+ * @extends   series,plotOptions.trendline
+ * @since     7.1.3
+ * @product   highstock
+ * @excluding dataParser, dataURL
+ * @requires  stock/indicators/indicators
+ * @requires  stock/indicators/trendline
+ * @apioption series.trendline
+ */
+''; // to include the above in the js output

+ 80 - 0
app/public/js/Highstock-8.0.0/code/es-modules/indicators/trix.src.js

@@ -0,0 +1,80 @@
+/* *
+ *
+ *  License: www.highcharts.com/license
+ *
+ *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
+ *
+ * */
+'use strict';
+import H from '../parts/Globals.js';
+import U from '../parts/Utilities.js';
+var correctFloat = U.correctFloat;
+import requiredIndicator from '../mixins/indicator-required.js';
+var TEMA = H.seriesTypes.tema;
+/**
+ * The TRIX series type.
+ *
+ * @private
+ * @class
+ * @name Highcharts.seriesTypes.trix
+ *
+ * @augments Highcharts.Series
+ */
+H.seriesType('trix', 'tema', 
+/**
+ * Triple exponential average (TRIX) oscillator. This series requires
+ * `linkedTo` option to be set.
+ *
+ * Requires https://code.highcharts.com/stock/indicators/ema.js
+ * and https://code.highcharts.com/stock/indicators/tema.js.
+ *
+ * @sample {highstock} stock/indicators/trix
+ *         TRIX indicator
+ *
+ * @extends      plotOptions.tema
+ * @since        7.0.0
+ * @product      highstock
+ * @excluding    allAreas, colorAxis, compare, compareBase, joinBy, keys,
+ *               navigatorOptions, pointInterval, pointIntervalUnit,
+ *               pointPlacement, pointRange, pointStart, showInNavigator,
+ *               stacking
+ * @optionparent plotOptions.trix
+ */
+{}, 
+/**
+ * @lends Highcharts.Series#
+ */
+{
+    init: function () {
+        var args = arguments, ctx = this;
+        requiredIndicator.isParentLoaded(TEMA, 'tema', ctx.type, function (indicator) {
+            indicator.prototype.init.apply(ctx, args);
+            return;
+        });
+    },
+    // TRIX is calculated using TEMA so we just extend getTemaPoint method.
+    getTemaPoint: function (xVal, tripledPeriod, EMAlevels, i) {
+        if (i > tripledPeriod) {
+            var TRIXPoint = [
+                xVal[i - 3],
+                EMAlevels.prevLevel3 !== 0 ?
+                    correctFloat(EMAlevels.level3 - EMAlevels.prevLevel3) /
+                        EMAlevels.prevLevel3 * 100 : null
+            ];
+        }
+        return TRIXPoint;
+    }
+});
+/**
+ * A `TRIX` series. If the [type](#series.tema.type) option is not specified, it
+ * is inherited from [chart.type](#chart.type).
+ *
+ * @extends   series,plotOptions.tema
+ * @since     7.0.0
+ * @product   highstock
+ * @excluding allAreas, colorAxis, compare, compareBase, dataParser, dataURL,
+ *            joinBy, keys, navigatorOptions, pointInterval, pointIntervalUnit,
+ *            pointPlacement, pointRange, pointStart, showInNavigator, stacking
+ * @apioption series.trix
+ */
+''; // to include the above in the js output

+ 489 - 0
app/public/js/Highstock-8.0.0/code/es-modules/indicators/volume-by-price.src.js

@@ -0,0 +1,489 @@
+/* *
+ *
+ *  (c) 2010-2019 Paweł Dalek
+ *
+ *  Volume By Price (VBP) indicator for Highstock
+ *
+ *  License: www.highcharts.com/license
+ *
+ *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
+ *
+ * */
+'use strict';
+import H from '../parts/Globals.js';
+import U from '../parts/Utilities.js';
+var animObject = U.animObject, arrayMax = U.arrayMax, arrayMin = U.arrayMin, correctFloat = U.correctFloat, extend = U.extend, isArray = U.isArray;
+/* eslint-disable require-jsdoc */
+// Utils
+function arrayExtremesOHLC(data) {
+    var dataLength = data.length, min = data[0][3], max = min, i = 1, currentPoint;
+    for (; i < dataLength; i++) {
+        currentPoint = data[i][3];
+        if (currentPoint < min) {
+            min = currentPoint;
+        }
+        if (currentPoint > max) {
+            max = currentPoint;
+        }
+    }
+    return {
+        min: min,
+        max: max
+    };
+}
+/* eslint-enable require-jsdoc */
+var abs = Math.abs, noop = H.noop, addEvent = H.addEvent, seriesType = H.seriesType, columnPrototype = H.seriesTypes.column.prototype;
+/**
+ * The Volume By Price (VBP) series type.
+ *
+ * @private
+ * @class
+ * @name Highcharts.seriesTypes.vbp
+ *
+ * @augments Highcharts.Series
+ */
+seriesType('vbp', 'sma', 
+/**
+ * Volume By Price indicator.
+ *
+ * This series requires `linkedTo` option to be set.
+ *
+ * @sample stock/indicators/volume-by-price
+ *         Volume By Price indicator
+ *
+ * @extends      plotOptions.sma
+ * @since        6.0.0
+ * @product      highstock
+ * @requires     stock/indicators/indicators
+ * @requires     stock/indicators/volume-by-price
+ * @optionparent plotOptions.vbp
+ */
+{
+    /**
+     * @excluding index, period
+     */
+    params: {
+        /**
+         * The number of price zones.
+         */
+        ranges: 12,
+        /**
+         * The id of volume series which is mandatory. For example using
+         * OHLC data, volumeSeriesID='volume' means the indicator will be
+         * calculated using OHLC and volume values.
+         */
+        volumeSeriesID: 'volume'
+    },
+    /**
+     * The styles for lines which determine price zones.
+     */
+    zoneLines: {
+        /**
+         * Enable/disable zone lines.
+         */
+        enabled: true,
+        /**
+         * Specify the style of zone lines.
+         *
+         * @type    {Highcharts.CSSObject}
+         * @default {"color": "#0A9AC9", "dashStyle": "LongDash", "lineWidth": 1}
+         */
+        styles: {
+            /** @ignore-options */
+            color: '#0A9AC9',
+            /** @ignore-options */
+            dashStyle: 'LongDash',
+            /** @ignore-options */
+            lineWidth: 1
+        }
+    },
+    /**
+     * The styles for bars when volume is divided into positive/negative.
+     */
+    volumeDivision: {
+        /**
+         * Option to control if volume is divided.
+         */
+        enabled: true,
+        styles: {
+            /**
+             * Color of positive volume bars.
+             *
+             * @type {Highcharts.ColorString}
+             */
+            positiveColor: 'rgba(144, 237, 125, 0.8)',
+            /**
+             * Color of negative volume bars.
+             *
+             * @type {Highcharts.ColorString}
+             */
+            negativeColor: 'rgba(244, 91, 91, 0.8)'
+        }
+    },
+    // To enable series animation; must be animationLimit > pointCount
+    animationLimit: 1000,
+    enableMouseTracking: false,
+    pointPadding: 0,
+    zIndex: -1,
+    crisp: true,
+    dataGrouping: {
+        enabled: false
+    },
+    dataLabels: {
+        allowOverlap: true,
+        enabled: true,
+        format: 'P: {point.volumePos:.2f} | N: {point.volumeNeg:.2f}',
+        padding: 0,
+        style: {
+            /** @internal */
+            fontSize: '7px'
+        },
+        verticalAlign: 'top'
+    }
+}, 
+/**
+ * @lends Highcharts.Series#
+ */
+{
+    nameBase: 'Volume by Price',
+    bindTo: {
+        series: false,
+        eventName: 'afterSetExtremes'
+    },
+    calculateOn: 'render',
+    markerAttribs: noop,
+    drawGraph: noop,
+    getColumnMetrics: columnPrototype.getColumnMetrics,
+    crispCol: columnPrototype.crispCol,
+    init: function (chart) {
+        var indicator = this, params, baseSeries, volumeSeries;
+        H.seriesTypes.sma.prototype.init.apply(indicator, arguments);
+        params = indicator.options.params;
+        baseSeries = indicator.linkedParent;
+        volumeSeries = chart.get(params.volumeSeriesID);
+        indicator.addCustomEvents(baseSeries, volumeSeries);
+        return indicator;
+    },
+    // Adds events related with removing series
+    addCustomEvents: function (baseSeries, volumeSeries) {
+        var indicator = this;
+        /* eslint-disable require-jsdoc */
+        function toEmptyIndicator() {
+            indicator.chart.redraw();
+            indicator.setData([]);
+            indicator.zoneStarts = [];
+            if (indicator.zoneLinesSVG) {
+                indicator.zoneLinesSVG.destroy();
+                delete indicator.zoneLinesSVG;
+            }
+        }
+        /* eslint-enable require-jsdoc */
+        // If base series is deleted, indicator series data is filled with
+        // an empty array
+        indicator.dataEventsToUnbind.push(addEvent(baseSeries, 'remove', function () {
+            toEmptyIndicator();
+        }));
+        // If volume series is deleted, indicator series data is filled with
+        // an empty array
+        if (volumeSeries) {
+            indicator.dataEventsToUnbind.push(addEvent(volumeSeries, 'remove', function () {
+                toEmptyIndicator();
+            }));
+        }
+        return indicator;
+    },
+    // Initial animation
+    animate: function (init) {
+        var series = this, attr = {};
+        if (H.svg && !init) {
+            attr.translateX = series.yAxis.pos;
+            series.group.animate(attr, extend(animObject(series.options.animation), {
+                step: function (val, fx) {
+                    series.group.attr({
+                        scaleX: Math.max(0.001, fx.pos)
+                    });
+                }
+            }));
+            // Delete this function to allow it only once
+            series.animate = null;
+        }
+    },
+    drawPoints: function () {
+        var indicator = this;
+        if (indicator.options.volumeDivision.enabled) {
+            indicator.posNegVolume(true, true);
+            columnPrototype.drawPoints.apply(indicator, arguments);
+            indicator.posNegVolume(false, false);
+        }
+        columnPrototype.drawPoints.apply(indicator, arguments);
+    },
+    // Function responsible for dividing volume into positive and negative
+    posNegVolume: function (initVol, pos) {
+        var indicator = this, signOrder = pos ?
+            ['positive', 'negative'] :
+            ['negative', 'positive'], volumeDivision = indicator.options.volumeDivision, pointLength = indicator.points.length, posWidths = [], negWidths = [], i = 0, pointWidth, priceZone, wholeVol, point;
+        if (initVol) {
+            indicator.posWidths = posWidths;
+            indicator.negWidths = negWidths;
+        }
+        else {
+            posWidths = indicator.posWidths;
+            negWidths = indicator.negWidths;
+        }
+        for (; i < pointLength; i++) {
+            point = indicator.points[i];
+            point[signOrder[0] + 'Graphic'] = point.graphic;
+            point.graphic = point[signOrder[1] + 'Graphic'];
+            if (initVol) {
+                pointWidth = point.shapeArgs.width;
+                priceZone = indicator.priceZones[i];
+                wholeVol = priceZone.wholeVolumeData;
+                if (wholeVol) {
+                    posWidths.push(pointWidth / wholeVol * priceZone.positiveVolumeData);
+                    negWidths.push(pointWidth / wholeVol * priceZone.negativeVolumeData);
+                }
+                else {
+                    posWidths.push(0);
+                    negWidths.push(0);
+                }
+            }
+            point.color = pos ?
+                volumeDivision.styles.positiveColor :
+                volumeDivision.styles.negativeColor;
+            point.shapeArgs.width = pos ?
+                indicator.posWidths[i] :
+                indicator.negWidths[i];
+            point.shapeArgs.x = pos ?
+                point.shapeArgs.x :
+                indicator.posWidths[i];
+        }
+    },
+    translate: function () {
+        var indicator = this, options = indicator.options, chart = indicator.chart, yAxis = indicator.yAxis, yAxisMin = yAxis.min, zoneLinesOptions = indicator.options.zoneLines, priceZones = (indicator.priceZones), yBarOffset = 0, indicatorPoints, volumeDataArray, maxVolume, primalBarWidth, barHeight, barHeightP, oldBarHeight, barWidth, pointPadding, chartPlotTop, barX, barY;
+        columnPrototype.translate.apply(indicator);
+        indicatorPoints = indicator.points;
+        // Do translate operation when points exist
+        if (indicatorPoints.length) {
+            pointPadding = options.pointPadding < 0.5 ?
+                options.pointPadding :
+                0.1;
+            volumeDataArray = indicator.volumeDataArray;
+            maxVolume = arrayMax(volumeDataArray);
+            primalBarWidth = chart.plotWidth / 2;
+            chartPlotTop = chart.plotTop;
+            barHeight = abs(yAxis.toPixels(yAxisMin) -
+                yAxis.toPixels(yAxisMin + indicator.rangeStep));
+            oldBarHeight = abs(yAxis.toPixels(yAxisMin) -
+                yAxis.toPixels(yAxisMin + indicator.rangeStep));
+            if (pointPadding) {
+                barHeightP = abs(barHeight * (1 - 2 * pointPadding));
+                yBarOffset = abs((barHeight - barHeightP) / 2);
+                barHeight = abs(barHeightP);
+            }
+            indicatorPoints.forEach(function (point, index) {
+                barX = point.barX = point.plotX = 0;
+                barY = point.plotY = (yAxis.toPixels(priceZones[index].start) -
+                    chartPlotTop -
+                    (yAxis.reversed ?
+                        (barHeight - oldBarHeight) :
+                        barHeight) -
+                    yBarOffset);
+                barWidth = correctFloat(primalBarWidth *
+                    priceZones[index].wholeVolumeData / maxVolume);
+                point.pointWidth = barWidth;
+                point.shapeArgs = indicator.crispCol.apply(// eslint-disable-line no-useless-call
+                indicator, [barX, barY, barWidth, barHeight]);
+                point.volumeNeg = priceZones[index].negativeVolumeData;
+                point.volumePos = priceZones[index].positiveVolumeData;
+                point.volumeAll = priceZones[index].wholeVolumeData;
+            });
+            if (zoneLinesOptions.enabled) {
+                indicator.drawZones(chart, yAxis, indicator.zoneStarts, zoneLinesOptions.styles);
+            }
+        }
+    },
+    getValues: function (series, params) {
+        var indicator = this, xValues = series.processedXData, yValues = series.processedYData, chart = indicator.chart, ranges = params.ranges, VBP = [], xData = [], yData = [], isOHLC, volumeSeries, priceZones;
+        // Checks if base series exists
+        if (!series.chart) {
+            H.error('Base series not found! In case it has been removed, add ' +
+                'a new one.', true, chart);
+            return;
+        }
+        // Checks if volume series exists
+        if (!(volumeSeries = (chart.get(params.volumeSeriesID)))) {
+            H.error('Series ' +
+                params.volumeSeriesID +
+                ' not found! Check `volumeSeriesID`.', true, chart);
+            return;
+        }
+        // Checks if series data fits the OHLC format
+        isOHLC = isArray(yValues[0]);
+        if (isOHLC && yValues[0].length !== 4) {
+            H.error('Type of ' +
+                series.name +
+                ' series is different than line, OHLC or candlestick.', true, chart);
+            return;
+        }
+        // Price zones contains all the information about the zones (index,
+        // start, end, volumes, etc.)
+        priceZones = indicator.priceZones = indicator.specifyZones(isOHLC, xValues, yValues, ranges, volumeSeries);
+        priceZones.forEach(function (zone, index) {
+            VBP.push([zone.x, zone.end]);
+            xData.push(VBP[index][0]);
+            yData.push(VBP[index][1]);
+        });
+        return {
+            values: VBP,
+            xData: xData,
+            yData: yData
+        };
+    },
+    // Specifing where each zone should start ans end
+    specifyZones: function (isOHLC, xValues, yValues, ranges, volumeSeries) {
+        var indicator = this, rangeExtremes = (isOHLC ? arrayExtremesOHLC(yValues) : false), lowRange = rangeExtremes ?
+            rangeExtremes.min :
+            arrayMin(yValues), highRange = rangeExtremes ?
+            rangeExtremes.max :
+            arrayMax(yValues), zoneStarts = indicator.zoneStarts = [], priceZones = [], i = 0, j = 1, rangeStep, zoneStartsLength;
+        if (!lowRange || !highRange) {
+            if (this.points.length) {
+                this.setData([]);
+                this.zoneStarts = [];
+                this.zoneLinesSVG.destroy();
+            }
+            return [];
+        }
+        rangeStep = indicator.rangeStep =
+            correctFloat(highRange - lowRange) / ranges;
+        zoneStarts.push(lowRange);
+        for (; i < ranges - 1; i++) {
+            zoneStarts.push(correctFloat(zoneStarts[i] + rangeStep));
+        }
+        zoneStarts.push(highRange);
+        zoneStartsLength = zoneStarts.length;
+        //    Creating zones
+        for (; j < zoneStartsLength; j++) {
+            priceZones.push({
+                index: j - 1,
+                x: xValues[0],
+                start: zoneStarts[j - 1],
+                end: zoneStarts[j]
+            });
+        }
+        return indicator.volumePerZone(isOHLC, priceZones, volumeSeries, xValues, yValues);
+    },
+    // Calculating sum of volume values for a specific zone
+    volumePerZone: function (isOHLC, priceZones, volumeSeries, xValues, yValues) {
+        var indicator = this, volumeXData = volumeSeries.processedXData, volumeYData = volumeSeries.processedYData, lastZoneIndex = priceZones.length - 1, baseSeriesLength = yValues.length, volumeSeriesLength = volumeYData.length, previousValue, startFlag, endFlag, value, i;
+        // Checks if each point has a corresponding volume value
+        if (abs(baseSeriesLength - volumeSeriesLength)) {
+            // If the first point don't have volume, add 0 value at the
+            // beggining of the volume array
+            if (xValues[0] !== volumeXData[0]) {
+                volumeYData.unshift(0);
+            }
+            // If the last point don't have volume, add 0 value at the end
+            // of the volume array
+            if (xValues[baseSeriesLength - 1] !==
+                volumeXData[volumeSeriesLength - 1]) {
+                volumeYData.push(0);
+            }
+        }
+        indicator.volumeDataArray = [];
+        priceZones.forEach(function (zone) {
+            zone.wholeVolumeData = 0;
+            zone.positiveVolumeData = 0;
+            zone.negativeVolumeData = 0;
+            for (i = 0; i < baseSeriesLength; i++) {
+                startFlag = false;
+                endFlag = false;
+                value = isOHLC ? yValues[i][3] : yValues[i];
+                previousValue = i ?
+                    (isOHLC ?
+                        yValues[i - 1][3] :
+                        yValues[i - 1]) :
+                    value;
+                // Checks if this is the point with the
+                // lowest close value and if so, adds it calculations
+                if (value <= zone.start && zone.index === 0) {
+                    startFlag = true;
+                }
+                // Checks if this is the point with the highest
+                // close value and if so, adds it calculations
+                if (value >= zone.end && zone.index === lastZoneIndex) {
+                    endFlag = true;
+                }
+                if ((value > zone.start || startFlag) &&
+                    (value < zone.end || endFlag)) {
+                    zone.wholeVolumeData += volumeYData[i];
+                    if (previousValue > value) {
+                        zone.negativeVolumeData += volumeYData[i];
+                    }
+                    else {
+                        zone.positiveVolumeData += volumeYData[i];
+                    }
+                }
+            }
+            indicator.volumeDataArray.push(zone.wholeVolumeData);
+        });
+        return priceZones;
+    },
+    // Function responsoble for drawing additional lines indicating zones
+    drawZones: function (chart, yAxis, zonesValues, zonesStyles) {
+        var indicator = this, renderer = chart.renderer, zoneLinesSVG = indicator.zoneLinesSVG, zoneLinesPath = [], leftLinePos = 0, rightLinePos = chart.plotWidth, verticalOffset = chart.plotTop, verticalLinePos;
+        zonesValues.forEach(function (value) {
+            verticalLinePos = yAxis.toPixels(value) - verticalOffset;
+            zoneLinesPath = zoneLinesPath.concat(chart.renderer.crispLine([
+                'M',
+                leftLinePos,
+                verticalLinePos,
+                'L',
+                rightLinePos,
+                verticalLinePos
+            ], zonesStyles.lineWidth));
+        });
+        // Create zone lines one path or update it while animating
+        if (zoneLinesSVG) {
+            zoneLinesSVG.animate({
+                d: zoneLinesPath
+            });
+        }
+        else {
+            zoneLinesSVG = indicator.zoneLinesSVG =
+                renderer.path(zoneLinesPath).attr({
+                    'stroke-width': zonesStyles.lineWidth,
+                    'stroke': zonesStyles.color,
+                    'dashstyle': zonesStyles.dashStyle,
+                    'zIndex': indicator.group.zIndex + 0.1
+                })
+                    .add(indicator.group);
+        }
+    }
+}, 
+/**
+ * @lends Highcharts.Point#
+ */
+{
+    // Required for destroying negative part of volume
+    destroy: function () {
+        // @todo: this.negativeGraphic doesn't seem to be used anywhere
+        if (this.negativeGraphic) {
+            this.negativeGraphic = this.negativeGraphic.destroy();
+        }
+        return H.Point.prototype.destroy.apply(this, arguments);
+    }
+});
+/**
+ * A `Volume By Price (VBP)` series. If the [type](#series.vbp.type) option is
+ * not specified, it is inherited from [chart.type](#chart.type).
+ *
+ * @extends   series,plotOptions.vbp
+ * @since     6.0.0
+ * @product   highstock
+ * @excluding dataParser, dataURL
+ * @requires  stock/indicators/indicators
+ * @requires  stock/indicators/volume-by-price
+ * @apioption series.vbp
+ */
+''; // to include the above in the js output

+ 149 - 0
app/public/js/Highstock-8.0.0/code/es-modules/indicators/vwap.src.js

@@ -0,0 +1,149 @@
+/* *
+ *
+ *  (c) 2010-2019 Paweł Dalek
+ *
+ *  Volume Weighted Average Price (VWAP) indicator for Highstock
+ *
+ *  License: www.highcharts.com/license
+ *
+ *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
+ *
+ * */
+'use strict';
+import H from '../parts/Globals.js';
+import U from '../parts/Utilities.js';
+var isArray = U.isArray;
+var seriesType = H.seriesType;
+/**
+ * The Volume Weighted Average Price (VWAP) series type.
+ *
+ * @private
+ * @class
+ * @name Highcharts.seriesTypes.vwap
+ *
+ * @augments Highcharts.Series
+ */
+seriesType('vwap', 'sma', 
+/**
+ * Volume Weighted Average Price indicator.
+ *
+ * This series requires `linkedTo` option to be set.
+ *
+ * @sample stock/indicators/vwap
+ *         Volume Weighted Average Price indicator
+ *
+ * @extends      plotOptions.sma
+ * @since        6.0.0
+ * @product      highstock
+ * @requires     stock/indicators/indicators
+ * @requires     stock/indicators/vwap
+ * @optionparent plotOptions.vwap
+ */
+{
+    /**
+     * @excluding index
+     */
+    params: {
+        period: 30,
+        /**
+         * The id of volume series which is mandatory. For example using
+         * OHLC data, volumeSeriesID='volume' means the indicator will be
+         * calculated using OHLC and volume values.
+         */
+        volumeSeriesID: 'volume'
+    }
+}, 
+/**
+ * @lends Highcharts.Series#
+ */
+{
+    /**
+     * Returns the final values of the indicator ready to be presented on a
+     * chart
+     * @private
+     * @param {Highcharts.VWAPIndicator} this indicator
+     * @param {Highcharts.Series} series - series for indicator
+     * @param {object} params - params
+     * @return {object} - computed VWAP
+     **/
+    getValues: function (series, params) {
+        var indicator = this, chart = series.chart, xValues = series.xData, yValues = series.yData, period = params.period, isOHLC = true, volumeSeries;
+        // Checks if volume series exists
+        if (!(volumeSeries = (chart.get(params.volumeSeriesID)))) {
+            H.error('Series ' +
+                params.volumeSeriesID +
+                ' not found! Check `volumeSeriesID`.', true, chart);
+            return;
+        }
+        // Checks if series data fits the OHLC format
+        if (!(isArray(yValues[0]))) {
+            isOHLC = false;
+        }
+        return indicator.calculateVWAPValues(isOHLC, xValues, yValues, volumeSeries, period);
+    },
+    /**
+     * Main algorithm used to calculate Volume Weighted Average Price (VWAP)
+     * values
+     * @private
+     * @param {boolean} isOHLC - says if data has OHLC format
+     * @param {Array<number>} xValues - array of timestamps
+     * @param {Array<number|Array<number,number,number,number>>} yValues -
+     * array of yValues, can be an array of a four arrays (OHLC) or array of
+     * values (line)
+     * @param {Array<*>} volumeSeries - volume series
+     * @param {number} period - number of points to be calculated
+     * @return {object} - Object contains computed VWAP
+     **/
+    calculateVWAPValues: function (isOHLC, xValues, yValues, volumeSeries, period) {
+        var volumeValues = volumeSeries.yData, volumeLength = volumeSeries.xData.length, pointsLength = xValues.length, cumulativePrice = [], cumulativeVolume = [], xData = [], yData = [], VWAP = [], commonLength, typicalPrice, cPrice, cVolume, i, j;
+        if (pointsLength <= volumeLength) {
+            commonLength = pointsLength;
+        }
+        else {
+            commonLength = volumeLength;
+        }
+        for (i = 0, j = 0; i < commonLength; i++) {
+            // Depending on whether series is OHLC or line type, price is
+            // average of the high, low and close or a simple value
+            typicalPrice = isOHLC ?
+                ((yValues[i][1] + yValues[i][2] +
+                    yValues[i][3]) / 3) :
+                yValues[i];
+            typicalPrice *= volumeValues[i];
+            cPrice = j ?
+                (cumulativePrice[i - 1] + typicalPrice) :
+                typicalPrice;
+            cVolume = j ?
+                (cumulativeVolume[i - 1] + volumeValues[i]) :
+                volumeValues[i];
+            cumulativePrice.push(cPrice);
+            cumulativeVolume.push(cVolume);
+            VWAP.push([xValues[i], (cPrice / cVolume)]);
+            xData.push(VWAP[i][0]);
+            yData.push(VWAP[i][1]);
+            j++;
+            if (j === period) {
+                j = 0;
+            }
+        }
+        return {
+            values: VWAP,
+            xData: xData,
+            yData: yData
+        };
+    }
+});
+/**
+ * A `Volume Weighted Average Price (VWAP)` series. If the
+ * [type](#series.vwap.type) option is not specified, it is inherited from
+ * [chart.type](#chart.type).
+ *
+ * @extends   series,plotOptions.vwap
+ * @since     6.0.0
+ * @product   highstock
+ * @excluding dataParser, dataURL
+ * @requires  stock/indicators/indicators
+ * @requires  stock/indicators/vwap
+ * @apioption series.vwap
+ */
+''; // to include the above in the js output

+ 107 - 0
app/public/js/Highstock-8.0.0/code/es-modules/indicators/williams-r.src.js

@@ -0,0 +1,107 @@
+/* *
+ *
+ *  License: www.highcharts.com/license
+ *
+ *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
+ *
+ * */
+'use strict';
+import H from '../parts/Globals.js';
+import U from '../parts/Utilities.js';
+var isArray = U.isArray;
+import reduceArrayMixin from '../mixins/reduce-array.js';
+var getArrayExtremes = reduceArrayMixin.getArrayExtremes;
+/**
+ * The Williams %R series type.
+ *
+ * @private
+ * @class
+ * @name Highcharts.seriesTypes.williamsr
+ *
+ * @augments Highcharts.Series
+ */
+H.seriesType('williamsr', 'sma', 
+/**
+ * Williams %R. This series requires the `linkedTo` option to be
+ * set and should be loaded after the `stock/indicators/indicators.js`.
+ *
+ * @sample {highstock} stock/indicators/williams-r
+ *         Williams %R
+ *
+ * @extends      plotOptions.sma
+ * @since        7.0.0
+ * @product      highstock
+ * @excluding    allAreas, colorAxis, joinBy, keys, navigatorOptions,
+ *               pointInterval, pointIntervalUnit, pointPlacement,
+ *               pointRange, pointStart, showInNavigator, stacking
+ * @requires     stock/indicators/indicators
+ * @requires     stock/indicators/williams-r
+ * @optionparent plotOptions.williamsr
+ */
+{
+    /**
+     * Paramters used in calculation of Williams %R series points.
+     * @excluding index
+     */
+    params: {
+        /**
+         * Period for Williams %R oscillator
+         */
+        period: 14
+    }
+}, 
+/**
+ * @lends Highcharts.Series#
+ */
+{
+    nameBase: 'Williams %R',
+    getValues: function (series, params) {
+        var period = params.period, xVal = series.xData, yVal = series.yData, yValLen = yVal ? yVal.length : 0, WR = [], // 0- date, 1- Williams %R
+        xData = [], yData = [], slicedY, close = 3, low = 2, high = 1, extremes, R, HH, // Highest high value in period
+        LL, // Lowest low value in period
+        CC, // Current close value
+        i;
+        // Williams %R requires close value
+        if (xVal.length < period ||
+            !isArray(yVal[0]) ||
+            yVal[0].length !== 4) {
+            return;
+        }
+        // For a N-period, we start from N-1 point, to calculate Nth point
+        // That is why we later need to comprehend slice() elements list
+        // with (+1)
+        for (i = period - 1; i < yValLen; i++) {
+            slicedY = yVal.slice(i - period + 1, i + 1);
+            extremes = getArrayExtremes(slicedY, low, high);
+            LL = extremes[0];
+            HH = extremes[1];
+            CC = yVal[i][close];
+            R = ((HH - CC) / (HH - LL)) * -100;
+            if (xVal[i]) {
+                WR.push([xVal[i], R]);
+                xData.push(xVal[i]);
+                yData.push(R);
+            }
+        }
+        return {
+            values: WR,
+            xData: xData,
+            yData: yData
+        };
+    }
+});
+/**
+ * A `Williams %R Oscillator` series. If the [type](#series.williamsr.type)
+ * option is not specified, it is inherited from [chart.type](#chart.type).
+ *
+ * @extends   series,plotOptions.williamsr
+ * @since     7.0.0
+ * @product   highstock
+ * @excluding allAreas, colorAxis, dataParser, dataURL, joinBy, keys,
+ *            navigatorOptions, pointInterval, pointIntervalUnit,
+ *            pointPlacement, pointRange, pointStart, showInNavigator, stacking
+ * @requires  stock/indicators/indicators
+ * @requires  stock/indicators/williams-r
+ * @apioption series.williamsr
+ */
+''; // adds doclets above to the transpiled file

+ 128 - 0
app/public/js/Highstock-8.0.0/code/es-modules/indicators/wma.src.js

@@ -0,0 +1,128 @@
+/* *
+ *
+ *  (c) 2010-2019 Kacper Madej
+ *
+ *  License: www.highcharts.com/license
+ *
+ *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
+ *
+ * */
+'use strict';
+import H from '../parts/Globals.js';
+import U from '../parts/Utilities.js';
+var isArray = U.isArray;
+var seriesType = H.seriesType;
+/* eslint-disable valid-jsdoc */
+// Utils:
+/**
+ * @private
+ */
+function accumulateAverage(points, xVal, yVal, i, index) {
+    var xValue = xVal[i], yValue = index < 0 ? yVal[i] : yVal[i][index];
+    points.push([xValue, yValue]);
+}
+/**
+ * @private
+ */
+function weightedSumArray(array, pLen) {
+    // The denominator is the sum of the number of days as a triangular number.
+    // If there are 5 days, the triangular numbers are 5, 4, 3, 2, and 1.
+    // The sum is 5 + 4 + 3 + 2 + 1 = 15.
+    var denominator = (pLen + 1) / 2 * pLen;
+    // reduce VS loop => reduce
+    return array.reduce(function (prev, cur, i) {
+        return [null, prev[1] + cur[1] * (i + 1)];
+    })[1] / denominator;
+}
+/**
+ * @private
+ */
+function populateAverage(points, xVal, yVal, i) {
+    var pLen = points.length, wmaY = weightedSumArray(points, pLen), wmaX = xVal[i - 1];
+    points.shift(); // remove point until range < period
+    return [wmaX, wmaY];
+}
+/* eslint-enable valid-jsdoc */
+/**
+ * The SMA series type.
+ *
+ * @private
+ * @class
+ * @name Highcharts.seriesTypes.wma
+ *
+ * @augments Highcharts.Series
+ */
+seriesType('wma', 'sma', 
+/**
+ * Weighted moving average indicator (WMA). This series requires `linkedTo`
+ * option to be set.
+ *
+ * @sample stock/indicators/wma
+ *         Weighted moving average indicator
+ *
+ * @extends      plotOptions.sma
+ * @since        6.0.0
+ * @product      highstock
+ * @requires     stock/indicators/indicators
+ * @requires     stock/indicators/wma
+ * @optionparent plotOptions.wma
+ */
+{
+    params: {
+        index: 3,
+        period: 9
+    }
+}, 
+/**
+ * @lends Highcharts.Series#
+ */
+{
+    getValues: function (series, params) {
+        var period = params.period, xVal = series.xData, yVal = series.yData, yValLen = yVal ? yVal.length : 0, range = 1, xValue = xVal[0], yValue = yVal[0], WMA = [], xData = [], yData = [], index = -1, i, points, WMAPoint;
+        if (xVal.length < period) {
+            return;
+        }
+        // Switch index for OHLC / Candlestick
+        if (isArray(yVal[0])) {
+            index = params.index;
+            yValue = yVal[0][index];
+        }
+        // Starting point
+        points = [[xValue, yValue]];
+        // Accumulate first N-points
+        while (range !== period) {
+            accumulateAverage(points, xVal, yVal, range, index);
+            range++;
+        }
+        // Calculate value one-by-one for each period in visible data
+        for (i = range; i < yValLen; i++) {
+            WMAPoint = populateAverage(points, xVal, yVal, i);
+            WMA.push(WMAPoint);
+            xData.push(WMAPoint[0]);
+            yData.push(WMAPoint[1]);
+            accumulateAverage(points, xVal, yVal, i, index);
+        }
+        WMAPoint = populateAverage(points, xVal, yVal, i);
+        WMA.push(WMAPoint);
+        xData.push(WMAPoint[0]);
+        yData.push(WMAPoint[1]);
+        return {
+            values: WMA,
+            xData: xData,
+            yData: yData
+        };
+    }
+});
+/**
+ * A `WMA` series. If the [type](#series.wma.type) option is not specified, it
+ * is inherited from [chart.type](#chart.type).
+ *
+ * @extends   series,plotOptions.wma
+ * @since     6.0.0
+ * @product   highstock
+ * @excluding dataParser, dataURL
+ * @requires  stock/indicators/indicators
+ * @requires  stock/indicators/wma
+ * @apioption series.wma
+ */
+''; // adds doclet above to the transpiled file

+ 182 - 0
app/public/js/Highstock-8.0.0/code/es-modules/indicators/zigzag.src.js

@@ -0,0 +1,182 @@
+/* *
+ *
+ *  (c) 2010-2019 Kacper Madej
+ *
+ *  License: www.highcharts.com/license
+ *
+ *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
+ *
+ * */
+'use strict';
+import H from '../parts/Globals.js';
+import '../parts/Utilities.js';
+var seriesType = H.seriesType, UNDEFINED;
+/**
+ * The Zig Zag series type.
+ *
+ * @private
+ * @class
+ * @name Highcharts.seriesTypes.zigzag
+ *
+ * @augments Highcharts.Series
+ */
+seriesType('zigzag', 'sma', 
+/**
+ * Zig Zag indicator.
+ *
+ * This series requires `linkedTo` option to be set.
+ *
+ * @sample stock/indicators/zigzag
+ *         Zig Zag indicator
+ *
+ * @extends      plotOptions.sma
+ * @since        6.0.0
+ * @product      highstock
+ * @requires     stock/indicators/indicators
+ * @requires     stock/indicators/zigzag
+ * @optionparent plotOptions.zigzag
+ */
+{
+    /**
+     * @excluding index, period
+     */
+    params: {
+        /**
+         * The point index which indicator calculations will base - low
+         * value.
+         *
+         * For example using OHLC data, index=2 means the indicator will be
+         * calculated using Low values.
+         */
+        lowIndex: 2,
+        /**
+         * The point index which indicator calculations will base - high
+         * value.
+         *
+         * For example using OHLC data, index=1 means the indicator will be
+         * calculated using High values.
+         */
+        highIndex: 1,
+        /**
+         * The threshold for the value change.
+         *
+         * For example deviation=1 means the indicator will ignore all price
+         * movements less than 1%.
+         */
+        deviation: 1
+    }
+}, 
+/**
+ * @lends Highcharts.Series#
+ */
+{
+    nameComponents: ['deviation'],
+    nameSuffixes: ['%'],
+    nameBase: 'Zig Zag',
+    getValues: function (series, params) {
+        var lowIndex = params.lowIndex, highIndex = params.highIndex, deviation = params.deviation / 100, deviations = {
+            'low': 1 + deviation,
+            'high': 1 - deviation
+        }, xVal = series.xData, yVal = series.yData, yValLen = yVal ? yVal.length : 0, zigzag = [], xData = [], yData = [], i, j, zigzagPoint, firstZigzagLow, firstZigzagHigh, directionUp, zigzagLen, exitLoop = false, yIndex = false;
+        // Exit if not enught points or no low or high values
+        if (!xVal || xVal.length <= 1 ||
+            (yValLen &&
+                (yVal[0][lowIndex] === UNDEFINED ||
+                    yVal[0][highIndex] === UNDEFINED))) {
+            return;
+        }
+        // Set first zigzag point candidate
+        firstZigzagLow = yVal[0][lowIndex];
+        firstZigzagHigh = yVal[0][highIndex];
+        // Search for a second zigzag point candidate,
+        // this will also set first zigzag point
+        for (i = 1; i < yValLen; i++) {
+            // requried change to go down
+            if (yVal[i][lowIndex] <= firstZigzagHigh * deviations.high) {
+                zigzag.push([xVal[0], firstZigzagHigh]);
+                // second zigzag point candidate
+                zigzagPoint = [xVal[i], yVal[i][lowIndex]];
+                // next line will be going up
+                directionUp = true;
+                exitLoop = true;
+                // requried change to go up
+            }
+            else if (yVal[i][highIndex] >= firstZigzagLow * deviations.low) {
+                zigzag.push([xVal[0], firstZigzagLow]);
+                // second zigzag point candidate
+                zigzagPoint = [xVal[i], yVal[i][highIndex]];
+                // next line will be going down
+                directionUp = false;
+                exitLoop = true;
+            }
+            if (exitLoop) {
+                xData.push(zigzag[0][0]);
+                yData.push(zigzag[0][1]);
+                j = i++;
+                i = yValLen;
+            }
+        }
+        // Search for next zigzags
+        for (i = j; i < yValLen; i++) {
+            if (directionUp) { // next line up
+                // lower when going down -> change zigzag candidate
+                if (yVal[i][lowIndex] <= zigzagPoint[1]) {
+                    zigzagPoint = [xVal[i], yVal[i][lowIndex]];
+                }
+                // requried change to go down -> new zigzagpoint and
+                // direction change
+                if (yVal[i][highIndex] >=
+                    zigzagPoint[1] * deviations.low) {
+                    yIndex = highIndex;
+                }
+            }
+            else { // next line down
+                // higher when going up -> change zigzag candidate
+                if (yVal[i][highIndex] >= zigzagPoint[1]) {
+                    zigzagPoint = [xVal[i], yVal[i][highIndex]];
+                }
+                // requried change to go down -> new zigzagpoint and
+                // direction change
+                if (yVal[i][lowIndex] <=
+                    zigzagPoint[1] * deviations.high) {
+                    yIndex = lowIndex;
+                }
+            }
+            if (yIndex !== false) { // new zigzag point and direction change
+                zigzag.push(zigzagPoint);
+                xData.push(zigzagPoint[0]);
+                yData.push(zigzagPoint[1]);
+                zigzagPoint = [xVal[i], yVal[i][yIndex]];
+                directionUp = !directionUp;
+                yIndex = false;
+            }
+        }
+        zigzagLen = zigzag.length;
+        // no zigzag for last point
+        if (zigzagLen !== 0 &&
+            zigzag[zigzagLen - 1][0] < xVal[yValLen - 1]) {
+            // set last point from zigzag candidate
+            zigzag.push(zigzagPoint);
+            xData.push(zigzagPoint[0]);
+            yData.push(zigzagPoint[1]);
+        }
+        return {
+            values: zigzag,
+            xData: xData,
+            yData: yData
+        };
+    }
+});
+/**
+ * A `Zig Zag` series. If the [type](#series.zigzag.type) option is not
+ * specified, it is inherited from [chart.type](#chart.type).
+ *
+ * @extends   series,plotOptions.zigzag
+ * @since     6.0.0
+ * @product   highstock
+ * @excluding dataParser, dataURL
+ * @requires  stock/indicators/indicators
+ * @requires  stock/indicators/zigzag
+ * @apioption series.zigzag
+ */
+''; // adds doclets above to transpiled file

+ 19 - 0
app/public/js/Highstock-8.0.0/code/es-modules/masters/highcharts-3d.src.js

@@ -0,0 +1,19 @@
+/**
+ * @license Highcharts JS v8.0.0 (2019-12-10)
+ * @module highcharts/highcharts-3d
+ * @requires highcharts
+ *
+ * 3D features for Highcharts JS
+ *
+ * License: www.highcharts.com/license
+ */
+'use strict';
+import '../parts-3d/Math.js';
+import '../parts-3d/SVGRenderer.js';
+import '../parts-3d/Chart.js';
+import '../parts-3d/Axis.js';
+import '../parts-3d/Series.js';
+import '../parts-3d/Column.js';
+import '../parts-3d/Pie.js';
+import '../parts-3d/Scatter.js';
+import '../parts-3d/VMLRenderer.js';

+ 24 - 0
app/public/js/Highstock-8.0.0/code/es-modules/masters/highcharts-more.src.js

@@ -0,0 +1,24 @@
+/**
+ * @license Highcharts JS v8.0.0 (2019-12-10)
+ * @module highcharts/highcharts-more
+ * @requires highcharts
+ *
+ * (c) 2009-2018 Torstein Honsi
+ *
+ * License: www.highcharts.com/license
+ */
+'use strict';
+import '../parts-more/Pane.js';
+import '../parts-more/RadialAxis.js';
+import '../parts-more/AreaRangeSeries.js';
+import '../parts-more/AreaSplineRangeSeries.js';
+import '../parts-more/ColumnRangeSeries.js';
+import '../parts-more/ColumnPyramidSeries.js';
+import '../parts-more/GaugeSeries.js';
+import '../parts-more/BoxPlotSeries.js';
+import '../parts-more/ErrorBarSeries.js';
+import '../parts-more/WaterfallSeries.js';
+import '../parts-more/PolygonSeries.js';
+import '../parts-more/BubbleSeries.js';
+import '../parts-more/PackedBubbleSeries.js';
+import '../parts-more/Polar.js';

+ 14 - 0
app/public/js/Highstock-8.0.0/code/es-modules/masters/highstock.src.js

@@ -0,0 +1,14 @@
+/**
+ * @license Highstock JS v8.0.0 (2019-12-10)
+ * @module highcharts/highstock
+ *
+ * (c) 2009-2018 Torstein Honsi
+ *
+ * License: www.highcharts.com/license
+ */
+'use strict';
+import Highcharts from './highcharts.src.js';
+import './modules/stock.src.js';
+
+Highcharts.product = 'Highstock';
+export default Highcharts;

+ 14 - 0
app/public/js/Highstock-8.0.0/code/es-modules/masters/indicators/acceleration-bands.src.js

@@ -0,0 +1,14 @@
+/**
+ * @license Highstock JS v8.0.0 (2019-12-10)
+ * @module highcharts/indicators/acceleration-bands
+ * @requires highcharts
+ * @requires highcharts/modules/stock
+ *
+ * Indicator series type for Highstock
+ *
+ * (c) 2010-2019 Daniel Studencki
+ *
+ * License: www.highcharts.com/license
+ */
+'use strict';
+import '../../indicators/acceleration-bands.src.js';

+ 14 - 0
app/public/js/Highstock-8.0.0/code/es-modules/masters/indicators/accumulation-distribution.src.js

@@ -0,0 +1,14 @@
+/**
+ * @license Highstock JS v8.0.0 (2019-12-10)
+ * @module highcharts/indicators/accumulation-distribution
+ * @requires highcharts
+ * @requires highcharts/modules/stock
+ *
+ * Indicator series type for Highstock
+ *
+ * (c) 2010-2019 Sebastian Bochan
+ *
+ * License: www.highcharts.com/license
+ */
+'use strict';
+import '../../indicators/accumulation-distribution.src.js';

+ 14 - 0
app/public/js/Highstock-8.0.0/code/es-modules/masters/indicators/ao.src.js

@@ -0,0 +1,14 @@
+/**
+ * @license Highstock JS v8.0.0 (2019-12-10)
+ * @module highcharts/indicators/ao
+ * @requires highcharts
+ * @requires highcharts/modules/stock
+ *
+ * Indicator series type for Highstock
+ *
+ * (c) 2010-2019 Wojciech Chmiel
+ *
+ * License: www.highcharts.com/license
+ */
+'use strict';
+import '../../indicators/ao.src.js';

+ 14 - 0
app/public/js/Highstock-8.0.0/code/es-modules/masters/indicators/apo.src.js

@@ -0,0 +1,14 @@
+/**
+ * @license Highstock JS v8.0.0 (2019-12-10)
+ * @module highcharts/indicators/apo
+ * @requires highcharts
+ * @requires highcharts/modules/stock
+ *
+ * Indicator series type for Highstock
+ *
+ * (c) 2010-2019 Wojciech Chmiel
+ *
+ * License: www.highcharts.com/license
+ */
+'use strict';
+import '../../indicators/apo.src.js';

+ 14 - 0
app/public/js/Highstock-8.0.0/code/es-modules/masters/indicators/aroon-oscillator.src.js

@@ -0,0 +1,14 @@
+/**
+ * @license Highstock JS v8.0.0 (2019-12-10)
+ * @module highcharts/indicators/aroon-oscillator
+ * @requires highcharts
+ * @requires highcharts/modules/stock
+ *
+ * Indicator series type for Highstock
+ *
+ * (c) 2010-2019 Wojciech Chmiel
+ *
+ * License: www.highcharts.com/license
+ */
+'use strict';
+import '../../indicators/aroon-oscillator.src.js';

+ 14 - 0
app/public/js/Highstock-8.0.0/code/es-modules/masters/indicators/aroon.src.js

@@ -0,0 +1,14 @@
+/**
+ * @license Highstock JS v8.0.0 (2019-12-10)
+ * @module highcharts/indicators/aroon
+ * @requires highcharts
+ * @requires highcharts/modules/stock
+ *
+ * Indicator series type for Highstock
+ *
+ * (c) 2010-2019 Wojciech Chmiel
+ *
+ * License: www.highcharts.com/license
+ */
+'use strict';
+import '../../indicators/aroon.src.js';

+ 14 - 0
app/public/js/Highstock-8.0.0/code/es-modules/masters/indicators/atr.src.js

@@ -0,0 +1,14 @@
+/**
+ * @license Highstock JS v8.0.0 (2019-12-10)
+ * @module highcharts/indicators/atr
+ * @requires highcharts
+ * @requires highcharts/modules/stock
+ *
+ * Indicator series type for Highstock
+ *
+ * (c) 2010-2019 Sebastian Bochan
+ *
+ * License: www.highcharts.com/license
+ */
+'use strict';
+import '../../indicators/atr.src.js';

+ 14 - 0
app/public/js/Highstock-8.0.0/code/es-modules/masters/indicators/bollinger-bands.src.js

@@ -0,0 +1,14 @@
+/**
+ * @license Highstock JS v8.0.0 (2019-12-10)
+ * @module highcharts/indicators/bollinger-bands
+ * @requires highcharts
+ * @requires highcharts/modules/stock
+ *
+ * Indicator series type for Highstock
+ *
+ * (c) 2010-2019 Paweł Fus
+ *
+ * License: www.highcharts.com/license
+ */
+'use strict';
+import '../../indicators/bollinger-bands.src.js';

+ 14 - 0
app/public/js/Highstock-8.0.0/code/es-modules/masters/indicators/cci.src.js

@@ -0,0 +1,14 @@
+/**
+ * @license Highstock JS v8.0.0 (2019-12-10)
+ * @module highcharts/indicators/cci
+ * @requires highcharts
+ * @requires highcharts/modules/stock
+ *
+ * Indicator series type for Highstock
+ *
+ * (c) 2010-2019 Sebastian Bochan
+ *
+ * License: www.highcharts.com/license
+ */
+'use strict';
+import '../../indicators/cci.src.js';

+ 14 - 0
app/public/js/Highstock-8.0.0/code/es-modules/masters/indicators/chaikin.src.js

@@ -0,0 +1,14 @@
+/**
+ * @license Highstock JS v8.0.0 (2019-12-10)
+ * @module highcharts/indicators/chaikin
+ * @requires highcharts
+ * @requires highcharts/modules/stock
+ *
+ * Indicator series type for Highstock
+ *
+ * (c) 2010-2019 Wojciech Chmiel
+ *
+ * License: www.highcharts.com/license
+ */
+'use strict';
+import '../../indicators/chaikin.src.js';

+ 13 - 0
app/public/js/Highstock-8.0.0/code/es-modules/masters/indicators/cmf.src.js

@@ -0,0 +1,13 @@
+/**
+ * @license Highstock JS v8.0.0 (2019-12-10)
+ * @module highcharts/indicators/cmf
+ * @requires highcharts
+ * @requires highcharts/modules/stock
+ *
+ * (c) 2010-2019 Highsoft AS
+ * Author: Sebastian Domas
+ *
+ * License: www.highcharts.com/license
+ */
+'use strict';
+import '../../indicators/cmf.src.js';

+ 14 - 0
app/public/js/Highstock-8.0.0/code/es-modules/masters/indicators/dema.src.js

@@ -0,0 +1,14 @@
+/**
+ * @license Highstock JS v8.0.0 (2019-12-10)
+ * @module highcharts/indicators/dema
+ * @requires highcharts
+ * @requires highcharts/modules/stock
+ *
+ * Indicator series type for Highstock
+ *
+ * (c) 2010-2019 Rafał Sebestjański
+ *
+ * License: www.highcharts.com/license
+ */
+'use strict';
+import '../../indicators/dema.src.js';

+ 14 - 0
app/public/js/Highstock-8.0.0/code/es-modules/masters/indicators/dpo.src.js

@@ -0,0 +1,14 @@
+/**
+ * @license Highstock JS v8.0.0 (2019-12-10)
+ * @module highcharts/indicators/dpo
+ * @requires highcharts
+ * @requires highcharts/modules/stock
+ *
+ * Indicator series type for Highstock
+ *
+ * (c) 2010-2019 Wojciech Chmiel
+ *
+ * License: www.highcharts.com/license
+ */
+'use strict';
+import '../../indicators/dpo.src.js';

+ 14 - 0
app/public/js/Highstock-8.0.0/code/es-modules/masters/indicators/ema.src.js

@@ -0,0 +1,14 @@
+/**
+ * @license Highstock JS v8.0.0 (2019-12-10)
+ * @module highcharts/indicators/ema
+ * @requires highcharts
+ * @requires highcharts/modules/stock
+ *
+ * Indicator series type for Highstock
+ *
+ * (c) 2010-2019 Sebastian Bochan
+ *
+ * License: www.highcharts.com/license
+ */
+'use strict';
+import '../../indicators/ema.src.js';

+ 14 - 0
app/public/js/Highstock-8.0.0/code/es-modules/masters/indicators/ichimoku-kinko-hyo.src.js

@@ -0,0 +1,14 @@
+/**
+ * @license Highstock JS v8.0.0 (2019-12-10)
+ * @module highcharts/indicators/ichimoku-kinko-hyo
+ * @requires highcharts
+ * @requires highcharts/modules/stock
+ *
+ * Indicator series type for Highstock
+ *
+ * (c) 2010-2019 Sebastian Bochan
+ *
+ * License: www.highcharts.com/license
+ */
+'use strict';
+import '../../indicators/ichimoku-kinko-hyo.src.js';

+ 54 - 0
app/public/js/Highstock-8.0.0/code/es-modules/masters/indicators/indicators-all.src.js

@@ -0,0 +1,54 @@
+/**
+ * @license Highstock JS v8.0.0 (2019-12-10)
+ * @module highcharts/indicators/indicators-all
+ * @requires highcharts
+ * @requires highcharts/modules/stock
+ *
+ * All technical indicators for Highstock
+ *
+ * (c) 2010-2019 Pawel Fus
+ *
+ * License: www.highcharts.com/license
+ */
+'use strict';
+
+import '../../indicators/indicators.src.js';
+import '../../indicators/accumulation-distribution.src.js';
+import '../../indicators/ao.src.js';
+import '../../indicators/aroon.src.js';
+import '../../indicators/aroon-oscillator.src.js';
+import '../../indicators/atr.src.js';
+import '../../indicators/bollinger-bands.src.js';
+import '../../indicators/cci.src.js';
+import '../../indicators/cmf.src.js';
+import '../../indicators/dpo.src.js';
+import '../../indicators/ema.src.js';
+import '../../indicators/chaikin.src.js';
+import '../../indicators/dema.src.js';
+import '../../indicators/tema.src.js';
+import '../../indicators/trix.src.js';
+import '../../indicators/apo.src.js';
+import '../../indicators/ichimoku-kinko-hyo.src.js';
+import '../../indicators/keltner-channels.src.js';
+import '../../indicators/macd.src.js';
+import '../../indicators/mfi.src.js';
+import '../../indicators/momentum.src.js';
+import '../../indicators/natr.src.js';
+import '../../indicators/pivot-points.src.js';
+import '../../indicators/ppo.src.js';
+import '../../indicators/price-channel.src.js';
+import '../../indicators/price-envelopes.src.js';
+import '../../indicators/psar.src.js';
+import '../../indicators/roc.src.js';
+import '../../indicators/rsi.src.js';
+import '../../indicators/stochastic.src.js';
+import '../../indicators/slow-stochastic.src.js';
+import '../../indicators/supertrend.src.js';
+import '../../indicators/volume-by-price.src.js';
+import '../../indicators/vwap.src.js';
+import '../../indicators/williams-r.src.js';
+import '../../indicators/wma.src.js';
+import '../../indicators/zigzag.src.js';
+import '../../indicators/regressions.src.js';
+import '../../indicators/acceleration-bands.src.js';
+import '../../indicators/trendline.src.js';

+ 14 - 0
app/public/js/Highstock-8.0.0/code/es-modules/masters/indicators/indicators.src.js

@@ -0,0 +1,14 @@
+/**
+ * @license Highstock JS v8.0.0 (2019-12-10)
+ * @module highcharts/indicators/indicators
+ * @requires highcharts
+ * @requires highcharts/modules/stock
+ *
+ * Indicator series type for Highstock
+ *
+ * (c) 2010-2019 Pawel Fus, Sebastian Bochan
+ *
+ * License: www.highcharts.com/license
+ */
+'use strict';
+import '../../indicators/indicators.src.js';

+ 14 - 0
app/public/js/Highstock-8.0.0/code/es-modules/masters/indicators/keltner-channels.src.js

@@ -0,0 +1,14 @@
+/**
+ * @license Highstock JS v8.0.0 (2019-12-10)
+ * @module highcharts/indicators/keltner-channels
+ * @requires highcharts
+ * @requires highcharts/modules/stock
+ *
+ * Indicator series type for Highstock
+ *
+ * (c) 2010-2019 Daniel Studencki
+ *
+ * License: www.highcharts.com/license
+ */
+'use strict';
+import '../../indicators/keltner-channels.src.js';

+ 14 - 0
app/public/js/Highstock-8.0.0/code/es-modules/masters/indicators/macd.src.js

@@ -0,0 +1,14 @@
+/**
+ * @license Highstock JS v8.0.0 (2019-12-10)
+ * @module highcharts/indicators/macd
+ * @requires highcharts
+ * @requires highcharts/modules/stock
+ *
+ * Indicator series type for Highstock
+ *
+ * (c) 2010-2019 Sebastian Bochan
+ *
+ * License: www.highcharts.com/license
+ */
+'use strict';
+import '../../indicators/macd.src.js';

+ 14 - 0
app/public/js/Highstock-8.0.0/code/es-modules/masters/indicators/mfi.src.js

@@ -0,0 +1,14 @@
+/**
+ * @license Highstock JS v8.0.0 (2019-12-10)
+ * @module highcharts/indicators/mfi
+ * @requires highcharts
+ * @requires highcharts/modules/stock
+ *
+ * Money Flow Index indicator for Highstock
+ *
+ * (c) 2010-2019 Grzegorz Blachliński
+ *
+ * License: www.highcharts.com/license
+ */
+'use strict';
+import '../../indicators/mfi.src.js';

Bu fark içinde çok fazla dosya değişikliği olduğu için bazı dosyalar gösterilmiyor