ngx-register-base 1.3.1 → 1.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (479) hide show
  1. package/esm2022/lib/components/checkbox-selector/checkbox-selector.component.mjs +129 -0
  2. package/esm2022/lib/components/checkbox-selector/checkbox-selector.types.mjs +8 -0
  3. package/esm2022/lib/components/column-settings/column-settings.component.mjs +249 -0
  4. package/esm2022/lib/components/column-settings/components/column-settings-template/column-settings-template.component.mjs +80 -0
  5. package/esm2022/lib/components/column-settings/consts/column-settings.consts.mjs +10 -0
  6. package/esm2022/lib/components/column-settings/index.mjs +3 -0
  7. package/esm2022/lib/components/column-settings/types/column-settings.types.mjs +7 -0
  8. package/esm2022/lib/components/divider/divider.component.mjs +16 -0
  9. package/esm2022/lib/components/filter-button/filter-button.component.mjs +19 -0
  10. package/esm2022/lib/components/filters/components/filter-list/filter-edit/filter-edit.component.mjs +31 -0
  11. package/esm2022/lib/components/filters/components/filter-list/filter-list-footer/filter-list-footer.component.mjs +57 -0
  12. package/esm2022/lib/components/filters/components/filter-list/filter-list-header/filter-list-header.component.mjs +110 -0
  13. package/esm2022/lib/components/filters/components/filter-list/filter-list-saved/filter-list-saved.component.mjs +130 -0
  14. package/esm2022/lib/components/filters/components/filter-list/filter-list.service.mjs +89 -0
  15. package/esm2022/lib/components/filters/components/filter-list/filters-section/filters-section.component.mjs +41 -0
  16. package/esm2022/lib/components/filters/components/filter-list.module.mjs +45 -0
  17. package/esm2022/lib/components/filters/index.mjs +3 -0
  18. package/esm2022/lib/components/filters/register-table-filter.component.mjs +155 -0
  19. package/esm2022/lib/components/filters/register-table-filter.module.mjs +39 -0
  20. package/esm2022/lib/components/index.mjs +11 -0
  21. package/esm2022/lib/components/inputs/index.mjs +20 -0
  22. package/esm2022/lib/components/inputs/inputs.module.mjs +166 -0
  23. package/esm2022/lib/components/inputs/param-calendar-year/param-calendar-year.component.mjs +45 -0
  24. package/esm2022/lib/components/inputs/param-custom/param-custom.component.mjs +12 -0
  25. package/esm2022/lib/components/inputs/param-date/param-date.component.mjs +76 -0
  26. package/esm2022/lib/components/inputs/param-date-range/param-date-range.component.mjs +60 -0
  27. package/esm2022/lib/components/inputs/param-date-time/param-date-time.component.mjs +86 -0
  28. package/esm2022/lib/components/inputs/param-date-time-range/param-date-time-range.component.mjs +95 -0
  29. package/esm2022/lib/components/inputs/param-month/param-month.component.mjs +50 -0
  30. package/esm2022/lib/components/inputs/param-month-range/param-month-range.component.mjs +62 -0
  31. package/esm2022/lib/components/inputs/param-multi-select/param-multi-select.component.mjs +309 -0
  32. package/esm2022/lib/components/inputs/param-select/param-select.component.mjs +225 -0
  33. package/esm2022/lib/components/inputs/param-switcher/param-switcher.component.mjs +21 -0
  34. package/esm2022/lib/components/inputs/param-switcher-date-time-range/consts/param-switcher-date-time-range.consts.mjs +28 -0
  35. package/esm2022/lib/components/inputs/param-switcher-date-time-range/index.mjs +3 -0
  36. package/esm2022/lib/components/inputs/param-switcher-date-time-range/param-switcher-date-time-range.component.mjs +105 -0
  37. package/esm2022/lib/components/inputs/param-switcher-date-time-range/types/param-switcher-date-time-range.types.mjs +10 -0
  38. package/esm2022/lib/components/inputs/param-text/param-text.component.mjs +40 -0
  39. package/esm2022/lib/components/inputs/param-textarea/param-textarea.component.mjs +38 -0
  40. package/esm2022/lib/components/inputs/param-toggle/param-toggle.component.mjs +20 -0
  41. package/esm2022/lib/components/inputs/param-tree/consts/param-tree.consts.mjs +37 -0
  42. package/esm2022/lib/components/inputs/param-tree/index.mjs +8 -0
  43. package/esm2022/lib/components/inputs/param-tree/param-tree.component.mjs +207 -0
  44. package/esm2022/lib/components/inputs/param-tree/services/param-tree.service.mjs +116 -0
  45. package/esm2022/lib/components/inputs/param-tree/services/sync-tree-loader.service.mjs +20 -0
  46. package/esm2022/lib/components/inputs/param-tree/tokens/param-tree.tokens.mjs +3 -0
  47. package/esm2022/lib/components/inputs/param-tree/types/param-tree.types.mjs +2 -0
  48. package/esm2022/lib/components/inputs/param-tree/utils/param-tree.utils.mjs +9 -0
  49. package/esm2022/lib/components/inputs/param-tree-multi-select/param-tree-multi-select.component.mjs +80 -0
  50. package/esm2022/lib/components/inputs/param-tree-select/param-tree-select.component.mjs +85 -0
  51. package/esm2022/lib/components/inputs/sub-components/param-delete-content-icon/param-delete-content-btn.component.mjs +15 -0
  52. package/esm2022/lib/components/inputs/sub-components/param-invalid-icon/param-invalid-icon.component.mjs +12 -0
  53. package/esm2022/lib/components/menu-constructor/index.mjs +5 -0
  54. package/esm2022/lib/components/menu-constructor/sproc-menu-constructor.component.mjs +559 -0
  55. package/esm2022/lib/components/menu-constructor/store/sproc-abstract-menu-constructor.store.mjs +3 -0
  56. package/esm2022/lib/components/menu-constructor/store/sproc-menu-constructor.consts.mjs +5 -0
  57. package/esm2022/lib/components/menu-constructor/store/sproc-menu.tokens.mjs +3 -0
  58. package/esm2022/lib/components/page-menu/index.mjs +6 -0
  59. package/esm2022/lib/components/page-menu/schema/sproc-page-menu.consts.mjs +9 -0
  60. package/esm2022/lib/components/page-menu/schema/sproc-page-menu.schema.mjs +2 -0
  61. package/esm2022/lib/components/page-menu/schema/sproc-page-menu.tokens.mjs +4 -0
  62. package/esm2022/lib/components/page-menu/schema/sproc-page-menu.types.mjs +3 -0
  63. package/esm2022/lib/components/page-menu/sproc-page-menu.component.mjs +275 -0
  64. package/esm2022/lib/components/paginator/paginator.component.mjs +159 -0
  65. package/esm2022/lib/components/paginator/types/paginator.types.mjs +2 -0
  66. package/esm2022/lib/components/register-table/consts/register-table.consts.mjs +4 -0
  67. package/esm2022/lib/components/register-table/directives/cell-template.directive.mjs +19 -0
  68. package/esm2022/lib/components/register-table/directives/header-template.directive.mjs +18 -0
  69. package/esm2022/lib/components/register-table/index.mjs +4 -0
  70. package/esm2022/lib/components/register-table/model/schema.mjs +10 -0
  71. package/esm2022/lib/components/register-table/pipes/class-by-type.pipe.mjs +33 -0
  72. package/esm2022/lib/components/register-table/pipes/sticky-column.pipe.mjs +17 -0
  73. package/esm2022/lib/components/register-table/register-table.component.mjs +544 -0
  74. package/esm2022/lib/components/reset-settings-form/reset-settings-form.component.mjs +18 -0
  75. package/esm2022/lib/components/search-input/search-input.component.mjs +28 -0
  76. package/esm2022/lib/components/sliding-panel/sliding-panel.component.mjs +48 -0
  77. package/esm2022/lib/components/sliding-panel/sliding-panel.module.mjs +19 -0
  78. package/esm2022/lib/consts/date-time.consts.mjs +2 -0
  79. package/esm2022/lib/consts/index.mjs +4 -0
  80. package/esm2022/lib/consts/inputs.consts.mjs +4 -0
  81. package/esm2022/lib/consts/month.consts.mjs +77 -0
  82. package/esm2022/lib/consts/params.consts.mjs +2 -0
  83. package/esm2022/lib/consts/register-base.consts.mjs +26 -0
  84. package/esm2022/lib/core/form-group-wrapper/errors-consts.mjs +8 -0
  85. package/esm2022/lib/core/form-group-wrapper/form-group-wrapper.mjs +81 -0
  86. package/esm2022/lib/core/form-group-wrapper/index.mjs +2 -0
  87. package/esm2022/lib/core/index.mjs +5 -0
  88. package/esm2022/lib/core/input-control/index.mjs +2 -0
  89. package/esm2022/lib/core/input-control/input-control.mjs +11 -0
  90. package/esm2022/lib/core/param/index.mjs +6 -0
  91. package/esm2022/lib/core/param/param-base.mjs +215 -0
  92. package/esm2022/lib/core/param/param-date-base.mjs +26 -0
  93. package/esm2022/lib/core/param/param-select-base.mjs +114 -0
  94. package/esm2022/lib/core/param/param-text-base.mjs +25 -0
  95. package/esm2022/lib/core/param/param.tokens.mjs +4 -0
  96. package/esm2022/lib/core/register-base/index.mjs +3 -0
  97. package/esm2022/lib/core/register-base/register-base.mjs +575 -0
  98. package/esm2022/lib/core/register-base/register-base.store.mjs +43 -0
  99. package/esm2022/lib/directives/date/date-time.types.mjs +34 -0
  100. package/esm2022/lib/directives/date/format-date.pipe.mjs +33 -0
  101. package/esm2022/lib/directives/index.mjs +3 -0
  102. package/esm2022/lib/directives/number/number-only.directive.mjs +41 -0
  103. package/esm2022/lib/directives/sticky/index.mjs +3 -0
  104. package/esm2022/lib/directives/sticky/sticky-relative.directive.mjs +32 -0
  105. package/esm2022/lib/directives/sticky/sticky-relative.service.mjs +32 -0
  106. package/esm2022/lib/directives/sticky/sticky.directive.mjs +169 -0
  107. package/esm2022/lib/services/date-time.service.mjs +314 -0
  108. package/esm2022/lib/services/dialog/dialog.service.mjs +53 -0
  109. package/esm2022/lib/services/dialog/dialog.types.mjs +2 -0
  110. package/esm2022/lib/services/dialog/index.mjs +3 -0
  111. package/esm2022/lib/services/dom-intersection.service.mjs +22 -0
  112. package/esm2022/lib/services/filter/filters-state.service.mjs +65 -0
  113. package/esm2022/lib/services/filter/filters-transmit.service.mjs +82 -0
  114. package/esm2022/lib/services/filter/filters.service.mjs +23 -0
  115. package/esm2022/lib/services/index.mjs +8 -0
  116. package/esm2022/lib/services/inputs-state.service.mjs +130 -0
  117. package/esm2022/lib/services/inputs.service.mjs +88 -0
  118. package/esm2022/lib/services/key-pressed.service.mjs +37 -0
  119. package/esm2022/lib/services/resize-window-observer.service.mjs +33 -0
  120. package/esm2022/lib/services/selected-objects-state.service.mjs +123 -0
  121. package/esm2022/lib/store/fast-query-store.service.mjs +110 -0
  122. package/esm2022/lib/store/index.mjs +2 -0
  123. package/esm2022/lib/types/event.types.mjs +2 -0
  124. package/esm2022/lib/types/hasura.types.mjs +2 -0
  125. package/esm2022/lib/types/index.mjs +7 -0
  126. package/esm2022/lib/types/inputs.types.mjs +19 -0
  127. package/esm2022/lib/types/params.types.mjs +2 -0
  128. package/esm2022/lib/types/register-base.types.mjs +6 -0
  129. package/esm2022/lib/types/sub-types.mjs +2 -0
  130. package/esm2022/lib/types/user-profile.types.mjs +2 -0
  131. package/esm2022/lib/utils/functions.mjs +10 -0
  132. package/esm2022/lib/utils/get-url-segment.mjs +35 -0
  133. package/esm2022/lib/utils/index.mjs +5 -0
  134. package/esm2022/lib/utils/prizm.shared.module.mjs +284 -0
  135. package/esm2022/lib/utils/rxjs.mjs +28 -0
  136. package/esm2022/lib/utils/select-all-utils.mjs +11 -0
  137. package/esm2022/ngx-register-base.mjs +5 -0
  138. package/esm2022/public-api.mjs +9 -0
  139. package/fesm2022/ngx-register-base.mjs +7479 -0
  140. package/fesm2022/ngx-register-base.mjs.map +1 -0
  141. package/index.d.ts +5 -0
  142. package/lib/components/checkbox-selector/checkbox-selector.component.d.ts +33 -0
  143. package/lib/components/checkbox-selector/checkbox-selector.types.d.ts +7 -0
  144. package/lib/components/column-settings/column-settings.component.d.ts +80 -0
  145. package/lib/components/column-settings/components/column-settings-template/column-settings-template.component.d.ts +24 -0
  146. package/lib/components/column-settings/consts/column-settings.consts.d.ts +8 -0
  147. package/lib/components/column-settings/types/column-settings.types.d.ts +22 -0
  148. package/lib/components/divider/divider.component.d.ts +6 -0
  149. package/lib/components/filter-button/filter-button.component.d.ts +8 -0
  150. package/lib/components/filters/components/filter-list/filter-edit/filter-edit.component.d.ts +14 -0
  151. package/lib/components/filters/components/filter-list/filter-list-footer/filter-list-footer.component.d.ts +25 -0
  152. package/lib/components/filters/components/filter-list/filter-list-header/filter-list-header.component.d.ts +39 -0
  153. package/lib/components/filters/components/filter-list/filter-list-saved/filter-list-saved.component.d.ts +41 -0
  154. package/lib/components/filters/components/filter-list/filter-list.service.d.ts +20 -0
  155. package/lib/components/filters/components/filter-list/filters-section/filters-section.component.d.ts +15 -0
  156. package/lib/components/filters/components/filter-list.module.d.ts +15 -0
  157. package/lib/components/filters/register-table-filter.component.d.ts +40 -0
  158. package/lib/components/filters/register-table-filter.module.d.ts +13 -0
  159. package/lib/components/inputs/inputs.module.d.ts +31 -0
  160. package/lib/components/inputs/param-calendar-year/param-calendar-year.component.d.ts +19 -0
  161. package/lib/components/inputs/param-custom/param-custom.component.d.ts +6 -0
  162. package/lib/components/inputs/param-date/param-date.component.d.ts +20 -0
  163. package/lib/components/inputs/param-date-range/param-date-range.component.d.ts +26 -0
  164. package/lib/components/inputs/param-date-time/param-date-time.component.d.ts +25 -0
  165. package/lib/components/inputs/param-date-time-range/param-date-time-range.component.d.ts +28 -0
  166. package/lib/components/inputs/param-month/param-month.component.d.ts +18 -0
  167. package/lib/components/inputs/param-month-range/param-month-range.component.d.ts +21 -0
  168. package/lib/components/inputs/param-multi-select/param-multi-select.component.d.ts +46 -0
  169. package/lib/components/inputs/param-select/param-select.component.d.ts +34 -0
  170. package/lib/components/inputs/param-switcher/param-switcher.component.d.ts +8 -0
  171. package/lib/components/inputs/param-switcher-date-time-range/consts/param-switcher-date-time-range.consts.d.ts +2 -0
  172. package/lib/components/inputs/param-switcher-date-time-range/param-switcher-date-time-range.component.d.ts +19 -0
  173. package/lib/components/inputs/param-switcher-date-time-range/types/param-switcher-date-time-range.types.d.ts +8 -0
  174. package/lib/components/inputs/param-text/param-text.component.d.ts +10 -0
  175. package/lib/components/inputs/param-textarea/param-textarea.component.d.ts +10 -0
  176. package/lib/components/inputs/param-toggle/param-toggle.component.d.ts +9 -0
  177. package/lib/components/inputs/param-tree/consts/param-tree.consts.d.ts +7 -0
  178. package/lib/components/inputs/param-tree/param-tree.component.d.ts +41 -0
  179. package/lib/components/inputs/param-tree/services/param-tree.service.d.ts +37 -0
  180. package/lib/components/inputs/param-tree/services/sync-tree-loader.service.d.ts +10 -0
  181. package/{src/lib/components/inputs/param-tree/tokens/param-tree.tokens.ts → lib/components/inputs/param-tree/tokens/param-tree.tokens.d.ts} +1 -2
  182. package/lib/components/inputs/param-tree/types/param-tree.types.d.ts +32 -0
  183. package/lib/components/inputs/param-tree/utils/param-tree.utils.d.ts +7 -0
  184. package/lib/components/inputs/param-tree-multi-select/param-tree-multi-select.component.d.ts +31 -0
  185. package/lib/components/inputs/param-tree-select/param-tree-select.component.d.ts +30 -0
  186. package/lib/components/inputs/sub-components/param-delete-content-icon/param-delete-content-btn.component.d.ts +6 -0
  187. package/lib/components/inputs/sub-components/param-invalid-icon/param-invalid-icon.component.d.ts +5 -0
  188. package/lib/components/menu-constructor/sproc-menu-constructor.component.d.ts +113 -0
  189. package/lib/components/menu-constructor/store/sproc-abstract-menu-constructor.store.d.ts +24 -0
  190. package/lib/components/menu-constructor/store/sproc-menu-constructor.consts.d.ts +36 -0
  191. package/{src/lib/components/menu-constructor/store/sproc-menu.tokens.ts → lib/components/menu-constructor/store/sproc-menu.tokens.d.ts} +1 -4
  192. package/lib/components/page-menu/schema/sproc-page-menu.consts.d.ts +7 -0
  193. package/lib/components/page-menu/schema/sproc-page-menu.schema.d.ts +30 -0
  194. package/lib/components/page-menu/schema/sproc-page-menu.tokens.d.ts +3 -0
  195. package/lib/components/page-menu/schema/sproc-page-menu.types.d.ts +36 -0
  196. package/lib/components/page-menu/sproc-page-menu.component.d.ts +48 -0
  197. package/lib/components/paginator/paginator.component.d.ts +52 -0
  198. package/lib/components/paginator/types/paginator.types.d.ts +15 -0
  199. package/lib/components/register-table/consts/register-table.consts.d.ts +3 -0
  200. package/lib/components/register-table/directives/cell-template.directive.d.ts +9 -0
  201. package/lib/components/register-table/directives/header-template.directive.d.ts +9 -0
  202. package/lib/components/register-table/model/schema.d.ts +52 -0
  203. package/lib/components/register-table/pipes/class-by-type.pipe.d.ts +8 -0
  204. package/lib/components/register-table/pipes/sticky-column.pipe.d.ts +7 -0
  205. package/lib/components/register-table/register-table.component.d.ts +165 -0
  206. package/lib/components/reset-settings-form/reset-settings-form.component.d.ts +9 -0
  207. package/lib/components/search-input/search-input.component.d.ts +11 -0
  208. package/lib/components/sliding-panel/sliding-panel.component.d.ts +14 -0
  209. package/lib/components/sliding-panel/sliding-panel.module.d.ts +9 -0
  210. package/lib/consts/date-time.consts.d.ts +1 -0
  211. package/lib/consts/index.d.ts +3 -0
  212. package/lib/consts/inputs.consts.d.ts +4 -0
  213. package/lib/consts/month.consts.d.ts +49 -0
  214. package/lib/consts/params.consts.d.ts +1 -0
  215. package/lib/consts/register-base.consts.d.ts +19 -0
  216. package/lib/core/form-group-wrapper/errors-consts.d.ts +5 -0
  217. package/lib/core/form-group-wrapper/form-group-wrapper.d.ts +15 -0
  218. package/lib/core/input-control/input-control.d.ts +11 -0
  219. package/lib/core/param/param-base.d.ts +68 -0
  220. package/lib/core/param/param-date-base.d.ts +18 -0
  221. package/lib/core/param/param-select-base.d.ts +42 -0
  222. package/lib/core/param/param-text-base.d.ts +15 -0
  223. package/{src/lib/core/param/param.tokens.ts → lib/core/param/param.tokens.d.ts} +1 -2
  224. package/lib/core/register-base/register-base.d.ts +168 -0
  225. package/lib/core/register-base/register-base.store.d.ts +35 -0
  226. package/lib/directives/date/date-time.types.d.ts +32 -0
  227. package/lib/directives/date/format-date.pipe.d.ts +10 -0
  228. package/lib/directives/number/number-only.directive.d.ts +10 -0
  229. package/lib/directives/sticky/sticky-relative.directive.d.ts +13 -0
  230. package/lib/directives/sticky/sticky-relative.service.d.ts +15 -0
  231. package/lib/directives/sticky/sticky.directive.d.ts +27 -0
  232. package/lib/services/date-time.service.d.ts +80 -0
  233. package/lib/services/dialog/dialog.service.d.ts +22 -0
  234. package/{src/lib/services/dialog/dialog.types.ts → lib/services/dialog/dialog.types.d.ts} +4 -8
  235. package/lib/services/dom-intersection.service.d.ts +8 -0
  236. package/lib/services/filter/filters-state.service.d.ts +21 -0
  237. package/lib/services/filter/filters-transmit.service.d.ts +28 -0
  238. package/lib/services/filter/filters.service.d.ts +12 -0
  239. package/lib/services/inputs-state.service.d.ts +57 -0
  240. package/lib/services/inputs.service.d.ts +28 -0
  241. package/lib/services/key-pressed.service.d.ts +15 -0
  242. package/lib/services/resize-window-observer.service.d.ts +11 -0
  243. package/lib/services/selected-objects-state.service.d.ts +47 -0
  244. package/lib/store/fast-query-store.service.d.ts +19 -0
  245. package/{src/lib/types/event.types.ts → lib/types/event.types.d.ts} +1 -1
  246. package/lib/types/hasura.types.d.ts +35 -0
  247. package/lib/types/inputs.types.d.ts +41 -0
  248. package/lib/types/params.types.d.ts +27 -0
  249. package/lib/types/register-base.types.d.ts +123 -0
  250. package/lib/types/sub-types.d.ts +8 -0
  251. package/lib/types/user-profile.types.d.ts +17 -0
  252. package/lib/utils/functions.d.ts +3 -0
  253. package/lib/utils/get-url-segment.d.ts +7 -0
  254. package/lib/utils/prizm.shared.module.d.ts +14 -0
  255. package/lib/utils/rxjs.d.ts +10 -0
  256. package/lib/utils/select-all-utils.d.ts +8 -0
  257. package/package.json +15 -12
  258. package/schematics/ng-update/replace-menu-state-token/index.d.ts +2 -0
  259. package/schematics/ng-update/replace-menu-state-token/index.js +29 -0
  260. package/schematics/ng-update/replace-menu-state-token/index.js.map +1 -0
  261. package/schematics/ng-update/update-prefix/index.d.ts +2 -0
  262. package/schematics/ng-update/update-prefix/index.js +33 -0
  263. package/schematics/ng-update/update-prefix/index.js.map +1 -0
  264. package/schematics/utils/{utils.ts → utils.d.ts} +2 -9
  265. package/schematics/utils/utils.js +25 -0
  266. package/schematics/utils/utils.js.map +1 -0
  267. package/ng-package.json +0 -15
  268. package/schematics/ng-update/replace-menu-state-token/index.ts +0 -33
  269. package/schematics/ng-update/update-prefix/index.ts +0 -38
  270. package/src/lib/components/checkbox-selector/checkbox-selector.component.html +0 -91
  271. package/src/lib/components/checkbox-selector/checkbox-selector.component.less +0 -67
  272. package/src/lib/components/checkbox-selector/checkbox-selector.component.ts +0 -176
  273. package/src/lib/components/checkbox-selector/checkbox-selector.types.ts +0 -8
  274. package/src/lib/components/column-settings/column-settings.component.html +0 -160
  275. package/src/lib/components/column-settings/column-settings.component.less +0 -131
  276. package/src/lib/components/column-settings/column-settings.component.ts +0 -352
  277. package/src/lib/components/column-settings/components/column-settings-template/column-settings-template.component.html +0 -65
  278. package/src/lib/components/column-settings/components/column-settings-template/column-settings-template.component.less +0 -79
  279. package/src/lib/components/column-settings/components/column-settings-template/column-settings-template.component.ts +0 -114
  280. package/src/lib/components/column-settings/consts/column-settings.consts.ts +0 -9
  281. package/src/lib/components/column-settings/types/column-settings.types.ts +0 -26
  282. package/src/lib/components/divider/divider.component.html +0 -4
  283. package/src/lib/components/divider/divider.component.less +0 -10
  284. package/src/lib/components/divider/divider.component.ts +0 -12
  285. package/src/lib/components/filter-button/filter-button.component.html +0 -20
  286. package/src/lib/components/filter-button/filter-button.component.less +0 -41
  287. package/src/lib/components/filter-button/filter-button.component.ts +0 -18
  288. package/src/lib/components/filters/components/filter-list/filter-edit/filter-edit.component.html +0 -22
  289. package/src/lib/components/filters/components/filter-list/filter-edit/filter-edit.component.less +0 -23
  290. package/src/lib/components/filters/components/filter-list/filter-edit/filter-edit.component.ts +0 -31
  291. package/src/lib/components/filters/components/filter-list/filter-list-footer/filter-list-footer.component.html +0 -49
  292. package/src/lib/components/filters/components/filter-list/filter-list-footer/filter-list-footer.component.less +0 -37
  293. package/src/lib/components/filters/components/filter-list/filter-list-footer/filter-list-footer.component.ts +0 -66
  294. package/src/lib/components/filters/components/filter-list/filter-list-header/filter-list-header.component.html +0 -147
  295. package/src/lib/components/filters/components/filter-list/filter-list-header/filter-list-header.component.less +0 -45
  296. package/src/lib/components/filters/components/filter-list/filter-list-header/filter-list-header.component.ts +0 -114
  297. package/src/lib/components/filters/components/filter-list/filter-list-saved/filter-list-saved.component.html +0 -44
  298. package/src/lib/components/filters/components/filter-list/filter-list-saved/filter-list-saved.component.less +0 -49
  299. package/src/lib/components/filters/components/filter-list/filter-list-saved/filter-list-saved.component.ts +0 -167
  300. package/src/lib/components/filters/components/filter-list/filter-list.service.ts +0 -97
  301. package/src/lib/components/filters/components/filter-list/filters-section/filters-section.component.html +0 -18
  302. package/src/lib/components/filters/components/filter-list/filters-section/filters-section.component.less +0 -55
  303. package/src/lib/components/filters/components/filter-list/filters-section/filters-section.component.ts +0 -69
  304. package/src/lib/components/filters/components/filter-list.module.ts +0 -29
  305. package/src/lib/components/filters/register-table-filter.component.html +0 -53
  306. package/src/lib/components/filters/register-table-filter.component.less +0 -17
  307. package/src/lib/components/filters/register-table-filter.component.ts +0 -167
  308. package/src/lib/components/filters/register-table-filter.module.ts +0 -22
  309. package/src/lib/components/inputs/inputs.module.ts +0 -104
  310. package/src/lib/components/inputs/param-calendar-year/param-calendar-year.component.html +0 -49
  311. package/src/lib/components/inputs/param-calendar-year/param-calendar-year.component.less +0 -70
  312. package/src/lib/components/inputs/param-calendar-year/param-calendar-year.component.ts +0 -52
  313. package/src/lib/components/inputs/param-custom/param-custom.component.html +0 -1
  314. package/src/lib/components/inputs/param-custom/param-custom.component.ts +0 -9
  315. package/src/lib/components/inputs/param-date/param-date.component.html +0 -55
  316. package/src/lib/components/inputs/param-date/param-date.component.less +0 -67
  317. package/src/lib/components/inputs/param-date/param-date.component.ts +0 -77
  318. package/src/lib/components/inputs/param-date-range/param-date-range.component.html +0 -45
  319. package/src/lib/components/inputs/param-date-range/param-date-range.component.less +0 -75
  320. package/src/lib/components/inputs/param-date-range/param-date-range.component.ts +0 -67
  321. package/src/lib/components/inputs/param-date-time/param-date-time.component.html +0 -70
  322. package/src/lib/components/inputs/param-date-time/param-date-time.component.less +0 -72
  323. package/src/lib/components/inputs/param-date-time/param-date-time.component.ts +0 -101
  324. package/src/lib/components/inputs/param-date-time-range/param-date-time-range.component.html +0 -67
  325. package/src/lib/components/inputs/param-date-time-range/param-date-time-range.component.less +0 -103
  326. package/src/lib/components/inputs/param-date-time-range/param-date-time-range.component.ts +0 -128
  327. package/src/lib/components/inputs/param-month/param-month.component.html +0 -46
  328. package/src/lib/components/inputs/param-month/param-month.component.less +0 -72
  329. package/src/lib/components/inputs/param-month/param-month.component.ts +0 -55
  330. package/src/lib/components/inputs/param-month-range/param-month-range.component.html +0 -39
  331. package/src/lib/components/inputs/param-month-range/param-month-range.component.less +0 -71
  332. package/src/lib/components/inputs/param-month-range/param-month-range.component.ts +0 -76
  333. package/src/lib/components/inputs/param-multi-select/param-multi-select.component.html +0 -84
  334. package/src/lib/components/inputs/param-multi-select/param-multi-select.component.less +0 -108
  335. package/src/lib/components/inputs/param-multi-select/param-multi-select.component.ts +0 -448
  336. package/src/lib/components/inputs/param-select/param-select.component.html +0 -106
  337. package/src/lib/components/inputs/param-select/param-select.component.less +0 -26
  338. package/src/lib/components/inputs/param-select/param-select.component.ts +0 -318
  339. package/src/lib/components/inputs/param-switcher/param-switcher.component.html +0 -8
  340. package/src/lib/components/inputs/param-switcher/param-switcher.component.less +0 -53
  341. package/src/lib/components/inputs/param-switcher/param-switcher.component.ts +0 -13
  342. package/src/lib/components/inputs/param-switcher-date-time-range/consts/param-switcher-date-time-range.consts.ts +0 -29
  343. package/src/lib/components/inputs/param-switcher-date-time-range/param-switcher-date-time-range.component.html +0 -19
  344. package/src/lib/components/inputs/param-switcher-date-time-range/param-switcher-date-time-range.component.less +0 -76
  345. package/src/lib/components/inputs/param-switcher-date-time-range/param-switcher-date-time-range.component.ts +0 -134
  346. package/src/lib/components/inputs/param-switcher-date-time-range/types/param-switcher-date-time-range.types.ts +0 -8
  347. package/src/lib/components/inputs/param-text/param-text.component.html +0 -59
  348. package/src/lib/components/inputs/param-text/param-text.component.less +0 -33
  349. package/src/lib/components/inputs/param-text/param-text.component.ts +0 -36
  350. package/src/lib/components/inputs/param-textarea/param-textarea.component.html +0 -61
  351. package/src/lib/components/inputs/param-textarea/param-textarea.component.less +0 -21
  352. package/src/lib/components/inputs/param-textarea/param-textarea.component.ts +0 -33
  353. package/src/lib/components/inputs/param-toggle/param-toggle.component.html +0 -40
  354. package/src/lib/components/inputs/param-toggle/param-toggle.component.less +0 -69
  355. package/src/lib/components/inputs/param-toggle/param-toggle.component.ts +0 -14
  356. package/src/lib/components/inputs/param-tree/consts/param-tree.consts.ts +0 -59
  357. package/src/lib/components/inputs/param-tree/param-tree.component.html +0 -51
  358. package/src/lib/components/inputs/param-tree/param-tree.component.less +0 -3
  359. package/src/lib/components/inputs/param-tree/param-tree.component.ts +0 -282
  360. package/src/lib/components/inputs/param-tree/services/param-tree.service.ts +0 -176
  361. package/src/lib/components/inputs/param-tree/services/sync-tree-loader.service.ts +0 -18
  362. package/src/lib/components/inputs/param-tree/types/param-tree.types.ts +0 -39
  363. package/src/lib/components/inputs/param-tree/utils/param-tree.utils.ts +0 -18
  364. package/src/lib/components/inputs/param-tree-multi-select/param-tree-multi-select.component.html +0 -78
  365. package/src/lib/components/inputs/param-tree-multi-select/param-tree-multi-select.component.less +0 -109
  366. package/src/lib/components/inputs/param-tree-multi-select/param-tree-multi-select.component.ts +0 -89
  367. package/src/lib/components/inputs/param-tree-select/param-tree-select.component.html +0 -54
  368. package/src/lib/components/inputs/param-tree-select/param-tree-select.component.less +0 -56
  369. package/src/lib/components/inputs/param-tree-select/param-tree-select.component.ts +0 -91
  370. package/src/lib/components/inputs/sub-components/param-delete-content-icon/param-delete-content-btn.component.html +0 -5
  371. package/src/lib/components/inputs/sub-components/param-delete-content-icon/param-delete-content-btn.component.ts +0 -13
  372. package/src/lib/components/inputs/sub-components/param-invalid-icon/param-invalid-icon.component.html +0 -4
  373. package/src/lib/components/inputs/sub-components/param-invalid-icon/param-invalid-icon.component.ts +0 -11
  374. package/src/lib/components/menu-constructor/sproc-menu-constructor.component.html +0 -95
  375. package/src/lib/components/menu-constructor/sproc-menu-constructor.component.less +0 -183
  376. package/src/lib/components/menu-constructor/sproc-menu-constructor.component.ts +0 -687
  377. package/src/lib/components/menu-constructor/store/sproc-abstract-menu-constructor.store.ts +0 -32
  378. package/src/lib/components/menu-constructor/store/sproc-menu-constructor.consts.ts +0 -46
  379. package/src/lib/components/page-menu/README.md +0 -60
  380. package/src/lib/components/page-menu/schema/sproc-page-menu.consts.ts +0 -8
  381. package/src/lib/components/page-menu/schema/sproc-page-menu.schema.ts +0 -35
  382. package/src/lib/components/page-menu/schema/sproc-page-menu.tokens.ts +0 -5
  383. package/src/lib/components/page-menu/schema/sproc-page-menu.types.ts +0 -42
  384. package/src/lib/components/page-menu/sproc-page-menu.component.html +0 -166
  385. package/src/lib/components/page-menu/sproc-page-menu.component.less +0 -228
  386. package/src/lib/components/page-menu/sproc-page-menu.component.ts +0 -337
  387. package/src/lib/components/paginator/paginator.component.html +0 -97
  388. package/src/lib/components/paginator/paginator.component.less +0 -101
  389. package/src/lib/components/paginator/paginator.component.ts +0 -192
  390. package/src/lib/components/paginator/types/paginator.types.ts +0 -16
  391. package/src/lib/components/register-table/consts/register-table.consts.ts +0 -3
  392. package/src/lib/components/register-table/directives/cell-template.directive.ts +0 -11
  393. package/src/lib/components/register-table/directives/header-template.directive.ts +0 -11
  394. package/src/lib/components/register-table/model/schema.ts +0 -62
  395. package/src/lib/components/register-table/pipes/class-by-type.pipe.ts +0 -28
  396. package/src/lib/components/register-table/pipes/sticky-column.pipe.ts +0 -11
  397. package/src/lib/components/register-table/register-table.component.html +0 -257
  398. package/src/lib/components/register-table/register-table.component.less +0 -151
  399. package/src/lib/components/register-table/register-table.component.ts +0 -743
  400. package/src/lib/components/reset-settings-form/reset-settings-form.component.html +0 -14
  401. package/src/lib/components/reset-settings-form/reset-settings-form.component.less +0 -26
  402. package/src/lib/components/reset-settings-form/reset-settings-form.component.ts +0 -15
  403. package/src/lib/components/search-input/search-input.component.html +0 -6
  404. package/src/lib/components/search-input/search-input.component.less +0 -17
  405. package/src/lib/components/search-input/search-input.component.ts +0 -31
  406. package/src/lib/components/sliding-panel/sliding-panel.component.html +0 -13
  407. package/src/lib/components/sliding-panel/sliding-panel.component.less +0 -112
  408. package/src/lib/components/sliding-panel/sliding-panel.component.ts +0 -36
  409. package/src/lib/components/sliding-panel/sliding-panel.module.ts +0 -11
  410. package/src/lib/consts/date-time.consts.ts +0 -1
  411. package/src/lib/consts/index.ts +0 -8
  412. package/src/lib/consts/inputs.consts.ts +0 -9
  413. package/src/lib/consts/month.consts.ts +0 -82
  414. package/src/lib/consts/params.consts.ts +0 -1
  415. package/src/lib/consts/register-base.consts.ts +0 -40
  416. package/src/lib/core/form-group-wrapper/errors-consts.ts +0 -6
  417. package/src/lib/core/form-group-wrapper/form-group-wrapper.ts +0 -109
  418. package/src/lib/core/input-control/input-control.ts +0 -30
  419. package/src/lib/core/param/param-base.ts +0 -262
  420. package/src/lib/core/param/param-date-base.ts +0 -30
  421. package/src/lib/core/param/param-select-base.ts +0 -118
  422. package/src/lib/core/param/param-text-base.ts +0 -23
  423. package/src/lib/core/register-base/register-base.store.ts +0 -84
  424. package/src/lib/core/register-base/register-base.ts +0 -854
  425. package/src/lib/directives/date/date-time.types.ts +0 -36
  426. package/src/lib/directives/date/format-date.pipe.ts +0 -28
  427. package/src/lib/directives/number/number-only.directive.ts +0 -36
  428. package/src/lib/directives/sticky/sticky-relative.directive.ts +0 -30
  429. package/src/lib/directives/sticky/sticky-relative.service.ts +0 -34
  430. package/src/lib/directives/sticky/sticky.directive.ts +0 -189
  431. package/src/lib/services/date-time.service.ts +0 -399
  432. package/src/lib/services/dialog/dialog.service.ts +0 -62
  433. package/src/lib/services/dom-intersection.service.ts +0 -23
  434. package/src/lib/services/filter/filters-state.service.ts +0 -83
  435. package/src/lib/services/filter/filters-transmit.service.ts +0 -105
  436. package/src/lib/services/filter/filters.service.ts +0 -21
  437. package/src/lib/services/inputs-state.service.ts +0 -157
  438. package/src/lib/services/inputs.service.ts +0 -114
  439. package/src/lib/services/key-pressed.service.ts +0 -40
  440. package/src/lib/services/resize-window-observer.service.ts +0 -37
  441. package/src/lib/services/selected-objects-state.service.ts +0 -159
  442. package/src/lib/store/fast-query-store.service.ts +0 -132
  443. package/src/lib/types/hasura.types.ts +0 -41
  444. package/src/lib/types/inputs.types.ts +0 -63
  445. package/src/lib/types/params.types.ts +0 -42
  446. package/src/lib/types/register-base.types.ts +0 -161
  447. package/src/lib/types/sub-types.ts +0 -15
  448. package/src/lib/types/user-profile.types.ts +0 -18
  449. package/src/lib/utils/functions.ts +0 -11
  450. package/src/lib/utils/get-url-segment.ts +0 -46
  451. package/src/lib/utils/prizm.shared.module.ts +0 -176
  452. package/src/lib/utils/rxjs.ts +0 -33
  453. package/src/lib/utils/select-all-utils.ts +0 -16
  454. package/tsconfig.lib.json +0 -16
  455. package/tsconfig.lib.prod.json +0 -11
  456. package/tsconfig.schematics.json +0 -26
  457. package/tsconfig.spec.json +0 -15
  458. /package/{src/lib/components/column-settings/index.ts → lib/components/column-settings/index.d.ts} +0 -0
  459. /package/{src/lib/components/filters/index.ts → lib/components/filters/index.d.ts} +0 -0
  460. /package/{src/lib/components/index.ts → lib/components/index.d.ts} +0 -0
  461. /package/{src/lib/components/inputs/index.ts → lib/components/inputs/index.d.ts} +0 -0
  462. /package/{src/lib/components/inputs/param-switcher-date-time-range/index.ts → lib/components/inputs/param-switcher-date-time-range/index.d.ts} +0 -0
  463. /package/{src/lib/components/inputs/param-tree/index.ts → lib/components/inputs/param-tree/index.d.ts} +0 -0
  464. /package/{src/lib/components/menu-constructor/index.ts → lib/components/menu-constructor/index.d.ts} +0 -0
  465. /package/{src/lib/components/page-menu/index.ts → lib/components/page-menu/index.d.ts} +0 -0
  466. /package/{src/lib/components/register-table/index.ts → lib/components/register-table/index.d.ts} +0 -0
  467. /package/{src/lib/core/form-group-wrapper/index.ts → lib/core/form-group-wrapper/index.d.ts} +0 -0
  468. /package/{src/lib/core/index.ts → lib/core/index.d.ts} +0 -0
  469. /package/{src/lib/core/input-control/index.ts → lib/core/input-control/index.d.ts} +0 -0
  470. /package/{src/lib/core/param/index.ts → lib/core/param/index.d.ts} +0 -0
  471. /package/{src/lib/core/register-base/index.ts → lib/core/register-base/index.d.ts} +0 -0
  472. /package/{src/lib/directives/index.ts → lib/directives/index.d.ts} +0 -0
  473. /package/{src/lib/directives/sticky/index.ts → lib/directives/sticky/index.d.ts} +0 -0
  474. /package/{src/lib/services/dialog/index.ts → lib/services/dialog/index.d.ts} +0 -0
  475. /package/{src/lib/services/index.ts → lib/services/index.d.ts} +0 -0
  476. /package/{src/lib/store/index.ts → lib/store/index.d.ts} +0 -0
  477. /package/{src/lib/types/index.ts → lib/types/index.d.ts} +0 -0
  478. /package/{src/lib/utils/index.ts → lib/utils/index.d.ts} +0 -0
  479. /package/{src/public-api.ts → public-api.d.ts} +0 -0
@@ -0,0 +1,559 @@
1
+ import { Component, computed, DestroyRef, inject, output, signal } from '@angular/core';
2
+ import { FormsModule } from '@angular/forms';
3
+ import { CdkDrag, CdkDragHandle, CdkDragPreview, CdkDropList, } from '@angular/cdk/drag-drop';
4
+ import { AsyncPipe, NgForOf } from '@angular/common';
5
+ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
6
+ import { filter } from 'rxjs';
7
+ import { EMPTY_UUID, MIGRATION_HINT, NEW_ITEM_PREFIX, ROOT_TITLE, } from './store/sproc-menu-constructor.consts';
8
+ import { MENU_CONSTRUCTOR_STORE_TOKEN } from './store/sproc-menu.tokens';
9
+ import * as i0 from "@angular/core";
10
+ import * as i1 from "@angular/forms";
11
+ export class SprocMenuConstructorComponent {
12
+ constructor() {
13
+ this._store = inject(MENU_CONSTRUCTOR_STORE_TOKEN);
14
+ this._ref = inject(DestroyRef);
15
+ this.ROOT_TITLE = ROOT_TITLE;
16
+ this.loading$ = this._store.loading$;
17
+ this.originalTree = new Map([]);
18
+ this.MIGRATION_HINT = MIGRATION_HINT;
19
+ this.deletedIds = [];
20
+ this.errorMsgOutput = output();
21
+ // плоское представление иерархического меню
22
+ this.flatTree = signal([]);
23
+ // ветка элементов, которая перетаскивается
24
+ this.draggedBranch = signal([]);
25
+ // вычисляемое свойство, возвращающее только видимые (не свернутые) элементы
26
+ this.visibleFlatTree = computed(() => {
27
+ const flatTree = this.flatTree();
28
+ return this._getVisibleFrom(flatTree);
29
+ });
30
+ this._pendingRecalc = false;
31
+ }
32
+ ngOnInit() {
33
+ this._store.menuItems$
34
+ .pipe(filter((arr) => Array.isArray(arr) && arr.length > 0), takeUntilDestroyed(this._ref))
35
+ .subscribe((value) => {
36
+ this.flatTree.set(this._convertToFlatNode(value));
37
+ this.originalTree = new Map(this.flatTree().map((item) => [item.id, { ...item }]));
38
+ });
39
+ }
40
+ /**
41
+ * Переключает состояние свернутости узла (collapse/expand)
42
+ * После изменения создает новый массив для триггера обновления сигнала
43
+ */
44
+ toggleCollapse(node) {
45
+ node.collapsed = !node.collapsed;
46
+ this.flatTree.set([...this.flatTree()]);
47
+ }
48
+ /**
49
+ * Начало перетаскивания: сохраняет всю ветку узла, которую тянут
50
+ */
51
+ dragStarted(node) {
52
+ const branch = this._collectBranch(this.flatTree(), node);
53
+ this.draggedBranch.set(branch);
54
+ }
55
+ /**
56
+ * Завершение перетаскивания: очищает информацию о текущей ветке
57
+ */
58
+ dragEnded() {
59
+ this.draggedBranch.set([]);
60
+ }
61
+ /**
62
+ * Основная логика drag&drop при отпускании элемента
63
+ * Определяет новую позицию узла, пересчитывает глубины и связи
64
+ */
65
+ drop(event) {
66
+ const before = [...this.flatTree()];
67
+ const visibleBefore = this._getVisibleFrom(before);
68
+ const prevIdx = event.previousIndex;
69
+ const currIdx = event.currentIndex;
70
+ // Получает перетаскиваемый элемент из списка видимых
71
+ const draggedVisible = visibleBefore[prevIdx];
72
+ if (!draggedVisible) {
73
+ return;
74
+ }
75
+ // Находит индекс узла в полном массиве
76
+ const start = before.findIndex((n) => n.id === draggedVisible.id);
77
+ if (start < 0) {
78
+ return;
79
+ }
80
+ // Собирает всю ветку, начинающуюся с перетаскиваемого узла
81
+ const branch = this._collectBranch(before, before[start]);
82
+ const branchIds = new Set(branch.map((n) => n.id));
83
+ // Убирает ветку из исходного списка
84
+ const full = before.filter((n) => !branchIds.has(n.id));
85
+ // Определяет видимые элементы после удаления ветки
86
+ const visible = this._getVisibleFrom(full);
87
+ const prevVisible = visible[currIdx - 1] ?? null;
88
+ const nextVisible = visible[currIdx] ?? null;
89
+ // Индекс вставки ветки в новый список
90
+ const insert = nextVisible ? full.findIndex((n) => n.id === nextVisible.id) : full.length;
91
+ // Рассчитывает глубину вставляемой ветки в зависимости от соседей
92
+ let targetDepth;
93
+ if (prevVisible && nextVisible) {
94
+ targetDepth =
95
+ prevVisible.depth < nextVisible.depth ? prevVisible.depth + 1 : nextVisible.depth;
96
+ }
97
+ else if (prevVisible && !nextVisible) {
98
+ targetDepth = prevVisible.depth;
99
+ }
100
+ else if (!prevVisible && nextVisible) {
101
+ targetDepth = nextVisible.depth;
102
+ }
103
+ else {
104
+ targetDepth = 0;
105
+ }
106
+ // Вставляет ветку в новое место
107
+ full.splice(insert, 0, ...branch);
108
+ // Сдвигает глубину всей ветки
109
+ this._applyDepthShift(branch, targetDepth - branch[0].depth);
110
+ // Планирует пересчет структуры дерева
111
+ this._scheduleRecalc(full);
112
+ }
113
+ /**
114
+ * Увеличивает глубину (depth) конкретного узла, если возможно
115
+ */
116
+ indent(node) {
117
+ const arr = [...this.flatTree()];
118
+ const index = arr.indexOf(node);
119
+ if (index === -1) {
120
+ return;
121
+ }
122
+ const proposedDepth = node.depth + 1;
123
+ // Ищет подходящего родителя с нужной глубиной
124
+ const parentCandidate = [...arr]
125
+ .slice(0, index)
126
+ .reverse()
127
+ .find((n) => n.depth === proposedDepth - 1);
128
+ if (!parentCandidate) {
129
+ return;
130
+ }
131
+ node.depth = proposedDepth;
132
+ this._scheduleRecalc(arr);
133
+ }
134
+ /**
135
+ * Уменьшает глубину (depth) узла + по возможности превращает его в родителя
136
+ */
137
+ outdent(node) {
138
+ const arr = [...this.flatTree()];
139
+ const index = arr.indexOf(node);
140
+ if (index === -1 || node.depth <= 0) {
141
+ return;
142
+ }
143
+ node.depth = Math.max(0, node.depth - 1);
144
+ this._scheduleRecalc(arr);
145
+ }
146
+ /**
147
+ * Увеличивает глубину всей ветки узла (вместе с потомками)
148
+ */
149
+ indentBranch(node) {
150
+ const arr = [...this.flatTree()];
151
+ const index = arr.indexOf(node);
152
+ if (index === -1) {
153
+ return;
154
+ }
155
+ const proposedDepth = node.depth + 1;
156
+ const parentCandidate = [...arr]
157
+ .slice(0, index)
158
+ .reverse()
159
+ .find((n) => n.depth === proposedDepth - 1);
160
+ if (!parentCandidate) {
161
+ return;
162
+ }
163
+ const branch = this._collectBranch(arr, node);
164
+ this._applyDepthShift(branch, 1);
165
+ this._scheduleRecalc(arr);
166
+ }
167
+ /**
168
+ * Уменьшает глубину всей ветки узла
169
+ */
170
+ outdentBranch(node) {
171
+ const arr = [...this.flatTree()];
172
+ const branch = this._collectBranch(arr, node);
173
+ this._applyDepthShift(branch, -1);
174
+ this._scheduleRecalc(arr);
175
+ }
176
+ /**
177
+ * Проверяет, есть ли у узла дочерние элементы
178
+ */
179
+ hasChildren(node) {
180
+ const arr = this.flatTree();
181
+ const idx = arr.indexOf(node);
182
+ if (idx === -1) {
183
+ return false;
184
+ }
185
+ for (let i = idx + 1; i < arr.length; i++) {
186
+ const next = arr[i];
187
+ if (next.depth <= node.depth) {
188
+ break;
189
+ }
190
+ if (next.depth === node.depth + 1) {
191
+ return true;
192
+ }
193
+ }
194
+ return false;
195
+ }
196
+ save() {
197
+ // Флаг для логгирования на время отладки
198
+ const logging = false;
199
+ const changedElements = this.flatTree().filter((newItem) => {
200
+ const originalItem = this.originalTree.get(newItem.id);
201
+ // Новый элемент
202
+ if (!originalItem) {
203
+ if (logging) {
204
+ console.log(`Новый элемент ${newItem.title}`);
205
+ }
206
+ return true;
207
+ }
208
+ const { order_num: originalOrderNum, id_parent: originalIdParent, title: originalTitle, allowed_roles: originalRoles, code: originalCode, route: originalRoute, icon: originalIcon, } = originalItem;
209
+ const { order_num: newOrderNum, id_parent: newIdParent, title: newTitle, allowed_roles: newRoles, code: newCode, route: newRoute, icon: newIcon, } = newItem;
210
+ const changedFields = [];
211
+ if (originalOrderNum !== newOrderNum) {
212
+ changedFields.push(`order_num: ${originalOrderNum} → ${newOrderNum}`);
213
+ }
214
+ if (originalIdParent !== newIdParent) {
215
+ changedFields.push(`id_parent: ${originalIdParent} → ${newIdParent}`);
216
+ }
217
+ if (originalTitle !== newTitle) {
218
+ changedFields.push(`title: ${originalTitle} → ${newTitle}`);
219
+ }
220
+ if (originalCode !== newCode) {
221
+ changedFields.push(`code: ${originalCode} → ${newCode}`);
222
+ }
223
+ if (originalRoute !== newRoute) {
224
+ changedFields.push(`route: ${originalRoute} → ${newRoute}`);
225
+ }
226
+ if (originalIcon !== newIcon) {
227
+ changedFields.push(`icon: ${originalIcon} → ${newIcon}`);
228
+ }
229
+ if (JSON.stringify(originalRoles) !== JSON.stringify(newRoles)) {
230
+ changedFields.push(`allowed_roles: ${originalRoles} → ${newRoles}`);
231
+ }
232
+ return changedFields.length > 0;
233
+ });
234
+ const isBlank = (s) => typeof s !== 'string' || s.trim() === '';
235
+ const isRouteValid = ({ route, code }) => {
236
+ // route считается заданным, только если это непустая строка
237
+ const hasRoute = route.trim() !== '';
238
+ return !hasRoute || route === code;
239
+ };
240
+ const invalidCodeTitles = [];
241
+ const invalidRouteTitles = [];
242
+ for (const el of changedElements) {
243
+ if (isBlank(el.code)) {
244
+ invalidCodeTitles.push(el.title ?? '(без названия)');
245
+ }
246
+ if (!isRouteValid(el)) {
247
+ invalidRouteTitles.push(el);
248
+ }
249
+ }
250
+ if (invalidCodeTitles.length > 0) {
251
+ this.errorMsgOutput.emit({
252
+ label: 'Конструктор меню',
253
+ appearance: 'negative',
254
+ // eslint-disable-next-line xss/no-mixed-html
255
+ content: `Все поля code должны быть заполнены. </br>
256
+ Исправьте следующие поля: </br>
257
+ ${invalidCodeTitles.map((t) => `- ${t}`).join('</br>')}
258
+ `,
259
+ });
260
+ return;
261
+ }
262
+ if (invalidRouteTitles.length > 0) {
263
+ this.errorMsgOutput.emit({
264
+ label: 'Конструктор меню',
265
+ appearance: 'negative',
266
+ // eslint-disable-next-line xss/no-mixed-html
267
+ content: `Все поля code должны быть равны полю route. </br>
268
+ Исправьте следующие поля: </br>
269
+ ${invalidRouteTitles.map((t) => `- ${t.title} (${t.code} | ${t.route})`).join('</br>')}
270
+ `,
271
+ });
272
+ return;
273
+ }
274
+ const elRoute = (route) => (route === '' ? null : route);
275
+ const normalizeElement = (el) => ({
276
+ title: el.title.trim(),
277
+ route: elRoute(el.route.trim()),
278
+ code: el.code,
279
+ icon: el.icon,
280
+ order_num: el.order_num,
281
+ allowed_roles: el.allowed_roles
282
+ ? el.allowed_roles.split(',').map((value) => value.trim())
283
+ : null,
284
+ id_parent: el.id_parent,
285
+ });
286
+ const objectsToSave = changedElements
287
+ .filter(({ id }) => !id.includes(NEW_ITEM_PREFIX))
288
+ .map((el) => ({
289
+ _set: normalizeElement(el),
290
+ where: { id: { _eq: el.id } },
291
+ }));
292
+ const objectsToInsert = changedElements
293
+ .filter(({ id }) => id.includes(NEW_ITEM_PREFIX))
294
+ .map((element) => {
295
+ element.id = EMPTY_UUID;
296
+ return normalizeElement(element);
297
+ });
298
+ const objectsToDelete = [...this.deletedIds];
299
+ if (logging) {
300
+ console.log(`Измененные элементы`, objectsToSave);
301
+ console.log(`Новые элементы`, objectsToInsert);
302
+ console.log('Удалённые элементы:', objectsToDelete);
303
+ }
304
+ this._store.updateMenu(objectsToSave, objectsToInsert, objectsToDelete);
305
+ this.deletedIds = [];
306
+ }
307
+ handleFold(state) {
308
+ for (const element of this.flatTree()) {
309
+ if (element.title !== ROOT_TITLE) {
310
+ element.collapsed = state;
311
+ }
312
+ }
313
+ this.flatTree.set([...this.flatTree()]);
314
+ }
315
+ /**
316
+ * Удаляет один элемент из дерева.
317
+ * Потомки становятся дочерними элементами родителя удалённого узла.
318
+ */
319
+ deleteItem(node) {
320
+ const arr = [...this.flatTree()];
321
+ const index = arr.indexOf(node);
322
+ if (index === -1) {
323
+ return;
324
+ }
325
+ const parentId = node.id_parent;
326
+ const nodeDepth = node.depth;
327
+ // Находим потомков, которые были напрямую под этим узлом
328
+ for (let i = index + 1; i < arr.length; i++) {
329
+ const next = arr[i];
330
+ if (next.depth <= nodeDepth) {
331
+ break;
332
+ }
333
+ if (next.depth === nodeDepth + 1) {
334
+ // потомок становится ребёнком родителя удалённого узла
335
+ next.id_parent = parentId ?? null;
336
+ next.depth = nodeDepth; // поднимаем на один уровень вверх
337
+ }
338
+ else if (next.depth > nodeDepth + 1) {
339
+ // поднимаем остальные на один уровень вверх
340
+ next.depth -= 1;
341
+ }
342
+ }
343
+ // Удаляем сам элемент
344
+ arr.splice(index, 1);
345
+ // Если id не временный — добавляем в список на удаление
346
+ if (!node.id.includes(NEW_ITEM_PREFIX)) {
347
+ this.deletedIds.push(node.id);
348
+ }
349
+ this._scheduleRecalc(arr);
350
+ }
351
+ /**
352
+ * Добавляет новый элемент в дерево.
353
+ * По умолчанию он создаётся как дочерний элемент root.
354
+ */
355
+ addNewItem() {
356
+ const arr = [...this.flatTree()];
357
+ const rootNode = arr.find((n) => n.title === this.ROOT_TITLE);
358
+ if (!rootNode) {
359
+ console.error('Root элемент не найден. Новый пункт не может быть добавлен.');
360
+ return;
361
+ }
362
+ const newNode = {
363
+ id: `${NEW_ITEM_PREFIX}${crypto.randomUUID()}`,
364
+ id_parent: rootNode.id,
365
+ title: 'Новый пункт меню',
366
+ route: '',
367
+ icon: '',
368
+ order_num: 1,
369
+ allowed_roles: null,
370
+ collapsed: true,
371
+ code: '',
372
+ depth: rootNode.depth + 1,
373
+ };
374
+ const insertIndex = arr.findIndex((n) => n.id === rootNode.id) + 1;
375
+ arr.splice(insertIndex, 0, newNode);
376
+ this._scheduleRecalc(arr);
377
+ }
378
+ /**
379
+ * Сбрасывает текущее состояние в исходное
380
+ */
381
+ reset() {
382
+ const originalMenu = structuredClone(this._store.originalMenu);
383
+ this.flatTree.set(this._convertToFlatNode(originalMenu));
384
+ this.deletedIds = [];
385
+ }
386
+ /**
387
+ * Проверяет, находится ли элемент в текущей перетаскиваемой ветке
388
+ */
389
+ isDragged(node) {
390
+ return this.draggedBranch().some((n) => n.id === node.id);
391
+ }
392
+ /**
393
+ * Собирает всю ветку элементов начиная с указанного узла (включая потомков)
394
+ */
395
+ _collectBranch(arr, root) {
396
+ const start = arr.indexOf(root);
397
+ if (start < 0) {
398
+ return [];
399
+ }
400
+ const branch = [{ ...root }];
401
+ for (let i = start + 1; i < arr.length; i++) {
402
+ const n = arr[i];
403
+ if (n.depth > root.depth) {
404
+ branch.push(n);
405
+ }
406
+ else {
407
+ break;
408
+ }
409
+ }
410
+ return branch;
411
+ }
412
+ /**
413
+ * Сдвигает глубину всех элементов ветки на указанную разницу
414
+ * Не допускает отрицательных глубин
415
+ */
416
+ _applyDepthShift(branch, diff) {
417
+ if (diff === 0) {
418
+ return;
419
+ }
420
+ for (const n of branch) {
421
+ n.depth = Math.max(0, n.depth + diff);
422
+ }
423
+ }
424
+ /**
425
+ * Преобразует иерархический JSON в плоский массив FlatNode[]
426
+ * Сохраняет порядок элементов и их вложенность
427
+ */
428
+ _convertToFlatNode(data) {
429
+ // Глубокая копия, чтобы не портить оригинал
430
+ const cloned = structuredClone(data);
431
+ const map = new Map();
432
+ const roots = [];
433
+ for (const item of cloned) {
434
+ map.set(item.id, item);
435
+ }
436
+ for (const item of cloned) {
437
+ if (item.id_parent && map.has(item.id_parent)) {
438
+ const parent = map.get(item.id_parent);
439
+ if (!parent.children) {
440
+ parent.children = [];
441
+ }
442
+ parent.children.push(item);
443
+ }
444
+ else {
445
+ roots.push(item);
446
+ }
447
+ }
448
+ const flat = [];
449
+ const walk = (node, depth) => {
450
+ flat.push({
451
+ id: node.id,
452
+ id_parent: node.id_parent,
453
+ title: node.title ?? '',
454
+ route: node.route ?? '',
455
+ icon: node.icon ?? '',
456
+ order_num: node.order_num ?? 0,
457
+ allowed_roles: node.allowed_roles?.join(',') ?? null,
458
+ collapsed: node.title !== ROOT_TITLE,
459
+ code: node.code ?? '',
460
+ depth,
461
+ });
462
+ if (node.children?.length) {
463
+ const sortedChildren = [...node.children].sort((a, b) => (a.order_num ?? 0) - (b.order_num ?? 0));
464
+ for (const child of sortedChildren) {
465
+ walk(child, depth + 1);
466
+ }
467
+ }
468
+ };
469
+ const sortedRoots = [...roots].sort((a, b) => (a.order_num ?? 0) - (b.order_num ?? 0));
470
+ for (const root of sortedRoots) {
471
+ walk(root, 0);
472
+ }
473
+ return flat;
474
+ }
475
+ /**
476
+ * Возвращает список видимых элементов на основе флагов collapsed
477
+ * Использует стек для отслеживания свернутости на каждом уровне
478
+ */
479
+ _getVisibleFrom(arr) {
480
+ const source = typeof arr === 'function' ? arr() : arr;
481
+ const out = [];
482
+ const collapsedStack = [];
483
+ for (const n of source) {
484
+ while (collapsedStack.length > n.depth) {
485
+ collapsedStack.pop();
486
+ }
487
+ if (!collapsedStack.includes(true)) {
488
+ out.push(n);
489
+ collapsedStack[n.depth] = !!n.collapsed;
490
+ }
491
+ }
492
+ return out;
493
+ }
494
+ /**
495
+ * Пересчитывает order_num и id_parent у всех элементов массива
496
+ * После перемещений поддерживает корректную структуру дерева
497
+ * order_num назначается относительно родителя (1..N)
498
+ */
499
+ _recalculateTree(arr) {
500
+ const parents = [];
501
+ const childCounters = new Map();
502
+ for (const node of arr) {
503
+ while (parents.length > 0 && parents[parents.length - 1].depth >= node.depth) {
504
+ parents.pop();
505
+ }
506
+ const parent = parents.length > 0 ? parents[parents.length - 1] : null;
507
+ node.id_parent = parent ? parent.id : null;
508
+ // вычисляем порядковый номер среди братьев
509
+ if (node.title !== ROOT_TITLE) {
510
+ const parentId = node.id_parent ?? null;
511
+ const currentCount = childCounters.get(parentId) ?? 1;
512
+ node.order_num = currentCount;
513
+ childCounters.set(parentId, currentCount + 1);
514
+ }
515
+ parents.push(node);
516
+ }
517
+ }
518
+ /**
519
+ * Асинхронно планирует пересчет дерева через requestAnimationFrame
520
+ * Это предотвращает множественные лишние пересчеты при частых изменениях
521
+ */
522
+ _scheduleRecalc(arr) {
523
+ if (this._pendingRecalc) {
524
+ return;
525
+ }
526
+ this._pendingRecalc = true;
527
+ requestAnimationFrame(() => {
528
+ this._recalculateTree([...arr]);
529
+ const current = this.flatTree();
530
+ if (!this._arraysEqual(current, arr)) {
531
+ this.flatTree.set([...arr]);
532
+ }
533
+ this._pendingRecalc = false;
534
+ });
535
+ }
536
+ /**
537
+ * Проверяет равенство двух массивов FlatNode по ключевым свойствам
538
+ */
539
+ _arraysEqual(a, b) {
540
+ if (a.length !== b.length) {
541
+ return false;
542
+ }
543
+ for (const [i, element] of a.entries()) {
544
+ if (element.id !== b[i].id ||
545
+ element.depth !== b[i].depth ||
546
+ element.order_num !== b[i].order_num) {
547
+ return false;
548
+ }
549
+ }
550
+ return true;
551
+ }
552
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SprocMenuConstructorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
553
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: SprocMenuConstructorComponent, isStandalone: true, selector: "sproc-menu-constructor", outputs: { errorMsgOutput: "errorMsgOutput" }, ngImport: i0, template: "<div class=\"menu-constructor\">\n <div class=\"pane editor\">\n <div class=\"pane-header\">\n <h2>\u0420\u0435\u0434\u0430\u043A\u0442\u043E\u0440 \u043C\u0435\u043D\u044E</h2>\n <div class=\"buttons\">\n <button [disabled]=\"$any(loading$ | async)\" class=\"btn secondary\" (click)=\"addNewItem()\">\n +\n </button>\n <button [disabled]=\"$any(loading$ | async)\" class=\"btn secondary\" (click)=\"reset()\">\n \u0421\u0431\u0440\u043E\u0441\u0438\u0442\u044C\n </button>\n <button [disabled]=\"$any(loading$ | async)\" class=\"btn primary\" (click)=\"save()\">\n \u0421\u043E\u0445\u0440\u0430\u043D\u0438\u0442\u044C\n </button>\n <button [disabled]=\"$any(loading$ | async)\" class=\"btn primary\" (click)=\"handleFold(false)\">\n \u0420\u0430\u0441\u043A\u0440\u044B\u0442\u044C \u0432\u0441\u0435 \u044D\u043B\u0435\u043C\u0435\u043D\u0442\u044B\n </button>\n <button [disabled]=\"$any(loading$ | async)\" class=\"btn primary\" (click)=\"handleFold(true)\">\n \u0421\u043A\u0440\u044B\u0442\u044C \u0432\u0441\u0435 \u044D\u043B\u0435\u043C\u0435\u043D\u0442\u044B\n </button>\n </div>\n </div>\n\n <div\n class=\"list-wrapper\"\n cdkDropList\n [cdkDropListData]=\"visibleFlatTree()\"\n (cdkDropListDropped)=\"drop($event)\"\n [cdkDropListLockAxis]=\"'y'\"\n >\n @for (node of visibleFlatTree(); track node.id + '-' + node.order_num) {\n <div\n class=\"node\"\n [style.marginLeft.px]=\"node.depth * 24\"\n [class.dragged]=\"isDragged(node)\"\n cdkDrag\n (cdkDragStarted)=\"dragStarted(node)\"\n (cdkDragEnded)=\"dragEnded()\"\n >\n <div class=\"node-bar\" cdkDragHandle>\n @if (hasChildren(node)) {\n <button\n class=\"collapse-btn\"\n (click)=\"toggleCollapse(node); $event.stopPropagation()\"\n [title]=\"node.collapsed ? '\u0420\u0430\u0437\u0432\u0435\u0440\u043D\u0443\u0442\u044C' : '\u0421\u0432\u0435\u0440\u043D\u0443\u0442\u044C'\"\n >\n {{ node.collapsed ? '\u25B6' : '\u25BC' }}\n </button>\n }\n\n @if (node.title === ROOT_TITLE) {\n <span class=\"root-title\">\u041A\u043E\u0440\u043D\u0435\u0432\u043E\u0439 \u044D\u043B\u0435\u043C\u0435\u043D\u0442</span>\n } @else {\n <div class=\"left-control\">\n <span class=\"grip\">\u22EE\u22EE</span>\n <input class=\"inp title\" [(ngModel)]=\"node.title\" placeholder=\"\u041D\u0430\u0437\u0432\u0430\u043D\u0438\u0435\" />\n <input\n class=\"inp code\"\n [required]=\"true\"\n [(ngModel)]=\"node.code\"\n placeholder=\"code\"\n />\n <input class=\"inp route\" [(ngModel)]=\"node.route\" placeholder=\"route\" />\n <input class=\"inp icon\" [(ngModel)]=\"node.icon\" placeholder=\"icon\" />\n <input class=\"inp roles\" [(ngModel)]=\"node.allowed_roles\" placeholder=\"\u0420\u043E\u043B\u0438\" />\n </div>\n\n <div class=\"depth-controls\">\n <button class=\"btn small\" (click)=\"outdent(node)\">\u2190</button>\n <button class=\"btn small\" (click)=\"indent(node)\">\u2192</button>\n @if (hasChildren(node)) {\n <button class=\"btn small\" (click)=\"outdentBranch(node)\">\u21D0</button>\n <button class=\"btn small\" (click)=\"indentBranch(node)\">\u21D2</button>\n }\n <button class=\"btn small\" (click)=\"deleteItem(node)\">\u0423\u0434\u0430\u043B\u0438\u0442\u044C</button>\n </div>\n }\n </div>\n\n <ng-template cdkDragPreview>\n <div class=\"drag-branch-preview\">\n <div\n class=\"preview-bar\"\n *ngFor=\"let n of draggedBranch()\"\n [style.marginLeft.px]=\"(n.depth - node.depth) * 20\"\n >\n {{ n.title }}\n </div>\n </div>\n </ng-template>\n </div>\n }\n </div>\n </div>\n</div>\n", styles: [".menu-constructor{display:flex;flex-direction:column;gap:16px;padding:16px;height:calc(100vh - var(--header-height))}.pane{border:1px solid #e2e8f0;border-radius:12px;padding:12px;background:#fff;display:flex;flex-direction:column}.pane.editor{height:100%}.hidden{display:none}.root-title{width:100%}.collapse-btn{background:none;border:none;cursor:pointer;font-size:12px;color:#334155;margin-right:4px;transition:transform .2s ease}.collapse-btn:hover{color:#1e3a8a}.pane-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:8px}.pane-header h2{margin:0;font-size:16px}.pane-header .buttons{display:flex;gap:6px}.btn{padding:6px 10px;border-radius:6px;border:1px solid #94a3b8;background:#f8fafc;cursor:pointer;font-size:12px;line-height:1}.btn.primary{border-color:#3b82f6;background:#e0f2fe}.btn.secondary{border-color:#b5b5b5;background:#d1d1d1}.btn.small{padding:2px 6px;margin-left:2px}.btn:hover{background:#e2e8f0}.list-wrapper{flex:1;overflow:auto;min-height:200px}.left-control{gap:6px;display:flex;flex-direction:row;align-items:center;justify-content:center;width:100%}.node{border:1px dashed #cbd5e1;border-radius:8px;margin:6px 0;background:#fafafa;padding:4px}.node-bar{display:flex;flex-direction:row;justify-content:space-between;gap:6px;align-items:center;background:#f1f5f9;padding:4px 6px;border-radius:6px}.grip{cursor:grab;text-align:center;color:#475569}.inp{border:1px solid #cbd5e1;width:100%;border-radius:6px;padding:3px 6px;font-size:12px}.depth-controls{display:flex;gap:2px}.node.dragged{background:#e0f2fe;border-color:#3b82f6;opacity:.85}.drag-branch-preview{background:#fff;border:1px solid #94a3b8;box-shadow:0 6px 18px #00000026;border-radius:8px;padding:6px;min-width:160px}.preview-bar{background:#f8fafc;border-left:3px solid #3b82f6;border-radius:4px;margin:3px 0;padding:4px 8px;font-size:12px}.drag-branch-placeholder{padding:6px 0}.placeholder-row{height:32px;margin:3px 0;background:repeating-linear-gradient(-45deg,#e2e8f0,#e2e8f0 6px,#f1f5f9 6px 12px);border-radius:4px}\n"], dependencies: [{ kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: CdkDragPreview, selector: "ng-template[cdkDragPreview]", inputs: ["data", "matchSize"] }, { kind: "directive", type: CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "pipe", type: AsyncPipe, name: "async" }] }); }
554
+ }
555
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SprocMenuConstructorComponent, decorators: [{
556
+ type: Component,
557
+ args: [{ standalone: true, selector: 'sproc-menu-constructor', imports: [CdkDrag, CdkDropList, NgForOf, FormsModule, CdkDragPreview, CdkDragHandle, AsyncPipe], template: "<div class=\"menu-constructor\">\n <div class=\"pane editor\">\n <div class=\"pane-header\">\n <h2>\u0420\u0435\u0434\u0430\u043A\u0442\u043E\u0440 \u043C\u0435\u043D\u044E</h2>\n <div class=\"buttons\">\n <button [disabled]=\"$any(loading$ | async)\" class=\"btn secondary\" (click)=\"addNewItem()\">\n +\n </button>\n <button [disabled]=\"$any(loading$ | async)\" class=\"btn secondary\" (click)=\"reset()\">\n \u0421\u0431\u0440\u043E\u0441\u0438\u0442\u044C\n </button>\n <button [disabled]=\"$any(loading$ | async)\" class=\"btn primary\" (click)=\"save()\">\n \u0421\u043E\u0445\u0440\u0430\u043D\u0438\u0442\u044C\n </button>\n <button [disabled]=\"$any(loading$ | async)\" class=\"btn primary\" (click)=\"handleFold(false)\">\n \u0420\u0430\u0441\u043A\u0440\u044B\u0442\u044C \u0432\u0441\u0435 \u044D\u043B\u0435\u043C\u0435\u043D\u0442\u044B\n </button>\n <button [disabled]=\"$any(loading$ | async)\" class=\"btn primary\" (click)=\"handleFold(true)\">\n \u0421\u043A\u0440\u044B\u0442\u044C \u0432\u0441\u0435 \u044D\u043B\u0435\u043C\u0435\u043D\u0442\u044B\n </button>\n </div>\n </div>\n\n <div\n class=\"list-wrapper\"\n cdkDropList\n [cdkDropListData]=\"visibleFlatTree()\"\n (cdkDropListDropped)=\"drop($event)\"\n [cdkDropListLockAxis]=\"'y'\"\n >\n @for (node of visibleFlatTree(); track node.id + '-' + node.order_num) {\n <div\n class=\"node\"\n [style.marginLeft.px]=\"node.depth * 24\"\n [class.dragged]=\"isDragged(node)\"\n cdkDrag\n (cdkDragStarted)=\"dragStarted(node)\"\n (cdkDragEnded)=\"dragEnded()\"\n >\n <div class=\"node-bar\" cdkDragHandle>\n @if (hasChildren(node)) {\n <button\n class=\"collapse-btn\"\n (click)=\"toggleCollapse(node); $event.stopPropagation()\"\n [title]=\"node.collapsed ? '\u0420\u0430\u0437\u0432\u0435\u0440\u043D\u0443\u0442\u044C' : '\u0421\u0432\u0435\u0440\u043D\u0443\u0442\u044C'\"\n >\n {{ node.collapsed ? '\u25B6' : '\u25BC' }}\n </button>\n }\n\n @if (node.title === ROOT_TITLE) {\n <span class=\"root-title\">\u041A\u043E\u0440\u043D\u0435\u0432\u043E\u0439 \u044D\u043B\u0435\u043C\u0435\u043D\u0442</span>\n } @else {\n <div class=\"left-control\">\n <span class=\"grip\">\u22EE\u22EE</span>\n <input class=\"inp title\" [(ngModel)]=\"node.title\" placeholder=\"\u041D\u0430\u0437\u0432\u0430\u043D\u0438\u0435\" />\n <input\n class=\"inp code\"\n [required]=\"true\"\n [(ngModel)]=\"node.code\"\n placeholder=\"code\"\n />\n <input class=\"inp route\" [(ngModel)]=\"node.route\" placeholder=\"route\" />\n <input class=\"inp icon\" [(ngModel)]=\"node.icon\" placeholder=\"icon\" />\n <input class=\"inp roles\" [(ngModel)]=\"node.allowed_roles\" placeholder=\"\u0420\u043E\u043B\u0438\" />\n </div>\n\n <div class=\"depth-controls\">\n <button class=\"btn small\" (click)=\"outdent(node)\">\u2190</button>\n <button class=\"btn small\" (click)=\"indent(node)\">\u2192</button>\n @if (hasChildren(node)) {\n <button class=\"btn small\" (click)=\"outdentBranch(node)\">\u21D0</button>\n <button class=\"btn small\" (click)=\"indentBranch(node)\">\u21D2</button>\n }\n <button class=\"btn small\" (click)=\"deleteItem(node)\">\u0423\u0434\u0430\u043B\u0438\u0442\u044C</button>\n </div>\n }\n </div>\n\n <ng-template cdkDragPreview>\n <div class=\"drag-branch-preview\">\n <div\n class=\"preview-bar\"\n *ngFor=\"let n of draggedBranch()\"\n [style.marginLeft.px]=\"(n.depth - node.depth) * 20\"\n >\n {{ n.title }}\n </div>\n </div>\n </ng-template>\n </div>\n }\n </div>\n </div>\n</div>\n", styles: [".menu-constructor{display:flex;flex-direction:column;gap:16px;padding:16px;height:calc(100vh - var(--header-height))}.pane{border:1px solid #e2e8f0;border-radius:12px;padding:12px;background:#fff;display:flex;flex-direction:column}.pane.editor{height:100%}.hidden{display:none}.root-title{width:100%}.collapse-btn{background:none;border:none;cursor:pointer;font-size:12px;color:#334155;margin-right:4px;transition:transform .2s ease}.collapse-btn:hover{color:#1e3a8a}.pane-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:8px}.pane-header h2{margin:0;font-size:16px}.pane-header .buttons{display:flex;gap:6px}.btn{padding:6px 10px;border-radius:6px;border:1px solid #94a3b8;background:#f8fafc;cursor:pointer;font-size:12px;line-height:1}.btn.primary{border-color:#3b82f6;background:#e0f2fe}.btn.secondary{border-color:#b5b5b5;background:#d1d1d1}.btn.small{padding:2px 6px;margin-left:2px}.btn:hover{background:#e2e8f0}.list-wrapper{flex:1;overflow:auto;min-height:200px}.left-control{gap:6px;display:flex;flex-direction:row;align-items:center;justify-content:center;width:100%}.node{border:1px dashed #cbd5e1;border-radius:8px;margin:6px 0;background:#fafafa;padding:4px}.node-bar{display:flex;flex-direction:row;justify-content:space-between;gap:6px;align-items:center;background:#f1f5f9;padding:4px 6px;border-radius:6px}.grip{cursor:grab;text-align:center;color:#475569}.inp{border:1px solid #cbd5e1;width:100%;border-radius:6px;padding:3px 6px;font-size:12px}.depth-controls{display:flex;gap:2px}.node.dragged{background:#e0f2fe;border-color:#3b82f6;opacity:.85}.drag-branch-preview{background:#fff;border:1px solid #94a3b8;box-shadow:0 6px 18px #00000026;border-radius:8px;padding:6px;min-width:160px}.preview-bar{background:#f8fafc;border-left:3px solid #3b82f6;border-radius:4px;margin:3px 0;padding:4px 8px;font-size:12px}.drag-branch-placeholder{padding:6px 0}.placeholder-row{height:32px;margin:3px 0;background:repeating-linear-gradient(-45deg,#e2e8f0,#e2e8f0 6px,#f1f5f9 6px 12px);border-radius:4px}\n"] }]
558
+ }] });
559
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3Byb2MtbWVudS1jb25zdHJ1Y3Rvci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtcmVnaXN0ZXItYmFzZS9zcmMvbGliL2NvbXBvbmVudHMvbWVudS1jb25zdHJ1Y3Rvci9zcHJvYy1tZW51LWNvbnN0cnVjdG9yLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1yZWdpc3Rlci1iYXNlL3NyYy9saWIvY29tcG9uZW50cy9tZW51LWNvbnN0cnVjdG9yL3Nwcm9jLW1lbnUtY29uc3RydWN0b3IuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBVSxNQUFNLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ2hHLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM3QyxPQUFPLEVBQ0wsT0FBTyxFQUVQLGFBQWEsRUFDYixjQUFjLEVBQ2QsV0FBVyxHQUNaLE1BQU0sd0JBQXdCLENBQUM7QUFDaEMsT0FBTyxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNyRCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRTlCLE9BQU8sRUFDTCxVQUFVLEVBSVYsY0FBYyxFQUNkLGVBQWUsRUFDZixVQUFVLEdBQ1gsTUFBTSx1Q0FBdUMsQ0FBQztBQUUvQyxPQUFPLEVBQUUsNEJBQTRCLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQzs7O0FBU3pFLE1BQU0sT0FBTyw2QkFBNkI7SUFQMUM7UUFRVSxXQUFNLEdBQUcsTUFBTSxDQUFDLDRCQUE0QixDQUFDLENBQUM7UUFDOUMsU0FBSSxHQUFH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Q0FBQyxPQUFPLEVBQUUsV0FBVyxFQUFFLE9BQU8sRUFBRSxXQUFXLEVBQUUsY0FBYyxFQUFFLGFBQWEsRUFBRSxTQUFTLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIGNvbXB1dGVkLCBEZXN0cm95UmVmLCBpbmplY3QsIE9uSW5pdCwgb3V0cHV0LCBzaWduYWwgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEZvcm1zTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHtcbiAgQ2RrRHJhZyxcbiAgQ2RrRHJhZ0Ryb3AsXG4gIENka0RyYWdIYW5kbGUsXG4gIENka0RyYWdQcmV2aWV3LFxuICBDZGtEcm9wTGlzdCxcbn0gZnJvbSAnQGFuZ3VsYXIvY2RrL2RyYWctZHJvcCc7XG5pbXBvcnQgeyBBc3luY1BpcGUsIE5nRm9yT2YgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgdGFrZVVudGlsRGVzdHJveWVkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZS9yeGpzLWludGVyb3AnO1xuaW1wb3J0IHsgZmlsdGVyIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBTcHJvY0Fic3RyYWN0TWVudUNvbnN0cnVjdG9yU3RvcmUgfSBmcm9tICcuL3N0b3JlL3Nwcm9jLWFic3RyYWN0LW1lbnUtY29uc3RydWN0b3Iuc3RvcmUnO1xuaW1wb3J0IHtcbiAgRU1QVFlfVVVJRCxcbiAgRmxhdE5vZGUsXG4gIElDbHNNZW51SXRlbUlucHV0LFxuICBJTWVudUNvbnN0cnVjdG9yRXJyb3IsXG4gIE1JR1JBVElPTl9ISU5ULFxuICBORVdfSVRFTV9QUkVGSVgsXG4gIFJPT1RfVElUTEUsXG59IGZyb20gJy4vc3RvcmUvc3Byb2MtbWVudS1jb25zdHJ1Y3Rvci5jb25zdHMnO1xuaW1wb3J0IHsgSUNsc01lbnVJdGVtIH0gZnJvbSAnLi4vcGFnZS1tZW51JztcbmltcG9ydCB7IE1FTlVfQ09OU1RSVUNUT1JfU1RPUkVfVE9LRU4gfSBmcm9tICcuL3N0b3JlL3Nwcm9jLW1lbnUudG9rZW5zJztcblxuQENvbXBvbmVudCh7XG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIHNlbGVjdG9yOiAnc3Byb2MtbWVudS1jb25zdHJ1Y3RvcicsXG4gIHRlbXBsYXRlVXJsOiAnLi9zcHJvYy1tZW51LWNvbnN0cnVjdG9yLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vc3Byb2MtbWVudS1jb25zdHJ1Y3Rvci5jb21wb25lbnQubGVzcyddLFxuICBpbXBvcnRzOiBbQ2RrRHJhZywgQ2RrRHJvcExpc3QsIE5nRm9yT2YsIEZvcm1zTW9kdWxlLCBDZGtEcmFnUHJldmlldywgQ2RrRHJhZ0hhbmRsZSwgQXN5bmNQaXBlXSxcbn0pXG5leHBvcnQgY2xhc3MgU3Byb2NNZW51Q29uc3RydWN0b3JDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuICBwcml2YXRlIF9zdG9yZSA9IGluamVjdChNRU5VX0NPTlNUUlVDVE9SX1NUT1JFX1RPS0VOKTtcbiAgcHJpdmF0ZSBfcmVmID0gaW5qZWN0KERlc3Ryb3lSZWYpO1xuXG4gIHByb3RlY3RlZCBST09UX1RJVExFID0gUk9PVF9USVRMRTtcbiAgcHJvdGVjdGVkIGxvYWRpbmckID0gdGhpcy5fc3RvcmUubG9hZGluZyQ7XG4gIHByb3RlY3RlZCBvcmlnaW5hbFRyZWU6IE1hcDxzdHJpbmcsIEZsYXROb2RlPiA9IG5ldyBNYXAoW10pO1xuICBwcm90ZWN0ZWQgTUlHUkFUSU9OX0hJTlQgPSBNSUdSQVRJT05fSElOVDtcbiAgcHJpdmF0ZSBkZWxldGVkSWRzOiBzdHJpbmdbXSA9IFtdO1xuXG4gIHB1YmxpYyBlcnJvck1zZ091dHB1dCA9IG91dHB1dDxJTWVudUNvbnN0cnVjdG9yRXJyb3I+KCk7XG5cbiAgLy8g0L/Qu9C+0YHQutC+0LUg0L/RgNC10LTRgdGC0LDQstC70LXQvdC40LUg0LjQtdGA0LDRgNGF0LjRh9C10YHQutC+0LPQviDQvNC10L3RjlxuICBwcm90ZWN0ZWQgZmxhdFRyZWUgPSBzaWduYWw8RmxhdE5vZGVbXT4oW10pO1xuXG4gIC8vINCy0LXRgtC60LAg0Y3Qu9C10LzQtdC90YLQvtCyLCDQutC+0YLQvtGA0LDRjyDQv9C10YDQtdGC0LDRgdC60LjQstCw0LXRgtGB0Y9cbiAgcHJvdGVjdGVkIGRyYWdnZWRCcmFuY2ggPSBzaWduYWw8RmxhdE5vZGVbXT4oW10pO1xuXG4gIC8vINCy0YvRh9C40YHQu9GP0LXQvNC+0LUg0YHQstC+0LnRgdGC0LLQviwg0LLQvtC30LLRgNCw0YnQsNGO0YnQtdC1INGC0L7Qu9GM0LrQviDQstC40LTQuNC80YvQtSAo0L3QtSDRgdCy0LXRgNC90YPRgtGL0LUpINGN0LvQtdC80LXQvdGC0YtcbiAgcHJvdGVjdGVkIHZpc2libGVGbGF0VHJlZSA9IGNvbXB1dGVkPEZsYXROb2RlW10+KCgpID0+IHtcbiAgICBjb25zdCBmbGF0VHJlZSA9IHRoaXMuZmxhdFRyZWUoKTtcbiAgICByZXR1cm4gdGhpcy5fZ2V0VmlzaWJsZUZyb20oZmxhdFRyZWUpO1xuICB9KTtcblxuICBwcml2YXRlIF9wZW5kaW5nUmVjYWxjID0gZmFsc2U7XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5fc3RvcmUubWVudUl0ZW1zJFxuICAgICAgLnBpcGUoXG4gICAgICAgIGZpbHRlcigoYXJyKSA9PiBBcnJheS5pc0FycmF5KGFycikgJiYgYXJyLmxlbmd0aCA+IDApLFxuICAgICAgICB0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5fcmVmKVxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSgodmFsdWUpID0+IHtcbiAgICAgICAgdGhpcy5mbGF0VHJlZS5zZXQodGhpcy5fY29udmVydFRvRmxhdE5vZGUodmFsdWUpKTtcbiAgICAgICAgdGhpcy5vcmlnaW5hbFRyZWUgPSBuZXcgTWFwKHRoaXMuZmxhdFRyZWUoKS5tYXAoKGl0ZW0pID0+IFtpdGVtLmlkLCB7IC4uLml0ZW0gfV0pKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqINCf0LXRgNC10LrQu9GO0YfQsNC10YIg0YHQvtGB0YLQvtGP0L3QuNC1INGB0LLQtdGA0L3Rg9GC0L7RgdGC0Lgg0YPQt9C70LAgKGNvbGxhcHNlL2V4cGFuZClcbiAgICog0J/QvtGB0LvQtSDQuNC30LzQtdC90LXQvdC40Y8g0YHQvtC30LTQsNC10YIg0L3QvtCy0YvQuSDQvNCw0YHRgdC40LIg0LTQu9GPINGC0YDQuNCz0LPQtdGA0LAg0L7QsdC90L7QstC70LXQvdC40Y8g0YHQuNCz0L3QsNC70LBcbiAgICovXG4gIHByb3RlY3RlZCB0b2dnbGVDb2xsYXBzZShub2RlOiBGbGF0Tm9kZSk6IHZvaWQge1xuICAgIG5vZGUuY29sbGFwc2VkID0gIW5vZGUuY29sbGFwc2VkO1xuICAgIHRoaXMuZmxhdFRyZWUuc2V0KFsuLi50aGlzLmZsYXRUcmVlKCldKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDQndCw0YfQsNC70L4g0L/QtdGA0LXRgtCw0YHQutC40LLQsNC90LjRjzog0YHQvtGF0YDQsNC90Y/QtdGCINCy0YHRjiDQstC10YLQutGDINGD0LfQu9CwLCDQutC+0YLQvtGA0YPRjiDRgtGP0L3Rg9GCXG4gICAqL1xuICBwcm90ZWN0ZWQgZHJhZ1N0YXJ0ZWQobm9kZTogRmxhdE5vZGUpOiB2b2lkIHtcbiAgICBjb25zdCBicmFuY2ggPSB0aGlzLl9jb2xsZWN0QnJhbmNoKHRoaXMuZmxhdFRyZWUoKSwgbm9kZSk7XG4gICAgdGhpcy5kcmFnZ2VkQnJhbmNoLnNldChicmFuY2gpO1xuICB9XG5cbiAgLyoqXG4gICAqINCX0LDQstC10YDRiNC10L3QuNC1INC/0LXRgNC10YLQsNGB0LrQuNCy0LDQvdC40Y86INC+0YfQuNGJ0LDQtdGCINC40L3RhNC+0YDQvNCw0YbQuNGOINC+INGC0LXQutGD0YnQtdC5INCy0LXRgtC60LVcbiAgICovXG4gIHByb3RlY3RlZCBkcmFnRW5kZWQoKTogdm9pZCB7XG4gICAgdGhpcy5kcmFnZ2VkQnJhbmNoLnNldChbXSk7XG4gIH1cblxuICAvKipcbiAgICog0J7RgdC90L7QstC90LDRjyDQu9C+0LPQuNC60LAgZHJhZyZkcm9wINC/0YDQuCDQvtGC0L/Rg9GB0LrQsNC90LjQuCDRjdC70LXQvNC10L3RgtCwXG4gICAqINCe0L/RgNC10LTQtdC70Y/QtdGCINC90L7QstGD0Y4g0L/QvtC30LjRhtC40Y4g0YPQt9C70LAsINC/0LXRgNC10YHRh9C40YLRi9Cy0LDQtdGCINCz0LvRg9Cx0LjQvdGLINC4INGB0LLRj9C30LhcbiAgICovXG4gIHByb3RlY3RlZCBkcm9wKGV2ZW50OiBDZGtEcmFnRHJvcDxGbGF0Tm9kZVtdPik6IHZvaWQge1xuICAgIGNvbnN0IGJlZm9yZSA9IFsuLi50aGlzLmZsYXRUcmVlKCldO1xuICAgIGNvbnN0IHZpc2libGVCZWZvcmUgPSB0aGlzLl9nZXRWaXNpYmxlRnJvbShiZWZvcmUpO1xuICAgIGNvbnN0IHByZXZJZHggPSBldmVudC5wcmV2aW91c0luZGV4O1xuICAgIGNvbnN0IGN1cnJJZHggPSBldmVudC5jdXJyZW50SW5kZXg7XG5cbiAgICAvLyDQn9C+0LvRg9GH0LDQtdGCINC/0LXRgNC10YLQsNGB0LrQuNCy0LDQtdC80YvQuSDRjdC70LXQvNC10L3RgiDQuNC3INGB0L/QuNGB0LrQsCDQstC40LTQuNC80YvRhVxuICAgIGNvbnN0IGRyYWdnZWRWaXNpYmxlID0gdmlzaWJsZUJlZm9yZVtwcmV2SWR4XTtcbiAgICBpZiAoIWRyYWdnZWRWaXNpYmxlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8g0J3QsNGF0L7QtNC40YIg0LjQvdC00LXQutGBINGD0LfQu9CwINCyINC/0L7Qu9C90L7QvCDQvNCw0YHRgdC40LLQtVxuICAgIGNvbnN0IHN0YXJ0ID0gYmVmb3JlLmZpbmRJbmRleCgobikgPT4gbi5pZCA9PT0gZHJhZ2dlZFZpc2libGUuaWQpO1xuICAgIGlmIChzdGFydCA8IDApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyDQodC+0LHQuNGA0LDQtdGCINCy0YHRjiDQstC10YLQutGDLCDQvdCw0YfQuNC90LDRjtGJ0YPRjtGB0Y8g0YEg0L/QtdGA0LXRgtCw0YHQutC40LLQsNC10LzQvtCz0L4g0YPQt9C70LBcbiAgICBjb25zdCBicmFuY2ggPSB0aGlzLl9jb2xsZWN0QnJhbmNoKGJlZm9yZSwgYmVmb3JlW3N0YXJ0XSk7XG4gICAgY29uc3QgYnJhbmNoSWRzID0gbmV3IFNldChicmFuY2gubWFwKChuKSA9PiBuLmlkKSk7XG5cbiAgICAvLyDQo9Cx0LjRgNCw0LXRgiDQstC10YLQutGDINC40Lcg0LjRgdGF0L7QtNC90L7Qs9C+INGB0L/QuNGB0LrQsFxuICAgIGNvbnN0IGZ1bGwgPSBiZWZvcmUuZmlsdGVyKChuKSA9PiAhYnJhbmNoSWRzLmhhcyhuLmlkKSk7XG5cbiAgICAvLyDQntC/0YDQtdC00LXQu9GP0LXRgiDQstC40LTQuNC80YvQtSDRjdC70LXQvNC10L3RgtGLINC/0L7RgdC70LUg0YPQtNCw0LvQtdC90LjRjyDQstC10YLQutC4XG4gICAgY29uc3QgdmlzaWJsZSA9IHRoaXMuX2dldFZpc2libGVGcm9tKGZ1bGwpO1xuICAgIGNvbnN0IHByZXZWaXNpYmxlID0gdmlzaWJsZVtjdXJySWR4IC0gMV0gPz8gbnVsbDtcbiAgICBjb25zdCBuZXh0VmlzaWJsZSA9IHZpc2libGVbY3VycklkeF0gPz8gbnVsbDtcblxuICAgIC8vINCY0L3QtNC10LrRgSDQstGB0YLQsNCy0LrQuCDQstC10YLQutC4INCyINC90L7QstGL0Lkg0YHQv9C40YHQvtC6XG4gICAgY29uc3QgaW5zZXJ0ID0gbmV4dFZpc2libGUgPyBmdWxsLmZpbmRJbmRleCgobikgPT4gbi5pZCA9PT0gbmV4dFZpc2libGUuaWQpIDogZnVsbC5sZW5ndGg7XG5cbiAgICAvLyDQoNCw0YHRgdGH0LjRgtGL0LLQsNC10YIg0LPQu9GD0LHQuNC90YMg0LLRgdGC0LDQstC70Y/QtdC80L7QuSDQstC10YLQutC4INCyINC30LDQstC40YHQuNC80L7RgdGC0Lgg0L7RgiDRgdC+0YHQtdC00LXQuVxuICAgIGxldCB0YXJnZXREZXB0aDtcbiAgICBpZiAocHJldlZpc2libGUgJiYgbmV4dFZpc2libGUpIHtcbiAgICAgIHRhcmdldERlcHRoID1cbiAgICAgICAgcHJldlZpc2libGUuZGVwdGggPCBuZXh0VmlzaWJsZS5kZXB0aCA/IHByZXZWaXNpYmxlLmRlcHRoICsgMSA6IG5leHRWaXNpYmxlLmRlcHRoO1xuICAgIH0gZWxzZSBpZiAocHJldlZpc2libGUgJiYgIW5leHRWaXNpYmxlKSB7XG4gICAgICB0YXJnZXREZXB0aCA9IHByZXZWaXNpYmxlLmRlcHRoO1xuICAgIH0gZWxzZSBpZiAoIXByZXZWaXNpYmxlICYmIG5leHRWaXNpYmxlKSB7XG4gICAgICB0YXJnZXREZXB0aCA9IG5leHRWaXNpYmxlLmRlcHRoO1xuICAgIH0gZWxzZSB7XG4gICAgICB0YXJnZXREZXB0aCA9IDA7XG4gICAgfVxuXG4gICAgLy8g0JLRgdGC0LDQstC70Y/QtdGCINCy0LXRgtC60YMg0LIg0L3QvtCy0L7QtSDQvNC10YHRgtC+XG4gICAgZnVsbC5zcGxpY2UoaW5zZXJ0LCAwLCAuLi5icmFuY2gpO1xuICAgIC8vINCh0LTQstC40LPQsNC10YIg0LPQu9GD0LHQuNC90YMg0LLRgdC10Lkg0LLQtdGC0LrQuFxuICAgIHRoaXMuX2FwcGx5RGVwdGhTaGlmdChicmFuY2gsIHRhcmdldERlcHRoIC0gYnJhbmNoWzBdLmRlcHRoKTtcblxuICAgIC8vINCf0LvQsNC90LjRgNGD0LXRgiDQv9C10YDQtdGB0YfQtdGCINGB0YLRgNGD0LrRgtGD0YDRiyDQtNC10YDQtdCy0LBcbiAgICB0aGlzLl9zY2hlZHVsZVJlY2FsYyhmdWxsKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDQo9Cy0LXQu9C40YfQuNCy0LDQtdGCINCz0LvRg9Cx0LjQvdGDIChkZXB0aCkg0LrQvtC90LrRgNC10YLQvdC+0LPQviDRg9C30LvQsCwg0LXRgdC70Lgg0LLQvtC30LzQvtC20L3QvlxuICAgKi9cbiAgcHJvdGVjdGVkIGluZGVudChub2RlOiBGbGF0Tm9kZSk6IHZvaWQge1xuICAgIGNvbnN0IGFyciA9IFsuLi50aGlzLmZsYXRUcmVlKCldO1xuICAgIGNvbnN0IGluZGV4ID0gYXJyLmluZGV4T2Yobm9kZSk7XG4gICAgaWYgKGluZGV4ID09PSAtMSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHByb3Bvc2VkRGVwdGggPSBub2RlLmRlcHRoICsgMTtcbiAgICAvLyDQmNGJ0LXRgiDQv9C+0LTRhdC+0LTRj9GJ0LXQs9C+INGA0L7QtNC40YLQtdC70Y8g0YEg0L3Rg9C20L3QvtC5INCz0LvRg9Cx0LjQvdC+0LlcbiAgICBjb25zdCBwYXJlbnRDYW5kaWRhdGUgPSBbLi4uYXJyXVxuICAgICAgLnNsaWNlKDAsIGluZGV4KVxuICAgICAgLnJldmVyc2UoKVxuICAgICAgLmZpbmQoKG4pID0+IG4uZGVwdGggPT09IHByb3Bvc2VkRGVwdGggLSAxKTtcblxuICAgIGlmICghcGFyZW50Q2FuZGlkYXRlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbm9kZS5kZXB0aCA9IHByb3Bvc2VkRGVwdGg7XG4gICAgdGhpcy5fc2NoZWR1bGVSZWNhbGMoYXJyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDQo9C80LXQvdGM0YjQsNC10YIg0LPQu9GD0LHQuNC90YMgKGRlcHRoKSDRg9C30LvQsCArINC/0L4g0LLQvtC30LzQvtC20L3QvtGB0YLQuCDQv9GA0LXQstGA0LDRidCw0LXRgiDQtdCz0L4g0LIg0YDQvtC00LjRgtC10LvRj1xuICAgKi9cbiAgcHJvdGVjdGVkIG91dGRlbnQobm9kZTogRmxhdE5vZGUpOiB2b2lkIHtcbiAgICBjb25zdCBhcnIgPSBbLi4udGhpcy5mbGF0VHJlZSgpXTtcbiAgICBjb25zdCBpbmRleCA9IGFyci5pbmRleE9mKG5vZGUpO1xuICAgIGlmIChpbmRleCA9PT0gLTEgfHwgbm9kZS5kZXB0aCA8PSAwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIG5vZGUuZGVwdGggPSBNYXRoLm1heCgwLCBub2RlLmRlcHRoIC0gMSk7XG4gICAgdGhpcy5fc2NoZWR1bGVSZWNhbGMoYXJyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDQo9Cy0LXQu9C40YfQuNCy0LDQtdGCINCz0LvRg9Cx0LjQvdGDINCy0YHQtdC5INCy0LXRgtC60Lgg0YPQt9C70LAgKNCy0LzQtdGB0YLQtSDRgSDQv9C+0YLQvtC80LrQsNC80LgpXG4gICAqL1xuICBwcm90ZWN0ZWQgaW5kZW50QnJhbmNoKG5vZGU6IEZsYXROb2RlKTogdm9pZCB7XG4gICAgY29uc3QgYXJyID0gWy4uLnRoaXMuZmxhdFRyZWUoKV07XG4gICAgY29uc3QgaW5kZXggPSBhcnIuaW5kZXhPZihub2RlKTtcbiAgICBpZiAoaW5kZXggPT09IC0xKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHByb3Bvc2VkRGVwdGggPSBub2RlLmRlcHRoICsgMTtcbiAgICBjb25zdCBwYXJlbnRDYW5kaWRhdGUgPSBbLi4uYXJyXVxuICAgICAgLnNsaWNlKDAsIGluZGV4KVxuICAgICAgLnJldmVyc2UoKVxuICAgICAgLmZpbmQoKG4pID0+IG4uZGVwdGggPT09IHByb3Bvc2VkRGVwdGggLSAxKTtcblxuICAgIGlmICghcGFyZW50Q2FuZGlkYXRlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgYnJhbmNoID0gdGhpcy5fY29sbGVjdEJyYW5jaChhcnIsIG5vZGUpO1xuICAgIHRoaXMuX2FwcGx5RGVwdGhTaGlmdChicmFuY2gsIDEpO1xuXG4gICAgdGhpcy5fc2NoZWR1bGVSZWNhbGMoYXJyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDQo9C80LXQvdGM0YjQsNC10YIg0LPQu9GD0LHQuNC90YMg0LLRgdC10Lkg0LLQtdGC0LrQuCDRg9C30LvQsFxuICAgKi9cbiAgcHJvdGVjdGVkIG91dGRlbnRCcmFuY2gobm9kZTogRmxhdE5vZGUpOiB2b2lkIHtcbiAgICBjb25zdCBhcnIgPSBbLi4udGhpcy5mbGF0VHJlZSgpXTtcbiAgICBjb25zdCBicmFuY2ggPSB0aGlzLl9jb2xsZWN0QnJhbmNoKGFyciwgbm9kZSk7XG4gICAgdGhpcy5fYXBwbHlEZXB0aFNoaWZ0KGJyYW5jaCwgLTEpO1xuICAgIHRoaXMuX3NjaGVkdWxlUmVjYWxjKGFycik7XG4gIH1cblxuICAvKipcbiAgICog0J/RgNC+0LLQtdGA0Y/QtdGCLCDQtdGB0YLRjCDQu9C4INGDINGD0LfQu9CwINC00L7Rh9C10YDQvdC40LUg0Y3Qu9C10LzQtdC90YLRi1xuICAgKi9cbiAgcHJvdGVjdGVkIGhhc0NoaWxkcmVuKG5vZGU6IEZsYXROb2RlKTogYm9vbGVhbiB7XG4gICAgY29uc3QgYXJyID0gdGhpcy5mbGF0VHJlZSgpO1xuICAgIGNvbnN0IGlkeCA9IGFyci5pbmRleE9mKG5vZGUpO1xuICAgIGlmIChpZHggPT09IC0xKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGZvciAobGV0IGkgPSBpZHggKyAxOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBuZXh0ID0gYXJyW2ldO1xuICAgICAgaWYgKG5leHQuZGVwdGggPD0gbm9kZS5kZXB0aCkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGlmIChuZXh0LmRlcHRoID09PSBub2RlLmRlcHRoICsgMSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgcHJvdGVjdGVkIHNhdmUoKTogdm9pZCB7XG4gICAgLy8g0KTQu9Cw0LMg0LTQu9GPINC70L7Qs9Cz0LjRgNC+0LLQsNC90LjRjyDQvdCwINCy0YDQtdC80Y8g0L7RgtC70LDQtNC60LhcbiAgICBjb25zdCBsb2dnaW5nID0gZmFsc2U7XG5cbiAgICBjb25zdCBjaGFuZ2VkRWxlbWVudHMgPSB0aGlzLmZsYXRUcmVlKCkuZmlsdGVyKChuZXdJdGVtKSA9PiB7XG4gICAgICBjb25zdCBvcmlnaW5hbEl0ZW0gPSB0aGlzLm9yaWdpbmFsVHJlZS5nZXQobmV3SXRlbS5pZCk7XG5cbiAgICAgIC8vINCd0L7QstGL0Lkg0Y3Qu9C10LzQtdC90YJcbiAgICAgIGlmICghb3JpZ2luYWxJdGVtKSB7XG4gICAgICAgIGlmIChsb2dnaW5nKSB7XG4gICAgICAgICAgY29uc29sZS5sb2coYNCd0L7QstGL0Lkg0Y3Qu9C10LzQtdC90YIgJHtuZXdJdGVtLnRpdGxlfWApO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHtcbiAgICAgICAgb3JkZXJfbnVtOiBvcmlnaW5hbE9yZGVyTnVtLFxuICAgICAgICBpZF9wYXJlbnQ6IG9yaWdpbmFsSWRQYXJlbnQsXG4gICAgICAgIHRpdGxlOiBvcmlnaW5hbFRpdGxlLFxuICAgICAgICBhbGxvd2VkX3JvbGVzOiBvcmlnaW5hbFJvbGVzLFxuICAgICAgICBjb2RlOiBvcmlnaW5hbENvZGUsXG4gICAgICAgIHJvdXRlOiBvcmlnaW5hbFJvdXRlLFxuICAgICAgICBpY29uOiBvcmlnaW5hbEljb24sXG4gICAgICB9ID0gb3JpZ2luYWxJdGVtO1xuXG4gICAgICBjb25zdCB7XG4gICAgICAgIG9yZGVyX251bTogbmV3T3JkZXJOdW0sXG4gICAgICAgIGlkX3BhcmVudDogbmV3SWRQYXJlbnQsXG4gICAgICAgIHRpdGxlOiBuZXdUaXRsZSxcbiAgICAgICAgYWxsb3dlZF9yb2xlczogbmV3Um9sZXMsXG4gICAgICAgIGNvZGU6IG5ld0NvZGUsXG4gICAgICAgIHJvdXRlOiBuZXdSb3V0ZSxcbiAgICAgICAgaWNvbjogbmV3SWNvbixcbiAgICAgIH0gPSBuZXdJdGVtO1xuXG4gICAgICBjb25zdCBjaGFuZ2VkRmllbGRzOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgICBpZiAob3JpZ2luYWxPcmRlck51bSAhPT0gbmV3T3JkZXJOdW0pIHtcbiAgICAgICAgY2hhbmdlZEZpZWxkcy5wdXNoKGBvcmRlcl9udW06ICR7b3JpZ2luYWxPcmRlck51bX0g4oaSICR7bmV3T3JkZXJOdW19YCk7XG4gICAgICB9XG4gICAgICBpZiAob3JpZ2luYWxJZFBhcmVudCAhPT0gbmV3SWRQYXJlbnQpIHtcbiAgICAgICAgY2hhbmdlZEZpZWxkcy5wdXNoKGBpZF9wYXJlbnQ6ICR7b3JpZ2luYWxJZFBhcmVudH0g4oaSICR7bmV3SWRQYXJlbnR9YCk7XG4gICAgICB9XG4gICAgICBpZiAob3JpZ2luYWxUaXRsZSAhPT0gbmV3VGl0bGUpIHtcbiAgICAgICAgY2hhbmdlZEZpZWxkcy5wdXNoKGB0aXRsZTogJHtvcmlnaW5hbFRpdGxlfSDihpIgJHtuZXdUaXRsZX1gKTtcbiAgICAgIH1cbiAgICAgIGlmIChvcmlnaW5hbENvZGUgIT09IG5ld0NvZGUpIHtcbiAgICAgICAgY2hhbmdlZEZpZWxkcy5wdXNoKGBjb2RlOiAke29yaWdpbmFsQ29kZX0g4oaSICR7bmV3Q29kZX1gKTtcbiAgICAgIH1cbiAgICAgIGlmIChvcmlnaW5hbFJvdXRlICE9PSBuZXdSb3V0ZSkge1xuICAgICAgICBjaGFuZ2VkRmllbGRzLnB1c2goYHJvdXRlOiAke29yaWdpbmFsUm91dGV9IOKGkiAke25ld1JvdXRlfWApO1xuICAgICAgfVxuICAgICAgaWYgKG9yaWdpbmFsSWNvbiAhPT0gbmV3SWNvbikge1xuICAgICAgICBjaGFuZ2VkRmllbGRzLnB1c2goYGljb246ICR7b3JpZ2luYWxJY29ufSDihpIgJHtuZXdJY29ufWApO1xuICAgICAgfVxuICAgICAgaWYgKEpTT04uc3RyaW5naWZ5KG9yaWdpbmFsUm9sZXMpICE9PSBKU09OLnN0cmluZ2lmeShuZXdSb2xlcykpIHtcbiAgICAgICAgY2hhbmdlZEZpZWxkcy5wdXNoKGBhbGxvd2VkX3JvbGVzOiAke29yaWdpbmFsUm9sZXN9IOKGkiAke25ld1JvbGVzfWApO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gY2hhbmdlZEZpZWxkcy5sZW5ndGggPiAwO1xuICAgIH0pO1xuXG4gICAgY29uc3QgaXNCbGFuayA9IChzOiB1bmtub3duKTogYm9vbGVhbiA9PiB0eXBlb2YgcyAhPT0gJ3N0cmluZycgfHwgcy50cmltKCkgPT09ICcnO1xuXG4gICAgY29uc3QgaXNSb3V0ZVZhbGlkID0gKHsgcm91dGUsIGNvZGUgfTogRmxhdE5vZGUpOiBib29sZWFuID0+IHtcbiAgICAgIC8vIHJvdXRlINGB0YfQuNGC0LDQtdGC0YHRjyDQt9Cw0LTQsNC90L3Ri9C8LCDRgtC+0LvRjNC60L4g0LXRgdC70Lgg0Y3RgtC+INC90LXQv9GD0YHRgtCw0Y8g0YHRgtGA0L7QutCwXG4gICAgICBjb25zdCBoYXNSb3V0ZSA9IHJvdXRlLnRyaW0oKSAhPT0gJyc7XG5cbiAgICAgIHJldHVybiAhaGFzUm91dGUgfHwgcm91dGUgPT09IGNvZGU7XG4gICAgfTtcblxuICAgIGNvbnN0IGludmFsaWRDb2RlVGl0bGVzOiBzdHJpbmdbXSA9IFtdO1xuICAgIGNvbnN0IGludmFsaWRSb3V0ZVRpdGxlczogRmxhdE5vZGVbXSA9IFtdO1xuXG4gICAgZm9yIChjb25zdCBlbCBvZiBjaGFuZ2VkRWxlbWVudHMpIHtcbiAgICAgIGlmIChpc0JsYW5rKGVsLmNvZGUpKSB7XG4gICAgICAgIGludmFsaWRDb2RlVGl0bGVzLnB1c2goZWwudGl0bGUgPz8gJyjQsdC10Lcg0L3QsNC30LLQsNC90LjRjyknKTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFpc1JvdXRlVmFsaWQoZWwpKSB7XG4gICAgICAgIGludmFsaWRSb3V0ZVRpdGxlcy5wdXNoKGVsKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoaW52YWxpZENvZGVUaXRsZXMubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy5lcnJvck1zZ091dHB1dC5lbWl0KHtcbiAgICAgICAgbGFiZWw6ICfQmtC+0L3RgdGC0YDRg9C60YLQvtGAINC80LXQvdGOJyxcbiAgICAgICAgYXBwZWFyYW5jZTogJ25lZ2F0aXZlJyxcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHhzcy9uby1taXhlZC1odG1sXG4gICAgICAgIGNvbnRlbnQ6IGDQktGB0LUg0L/QvtC70Y8gY29kZSDQtNC+0LvQttC90Ysg0LHRi9GC0Ywg0LfQsNC/0L7Qu9C90LXQvdGLLiA8L2JyPlxuICAgICAgICDQmNGB0L/RgNCw0LLRjNGC0LUg0YHQu9C10LTRg9GO0YnQuNC1INC/0L7Qu9GPOiA8L2JyPlxuICAgICAgICAke2ludmFsaWRDb2RlVGl0bGVzLm1hcCgodCkgPT4gYC0gJHt0fWApLmpvaW4oJzwvYnI+Jyl9XG4gICAgICAgIGAsXG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChpbnZhbGlkUm91dGVUaXRsZXMubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy5lcnJvck1zZ091dHB1dC5lbWl0KHtcbiAgICAgICAgbGFiZWw6ICfQmtC+0L3RgdGC0YDRg9C60YLQvtGAINC80LXQvdGOJyxcbiAgICAgICAgYXBwZWFyYW5jZTogJ25lZ2F0aXZlJyxcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHhzcy9uby1taXhlZC1odG1sXG4gICAgICAgIGNvbnRlbnQ6IGDQktGB0LUg0L/QvtC70Y8gY29kZSDQtNC+0LvQttC90Ysg0LHRi9GC0Ywg0YDQsNCy0L3RiyDQv9C+0LvRjiByb3V0ZS4gPC9icj5cbiAgICAgICAg0JjRgdC/0YDQsNCy0YzRgtC1INGB0LvQtdC00YPRjtGJ0LjQtSDQv9C+0LvRjzogPC9icj5cbiAgICAgICAgJHtpbnZhbGlkUm91dGVUaXRsZXMubWFwKCh0KSA9PiBgLSAke3QudGl0bGV9ICgke3QuY29kZX0gfCAke3Qucm91dGV9KWApLmpvaW4oJzwvYnI+Jyl9XG4gICAgICAgIGAsXG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGVsUm91dGUgPSAocm91dGU6IHN0cmluZyk6IHN0cmluZyB8IG51bGwgPT4gKHJvdXRlID09PSAnJyA/IG51bGwgOiByb3V0ZSk7XG5cbiAgICBjb25zdCBub3JtYWxpemVFbGVtZW50ID0gKGVsOiBGbGF0Tm9kZSk6IElDbHNNZW51SXRlbUlucHV0ID0+ICh7XG4gICAgICB0aXRsZTogZWwudGl0bGUudHJpbSgpLFxuICAgICAgcm91dGU6IGVsUm91dGUoZWwucm91dGUudHJpbSgpKSxcbiAgICAgIGNvZGU6IGVsLmNvZGUsXG4gICAgICBpY29uOiBlbC5pY29uLFxuICAgICAgb3JkZXJfbnVtOiBlbC5vcmRlcl9udW0sXG4gICAgICBhbGxvd2VkX3JvbGVzOiBlbC5hbGxvd2VkX3JvbGVzXG4gICAgICAgID8gZWwuYWxsb3dlZF9yb2xlcy5zcGxpdCgnLCcpLm1hcCgodmFsdWUpID0+IHZhbHVlLnRyaW0oKSlcbiAgICAgICAgOiBudWxsLFxuICAgICAgaWRfcGFyZW50OiBlbC5pZF9wYXJlbnQsXG4gICAgfSk7XG5cbiAgICBjb25zdCBvYmplY3RzVG9TYXZlID0gY2hhbmdlZEVsZW1lbnRzXG4gICAgICAuZmlsdGVyKCh7IGlkIH0pID0+ICFpZC5pbmNsdWRlcyhORVdfSVRFTV9QUkVGSVgpKVxuICAgICAgLm1hcCgoZWwpID0+ICh7XG4gICAgICAgIF9zZXQ6IG5vcm1hbGl6ZUVsZW1lbnQoZWwpLFxuICAgICAgICB3aGVyZTogeyBpZDogeyBfZXE6IGVsLmlkIH0gfSxcbiAgICAgIH0pKTtcblxuICAgIGNvbnN0IG9iamVjdHNUb0luc2VydCA9IGNoYW5nZWRFbGVtZW50c1xuICAgICAgLmZpbHRlcigoeyBpZCB9KSA9PiBpZC5pbmNsdWRlcyhORVdfSVRFTV9QUkVGSVgpKVxuICAgICAgLm1hcCgoZWxlbWVudCkgPT4ge1xuICAgICAgICBlbGVtZW50LmlkID0gRU1QVFlfVVVJRDtcblxuICAgICAgICByZXR1cm4gbm9ybWFsaXplRWxlbWVudChlbGVtZW50KTtcbiAgICAgIH0pO1xuXG4gICAgY29uc3Qgb2JqZWN0c1RvRGVsZXRlID0gWy4uLnRoaXMuZGVsZXRlZElkc107XG5cbiAgICBpZiAobG9nZ2luZykge1xuICAgICAgY29uc29sZS5sb2coYNCY0LfQvNC10L3QtdC90L3Ri9C1INGN0LvQtdC80LXQvdGC0YtgLCBvYmplY3RzVG9TYXZlKTtcbiAgICAgIGNvbnNvbGUubG9nKGDQndC+0LLRi9C1INGN0LvQtdC80LXQvdGC0YtgLCBvYmplY3RzVG9JbnNlcnQpO1xuICAgICAgY29uc29sZS5sb2coJ9Cj0LTQsNC70ZHQvdC90YvQtSDRjdC70LXQvNC10L3RgtGLOicsIG9iamVjdHNUb0RlbGV0ZSk7XG4gICAgfVxuXG4gICAgdGhpcy5fc3RvcmUudXBkYXRlTWVudShvYmplY3RzVG9TYXZlLCBvYmplY3RzVG9JbnNlcnQsIG9iamVjdHNUb0RlbGV0ZSk7XG5cbiAgICB0aGlzLmRlbGV0ZWRJZHMgPSBbXTtcbiAgfVxuXG4gIHByb3RlY3RlZCBoYW5kbGVGb2xkKHN0YXRlOiBib29sZWFuKTogdm9pZCB7XG4gICAgZm9yIChjb25zdCBlbGVtZW50IG9mIHRoaXMuZmxhdFRyZWUoKSkge1xuICAgICAgaWYgKGVsZW1lbnQudGl0bGUgIT09IFJPT1RfVElUTEUpIHtcbiAgICAgICAgZWxlbWVudC5jb2xsYXBzZWQgPSBzdGF0ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLmZsYXRUcmVlLnNldChbLi4udGhpcy5mbGF0VHJlZSgpXSk7XG4gIH1cblxuICAvKipcbiAgICog0KPQtNCw0LvRj9C10YIg0L7QtNC40L0g0Y3Qu9C10LzQtdC90YIg0LjQtyDQtNC10YDQtdCy0LAuXG4gICAqINCf0L7RgtC+0LzQutC4INGB0YLQsNC90L7QstGP0YLRgdGPINC00L7Rh9C10YDQvdC40LzQuCDRjdC70LXQvNC10L3RgtCw0LzQuCDRgNC+0LTQuNGC0LXQu9GPINGD0LTQsNC70ZHQvdC90L7Qs9C+INGD0LfQu9CwLlxuICAgKi9cbiAgcHJvdGVjdGVkIGRlbGV0ZUl0ZW0obm9kZTogRmxhdE5vZGUpOiB2b2lkIHtcbiAgICBjb25zdCBhcnIgPSBbLi4udGhpcy5mbGF0VHJlZSgpXTtcbiAgICBjb25zdCBpbmRleCA9IGFyci5pbmRleE9mKG5vZGUpO1xuICAgIGlmIChpbmRleCA9PT0gLTEpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBwYXJlbnRJZCA9IG5vZGUuaWRfcGFyZW50O1xuICAgIGNvbnN0IG5vZGVEZXB0aCA9IG5vZGUuZGVwdGg7XG5cbiAgICAvLyDQndCw0YXQvtC00LjQvCDQv9C+0YLQvtC80LrQvtCyLCDQutC+0YLQvtGA0YvQtSDQsdGL0LvQuCDQvdCw0L/RgNGP0LzRg9GOINC/0L7QtCDRjdGC0LjQvCDRg9C30LvQvtC8XG4gICAgZm9yIChsZXQgaSA9IGluZGV4ICsgMTsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgbmV4dCA9IGFycltpXTtcbiAgICAgIGlmIChuZXh0LmRlcHRoIDw9IG5vZGVEZXB0aCkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGlmIChuZXh0LmRlcHRoID09PSBub2RlRGVwdGggKyAxKSB7XG4gICAgICAgIC8vINC/0L7RgtC+0LzQvtC6INGB0YLQsNC90L7QstC40YLRgdGPINGA0LXQsdGR0L3QutC+0Lwg0YDQvtC00LjRgtC10LvRjyDRg9C00LDQu9GR0L3QvdC+0LPQviDRg9C30LvQsFxuICAgICAgICBuZXh0LmlkX3BhcmVudCA9IHBhcmVudElkID8/IG51bGw7XG4gICAgICAgIG5leHQuZGVwdGggPSBub2RlRGVwdGg7IC8vINC/0L7QtNC90LjQvNCw0LXQvCDQvdCwINC+0LTQuNC9INGD0YDQvtCy0LXQvdGMINCy0LLQtdGA0YVcbiAgICAgIH0gZWxzZSBpZiAobmV4dC5kZXB0aCA+IG5vZGVEZXB0aCArIDEpIHtcbiAgICAgICAgLy8g0L/QvtC00L3QuNC80LDQtdC8INC+0YHRgtCw0LvRjNC90YvQtSDQvdCwINC+0LTQuNC9INGD0YDQvtCy0LXQvdGMINCy0LLQtdGA0YVcbiAgICAgICAgbmV4dC5kZXB0aCAtPSAxO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vINCj0LTQsNC70Y/QtdC8INGB0LDQvCDRjdC70LXQvNC10L3RglxuICAgIGFyci5zcGxpY2UoaW5kZXgsIDEpO1xuXG4gICAgLy8g0JXRgdC70LggaWQg0L3QtSDQstGA0LXQvNC10L3QvdGL0Lkg4oCUINC00L7QsdCw0LLQu9GP0LXQvCDQsiDRgdC/0LjRgdC+0Log0L3QsCDRg9C00LDQu9C10L3QuNC1XG4gICAgaWYgKCFub2RlLmlkLmluY2x1ZGVzKE5FV19JVEVNX1BSRUZJWCkpIHtcbiAgICAgIHRoaXMuZGVsZXRlZElkcy5wdXNoKG5vZGUuaWQpO1xuICAgIH1cblxuICAgIHRoaXMuX3NjaGVkdWxlUmVjYWxjKGFycik7XG4gIH1cblxuICAvKipcbiAgICog0JTQvtCx0LDQstC70Y/QtdGCINC90L7QstGL0Lkg0Y3Qu9C10LzQtdC90YIg0LIg0LTQtdGA0LXQstC+LlxuICAgKiDQn9C+INGD0LzQvtC70YfQsNC90LjRjiDQvtC9INGB0L7Qt9C00LDRkdGC0YHRjyDQutCw0Log0LTQvtGH0LXRgNC90LjQuSDRjdC70LXQvNC10L3RgiByb290LlxuICAgKi9cbiAgcHJvdGVjdGVkIGFkZE5ld0l0ZW0oKTogdm9pZCB7XG4gICAgY29uc3QgYXJyID0gWy4uLnRoaXMuZmxhdFRyZWUoKV07XG5cbiAgICBjb25zdCByb290Tm9kZSA9IGFyci5maW5kKChuKSA9PiBuLnRpdGxlID09PSB0aGlzLlJPT1RfVElUTEUpO1xuXG4gICAgaWYgKCFyb290Tm9kZSkge1xuICAgICAgY29uc29sZS5lcnJvcignUm9vdCDRjdC70LXQvNC10L3RgiDQvdC1INC90LDQudC00LXQvS4g0J3QvtCy0YvQuSDQv9GD0L3QutGCINC90LUg0LzQvtC20LXRgiDQsdGL0YLRjCDQtNC+0LHQsNCy0LvQtdC9LicpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IG5ld05vZGU6IEZsYXROb2RlID0ge1xuICAgICAgaWQ6IGAke05FV19JVEVNX1BSRUZJWH0ke2NyeXB0by5yYW5kb21VVUlEKCl9YCxcbiAgICAgIGlkX3BhcmVudDogcm9vdE5vZGUuaWQsXG4gICAgICB0aXRsZTogJ9Cd0L7QstGL0Lkg0L/Rg9C90LrRgiDQvNC10L3RjicsXG4gICAgICByb3V0ZTogJycsXG4gICAgICBpY29uOiAnJyxcbiAgICAgIG9yZGVyX251bTogMSxcbiAgICAgIGFsbG93ZWRfcm9sZXM6IG51bGwsXG4gICAgICBjb2xsYXBzZWQ6IHRydWUsXG4gICAgICBjb2RlOiAnJyxcbiAgICAgIGRlcHRoOiByb290Tm9kZS5kZXB0aCArIDEsXG4gICAgfTtcblxuICAgIGNvbnN0IGluc2VydEluZGV4ID0gYXJyLmZpbmRJbmRleCgobikgPT4gbi5pZCA9PT0gcm9vdE5vZGUuaWQpICsgMTtcbiAgICBhcnIuc3BsaWNlKGluc2VydEluZGV4LCAwLCBuZXdOb2RlKTtcblxuICAgIHRoaXMuX3NjaGVkdWxlUmVjYWxjKGFycik7XG4gIH1cblxuICAvKipcbiAgICog0KHQsdGA0LDRgdGL0LLQsNC10YIg0YLQtdC60YPRidC10LUg0YHQvtGB0YLQvtGP0L3QuNC1INCyINC40YHRhdC+0LTQvdC+0LVcbiAgICovXG4gIHByb3RlY3RlZCByZXNldCgpOiB2b2lkIHtcbiAgICBjb25zdCBvcmlnaW5hbE1lbnUgPSBzdHJ1Y3R1cmVkQ2xvbmUodGhpcy5fc3RvcmUub3JpZ2luYWxNZW51KTtcbiAgICB0aGlzLmZsYXRUcmVlLnNldCh0aGlzLl9jb252ZXJ0VG9GbGF0Tm9kZShvcmlnaW5hbE1lbnUpKTtcbiAgICB0aGlzLmRlbGV0ZWRJZHMgPSBbXTtcbiAgfVxuXG4gIC8qKlxuICAgKiDQn9GA0L7QstC10YDRj9C10YIsINC90LDRhdC+0LTQuNGC0YHRjyDQu9C4INGN0LvQtdC80LXQvdGCINCyINGC0LXQutGD0YnQtdC5INC/0LXRgNC10YLQsNGB0LrQuNCy0LDQtdC80L7QuSDQstC10YLQutC1XG4gICAqL1xuICBwcm90ZWN0ZWQgaXNEcmFnZ2VkKG5vZGU6IEZsYXROb2RlKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuZHJhZ2dlZEJyYW5jaCgpLnNvbWUoKG4pID0+IG4uaWQgPT09IG5vZGUuaWQpO1xuICB9XG5cbiAgLyoqXG4gICAqINCh0L7QsdC40YDQsNC10YIg0LLRgdGOINCy0LXRgtC60YMg0Y3Qu9C10LzQtdC90YLQvtCyINC90LDRh9C40L3QsNGPINGBINGD0LrQsNC30LDQvdC90L7Qs9C+INGD0LfQu9CwICjQstC60LvRjtGH0LDRjyDQv9C+0YLQvtC80LrQvtCyKVxuICAgKi9cbiAgcHJpdmF0ZSBfY29sbGVjdEJyYW5jaChhcnI6IEZsYXROb2RlW10sIHJvb3Q6IEZsYXROb2RlKTogRmxhdE5vZGVbXSB7XG4gICAgY29uc3Qgc3RhcnQgPSBhcnIuaW5kZXhPZihyb290KTtcbiAgICBpZiAoc3RhcnQgPCAwKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuICAgIGNvbnN0IGJyYW5jaDogRmxhdE5vZGVbXSA9IFt7IC4uLnJvb3QgfV07XG4gICAgZm9yIChsZXQgaSA9IHN0YXJ0ICsgMTsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgbiA9IGFycltpXTtcbiAgICAgIGlmIChuLmRlcHRoID4gcm9vdC5kZXB0aCkge1xuICAgICAgICBicmFuY2gucHVzaChuKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gYnJhbmNoO1xuICB9XG5cbiAgLyoqXG4gICAqINCh0LTQstC40LPQsNC10YIg0LPQu9GD0LHQuNC90YMg0LLRgdC10YUg0Y3Qu9C10LzQtdC90YLQvtCyINCy0LXRgtC60Lgg0L3QsCDRg9C60LDQt9Cw0L3QvdGD0Y4g0YDQsNC30L3QuNGG0YNcbiAgICog0J3QtSDQtNC+0L/Rg9GB0LrQsNC10YIg0L7RgtGA0LjRhtCw0YLQtdC70YzQvdGL0YUg0LPQu9GD0LHQuNC9XG4gICAqL1xuICBwcml2YXRlIF9hcHBseURlcHRoU2hpZnQoYnJhbmNoOiBGbGF0Tm9kZVtdLCBkaWZmOiBudW1iZXIpOiB2b2lkIHtcbiAgICBpZiAoZGlmZiA9PT0gMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IG4gb2YgYnJhbmNoKSB7XG4gICAgICBuLmRlcHRoID0gTWF0aC5tYXgoMCwgbi5kZXB0aCArIGRpZmYpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiDQn9GA0LXQvtCx0YDQsNC30YPQtdGCINC40LXRgNCw0YDRhdC40YfQtdGB0LrQuNC5IEpTT04g0LIg0L/Qu9C+0YHQutC40Lkg0LzQsNGB0YHQuNCyIEZsYXROb2RlW11cbiAgICog0KHQvtGF0YDQsNC90Y/QtdGCINC/0L7RgNGP0LTQvtC6INGN0LvQtdC80LXQvdGC0L7QsiDQuCDQuNGFINCy0LvQvtC20LXQvdC90L7RgdGC0YxcbiAgICovXG4gIHByaXZhdGUgX2NvbnZlcnRUb0ZsYXROb2RlKGRhdGE6IElDbHNNZW51SXRlbVtdKTogRmxhdE5vZGVbXSB7XG4gICAgLy8g0JPQu9GD0LHQvtC60LDRjyDQutC+0L/QuNGPLCDRh9GC0L7QsdGLINC90LUg0L/QvtGA0YLQuNGC0Ywg0L7RgNC40LPQuNC90LDQu1xuICAgIGNvbnN0IGNsb25lZCA9IHN0cnVjdHVyZWRDbG9uZShkYXRhKTtcblxuICAgIGNvbnN0IG1hcCA9IG5ldyBNYXA8c3RyaW5nLCBJQ2xzTWVudUl0ZW0+KCk7XG4gICAgY29uc3Qgcm9vdHM6IElDbHNNZW51SXRlbVtdID0gW107XG5cbiAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgY2xvbmVkKSB7XG4gICAgICBtYXAuc2V0KGl0ZW0uaWQsIGl0ZW0pO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgaXRlbSBvZiBjbG9uZWQpIHtcbiAgICAgIGlmIChpdGVtLmlkX3BhcmVudCAmJiBtYXAuaGFzKGl0ZW0uaWRfcGFyZW50KSkge1xuICAgICAgICBjb25zdCBwYXJlbnQgPSBtYXAuZ2V0KGl0ZW0uaWRfcGFyZW50KSE7XG4gICAgICAgIGlmICghcGFyZW50LmNoaWxkcmVuKSB7XG4gICAgICAgICAgcGFyZW50LmNoaWxkcmVuID0gW107XG4gICAgICAgIH1cbiAgICAgICAgcGFyZW50LmNoaWxkcmVuLnB1c2goaXRlbSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByb290cy5wdXNoKGl0ZW0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGZsYXQ6IEZsYXROb2RlW10gPSBbXTtcbiAgICBjb25zdCB3YWxrID0gKG5vZGU6IElDbHNNZW51SXRlbSwgZGVwdGg6IG51bWJlcik6IHZvaWQgPT4ge1xuICAgICAgZmxhdC5wdXNoKHtcbiAgICAgICAgaWQ6IG5vZGUuaWQsXG4gICAgICAgIGlkX3BhcmVudDogbm9kZS5pZF9wYXJlbnQsXG4gICAgICAgIHRpdGxlOiBub2RlLnRpdGxlID8/ICcnLFxuICAgICAgICByb3V0ZTogbm9kZS5yb3V0ZSA/PyAnJyxcbiAgICAgICAgaWNvbjogbm9kZS5pY29uID8/ICcnLFxuICAgICAgICBvcmRlcl9udW06IG5vZGUub3JkZXJfbnVtID8/IDAsXG4gICAgICAgIGFsbG93ZWRfcm9sZXM6IG5vZGUuYWxsb3dlZF9yb2xlcz8uam9pbignLCcpID8/IG51bGwsXG4gICAgICAgIGNvbGxhcHNlZDogbm9kZS50aXRsZSAhPT0gUk9PVF9USVRMRSxcbiAgICAgICAgY29kZTogbm9kZS5jb2RlID8/ICcnLFxuICAgICAgICBkZXB0aCxcbiAgICAgIH0pO1xuXG4gICAgICBpZiAobm9kZS5jaGlsZHJlbj8ubGVuZ3RoKSB7XG4gICAgICAgIGNvbnN0IHNvcnRlZENoaWxkcmVuID0gWy4uLm5vZGUuY2hpbGRyZW5dLnNvcnQoXG4gICAgICAgICAgKGEsIGIpID0+IChhLm9yZGVyX251bSA/PyAwKSAtIChiLm9yZGVyX251bSA/PyAwKVxuICAgICAgICApO1xuICAgICAgICBmb3IgKGNvbnN0IGNoaWxkIG9mIHNvcnRlZENoaWxkcmVuKSB7XG4gICAgICAgICAgd2FsayhjaGlsZCwgZGVwdGggKyAxKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG5cbiAgICBjb25zdCBzb3J0ZWRSb290cyA9IFsuLi5yb290c10uc29ydCgoYSwgYikgPT4gKGEub3JkZXJfbnVtID8/IDApIC0gKGIub3JkZXJfbnVtID8/IDApKTtcbiAgICBmb3IgKGNvbnN0IHJvb3Qgb2Ygc29ydGVkUm9vdHMpIHtcbiAgICAgIHdhbGsocm9vdCwgMCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZsYXQ7XG4gIH1cblxuICAvKipcbiAgICog0JLQvtC30LLRgNCw0YnQsNC10YIg0YHQv9C40YHQvtC6INCy0LjQtNC40LzRi9GFINGN0LvQtdC80LXQvdGC0L7QsiDQvdCwINC+0YHQvdC+0LLQtSDRhNC70LDQs9C+0LIgY29sbGFwc2VkXG4gICAqINCY0YHQv9C+0LvRjNC30YPQtdGCINGB0YLQtdC6INC00LvRjyDQvtGC0YHQu9C10LbQuNCy0LDQvdC40Y8g0YHQstC10YDQvdGD0YLQvtGB0YLQuCDQvdCwINC60LDQttC00L7QvCDRg9GA0L7QstC90LVcbiAgICovXG4gIHByaXZhdGUgX2dldFZpc2libGVGcm9tKGFycjogRmxhdE5vZGVbXSB8ICgoKSA9PiBGbGF0Tm9kZVtdKSk6IEZsYXROb2RlW10ge1xuICAgIGNvbnN0IHNvdXJjZSA9IHR5cGVvZiBhcnIgPT09ICdmdW5jdGlvbicgPyBhcnIoKSA6IGFycjtcbiAgICBjb25zdCBvdXQ6IEZsYXROb2RlW10gPSBbXTtcbiAgICBjb25zdCBjb2xsYXBzZWRTdGFjazogYm9vbGVhbltdID0gW107XG5cbiAgICBmb3IgKGNvbnN0IG4gb2Ygc291cmNlKSB7XG4gICAgICB3aGlsZSAoY29sbGFwc2VkU3RhY2subGVuZ3RoID4gbi5kZXB0aCkge1xuICAgICAgICBjb2xsYXBzZWRTdGFjay5wb3AoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFjb2xsYXBzZWRTdGFjay5pbmNsdWRlcyh0cnVlKSkge1xuICAgICAgICBvdXQucHVzaChuKTtcbiAgICAgICAgY29sbGFwc2VkU3RhY2tbbi5kZXB0aF0gPSAhIW4uY29sbGFwc2VkO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBvdXQ7XG4gIH1cblxuICAvKipcbiAgICog0J/QtdGA0LXRgdGH0LjRgtGL0LLQsNC10YIgb3JkZXJfbnVtINC4IGlkX3BhcmVudCDRgyDQstGB0LXRhSDRjdC70LXQvNC10L3RgtC+0LIg0LzQsNGB0YHQuNCy0LBcbiAgICog0J/QvtGB0LvQtSDQv9C10YDQtdC80LXRidC10L3QuNC5INC/0L7QtNC00LXRgNC20LjQstCw0LXRgiDQutC+0YDRgNC10LrRgtC90YPRjiDRgdGC0YDRg9C60YLRg9GA0YMg0LTQtdGA0LXQstCwXG4gICAqIG9yZGVyX251bSDQvdCw0LfQvdCw0YfQsNC10YLRgdGPINC+0YLQvdC+0YHQuNGC0LXQu9GM0L3QviDRgNC+0LTQuNGC0LXQu9GPICgxLi5OKVxuICAgKi9cbiAgcHJpdmF0ZSBfcmVjYWxjdWxhdGVUcmVlKGFycjogRmxhdE5vZGVbXSk6IHZvaWQge1xuICAgIGNvbnN0IHBhcmVudHM6IEZsYXROb2RlW10gPSBbXTtcbiAgICBjb25zdCBjaGlsZENvdW50ZXJzID0gbmV3IE1hcDxzdHJpbmcgfCBudWxsLCBudW1iZXI+KCk7XG5cbiAgICBmb3IgKGNvbnN0IG5vZGUgb2YgYXJyKSB7XG4gICAgICB3aGlsZSAocGFyZW50cy5sZW5ndGggPiAwICYmIHBhcmVudHNbcGFyZW50cy5sZW5ndGggLSAxXS5kZXB0aCA+PSBub2RlLmRlcHRoKSB7XG4gICAgICAgIHBhcmVudHMucG9wKCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHBhcmVudCA9IHBhcmVudHMubGVuZ3RoID4gMCA/IHBhcmVudHNbcGFyZW50cy5sZW5ndGggLSAxXSA6IG51bGw7XG4gICAgICBub2RlLmlkX3BhcmVudCA9IHBhcmVudCA/IHBhcmVudC5pZCA6IG51bGw7XG5cbiAgICAgIC8vINCy0YvRh9C40YHQu9GP0LXQvCDQv9C+0YDRj9C00LrQvtCy0YvQuSDQvdC+0LzQtdGAINGB0YDQtdC00Lgg0LHRgNCw0YLRjNC10LJcbiAgICAgIGlmIChub2RlLnRpdGxlICE9PSBST09UX1RJVExFKSB7XG4gICAgICAgIGNvbnN0IHBhcmVudElkID0gbm9kZS5pZF9wYXJlbnQgPz8gbnVsbDtcbiAgICAgICAgY29uc3QgY3VycmVudENvdW50ID0gY2hpbGRDb3VudGVycy5nZXQocGFyZW50SWQpID8/IDE7XG4gICAgICAgIG5vZGUub3JkZXJfbnVtID0gY3VycmVudENvdW50O1xuICAgICAgICBjaGlsZENvdW50ZXJzLnNldChwYXJlbnRJZCwgY3VycmVudENvdW50ICsgMSk7XG4gICAgICB9XG5cbiAgICAgIHBhcmVudHMucHVzaChub2RlKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICog0JDRgdC40L3RhdGA0L7QvdC90L4g0L/Qu9Cw0L3QuNGA0YPQtdGCINC/0LXRgNC10YHRh9C10YIg0LTQtdGA0LXQstCwINGH0LXRgNC10LcgcmVxdWVzdEFuaW1hdGlvbkZyYW1lXG4gICAqINCt0YLQviDQv9GA0LXQtNC+0YLQstGA0LDRidCw0LXRgiDQvNC90L7QttC10YHRgtCy0LXQvdC90YvQtSDQu9C40YjQvdC40LUg0L/QtdGA0LXRgdGH0LXRgtGLINC/0YDQuCDRh9Cw0YHRgtGL0YUg0LjQt9C80LXQvdC10L3QuNGP0YVcbiAgICovXG4gIHByaXZhdGUgX3NjaGVkdWxlUmVjYWxjKGFycjogRmxhdE5vZGVbXSk6IHZvaWQge1xuICAgIGlmICh0aGlzLl9wZW5kaW5nUmVjYWxjKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5fcGVuZGluZ1JlY2FsYyA9IHRydWU7XG4gICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcbiAgICAgIHRoaXMuX3JlY2FsY3VsYXRlVHJlZShbLi4uYXJyXSk7XG4gICAgICBjb25zdCBjdXJyZW50ID0gdGhpcy5mbGF0VHJlZSgpO1xuICAgICAgaWYgKCF0aGlzLl9hcnJheXNFcXVhbChjdXJyZW50LCBhcnIpKSB7XG4gICAgICAgIHRoaXMuZmxhdFRyZWUuc2V0KFsuLi5hcnJdKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuX3BlbmRpbmdSZWNhbGMgPSBmYWxzZTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiDQn9GA0L7QstC10YDRj9C10YIg0YDQsNCy0LXQvdGB0YLQstC+INC00LLRg9GFINC80LDRgdGB0LjQstC+0LIgRmxhdE5vZGUg0L/QviDQutC70Y7Rh9C10LLRi9C8INGB0LLQvtC50YHRgtCy0LDQvFxuICAgKi9cbiAgcHJpdmF0ZSBfYXJyYXlzRXF1YWwoYTogRmxhdE5vZGVbXSwgYjogRmxhdE5vZGVbXSk6IGJvb2xlYW4ge1xuICAgIGlmIChhLmxlbmd0aCAhPT0gYi5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgZm9yIChjb25zdCBbaSwgZWxlbWVudF0gb2YgYS5lbnRyaWVzKCkpIHtcbiAgICAgIGlmIChcbiAgICAgICAgZWxlbWVudC5pZCAhPT0gYltpXS5pZCB8fFxuICAgICAgICBlbGVtZW50LmRlcHRoICE9PSBiW2ldLmRlcHRoIHx8XG4gICAgICAgIGVsZW1lbnQub3JkZXJfbnVtICE9PSBiW2ldLm9yZGVyX251bVxuICAgICAgKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxufVxuIiwiPGRpdiBjbGFzcz1cIm1lbnUtY29uc3RydWN0b3JcIj5cbiAgPGRpdiBjbGFzcz1cInBhbmUgZWRpdG9yXCI+XG4gICAgPGRpdiBjbGFzcz1cInBhbmUtaGVhZGVyXCI+XG4gICAgICA8aDI+0KDQtdC00LDQutGC0L7RgCDQvNC10L3RjjwvaDI+XG4gICAgICA8ZGl2IGNsYXNzPVwiYnV0dG9uc1wiPlxuICAgICAgICA8YnV0dG9uIFtkaXNhYmxlZF09XCIkYW55KGxvYWRpbmckIHwgYXN5bmMpXCIgY2xhc3M9XCJidG4gc2Vjb25kYXJ5XCIgKGNsaWNrKT1cImFkZE5ld0l0ZW0oKVwiPlxuICAgICAgICAgICtcbiAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDxidXR0b24gW2Rpc2FibGVkXT1cIiRhbnkobG9hZGluZyQgfCBhc3luYylcIiBjbGFzcz1cImJ0biBzZWNvbmRhcnlcIiAoY2xpY2spPVwicmVzZXQoKVwiPlxuICAgICAgICAgINCh0LHRgNC+0YHQuNGC0YxcbiAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDxidXR0b24gW2Rpc2FibGVkXT1cIiRhbnkobG9hZGluZyQgfCBhc3luYylcIiBjbGFzcz1cImJ0biBwcmltYXJ5XCIgKGNsaWNrKT1cInNhdmUoKVwiPlxuICAgICAgICAgINCh0L7RhdGA0LDQvdC40YLRjFxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPGJ1dHRvbiBbZGlzYWJsZWRdPVwiJGFueShsb2FkaW5nJCB8IGFzeW5jKVwiIGNsYXNzPVwiYnRuIHByaW1hcnlcIiAoY2xpY2spPVwiaGFuZGxlRm9sZChmYWxzZSlcIj5cbiAgICAgICAgICDQoNCw0YHQutGA0YvRgtGMINCy0YHQtSDRjdC70LXQvNC10L3RgtGLXG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8YnV0dG9uIFtkaXNhYmxlZF09XCIkYW55KGxvYWRpbmckIHwgYXN5bmMpXCIgY2xhc3M9XCJidG4gcHJpbWFyeVwiIChjbGljayk9XCJoYW5kbGVGb2xkKHRydWUpXCI+XG4gICAgICAgICAg0KHQutGA0YvRgtGMINCy0YHQtSDRjdC70LXQvNC10L3RgtGLXG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2XG4gICAgICBjbGFzcz1cImxpc3Qtd3JhcHBlclwiXG4gICAgICBjZGtEcm9wTGlzdFxuICAgICAgW2Nka0Ryb3BMaXN0RGF0YV09XCJ2aXNpYmxlRmxhdFRyZWUoKVwiXG4gICAgICAoY2RrRHJvcExpc3REcm9wcGVkKT1cImRyb3AoJGV2ZW50KVwiXG4gICAgICBbY2RrRHJvcExpc3RMb2NrQXhpc109XCIneSdcIlxuICAgID5cbiAgICAgIEBmb3IgKG5vZGUgb2YgdmlzaWJsZUZsYXRUcmVlKCk7IHRyYWNrIG5vZGUuaWQgKyAnLScgKyBub2RlLm9yZGVyX251bSkge1xuICAgICAgICA8ZGl2XG4gICAgICAgICAgY2xhc3M9XCJub2RlXCJcbiAgICAgICAgICBbc3R5bGUubWFyZ2luTGVmdC5weF09XCJub2RlLmRlcHRoICogMjRcIlxuICAgICAgICAgIFtjbGFzcy5kcmFnZ2VkXT1cImlzRHJhZ2dlZChub2RlKVwiXG4gICAgICAgICAgY2RrRHJhZ1xuICAgICAgICAgIChjZGtEcmFnU3RhcnRlZCk9XCJkcmFnU3RhcnRlZChub2RlKVwiXG4gICAgICAgICAgKGNka0RyYWdFbmRlZCk9XCJkcmFnRW5kZWQoKVwiXG4gICAgICAgID5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwibm9kZS1iYXJcIiBjZGtEcmFnSGFuZGxlPlxuICAgICAgICAgICAgQGlmIChoYXNDaGlsZHJlbihub2RlKSkge1xuICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJjb2xsYXBzZS1idG5cIlxuICAgICAgICAgICAgICAgIChjbGljayk9XCJ0b2dnbGVDb2xsYXBzZShub2RlKTsgJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCJcbiAgICAgICAgICAgICAgICBbdGl0bGVdPVwibm9kZS5jb2xsYXBzZWQgPyAn0KDQsNC30LLQtdGA0L3Rg9GC0YwnIDogJ9Ch0LLQtdGA0L3Rg9GC0YwnXCJcbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIHt7IG5vZGUuY29sbGFwc2VkID8gJ+KWticgOiAn4pa8JyB9fVxuICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgQGlmIChub2RlLnRpdGxlID09PSBST09UX1RJVExFKSB7XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicm9vdC10aXRsZVwiPtCa0L7RgNC90LXQstC+0Lkg0Y3Qu9C10LzQtdC90YI8L3NwYW4+XG4gICAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImxlZnQtY29udHJvbFwiPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZ3JpcFwiPuKLruKLrjwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8aW5wdXQgY2xhc3M9XCJpbnAgdGl0bGVcIiBbKG5nTW9kZWwpXT1cIm5vZGUudGl0bGVcIiBwbGFjZWhvbGRlcj1cItCd0LDQt9Cy0LDQvdC40LVcIiAvPlxuICAgICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgICAgY2xhc3M9XCJpbnAgY29kZVwiXG4gICAgICAgICAgICAgICAgICBbcmVxdWlyZWRdPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cIm5vZGUuY29kZVwiXG4gICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cImNvZGVcIlxuICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgPGlucHV0IGNsYXNzPVwiaW5wIHJvdXRlXCIgWyhuZ01vZGVsKV09XCJub2RlLnJvdXRlXCIgcGxhY2Vob2xkZXI9XCJyb3V0ZVwiIC8+XG4gICAgICAgICAgICAgICAgPGlucHV0IGNsYXNzPVwiaW5wIGljb25cIiBbKG5nTW9kZWwpXT1cIm5vZGUuaWNvblwiIHBsYWNlaG9sZGVyPVwiaWNvblwiIC8+XG4gICAgICAgICAgICAgICAgPGlucHV0IGNsYXNzPVwiaW5wIHJvbGVzXCIgWyhuZ01vZGVsKV09XCJub2RlLmFsbG93ZWRfcm9sZXNcIiBwbGFjZWhvbGRlcj1cItCg0L7Qu9C4XCIgLz5cbiAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRlcHRoLWNvbnRyb2xzXCI+XG4gICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBzbWFsbFwiIChjbGljayk9XCJvdXRkZW50KG5vZGUpXCI+4oaQPC9idXR0b24+XG4gICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBzbWFsbFwiIChjbGljayk9XCJpbmRlbnQobm9kZSlcIj7ihpI8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICBAaWYgKGhhc0NoaWxkcmVuKG5vZGUpKSB7XG4gICAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIHNtYWxsXCIgKGNsaWNrKT1cIm91dGRlbnRCcmFuY2gobm9kZSlcIj7ih5A8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gc21hbGxcIiAoY2xpY2spPVwiaW5kZW50QnJhbmNoKG5vZGUpXCI+4oeSPC9idXR0b24+XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gc21hbGxcIiAoY2xpY2spPVwiZGVsZXRlSXRlbShub2RlKVwiPtCj0LTQsNC70LjRgtGMPC9idXR0b24+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgfVxuICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgPG5nLXRlbXBsYXRlIGNka0RyYWdQcmV2aWV3PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRyYWctYnJhbmNoLXByZXZpZXdcIj5cbiAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgIGNsYXNzPVwicHJldmlldy1iYXJcIlxuICAgICAgICAgICAgICAgICpuZ0Zvcj1cImxldCBuIG9mIGRyYWdnZWRCcmFuY2goKVwiXG4gICAgICAgICAgICAgICAgW3N0eWxlLm1hcmdpbkxlZnQucHhdPVwiKG4uZGVwdGggLSBub2RlLmRlcHRoKSAqIDIwXCJcbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIHt7IG4udGl0bGUgfX1cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIH1cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L2Rpdj5cbiJdfQ==