@grnsft/if 0.1.8 → 0.2.0

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 (208) hide show
  1. package/.commitlintrc.js +45 -0
  2. package/.husky/commit-msg +4 -0
  3. package/.husky/pre-commit +6 -0
  4. package/CONTRIBUTING.md +81 -98
  5. package/README.md +16 -12
  6. package/build/config/config.d.ts +4 -5
  7. package/build/config/config.js +16 -12
  8. package/build/config/index.d.ts +1 -0
  9. package/build/config/index.js +4 -2
  10. package/build/config/params.d.ts +2 -0
  11. package/build/config/params.js +146 -0
  12. package/build/config/strings.d.ts +14 -8
  13. package/build/config/strings.js +18 -12
  14. package/build/index.js +18 -38
  15. package/build/lib/aggregate.d.ts +6 -0
  16. package/build/lib/aggregate.js +72 -0
  17. package/build/lib/compute.d.ts +5 -0
  18. package/build/lib/compute.js +84 -0
  19. package/build/lib/exhaust.d.ts +6 -0
  20. package/build/lib/exhaust.js +47 -0
  21. package/build/lib/initialize.d.ts +6 -0
  22. package/build/lib/initialize.js +98 -0
  23. package/build/lib/load.d.ts +6 -0
  24. package/build/lib/load.js +24 -0
  25. package/build/lib/parameterize.d.ts +5 -0
  26. package/build/lib/parameterize.js +49 -0
  27. package/build/models/export-csv.d.ts +2 -0
  28. package/build/models/export-csv.js +129 -0
  29. package/build/models/export-log.d.ts +4 -0
  30. package/build/models/export-log.js +18 -0
  31. package/build/models/export-yaml.d.ts +4 -0
  32. package/build/models/export-yaml.js +24 -0
  33. package/build/models/group-by.d.ts +11 -0
  34. package/build/models/group-by.js +56 -0
  35. package/build/models/index.d.ts +2 -1
  36. package/build/models/index.js +5 -3
  37. package/build/models/time-sync.d.ts +2 -54
  38. package/build/models/time-sync.js +216 -147
  39. package/build/types/aggregation.d.ts +3 -0
  40. package/build/types/aggregation.js +5 -0
  41. package/build/types/compute.d.ts +25 -0
  42. package/build/types/compute.js +3 -0
  43. package/build/types/exhaust-plugin-interface.d.ts +7 -0
  44. package/build/types/exhaust-plugin-interface.js +3 -0
  45. package/build/types/group-by.d.ts +3 -0
  46. package/build/types/group-by.js +3 -0
  47. package/build/types/initialize.d.ts +4 -0
  48. package/build/types/initialize.js +3 -0
  49. package/build/types/interface.d.ts +8 -0
  50. package/build/types/interface.js +3 -0
  51. package/build/types/load.d.ts +7 -0
  52. package/build/types/load.js +3 -0
  53. package/build/types/manifest.d.ts +40 -0
  54. package/build/types/manifest.js +3 -0
  55. package/build/types/parameters.d.ts +15 -0
  56. package/build/types/parameters.js +5 -0
  57. package/build/types/process-args.d.ts +4 -5
  58. package/build/types/process-args.js +1 -1
  59. package/build/types/time-sync.d.ts +10 -2
  60. package/build/types/time-sync.js +1 -1
  61. package/build/util/aggregation-helper.d.ts +6 -0
  62. package/build/util/aggregation-helper.js +56 -0
  63. package/build/util/args.d.ts +7 -3
  64. package/build/util/args.js +46 -18
  65. package/build/util/errors.d.ts +1 -1
  66. package/build/util/errors.js +8 -4
  67. package/build/util/helpers.d.ts +4 -0
  68. package/build/util/helpers.js +23 -4
  69. package/build/util/json.d.ts +4 -0
  70. package/build/util/json.js +16 -0
  71. package/build/util/logger.d.ts +5 -0
  72. package/build/util/logger.js +40 -0
  73. package/build/util/validations.d.ts +30 -21
  74. package/build/util/validations.js +54 -55
  75. package/build/util/yaml.js +27 -4
  76. package/examples/manifests/azure-importer.yml +24 -0
  77. package/examples/manifests/basic-demo.yml +75 -0
  78. package/examples/manifests/basic.yml +27 -0
  79. package/examples/manifests/boavizta-pipeline.yml +85 -0
  80. package/examples/{impls/case-studies → manifests}/boavizta.yml +14 -14
  81. package/examples/{impls/test → manifests}/ccf.yml +9 -10
  82. package/examples/manifests/cim.yml +20 -0
  83. package/examples/manifests/cloud-metadata.yml +41 -0
  84. package/examples/manifests/co2js.yml +30 -0
  85. package/examples/manifests/coefficient.yml +23 -0
  86. package/examples/manifests/csv-export.yml +34 -0
  87. package/examples/manifests/e-mem.yml +21 -0
  88. package/examples/{impls/test → manifests}/e-net.yml +9 -8
  89. package/examples/manifests/generics.yml +71 -0
  90. package/examples/manifests/group-by.yml +48 -0
  91. package/examples/manifests/mock-observation.yml +33 -0
  92. package/examples/manifests/multiply.yml +23 -0
  93. package/examples/manifests/nesting-demo.yml +89 -0
  94. package/examples/manifests/nesting.yml +215 -0
  95. package/examples/manifests/pipeline-demo-1.yml +85 -0
  96. package/examples/manifests/pipeline-demo-2.yml +149 -0
  97. package/examples/manifests/pipeline-demo.yml +128 -0
  98. package/examples/manifests/pipeline-teads-sci.yml +82 -0
  99. package/examples/manifests/pipeline-with-generics.yml +147 -0
  100. package/examples/manifests/pipeline-with-mocks.yml +146 -0
  101. package/examples/{impls/test → manifests}/sci-e.yml +6 -8
  102. package/examples/manifests/sci-m.yml +23 -0
  103. package/examples/{impls/test → manifests}/sci-o.yml +10 -10
  104. package/examples/{impls/test → manifests}/sci.yml +10 -9
  105. package/examples/manifests/shell.yml +20 -0
  106. package/examples/manifests/sum.yml +23 -0
  107. package/examples/{impls/test → manifests}/tdp-finder.yml +6 -7
  108. package/examples/manifests/teads-aws.yml +22 -0
  109. package/examples/manifests/teads-curve.yml +20 -0
  110. package/examples/manifests/time-sync.yml +32 -0
  111. package/examples/manifests/watt-time.yml +42 -0
  112. package/jest.config.js +6 -1
  113. package/package.json +13 -8
  114. package/src/__tests__/integration/templates/integration.yaml +16 -0
  115. package/src/models/README.md +9 -7
  116. package/tsconfig.test.json +1 -1
  117. package/Makefile +0 -16
  118. package/build/config/units.yaml +0 -112
  119. package/build/lib/models-universe.d.ts +0 -36
  120. package/build/lib/models-universe.js +0 -113
  121. package/build/lib/observatory.d.ts +0 -20
  122. package/build/lib/observatory.js +0 -31
  123. package/build/lib/planet-aggregator.d.ts +0 -6
  124. package/build/lib/planet-aggregator.js +0 -35
  125. package/build/lib/supercomputer.d.ts +0 -37
  126. package/build/lib/supercomputer.js +0 -148
  127. package/build/types/helpers.d.ts +0 -1
  128. package/build/types/helpers.js +0 -3
  129. package/build/types/impl.d.ts +0 -45
  130. package/build/types/impl.js +0 -5
  131. package/build/types/model-interface.d.ts +0 -14
  132. package/build/types/model-interface.js +0 -3
  133. package/build/types/models-universe.d.ts +0 -23
  134. package/build/types/models-universe.js +0 -3
  135. package/build/types/planet-aggregator.d.ts +0 -6
  136. package/build/types/planet-aggregator.js +0 -3
  137. package/build/types/supercomputer.d.ts +0 -4
  138. package/build/types/supercomputer.js +0 -3
  139. package/build/types/units-dealer.d.ts +0 -3
  140. package/build/types/units-dealer.js +0 -3
  141. package/build/types/units.d.ts +0 -11
  142. package/build/types/units.js +0 -37
  143. package/build/util/units-dealer.d.ts +0 -10
  144. package/build/util/units-dealer.js +0 -32
  145. package/coverage/clover.xml +0 -379
  146. package/coverage/coverage-final.json +0 -14
  147. package/coverage/lcov-report/base.css +0 -224
  148. package/coverage/lcov-report/block-navigation.js +0 -87
  149. package/coverage/lcov-report/config/config.ts.html +0 -250
  150. package/coverage/lcov-report/config/index.html +0 -146
  151. package/coverage/lcov-report/config/index.ts.html +0 -91
  152. package/coverage/lcov-report/config/strings.ts.html +0 -208
  153. package/coverage/lcov-report/favicon.png +0 -0
  154. package/coverage/lcov-report/index.html +0 -161
  155. package/coverage/lcov-report/lib/index.html +0 -161
  156. package/coverage/lcov-report/lib/models-universe.ts.html +0 -517
  157. package/coverage/lcov-report/lib/observatory.ts.html +0 -187
  158. package/coverage/lcov-report/lib/planet-aggregator.ts.html +0 -274
  159. package/coverage/lcov-report/lib/supercomputer.ts.html +0 -472
  160. package/coverage/lcov-report/models/index.html +0 -131
  161. package/coverage/lcov-report/models/index.ts.html +0 -88
  162. package/coverage/lcov-report/models/planet-aggregator.ts.html +0 -271
  163. package/coverage/lcov-report/models/time-sync.ts.html +0 -1165
  164. package/coverage/lcov-report/prettify.css +0 -1
  165. package/coverage/lcov-report/prettify.js +0 -2
  166. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  167. package/coverage/lcov-report/sorter.js +0 -196
  168. package/coverage/lcov-report/util/args.ts.html +0 -289
  169. package/coverage/lcov-report/util/errors.ts.html +0 -166
  170. package/coverage/lcov-report/util/index.html +0 -161
  171. package/coverage/lcov-report/util/units-dealer.ts.html +0 -199
  172. package/coverage/lcov-report/util/yaml.ts.html +0 -193
  173. package/coverage/lcov.info +0 -637
  174. package/examples/impls/case-studies/accenture.yml +0 -155
  175. package/examples/impls/case-studies/aggregation.yml +0 -97
  176. package/examples/impls/case-studies/aveva.yaml +0 -48
  177. package/examples/impls/case-studies/azure-yassine.yaml +0 -67
  178. package/examples/impls/case-studies/dow_msft.yml +0 -173
  179. package/examples/impls/case-studies/farm-insights.yaml +0 -35
  180. package/examples/impls/case-studies/gsf-website.yaml +0 -93
  181. package/examples/impls/case-studies/msft-eshoppen.yaml +0 -162
  182. package/examples/impls/case-studies/msft-green-ai.yaml +0 -58
  183. package/examples/impls/case-studies/ntt-data-on-premise.yaml +0 -201
  184. package/examples/impls/test/aggregation-test.yml +0 -109
  185. package/examples/impls/test/azure.yml +0 -26
  186. package/examples/impls/test/if-demo.yml +0 -61
  187. package/examples/impls/test/large-impl.yml +0 -257303
  188. package/examples/impls/test/metadata.yml +0 -21
  189. package/examples/impls/test/nesting.yml +0 -113
  190. package/examples/impls/test/sci-m.yml +0 -24
  191. package/examples/impls/test/shell.yml +0 -19
  192. package/examples/impls/test/time-sync.yml +0 -75
  193. package/examples/ompls/aggregation-test.yml +0 -340
  194. package/examples/ompls/azure.yml +0 -145
  195. package/examples/ompls/ccf.yml +0 -29
  196. package/examples/ompls/complex-pipeline.yml +0 -105
  197. package/examples/ompls/full-sci.yml +0 -64
  198. package/examples/ompls/if-demo.yml +0 -517
  199. package/examples/ompls/metadata.yml +0 -29
  200. package/examples/ompls/nesting.yml +0 -113
  201. package/examples/ompls/sci-e.yml +0 -23
  202. package/examples/ompls/sci-m.yml +0 -33
  203. package/examples/ompls/sci-o.yml +0 -29
  204. package/examples/ompls/sci.yml +0 -37
  205. package/examples/ompls/shell.yml +0 -23
  206. package/examples/ompls/time-sync.yml +0 -212
  207. package/src/config/units.yaml +0 -112
  208. package/tsconfig.build.tsbuildinfo +0 -1
@@ -1,91 +1,138 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.TimeSyncModel = void 0;
4
- const moment = require("moment");
5
- const moment_range_1 = require("moment-range");
6
- const config_1 = require("../config");
3
+ exports.TimeSync = void 0;
4
+ const types_1 = require("node:util/types");
5
+ const luxon_1 = require("luxon");
6
+ const zod_1 = require("zod");
7
+ const parameterize_1 = require("../lib/parameterize");
7
8
  const errors_1 = require("../util/errors");
8
- const units_dealer_1 = require("../util/units-dealer");
9
- const momentRange = (0, moment_range_1.extendMoment)(moment);
9
+ const config_1 = require("../config");
10
+ const validations_1 = require("../util/validations");
10
11
  const { InputValidationError } = errors_1.ERRORS;
11
- const { INVALID_TIME_NORMALIZATION, INVALID_TIME_INTERVAL, INVALID_OBSERVATION_OVERLAP, } = config_1.STRINGS;
12
- class TimeSyncModel {
13
- constructor() {
14
- this.interval = 1;
15
- /**
16
- * Calculates minimal factor.
17
- */
18
- this.convertPerInterval = (value, duration) => value / duration;
19
- /**
20
- * Normalize time per given second.
21
- */
22
- this.normalizeTimePerSecond = (currentRoundMoment, i) => {
23
- const thisMoment = moment(currentRoundMoment).milliseconds(0);
24
- return thisMoment.add(i, 'second');
12
+ const { INVALID_TIME_NORMALIZATION, INVALID_OBSERVATION_OVERLAP, AVOIDING_PADDING_BY_EDGES, } = config_1.STRINGS;
13
+ const TimeSync = (globalConfig) => {
14
+ const metadata = {
15
+ kind: 'execute',
16
+ };
17
+ /**
18
+ * Take input array and return time-synchronized input array.
19
+ */
20
+ const execute = (inputs) => {
21
+ const validatedConfig = validateGlobalConfig();
22
+ const timeParams = {
23
+ startTime: luxon_1.DateTime.fromISO(validatedConfig['start-time']),
24
+ endTime: luxon_1.DateTime.fromISO(validatedConfig['end-time']),
25
+ interval: validatedConfig.interval,
26
+ allowPadding: validatedConfig['allow-padding'],
25
27
  };
26
- /**
27
- * Iterates over given inputs frame, meanwhile checking if aggregation method is `sum`, then calculates it.
28
- * For methods is `avg` and `none` calculating average of the frame.
29
- */
30
- this.resampleInputFrame = (inputsInTimeslot) => {
31
- return inputsInTimeslot.reduce((acc, input, index, inputs) => {
32
- const metrics = Object.keys(input);
33
- metrics.forEach(metric => {
34
- const method = this.dealer.askToGiveMethodFor(metric);
35
- acc[metric] = acc[metric] ?? 0;
36
- if (metric === 'timestamp') {
37
- acc[metric] = inputs[0][metric];
38
- return;
39
- }
40
- if (method === 'sum') {
41
- acc[metric] += input[metric];
42
- return;
43
- }
44
- /** divide each metric by the timeslot length, so that their sum yields the timeslot average.*/
45
- if (index === inputsInTimeslot.length - 1) {
46
- acc[metric] /= inputsInTimeslot.length;
47
- return;
48
- }
49
- acc[metric] += input[metric];
28
+ const pad = checkForPadding(inputs, timeParams);
29
+ validatePadding(pad, timeParams);
30
+ const paddedInputs = padInputs(inputs, pad, timeParams);
31
+ const flattenInputs = paddedInputs.reduce((acc, input, index) => {
32
+ const safeInput = Object.assign({}, input, validateInput(input, index));
33
+ const currentMoment = parseDate(safeInput.timestamp);
34
+ /** Checks if not the first input, then check consistency with previous ones. */
35
+ if (index > 0) {
36
+ const previousInput = paddedInputs[index - 1];
37
+ const previousInputTimestamp = parseDate(previousInput.timestamp);
38
+ /** Checks for timestamps overlap. */
39
+ if (parseDate(previousInput.timestamp).plus({
40
+ seconds: previousInput.duration,
41
+ }) > currentMoment) {
42
+ throw new InputValidationError(INVALID_OBSERVATION_OVERLAP);
43
+ }
44
+ const compareableTime = previousInputTimestamp.plus({
45
+ seconds: previousInput.duration,
50
46
  });
51
- return acc;
52
- }, {});
53
- };
54
- }
47
+ const timelineGapSize = currentMoment
48
+ .diff(compareableTime)
49
+ .as('seconds');
50
+ /** Checks if there is gap in timeline. */
51
+ if (timelineGapSize > 1) {
52
+ acc.push(...getZeroishInputPerSecondBetweenRange(compareableTime, currentMoment, safeInput));
53
+ }
54
+ }
55
+ /** Break down current observation. */
56
+ for (let i = 0; i < safeInput.duration; i++) {
57
+ const normalizedInput = breakDownInput(safeInput, i);
58
+ acc.push(normalizedInput);
59
+ }
60
+ return trimInputsByGlobalTimeline(acc, timeParams);
61
+ }, []);
62
+ const sortedInputs = flattenInputs.sort((a, b) => parseDate(a.timestamp).diff(parseDate(b.timestamp)).as('seconds'));
63
+ return resampleInputs(sortedInputs, timeParams);
64
+ };
65
+ const parseDate = (date) => {
66
+ if (!date)
67
+ return luxon_1.DateTime.invalid('Invalid date');
68
+ // dates are passed to time-sync.ts both in ISO 8601 format
69
+ // and as a Date object (from the deserialization of a YAML file)
70
+ // if the YAML parser fails to identify as a date, it passes as a string
71
+ if ((0, types_1.isDate)(date)) {
72
+ return luxon_1.DateTime.fromJSDate(date);
73
+ }
74
+ if (typeof date === 'string') {
75
+ return luxon_1.DateTime.fromISO(date);
76
+ }
77
+ throw new InputValidationError(`Unexpected date datatype: ${typeof date}: ${date}`);
78
+ };
55
79
  /**
56
- * Setups basic configuration.
80
+ * Validates input parameters.
57
81
  */
58
- async configure(params) {
59
- this.startTime = params['start-time'];
60
- this.endTime = params['end-time'];
61
- this.interval = params.interval;
62
- this.dealer = await (0, units_dealer_1.UnitsDealer)();
63
- return this;
64
- }
82
+ const validateInput = (input, index) => {
83
+ const schema = zod_1.z.object({
84
+ timestamp: zod_1.z
85
+ .string({
86
+ required_error: `required in input[${index}]`,
87
+ })
88
+ .datetime({
89
+ message: `invalid datetime in input[${index}]`,
90
+ })
91
+ .or(zod_1.z.date()),
92
+ duration: zod_1.z.number(),
93
+ });
94
+ return (0, validations_1.validate)(schema, input);
95
+ };
65
96
  /**
66
- * Validates `startTime`, `endTime` and `interval` params.
97
+ * Validates global config parameters.
67
98
  */
68
- validateParams() {
69
- if (!this.startTime || !this.endTime) {
70
- throw new InputValidationError(INVALID_TIME_NORMALIZATION);
71
- }
72
- if (this.startTime > this.endTime) {
99
+ const validateGlobalConfig = () => {
100
+ if (globalConfig === undefined) {
73
101
  throw new InputValidationError(INVALID_TIME_NORMALIZATION);
74
102
  }
75
- if (!this.interval) {
76
- throw new InputValidationError(INVALID_TIME_INTERVAL);
77
- }
78
- }
103
+ const schema = zod_1.z
104
+ .object({
105
+ 'start-time': zod_1.z.string().datetime(),
106
+ 'end-time': zod_1.z.string().datetime(),
107
+ interval: zod_1.z.number(),
108
+ 'allow-padding': zod_1.z.boolean(),
109
+ })
110
+ .refine(data => data['start-time'] < data['end-time'], {
111
+ message: '`start-time` should be lower than `end-time`',
112
+ });
113
+ return (0, validations_1.validate)(schema, globalConfig);
114
+ };
115
+ /**
116
+ * Calculates minimal factor.
117
+ */
118
+ const convertPerInterval = (value, duration) => value / duration;
79
119
  /**
80
- * Barkes down input per minimal time unit.
120
+ * Normalize time per given second.
81
121
  */
82
- breakDownInput(input, i) {
122
+ const normalizeTimePerSecond = (currentRoundMoment, i) => {
123
+ const thisMoment = parseDate(currentRoundMoment).startOf('second');
124
+ return thisMoment.plus({ seconds: i });
125
+ };
126
+ /**
127
+ * Breaks down input per minimal time unit.
128
+ */
129
+ const breakDownInput = (input, i) => {
83
130
  const inputKeys = Object.keys(input);
84
131
  return inputKeys.reduce((acc, key) => {
85
- const method = this.dealer.askToGiveMethodFor(key);
132
+ const method = parameterize_1.parameterize.getAggregationMethod(key);
86
133
  if (key === 'timestamp') {
87
- const perSecond = this.normalizeTimePerSecond(input.timestamp, i);
88
- acc[key] = moment(perSecond).milliseconds(0).toISOString();
134
+ const perSecond = normalizeTimePerSecond(input.timestamp, i);
135
+ acc[key] = perSecond.toUTC().toISO() ?? '';
89
136
  return acc;
90
137
  }
91
138
  /** @todo use user defined resolution later */
@@ -95,19 +142,19 @@ class TimeSyncModel {
95
142
  }
96
143
  acc[key] =
97
144
  method === 'sum'
98
- ? this.convertPerInterval(input[key], input['duration'])
145
+ ? convertPerInterval(input[key], input['duration'])
99
146
  : input[key];
100
147
  return acc;
101
148
  }, {});
102
- }
149
+ };
103
150
  /**
104
151
  * Populates object to fill the gaps in observational timeline using zeroish values.
105
152
  */
106
- fillWithZeroishInput(input, missingTimestamp) {
153
+ const fillWithZeroishInput = (input, missingTimestamp) => {
107
154
  const metrics = Object.keys(input);
108
155
  return metrics.reduce((acc, metric) => {
109
156
  if (metric === 'timestamp') {
110
- acc[metric] = moment(missingTimestamp).milliseconds(0).toISOString();
157
+ acc[metric] = missingTimestamp.startOf('second').toUTC().toISO() ?? '';
111
158
  return acc;
112
159
  }
113
160
  /** @todo later will be changed to user defined interval */
@@ -119,117 +166,139 @@ class TimeSyncModel {
119
166
  acc[metric] = acc['duration'];
120
167
  return acc;
121
168
  }
122
- const method = this.dealer.askToGiveMethodFor(metric);
123
- acc[metric] = method === 'avg' || method === 'sum' ? 0 : input[metric];
169
+ const method = parameterize_1.parameterize.getAggregationMethod(metric);
170
+ if (method === 'avg' || method === 'sum') {
171
+ acc[metric] = 0;
172
+ return acc;
173
+ }
174
+ acc[metric] = input[metric];
124
175
  return acc;
125
176
  }, {});
126
- }
177
+ };
178
+ /**
179
+ * Checks if `error on padding` is enabled and padding is needed. If so, then throws error.
180
+ */
181
+ const validatePadding = (pad, params) => {
182
+ const { start, end } = pad;
183
+ const isPaddingNeeded = start || end;
184
+ if (!params.allowPadding && isPaddingNeeded) {
185
+ throw new InputValidationError(AVOIDING_PADDING_BY_EDGES(start, end));
186
+ }
187
+ };
127
188
  /**
128
189
  * Checks if padding is needed either at start of the timeline or the end and returns status.
129
190
  */
130
- checkForPadding(inputs) {
131
- const startDiffInSeconds = moment(inputs[0].timestamp).diff(moment(this.startTime)) / 1000;
191
+ const checkForPadding = (inputs, params) => {
192
+ const startDiffInSeconds = parseDate(inputs[0].timestamp)
193
+ .diff(params.startTime)
194
+ .as('seconds');
132
195
  const lastInput = inputs[inputs.length - 1];
133
- const endDiffInSeconds = moment(lastInput.timestamp)
134
- .add(lastInput.duration, 'seconds')
135
- .diff(moment(this.endTime)) / 1000;
196
+ const endDiffInSeconds = parseDate(lastInput.timestamp)
197
+ .plus({ second: lastInput.duration })
198
+ .diff(params.endTime)
199
+ .as('seconds');
136
200
  return {
137
201
  start: startDiffInSeconds > 0,
138
202
  end: endDiffInSeconds < 0,
139
203
  };
140
- }
204
+ };
205
+ /**
206
+ * Iterates over given inputs frame, meanwhile checking if aggregation method is `sum`, then calculates it.
207
+ * For methods is `avg` and `none` calculating average of the frame.
208
+ */
209
+ const resampleInputFrame = (inputsInTimeslot) => {
210
+ return inputsInTimeslot.reduce((acc, input, index, inputs) => {
211
+ const metrics = Object.keys(input);
212
+ metrics.forEach(metric => {
213
+ const method = parameterize_1.parameterize.getAggregationMethod(metric);
214
+ acc[metric] = acc[metric] ?? 0;
215
+ if (metric === 'timestamp') {
216
+ acc[metric] = inputs[0][metric];
217
+ return;
218
+ }
219
+ if (method === 'sum') {
220
+ acc[metric] += input[metric];
221
+ return;
222
+ }
223
+ if (method === 'none') {
224
+ acc[metric] = input[metric];
225
+ return;
226
+ }
227
+ /**
228
+ * If timeslot contains records more than one, then divide each metric by the timeslot length,
229
+ * so that their sum yields the timeslot average.
230
+ */
231
+ if (inputsInTimeslot.length > 1 &&
232
+ index === inputsInTimeslot.length - 1) {
233
+ acc[metric] /= inputsInTimeslot.length;
234
+ return;
235
+ }
236
+ acc[metric] += input[metric];
237
+ });
238
+ return acc;
239
+ }, {});
240
+ };
141
241
  /**
142
242
  * Takes each array frame with interval length, then aggregating them together as from units.yaml file.
143
243
  */
144
- resampleInputs(inputs) {
244
+ const resampleInputs = (inputs, params) => {
145
245
  return inputs.reduce((acc, _input, index, inputs) => {
146
- const frameStart = index * this.interval;
147
- const frameEnd = (index + 1) * this.interval;
246
+ const frameStart = index * params.interval;
247
+ const frameEnd = (index + 1) * params.interval;
148
248
  const inputsFrame = inputs.slice(frameStart, frameEnd);
149
- const resampledInput = this.resampleInputFrame(inputsFrame);
249
+ const resampledInput = resampleInputFrame(inputsFrame);
150
250
  /** Checks if resampled input is not empty, then includes in result. */
151
251
  if (Object.keys(resampledInput).length > 0) {
152
252
  acc.push(resampledInput);
153
253
  }
154
254
  return acc;
155
255
  }, []);
156
- }
256
+ };
157
257
  /**
158
258
  * Pads zeroish inputs from the beginning or at the end of the inputs if needed.
159
259
  */
160
- padInputs(inputs, pad) {
260
+ const padInputs = (inputs, pad, params) => {
161
261
  const { start, end } = pad;
162
262
  const paddedFromBeginning = [];
163
263
  if (start) {
164
- const dateRange = momentRange.range(moment(this.startTime), moment(inputs[0].timestamp).subtract(1, 'second'));
165
- /** Checks if converting to value of is needed. */
166
- for (const second of dateRange.by('second')) {
167
- paddedFromBeginning.push(this.fillWithZeroishInput(inputs[0], second.valueOf()));
168
- }
264
+ paddedFromBeginning.push(...getZeroishInputPerSecondBetweenRange(params.startTime, parseDate(inputs[0].timestamp), inputs[0]));
169
265
  }
170
266
  const paddedArray = paddedFromBeginning.concat(inputs);
171
267
  if (end) {
172
268
  const lastInput = inputs[inputs.length - 1];
173
- const dateRange = momentRange.range(moment(lastInput.timestamp).add(lastInput.duration, 'seconds'), moment(this.endTime));
174
- for (const second of dateRange.by('second')) {
175
- paddedArray.push(this.fillWithZeroishInput(lastInput, second.valueOf()));
176
- }
269
+ const lastInputEnd = parseDate(lastInput.timestamp).plus({
270
+ seconds: lastInput.duration,
271
+ });
272
+ paddedArray.push(...getZeroishInputPerSecondBetweenRange(lastInputEnd, params.endTime.plus({ seconds: 1 }), lastInput));
177
273
  }
178
274
  return paddedArray;
179
- }
275
+ };
276
+ const getZeroishInputPerSecondBetweenRange = (startDate, endDate, templateInput) => {
277
+ const array = [];
278
+ const dateRange = luxon_1.Interval.fromDateTimes(startDate, endDate);
279
+ for (const interval of dateRange.splitBy({ second: 1 })) {
280
+ array.push(fillWithZeroishInput(templateInput,
281
+ // as far as I can tell, start will never be null
282
+ // because if we pass an invalid start/endDate to
283
+ // Interval, we get a zero length array as the range
284
+ interval.start || luxon_1.DateTime.invalid('not expected - start is null')));
285
+ }
286
+ return array;
287
+ };
180
288
  /*
181
289
  * Checks if input's timestamp is included in global specified period then leaves it, otherwise.
182
290
  */
183
- trimInputsByGlobalTimeline(inputs) {
291
+ const trimInputsByGlobalTimeline = (inputs, params) => {
184
292
  return inputs.reduce((acc, item) => {
185
293
  const { timestamp } = item;
186
- if (moment(timestamp).isSameOrAfter(moment(this.startTime)) &&
187
- moment(timestamp).isSameOrBefore(moment(this.endTime))) {
294
+ if (parseDate(timestamp) >= params.startTime &&
295
+ parseDate(timestamp) <= params.endTime) {
188
296
  acc.push(item);
189
297
  }
190
298
  return acc;
191
299
  }, []);
192
- }
193
- /**
194
- * Normalizes provided time window according to time configuration.
195
- */
196
- async execute(inputs) {
197
- this.validateParams();
198
- const pad = this.checkForPadding(inputs);
199
- const paddedInputs = this.padInputs(inputs, pad);
200
- const flattenInputs = paddedInputs.reduce((acc, input, index) => {
201
- const currentMoment = moment(input.timestamp);
202
- /** Checks if not the first input, then check consistency with previous ones. */
203
- if (index > 0) {
204
- const previousInput = paddedInputs[index - 1];
205
- const previousInputTimestamp = moment(previousInput.timestamp);
206
- /** Checks for timestamps overlap. */
207
- if (moment(previousInput.timestamp)
208
- .add(previousInput.duration, 'seconds')
209
- .isAfter(currentMoment)) {
210
- throw new InputValidationError(INVALID_OBSERVATION_OVERLAP);
211
- }
212
- const compareableTime = previousInputTimestamp.add(previousInput.duration, 'second');
213
- const timelineGapSize = currentMoment.diff(compareableTime, 'second');
214
- //console.log(currentMoment, timelineGapSize)
215
- /** Checks if there is gap in timeline. */
216
- if (timelineGapSize > 1) {
217
- for (let missingTimestamp = compareableTime.valueOf(); missingTimestamp <= currentMoment.valueOf() - 1000; missingTimestamp += 1000) {
218
- const filledGap = this.fillWithZeroishInput(input, missingTimestamp);
219
- acc.push(filledGap);
220
- }
221
- }
222
- }
223
- /** Break down current observation. */
224
- for (let i = 0; i < input.duration; i++) {
225
- const normalizedInput = this.breakDownInput(input, i);
226
- acc.push(normalizedInput);
227
- }
228
- return this.trimInputsByGlobalTimeline(acc);
229
- }, []);
230
- const sortedInputs = flattenInputs.sort((a, b) => moment(a.timestamp).diff(moment(b.timestamp)));
231
- return this.resampleInputs(sortedInputs);
232
- }
233
- }
234
- exports.TimeSyncModel = TimeSyncModel;
235
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGltZS1zeW5jLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL21vZGVscy90aW1lLXN5bmMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsaUNBQWtDO0FBQ2xDLCtDQUEwQztBQUUxQyxzQ0FBa0M7QUFFbEMsMkNBQXNDO0FBQ3RDLHVEQUFpRDtBQU9qRCxNQUFNLFdBQVcsR0FBRyxJQUFBLDJCQUFZLEVBQUMsTUFBTSxDQUFDLENBQUM7QUFFekMsTUFBTSxFQUFDLG9CQUFvQixFQUFDLEdBQUcsZUFBTSxDQUFDO0FBRXRDLE1BQU0sRUFDSiwwQkFBMEIsRUFDMUIscUJBQXFCLEVBQ3JCLDJCQUEyQixHQUM1QixHQUFHLGdCQUFPLENBQUM7QUFFWixNQUFhLGFBQWE7SUFBMUI7UUFJRSxhQUFRLEdBQUcsQ0FBQyxDQUFDO1FBK0JiOztXQUVHO1FBQ0ssdUJBQWtCLEdBQUcsQ0FBQyxLQUFhLEVBQUUsUUFBZ0IsRUFBRSxFQUFFLENBQy9ELEtBQUssR0FBRyxRQUFRLENBQUM7UUFFbkI7O1dBRUc7UUFDSywyQkFBc0IsR0FBRyxDQUFDLGtCQUEwQixFQUFFLENBQVMsRUFBRSxFQUFFO1lBQ3pFLE1BQU0sVUFBVSxHQUFHLE1BQU0sQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUU5RCxPQUFPLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQ3JDLENBQUMsQ0FBQztRQXNGRjs7O1dBR0c7UUFDSyx1QkFBa0IsR0FBRyxDQUFDLGdCQUErQixFQUFFLEVBQUU7WUFDL0QsT0FBTyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsRUFBRTtnQkFDM0QsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQWtCLENBQUM7Z0JBRXBELE9BQU8sQ0FBQyxP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LEVBQUUsRUFDaEQsZ0JBQWdCLElBQUksYUFBYSxDQUFDLE9BQU8sRUFBRSxHQUFHLElBQUksRUFDbEQsZ0JBQWdCLElBQUksSUFBSSxFQUN4Qjt3QkFDQSxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQ3pDLEtBQUssRUFDTCxnQkFBZ0IsQ0FDakIsQ0FBQzt3QkFFRixHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO3FCQUNyQjtpQkFDRjthQUNGO1lBRUQsc0NBQXNDO1lBQ3RDLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxLQUFLLENBQUMsUUFBUSxFQUFFLENBQUMsRUFBRSxFQUFFO2dCQUN2QyxNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQztnQkFFdEQsR0FBRyxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQzthQUMzQjtZQUVELE9BQU8sSUFBSSxDQUFDLDBCQUEwQixDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQzlDLENBQUMsRUFBRSxFQUFtQixDQUFDLENBQUM7UUFFeEIsTUFBTSxZQUFZLEdBQUcsYUFBYSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUMvQyxNQUFNLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQzlDLENBQUM7UUFFRixPQUFPLElBQUksQ0FBQyxjQUFjLENBQUMsWUFBWSxDQUFDLENBQUM7SUFDM0MsQ0FBQztDQUNGO0FBNVRELHNDQTRUQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBtb21lbnQgPSByZXF1aXJlKCdtb21lbnQnKTtcbmltcG9ydCB7ZXh0ZW5kTW9tZW50fSBmcm9tICdtb21lbnQtcmFuZ2UnO1xuXG5pbXBvcnQge1NUUklOR1N9IGZyb20gJy4uL2NvbmZpZyc7XG5cbmltcG9ydCB7RVJST1JTfSBmcm9tICcuLi91dGlsL2Vycm9ycyc7XG5pbXBvcnQge1VuaXRzRGVhbGVyfSBmcm9tICcuLi91dGlsL3VuaXRzLWRlYWxlcic7XG5cbmltcG9ydCB7TW9kZWxQYXJhbXMsIE1vZGVsUGx1Z2luSW50ZXJmYWNlfSBmcm9tICcuLi90eXBlcy9tb2RlbC1pbnRlcmZhY2UnO1xuaW1wb3J0IHtQYWRkaW5nUmVjZWlwdCwgVGltZU5vcm1hbGl6ZXJDb25maWd9IGZyb20gJy4uL3R5cGVzL3RpbWUtc3luYyc7XG5pbXBvcnQge1VuaXRzRGVhbGVyVXNhZ2V9IGZyb20gJy4uL3R5cGVzL3VuaXRzLWRlYWxlcic7XG5pbXBvcnQge1VuaXRLZXlOYW1lfSBmcm9tICcuLi90eXBlcy91bml0cyc7XG5cbmNvbnN0IG1vbWVudFJhbmdlID0gZXh0ZW5kTW9tZW50KG1vbWVudCk7XG5cbmNvbnN0IHtJbnB1dFZhbGlkYXRpb25FcnJvcn0gPSBFUlJPUlM7XG5cbmNvbnN0IHtcbiAgSU5WQUxJRF9USU1FX05PUk1BTElaQVRJT04sXG4gIElOVkFMSURfVElNRV9JTlRFUlZBTCxcbiAgSU5WQUxJRF9PQlNFUlZBVElPTl9PVkVSTEFQLFxufSA9IFNUUklOR1M7XG5cbmV4cG9ydCBjbGFzcyBUaW1lU3luY01vZGVsIGltcGxlbWVudHMgTW9kZWxQbHVnaW5JbnRlcmZhY2Uge1xuICBzdGFydFRpbWU6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgZW5kVGltZTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICBkZWFsZXIhOiBVbml0c0RlYWxlclVzYWdlO1xuICBpbnRlcnZhbCA9IDE7XG5cbiAgLyoqXG4gICAqIFNldHVwcyBiYXNpYyBjb25maWd1cmF0aW9uLlxuICAgKi9cbiAgYXN5bmMgY29uZmlndXJlKHBhcmFtczogVGltZU5vcm1hbGl6ZXJDb25maWcpOiBQcm9taXNlPE1vZGVsUGx1Z2luSW50ZXJmYWNlPiB7XG4gICAgdGhpcy5zdGFydFRpbWUgPSBwYXJhbXNbJ3N0YXJ0LXRpbWUnXTtcbiAgICB0aGlzLmVuZFRpbWUgPSBwYXJhbXNbJ2VuZC10aW1lJ107XG4gICAgdGhpcy5pbnRlcnZhbCA9IHBhcmFtcy5pbnRlcnZhbDtcbiAgICB0aGlzLmRlYWxlciA9IGF3YWl0IFVuaXRzRGVhbGVyKCk7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZXMgYHN0YXJ0VGltZWAsIGBlbmRUaW1lYCBhbmQgYGludGVydmFsYCBwYXJhbXMuXG4gICAqL1xuICBwcml2YXRlIHZhbGlkYXRlUGFyYW1zKCkge1xuICAgIGlmICghdGhpcy5zdGFydFRpbWUgfHwgIXRoaXMuZW5kVGltZSkge1xuICAgICAgdGhyb3cgbmV3IElucHV0VmFsaWRhdGlvbkVycm9yKElOVkFMSURfVElNRV9OT1JNQUxJWkFUSU9OKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5zdGFydFRpbWUgPiB0aGlzLmVuZFRpbWUpIHtcbiAgICAgIHRocm93IG5ldyBJbnB1dFZhbGlkYXRpb25FcnJvcihJTlZBTElEX1RJTUVfTk9STUFMSVpBVElPTik7XG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLmludGVydmFsKSB7XG4gICAgICB0aHJvdyBuZXcgSW5wdXRWYWxpZGF0aW9uRXJyb3IoSU5WQUxJRF9USU1FX0lOVEVSVkFMKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ2FsY3VsYXRlcyBtaW5pbWFsIGZhY3Rvci5cbiAgICovXG4gIHByaXZhdGUgY29udmVydFBlckludGVydmFsID0gKHZhbHVlOiBudW1iZXIsIGR1cmF0aW9uOiBudW1iZXIpID0+XG4gICAgdmFsdWUgLyBkdXJhdGlvbjtcblxuICAvKipcbiAgICogTm9ybWFsaXplIHRpbWUgcGVyIGdpdmVuIHNlY29uZC5cbiAgICovXG4gIHByaXZhdGUgbm9ybWFsaXplVGltZVBlclNlY29uZCA9IChjdXJyZW50Um91bmRNb21lbnQ6IHN0cmluZywgaTogbnVtYmVyKSA9PiB7XG4gICAgY29uc3QgdGhpc01vbWVudCA9IG1vbWVudChjdXJyZW50Um91bmRNb21lbnQpLm1pbGxpc2Vjb25kcygwKTtcblxuICAgIHJldHVybiB0aGlzTW9tZW50LmFkZChpLCAnc2Vjb25kJyk7XG4gIH07XG5cbiAgLyoqXG4gICAqIEJhcmtlcyBkb3duIGlucHV0IHBlciBtaW5pbWFsIHRpbWUgdW5pdC5cbiAgICovXG4gIHByaXZhdGUgYnJlYWtEb3duSW5wdXQoaW5wdXQ6IE1vZGVsUGFyYW1zLCBpOiBudW1iZXIpIHtcbiAgICBjb25zdCBpbnB1dEtleXMgPSBPYmplY3Qua2V5cyhpbnB1dCkgYXMgVW5pdEtleU5hbWVbXTtcblxuICAgIHJldHVybiBpbnB1dEtleXMucmVkdWNlKChhY2MsIGtleSkgPT4ge1xuICAgICAgY29uc3QgbWV0aG9kID0gdGhpcy5kZWFsZXIuYXNrVG9HaXZlTWV0aG9kRm9yKGtleSk7XG5cbiAgICAgIGlmIChrZXkgPT09ICd0aW1lc3RhbXAnKSB7XG4gICAgICAgIGNvbnN0IHBlclNlY29uZCA9IHRoaXMubm9ybWFsaXplVGltZVBlclNlY29uZChpbnB1dC50aW1lc3RhbXAsIGkpO1xuICAgICAgICBhY2Nba2V5XSA9IG1vbWVudChwZXJTZWNvbmQpLm1pbGxpc2Vjb25kcygwKS50b0lTT1N0cmluZygpO1xuXG4gICAgICAgIHJldHVybiBhY2M7XG4gICAgICB9XG5cbiAgICAgIC8qKiBAdG9kbyB1c2UgdXNlciBkZWZpbmVkIHJlc29sdXRpb24gbGF0ZXIgKi9cbiAgICAgIGlmIChrZXkgPT09ICdkdXJhdGlvbicpIHtcbiAgICAgICAgYWNjW2tleV0gPSAxO1xuXG4gICAgICAgIHJldHVybiBhY2M7XG4gICAgICB9XG5cbiAgICAgIGFjY1trZXldID1cbiAgICAgICAgbWV0aG9kID09PSAnc3VtJ1xuICAgICAgICAgID8gdGhpcy5jb252ZXJ0UGVySW50ZXJ2YWwoaW5wdXRba2V5XSwgaW5wdXRbJ2R1cmF0aW9uJ10pXG4gICAgICAgICAgOiBpbnB1dFtrZXldO1xuXG4gICAgICByZXR1cm4gYWNjO1xuICAgIH0sIHt9IGFzIE1vZGVsUGFyYW1zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQb3B1bGF0ZXMgb2JqZWN0IHRvIGZpbGwgdGhlIGdhcHMgaW4gb2JzZXJ2YXRpb25hbCB0aW1lbGluZSB1c2luZyB6ZXJvaXNoIHZhbHVlcy5cbiAgICovXG4gIHByaXZhdGUgZmlsbFdpdGhaZXJvaXNoSW5wdXQoaW5wdXQ6IE1vZGVsUGFyYW1zLCBtaXNzaW5nVGltZXN0YW1wOiBudW1iZXIpIHtcbiAgICBjb25zdCBtZXRyaWNzID0gT2JqZWN0LmtleXMoaW5wdXQpIGFzIFVuaXRLZXlOYW1lW107XG5cbiAgICByZXR1cm4gbWV0cmljcy5yZWR1Y2UoKGFjYywgbWV0cmljKSA9PiB7XG4gICAgICBpZiAobWV0cmljID09PSAndGltZXN0YW1wJykge1xuICAgICAgICBhY2NbbWV0cmljXSA9IG1vbWVudChtaXNzaW5nVGltZXN0YW1wKS5taWxsaXNlY29uZHMoMCkudG9JU09TdHJpbmcoKTtcblxuICAgICAgICByZXR1cm4gYWNjO1xuICAgICAgfVxuXG4gICAgICAvKiogQHRvZG8gbGF0ZXIgd2lsbCBiZSBjaGFuZ2VkIHRvIHVzZXIgZGVmaW5lZCBpbnRlcnZhbCAqL1xuICAgICAgaWYgKG1ldHJpYyA9PT0gJ2R1cmF0aW9uJykge1xuICAgICAgICBhY2NbbWV0cmljXSA9IDE7XG5cbiAgICAgICAgcmV0dXJuIGFjYztcbiAgICAgIH1cblxuICAgICAgaWYgKG1ldHJpYyA9PT0gJ3RpbWUtcmVzZXJ2ZWQnKSB7XG4gICAgICAgIGFjY1ttZXRyaWNdID0gYWNjWydkdXJhdGlvbiddO1xuXG4gICAgICAgIHJldHVybiBhY2M7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG1ldGhvZCA9IHRoaXMuZGVhbGVyLmFza1RvR2l2ZU1ldGhvZEZvcihtZXRyaWMpO1xuICAgICAgYWNjW21ldHJpY10gPSBtZXRob2QgPT09ICdhdmcnIHx8IG1ldGhvZCA9PT0gJ3N1bScgPyAwIDogaW5wdXRbbWV0cmljXTtcblxuICAgICAgcmV0dXJuIGFjYztcbiAgICB9LCB7fSBhcyBNb2RlbFBhcmFtcyk7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2tzIGlmIHBhZGRpbmcgaXMgbmVlZGVkIGVpdGhlciBhdCBzdGFydCBvZiB0aGUgdGltZWxpbmUgb3IgdGhlIGVuZCBhbmQgcmV0dXJucyBzdGF0dXMuXG4gICAqL1xuICBwcml2YXRlIGNoZWNrRm9yUGFkZGluZyhpbnB1dHM6IE1vZGVsUGFyYW1zW10pOiBQYWRkaW5nUmVjZWlwdCB7XG4gICAgY29uc3Qgc3RhcnREaWZmSW5TZWNvbmRzID1cbiAgICAgIG1vbWVudChpbnB1dHNbMF0udGltZXN0YW1wKS5kaWZmKG1vbWVudCh0aGlzLnN0YXJ0VGltZSkpIC8gMTAwMDtcblxuICAgIGNvbnN0IGxhc3RJbnB1dCA9IGlucHV0c1tpbnB1dHMubGVuZ3RoIC0gMV07XG4gICAgY29uc3QgZW5kRGlmZkluU2Vjb25kcyA9XG4gICAgICBtb21lbnQobGFzdElucHV0LnRpbWVzdGFtcClcbiAgICAgICAgLmFkZChsYXN0SW5wdXQuZHVyYXRpb24sICdzZWNvbmRzJylcbiAgICAgICAgLmRpZmYobW9tZW50KHRoaXMuZW5kVGltZSkpIC8gMTAwMDtcblxuICAgIHJldHVybiB7XG4gICAgICBzdGFydDogc3RhcnREaWZmSW5TZWNvbmRzID4gMCxcbiAgICAgIGVuZDogZW5kRGlmZkluU2Vjb25kcyA8IDAsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJdGVyYXRlcyBvdmVyIGdpdmVuIGlucHV0cyBmcmFtZSwgbWVhbndoaWxlIGNoZWNraW5nIGlmIGFnZ3JlZ2F0aW9uIG1ldGhvZCBpcyBgc3VtYCwgdGhlbiBjYWxjdWxhdGVzIGl0LlxuICAgKiBGb3IgbWV0aG9kcyBpcyBgYXZnYCBhbmQgYG5vbmVgIGNhbGN1bGF0aW5nIGF2ZXJhZ2Ugb2YgdGhlIGZyYW1lLlxuICAgKi9cbiAgcHJpdmF0ZSByZXNhbXBsZUlucHV0RnJhbWUgPSAoaW5wdXRzSW5UaW1lc2xvdDogTW9kZWxQYXJhbXNbXSkgPT4ge1xuICAgIHJldHVybiBpbnB1dHNJblRpbWVzbG90LnJlZHVjZSgoYWNjLCBpbnB1dCwgaW5kZXgsIGlucHV0cykgPT4ge1xuICAgICAgY29uc3QgbWV0cmljcyA9IE9iamVjdC5rZXlzKGlucHV0KSBhcyBVbml0S2V5TmFtZVtdO1xuXG4gICAgICBtZXRyaWNzLmZvckVhY2gobWV0cmljID0+IHtcbiAgICAgICAgY29uc3QgbWV0aG9kID0gdGhpcy5kZWFsZXIuYXNrVG9HaXZlTWV0aG9kRm9yKG1ldHJpYyk7XG4gICAgICAgIGFjY1ttZXRyaWNdID0gYWNjW21ldHJpY10gPz8gMDtcblxuICAgICAgICBpZiAobWV0cmljID09PSAndGltZXN0YW1wJykge1xuICAgICAgICAgIGFjY1ttZXRyaWNdID0gaW5wdXRzWzBdW21ldHJpY107XG5cbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAobWV0aG9kID09PSAnc3VtJykge1xuICAgICAgICAgIGFjY1ttZXRyaWNdICs9IGlucHV0W21ldHJpY107XG5cbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvKiogZGl2aWRlIGVhY2ggbWV0cmljIGJ5IHRoZSB0aW1lc2xvdCBsZW5ndGgsIHNvIHRoYXQgdGhlaXIgc3VtIHlpZWxkcyB0aGUgdGltZXNsb3QgYXZlcmFnZS4qL1xuICAgICAgICBpZiAoaW5kZXggPT09IGlucHV0c0luVGltZXNsb3QubGVuZ3RoIC0gMSkge1xuICAgICAgICAgIGFjY1ttZXRyaWNdIC89IGlucHV0c0luVGltZXNsb3QubGVuZ3RoO1xuXG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgYWNjW21ldHJpY10gKz0gaW5wdXRbbWV0cmljXTtcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gYWNjO1xuICAgIH0sIHt9IGFzIE1vZGVsUGFyYW1zKTtcbiAgfTtcblxuICAvKipcbiAgICogVGFrZXMgZWFjaCBhcnJheSBmcmFtZSB3aXRoIGludGVydmFsIGxlbmd0aCwgdGhlbiBhZ2dyZWdhdGluZyB0aGVtIHRvZ2V0aGVyIGFzIGZyb20gdW5pdHMueWFtbCBmaWxlLlxuICAgKi9cbiAgcHJpdmF0ZSByZXNhbXBsZUlucHV0cyhpbnB1dHM6IE1vZGVsUGFyYW1zW10pIHtcbiAgICByZXR1cm4gaW5wdXRzLnJlZHVjZSgoYWNjLCBfaW5wdXQsIGluZGV4LCBpbnB1dHMpID0+IHtcbiAgICAgIGNvbnN0IGZyYW1lU3RhcnQgPSBpbmRleCAqIHRoaXMuaW50ZXJ2YWw7XG4gICAgICBjb25zdCBmcmFtZUVuZCA9IChpbmRleCArIDEpICogdGhpcy5pbnRlcnZhbDtcbiAgICAgIGNvbnN0IGlucHV0c0ZyYW1lID0gaW5wdXRzLnNsaWNlKGZyYW1lU3RhcnQsIGZyYW1lRW5kKTtcblxuICAgICAgY29uc3QgcmVzYW1wbGVkSW5wdXQgPSB0aGlzLnJlc2FtcGxlSW5wdXRGcmFtZShpbnB1dHNGcmFtZSk7XG5cbiAgICAgIC8qKiBDaGVja3MgaWYgcmVzYW1wbGVkIGlucHV0IGlzIG5vdCBlbXB0eSwgdGhlbiBpbmNsdWRlcyBpbiByZXN1bHQuICovXG4gICAgICBpZiAoT2JqZWN0LmtleXMocmVzYW1wbGVkSW5wdXQpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgYWNjLnB1c2gocmVzYW1wbGVkSW5wdXQpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gYWNjO1xuICAgIH0sIFtdIGFzIE1vZGVsUGFyYW1zW10pO1xuICB9XG5cbiAgLyoqXG4gICAqIFBhZHMgemVyb2lzaCBpbnB1dHMgZnJvbSB0aGUgYmVnaW5uaW5nIG9yIGF0IHRoZSBlbmQgb2YgdGhlIGlucHV0cyBpZiBuZWVkZWQuXG4gICAqL1xuICBwcml2YXRlIHBhZElucHV0cyhpbnB1dHM6IE1vZGVsUGFyYW1zW10sIHBhZDogUGFkZGluZ1JlY2VpcHQpOiBNb2RlbFBhcmFtc1tdIHtcbiAgICBjb25zdCB7c3RhcnQsIGVuZH0gPSBwYWQ7XG4gICAgY29uc3QgcGFkZGVkRnJvbUJlZ2lubmluZyA9IFtdO1xuXG4gICAgaWYgKHN0YXJ0KSB7XG4gICAgICBjb25zdCBkYXRlUmFuZ2UgPSBtb21lbnRSYW5nZS5yYW5nZShcbiAgICAgICAgbW9tZW50KHRoaXMuc3RhcnRUaW1lKSxcbiAgICAgICAgbW9tZW50KGlucHV0c1swXS50aW1lc3RhbXApLnN1YnRyYWN0KDEsICdzZWNvbmQnKVxuICAgICAgKTtcblxuICAgICAgLyoqIENoZWNrcyBpZiBjb252ZXJ0aW5nIHRvIHZhbHVlIG9mIGlzIG5lZWRlZC4gKi9cbiAgICAgIGZvciAoY29uc3Qgc2Vjb25kIG9mIGRhdGVSYW5nZS5ieSgnc2Vjb25kJykpIHtcbiAgICAgICAgcGFkZGVkRnJvbUJlZ2lubmluZy5wdXNoKFxuICAgICAgICAgIHRoaXMuZmlsbFdpdGhaZXJvaXNoSW5wdXQoaW5wdXRzWzBdLCBzZWNvbmQudmFsdWVPZigpKVxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHBhZGRlZEFycmF5ID0gcGFkZGVkRnJvbUJlZ2lubmluZy5jb25jYXQoaW5wdXRzKTtcblxuICAgIGlmIChlbmQpIHtcbiAgICAgIGNvbnN0IGxhc3RJbnB1dCA9IGlucHV0c1tpbnB1dHMubGVuZ3RoIC0gMV07XG4gICAgICBjb25zdCBkYXRlUmFuZ2UgPSBtb21lbnRSYW5nZS5yYW5nZShcbiAgICAgICAgbW9tZW50KGxhc3RJbnB1dC50aW1lc3RhbXApLmFkZChsYXN0SW5wdXQuZHVyYXRpb24sICdzZWNvbmRzJyksXG4gICAgICAgIG1vbWVudCh0aGlzLmVuZFRpbWUpXG4gICAgICApO1xuXG4gICAgICBmb3IgKGNvbnN0IHNlY29uZCBvZiBkYXRlUmFuZ2UuYnkoJ3NlY29uZCcpKSB7XG4gICAgICAgIHBhZGRlZEFycmF5LnB1c2goXG4gICAgICAgICAgdGhpcy5maWxsV2l0aFplcm9pc2hJbnB1dChsYXN0SW5wdXQsIHNlY29uZC52YWx1ZU9mKCkpXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHBhZGRlZEFycmF5O1xuICB9XG5cbiAgLypcbiAgICogQ2hlY2tzIGlmIGlucHV0J3MgdGltZXN0YW1wIGlzIGluY2x1ZGVkIGluIGdsb2JhbCBzcGVjaWZpZWQgcGVyaW9kIHRoZW4gbGVhdmVzIGl0LCBvdGhlcndpc2UuXG4gICAqL1xuICBwcml2YXRlIHRyaW1JbnB1dHNCeUdsb2JhbFRpbWVsaW5lKGlucHV0czogTW9kZWxQYXJhbXNbXSk6IE1vZGVsUGFyYW1zW10ge1xuICAgIHJldHVybiBpbnB1dHMucmVkdWNlKChhY2MsIGl0ZW0pID0+IHtcbiAgICAgIGNvbnN0IHt0aW1lc3RhbXB9ID0gaXRlbTtcblxuICAgICAgaWYgKFxuICAgICAgICBtb21lbnQodGltZXN0YW1wKS5pc1NhbWVPckFmdGVyKG1vbWVudCh0aGlzLnN0YXJ0VGltZSkpICYmXG4gICAgICAgIG1vbWVudCh0aW1lc3RhbXApLmlzU2FtZU9yQmVmb3JlKG1vbWVudCh0aGlzLmVuZFRpbWUpKVxuICAgICAgKSB7XG4gICAgICAgIGFjYy5wdXNoKGl0ZW0pO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gYWNjO1xuICAgIH0sIFtdIGFzIE1vZGVsUGFyYW1zW10pO1xuICB9XG5cbiAgLyoqXG4gICAqIE5vcm1hbGl6ZXMgcHJvdmlkZWQgdGltZSB3aW5kb3cgYWNjb3JkaW5nIHRvIHRpbWUgY29uZmlndXJhdGlvbi5cbiAgICovXG4gIGFzeW5jIGV4ZWN1dGUoaW5wdXRzOiBNb2RlbFBhcmFtc1tdKTogUHJvbWlzZTxNb2RlbFBhcmFtc1tdPiB7XG4gICAgdGhpcy52YWxpZGF0ZVBhcmFtcygpO1xuXG4gICAgY29uc3QgcGFkID0gdGhpcy5jaGVja0ZvclBhZGRpbmcoaW5wdXRzKTtcbiAgICBjb25zdCBwYWRkZWRJbnB1dHMgPSB0aGlzLnBhZElucHV0cyhpbnB1dHMsIHBhZCk7XG5cbiAgICBjb25zdCBmbGF0dGVuSW5wdXRzID0gcGFkZGVkSW5wdXRzLnJlZHVjZSgoYWNjLCBpbnB1dCwgaW5kZXgpID0+IHtcbiAgICAgIGNvbnN0IGN1cnJlbnRNb21lbnQgPSBtb21lbnQoaW5wdXQudGltZXN0YW1wKTtcblxuICAgICAgLyoqIENoZWNrcyBpZiBub3QgdGhlIGZpcnN0IGlucHV0LCB0aGVuIGNoZWNrIGNvbnNpc3RlbmN5IHdpdGggcHJldmlvdXMgb25lcy4gKi9cbiAgICAgIGlmIChpbmRleCA+IDApIHtcbiAgICAgICAgY29uc3QgcHJldmlvdXNJbnB1dCA9IHBhZGRlZElucHV0c1tpbmRleCAtIDFdO1xuICAgICAgICBjb25zdCBwcmV2aW91c0lucHV0VGltZXN0YW1wID0gbW9tZW50KHByZXZpb3VzSW5wdXQudGltZXN0YW1wKTtcblxuICAgICAgICAvKiogQ2hlY2tzIGZvciB0aW1lc3RhbXBzIG92ZXJsYXAuICovXG4gICAgICAgIGlmIChcbiAgICAgICAgICBtb21lbnQocHJldmlvdXNJbnB1dC50aW1lc3RhbXApXG4gICAgICAgICAgICAuYWRkKHByZXZpb3VzSW5wdXQuZHVyYXRpb24sICdzZWNvbmRzJylcbiAgICAgICAgICAgIC5pc0FmdGVyKGN1cnJlbnRNb21lbnQpXG4gICAgICAgICkge1xuICAgICAgICAgIHRocm93IG5ldyBJbnB1dFZhbGlkYXRpb25FcnJvcihJTlZBTElEX09CU0VSVkFUSU9OX09WRVJMQVApO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgY29tcGFyZWFibGVUaW1lID0gcHJldmlvdXNJbnB1dFRpbWVzdGFtcC5hZGQoXG4gICAgICAgICAgcHJldmlvdXNJbnB1dC5kdXJhdGlvbixcbiAgICAgICAgICAnc2Vjb25kJ1xuICAgICAgICApO1xuXG4gICAgICAgIGNvbnN0IHRpbWVsaW5lR2FwU2l6ZSA9IGN1cnJlbnRNb21lbnQuZGlmZihjb21wYXJlYWJsZVRpbWUsICdzZWNvbmQnKTtcbiAgICAgICAgLy9jb25zb2xlLmxvZyhjdXJyZW50TW9tZW50LCB0aW1lbGluZUdhcFNpemUpXG4gICAgICAgIC8qKiBDaGVja3MgaWYgdGhlcmUgaXMgZ2FwIGluIHRpbWVsaW5lLiAqL1xuICAgICAgICBpZiAodGltZWxpbmVHYXBTaXplID4gMSkge1xuICAgICAgICAgIGZvciAoXG4gICAgICAgICAgICBsZXQgbWlzc2luZ1RpbWVzdGFtcCA9IGNvbXBhcmVhYmxlVGltZS52YWx1ZU9mKCk7XG4gICAgICAgICAgICBtaXNzaW5nVGltZXN0YW1wIDw9IGN1cnJlbnRNb21lbnQudmFsdWVPZigpIC0gMTAwMDtcbiAgICAgICAgICAgIG1pc3NpbmdUaW1lc3RhbXAgKz0gMTAwMFxuICAgICAgICAgICkge1xuICAgICAgICAgICAgY29uc3QgZmlsbGVkR2FwID0gdGhpcy5maWxsV2l0aFplcm9pc2hJbnB1dChcbiAgICAgICAgICAgICAgaW5wdXQsXG4gICAgICAgICAgICAgIG1pc3NpbmdUaW1lc3RhbXBcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIGFjYy5wdXNoKGZpbGxlZEdhcCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8qKiBCcmVhayBkb3duIGN1cnJlbnQgb2JzZXJ2YXRpb24uICovXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGlucHV0LmR1cmF0aW9uOyBpKyspIHtcbiAgICAgICAgY29uc3Qgbm9ybWFsaXplZElucHV0ID0gdGhpcy5icmVha0Rvd25JbnB1dChpbnB1dCwgaSk7XG5cbiAgICAgICAgYWNjLnB1c2gobm9ybWFsaXplZElucHV0KTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXMudHJpbUlucHV0c0J5R2xvYmFsVGltZWxpbmUoYWNjKTtcbiAgICB9LCBbXSBhcyBNb2RlbFBhcmFtc1tdKTtcblxuICAgIGNvbnN0IHNvcnRlZElucHV0cyA9IGZsYXR0ZW5JbnB1dHMuc29ydCgoYSwgYikgPT5cbiAgICAgIG1vbWVudChhLnRpbWVzdGFtcCkuZGlmZihtb21lbnQoYi50aW1lc3RhbXApKVxuICAgICk7XG5cbiAgICByZXR1cm4gdGhpcy5yZXNhbXBsZUlucHV0cyhzb3J0ZWRJbnB1dHMpO1xuICB9XG59XG4iXX0=
300
+ };
301
+ return { metadata, execute };
302
+ };
303
+ exports.TimeSync = TimeSync;
304
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGltZS1zeW5jLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL21vZGVscy90aW1lLXN5bmMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsMkNBQXVDO0FBQ3ZDLGlDQUE2RDtBQUM3RCw2QkFBc0I7QUFFdEIsc0RBQWlEO0FBRWpELDJDQUFzQztBQUV0QyxzQ0FBa0M7QUFTbEMscURBQTZDO0FBRTdDLE1BQU0sRUFBQyxvQkFBb0IsRUFBQyxHQUFHLGVBQU0sQ0FBQztBQUV0QyxNQUFNLEVBQ0osMEJBQTBCLEVBQzFCLDJCQUEyQixFQUMzQix5QkFBeUIsR0FDMUIsR0FBRyxnQkFBTyxDQUFDO0FBRUwsTUFBTSxRQUFRLEdBQUcsQ0FDdEIsWUFBa0MsRUFDakIsRUFBRTtJQUNuQixNQUFNLFFBQVEsR0FBRztRQUNmLElBQUksRUFBRSxTQUFTO0tBQ2hCLENBQUM7SUFFRjs7T0FFRztJQUNILE1BQU0sT0FBTyxHQUFHLENBQUMsTUFBc0IsRUFBa0IsRUFBRTtRQUN6RCxNQUFNLGVBQWUsR0FBRyxvQkFBb0IsRUFBRSxDQUFDO1FBQy9DLE1BQU0sVUFBVSxHQUFHO1lBQ2pCLFNBQVMsRUFBRSxnQkFBUSxDQUFDLE9BQU8sQ0FBQyxlQUFlLENBQUMsWUFBWSxDQUFDLENBQUM7WUFDMUQsT0FBTyxFQUFFLGdCQUFRLENBQUMsT0FBTyxDQUFDLGVBQWUsQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUN0RCxRQUFRLEVBQUUsZUFBZSxDQUFDLFFBQVE7WUFDbEMsWUFBWSxFQUFFLGVBQWUsQ0FBQyxlQUFlLENBQUM7U0FDL0MsQ0FBQztRQUVGLE1BQU0sR0FBRyxHQUFHLGVBQWUsQ0FBQyxNQUFNLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFDaEQsZUFBZSxDQUFDLEdBQUcsRUFBRSxVQUFVLENBQUMsQ0FBQztRQUVqQyxNQUFNLFlBQVksR0FBRyxTQUFTLENBQUMsTUFBTSxFQUFFLEdBQUcsRUFBRSxVQUFVLENBQUMsQ0FBQztRQUV4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LENBQUMsYUFBYSxDQUFDLFNBQVMsRUFBRSxPQUFPLENBQUMsQ0FBQztRQUM3RCxLQUFLLE1BQU0sUUFBUSxJQUFJLFNBQVMsQ0FBQyxPQUFPLENBQUMsRUFBQyxNQUFNLEVBQUUsQ0FBQyxFQUFDLENBQUMsRUFBRTtZQUNyRCxLQUFLLENBQUMsSUFBSSxDQUNSLG9CQUFvQixDQUNsQixhQUFhO1lBQ2IsaURBQWlEO1lBQ2pELGlEQUFpRDtZQUNqRCxvREFBb0Q7WUFDcEQsUUFBUSxDQUFDLEtBQUssSUFBSSxnQkFBUSxDQUFDLE9BQU8sQ0FBQyw4QkFBOEIsQ0FBQyxDQUNuRSxDQUNGLENBQUM7U0FDSDtRQUNELE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQyxDQUFDO0lBRUY7O09BRUc7SUFDSCxNQUFNLDBCQUEwQixHQUFHLENBQ2pDLE1BQXNCLEVBQ3RCLE1BQWtCLEVBQ0YsRUFBRTtRQUNsQixPQUFPLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFtQixFQUFFLElBQUksRUFBRSxFQUFFO1lBQ2pELE1BQU0sRUFBQyxTQUFTLEVBQUMsR0FBRyxJQUFJLENBQUM7WUFFekIsSUFDRSxTQUFTLENBQUMsU0FBUyxDQUFDLElBQUksTUFBTSxDQUFDLFNBQVM7Z0JBQ3hDLFNBQVMsQ0FBQyxTQUFTLENBQUMsSUFBSSxNQUFNLENBQUMsT0FBTyxFQUN0QztnQkFDQSxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO2FBQ2hCO1lBRUQsT0FBTyxHQUFHLENBQUM7UUFDYixDQUFDLEVBQUUsRUFBb0IsQ0FBQyxDQUFDO0lBQzNCLENBQUMsQ0FBQztJQUVGLE9BQU8sRUFBQyxRQUFRLEVBQUUsT0FBTyxFQUFDLENBQUM7QUFDN0IsQ0FBQyxDQUFDO0FBaGFXLFFBQUEsUUFBUSxZQWdhbkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge2lzRGF0ZX0gZnJvbSAnbm9kZTp1dGlsL3R5cGVzJztcbmltcG9ydCB7RGF0ZVRpbWUsIERhdGVUaW1lTWF5YmVWYWxpZCwgSW50ZXJ2YWx9IGZyb20gJ2x1eG9uJztcbmltcG9ydCB7en0gZnJvbSAnem9kJztcblxuaW1wb3J0IHtwYXJhbWV0ZXJpemV9IGZyb20gJy4uL2xpYi9wYXJhbWV0ZXJpemUnO1xuXG5pbXBvcnQge0VSUk9SU30gZnJvbSAnLi4vdXRpbC9lcnJvcnMnO1xuXG5pbXBvcnQge1NUUklOR1N9IGZyb20gJy4uL2NvbmZpZyc7XG5cbmltcG9ydCB7UGx1Z2luUGFyYW1zfSBmcm9tICcuLi90eXBlcy9pbnRlcmZhY2UnO1xuaW1wb3J0IHtcbiAgUGFkZGluZ1JlY2VpcHQsXG4gIFRpbWVOb3JtYWxpemVyQ29uZmlnLFxuICBUaW1lUGFyYW1zLFxufSBmcm9tICcuLi90eXBlcy90aW1lLXN5bmMnO1xuaW1wb3J0IHtQbHVnaW5JbnRlcmZhY2V9IGZyb20gJy4uL3R5cGVzL2ludGVyZmFjZSc7XG5pbXBvcnQge3ZhbGlkYXRlfSBmcm9tICcuLi91dGlsL3ZhbGlkYXRpb25zJztcblxuY29uc3Qge0lucHV0VmFsaWRhdGlvbkVycm9yfSA9IEVSUk9SUztcblxuY29uc3Qge1xuICBJTlZBTElEX1RJTUVfTk9STUFMSVpBVElPTixcbiAgSU5WQUxJRF9PQlNFUlZBVElPTl9PVkVSTEFQLFxuICBBVk9JRElOR19QQURESU5HX0JZX0VER0VTLFxufSA9IFNUUklOR1M7XG5cbmV4cG9ydCBjb25zdCBUaW1lU3luYyA9IChcbiAgZ2xvYmFsQ29uZmlnOiBUaW1lTm9ybWFsaXplckNvbmZpZ1xuKTogUGx1Z2luSW50ZXJmYWNlID0+IHtcbiAgY29uc3QgbWV0YWRhdGEgPSB7XG4gICAga2luZDogJ2V4ZWN1dGUnLFxuICB9O1xuXG4gIC8qKlxuICAgKiBUYWtlIGlucHV0IGFycmF5IGFuZCByZXR1cm4gdGltZS1zeW5jaHJvbml6ZWQgaW5wdXQgYXJyYXkuXG4gICAqL1xuICBjb25zdCBleGVjdXRlID0gKGlucHV0czogUGx1Z2luUGFyYW1zW10pOiBQbHVnaW5QYXJhbXNbXSA9PiB7XG4gICAgY29uc3QgdmFsaWRhdGVkQ29uZmlnID0gdmFsaWRhdGVHbG9iYWxDb25maWcoKTtcbiAgICBjb25zdCB0aW1lUGFyYW1zID0ge1xuICAgICAgc3RhcnRUaW1lOiBEYXRlVGltZS5mcm9tSVNPKHZhbGlkYXRlZENvbmZpZ1snc3RhcnQtdGltZSddKSxcbiAgICAgIGVuZFRpbWU6IERhdGVUaW1lLmZyb21JU08odmFsaWRhdGVkQ29uZmlnWydlbmQtdGltZSddKSxcbiAgICAgIGludGVydmFsOiB2YWxpZGF0ZWRDb25maWcuaW50ZXJ2YWwsXG4gICAgICBhbGxvd1BhZGRpbmc6IHZhbGlkYXRlZENvbmZpZ1snYWxsb3ctcGFkZGluZyddLFxuICAgIH07XG5cbiAgICBjb25zdCBwYWQgPSBjaGVja0ZvclBhZGRpbmcoaW5wdXRzLCB0aW1lUGFyYW1zKTtcbiAgICB2YWxpZGF0ZVBhZGRpbmcocGFkLCB0aW1lUGFyYW1zKTtcblxuICAgIGNvbnN0IHBhZGRlZElucHV0cyA9IHBhZElucHV0cyhpbnB1dHMsIHBhZCwgdGltZVBhcmFtcyk7XG5cbiAgICBjb25zdCBmbGF0dGVuSW5wdXRzID0gcGFkZGVkSW5wdXRzLnJlZHVjZShcbiAgICAgIChhY2M6IFBsdWdpblBhcmFtc1tdLCBpbnB1dCwgaW5kZXgpID0+IHtcbiAgICAgICAgY29uc3Qgc2FmZUlucHV0ID0gT2JqZWN0LmFzc2lnbih7fSwgaW5wdXQsIHZhbGlkYXRlSW5wdXQoaW5wdXQsIGluZGV4KSk7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRNb21lbnQgPSBwYXJzZURhdGUoc2FmZUlucHV0LnRpbWVzdGFtcCk7XG5cbiAgICAgICAgLyoqIENoZWNrcyBpZiBub3QgdGhlIGZpcnN0IGlucHV0LCB0aGVuIGNoZWNrIGNvbnNpc3RlbmN5IHdpdGggcHJldmlvdXMgb25lcy4gKi9cbiAgICAgICAgaWYgKGluZGV4ID4gMCkge1xuICAgICAgICAgIGNvbnN0IHByZXZpb3VzSW5wdXQgPSBwYWRkZWRJbnB1dHNbaW5kZXggLSAxXTtcbiAgICAgICAgICBjb25zdCBwcmV2aW91c0lucHV0VGltZXN0YW1wID0gcGFyc2VEYXRlKHByZXZpb3VzSW5wdXQudGltZXN0YW1wKTtcblxuICAgICAgICAgIC8qKiBDaGVja3MgZm9yIHRpbWVzdGFtcHMgb3ZlcmxhcC4gKi9cbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICBwYXJzZURhdGUocHJldmlvdXNJbnB1dC50aW1lc3RhbXApLnBsdXMoe1xuICAgICAgICAgICAgICBzZWNvbmRzOiBwcmV2aW91c0lucHV0LmR1cmF0aW9uLFxuICAgICAgICAgICAgfSkgPiBjdXJyZW50TW9tZW50XG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgSW5wdXRWYWxpZGF0aW9uRXJyb3IoSU5WQUxJRF9PQlNFUlZBVElPTl9PVkVSTEFQKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBjb21wYXJlYWJsZVRpbWUgPSBwcmV2aW91c0lucHV0VGltZXN0YW1wLnBsdXMoe1xuICAgICAgICAgICAgc2Vjb25kczogcHJldmlvdXNJbnB1dC5kdXJhdGlvbixcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGNvbnN0IHRpbWVsaW5lR2FwU2l6ZSA9IGN1cnJlbnRNb21lbnRcbiAgICAgICAgICAgIC5kaWZmKGNvbXBhcmVhYmxlVGltZSlcbiAgICAgICAgICAgIC5hcygnc2Vjb25kcycpO1xuXG4gICAgICAgICAgLyoqIENoZWNrcyBpZiB0aGVyZSBpcyBnYXAgaW4gdGltZWxpbmUuICovXG4gICAgICAgICAgaWYgKHRpbWVsaW5lR2FwU2l6ZSA+IDEpIHtcbiAgICAgICAgICAgIGFjYy5wdXNoKFxuICAgICAgICAgICAgICAuLi5nZXRaZXJvaXNoSW5wdXRQZXJTZWNvbmRCZXR3ZWVuUmFuZ2UoXG4gICAgICAgICAgICAgICAgY29tcGFyZWFibGVUaW1lLFxuICAgICAgICAgICAgICAgIGN1cnJlbnRNb21lbnQsXG4gICAgICAgICAgICAgICAgc2FmZUlucHV0XG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8qKiBCcmVhayBkb3duIGN1cnJlbnQgb2JzZXJ2YXRpb24uICovXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2FmZUlucHV0LmR1cmF0aW9uOyBpKyspIHtcbiAgICAgICAgICBjb25zdCBub3JtYWxpemVkSW5wdXQgPSBicmVha0Rvd25JbnB1dChzYWZlSW5wdXQsIGkpO1xuXG4gICAgICAgICAgYWNjLnB1c2gobm9ybWFsaXplZElucHV0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0cmltSW5wdXRzQnlHbG9iYWxUaW1lbGluZShhY2MsIHRpbWVQYXJhbXMpO1xuICAgICAgfSxcbiAgICAgIFtdIGFzIFBsdWdpblBhcmFtc1tdXG4gICAgKTtcblxuICAgIGNvbnN0IHNvcnRlZElucHV0cyA9IGZsYXR0ZW5JbnB1dHMuc29ydCgoYSwgYikgPT5cbiAgICAgIHBhcnNlRGF0ZShhLnRpbWVzdGFtcCkuZGlmZihwYXJzZURhdGUoYi50aW1lc3RhbXApKS5hcygnc2Vjb25kcycpXG4gICAgKTtcblxuICAgIHJldHVybiByZXNhbXBsZUlucHV0cyhzb3J0ZWRJbnB1dHMsIHRpbWVQYXJhbXMpIGFzIFBsdWdpblBhcmFtc1tdO1xuICB9O1xuXG4gIGNvbnN0IHBhcnNlRGF0ZSA9IChkYXRlOiBEYXRlIHwgc3RyaW5nKSA9PiB7XG4gICAgaWYgKCFkYXRlKSByZXR1cm4gRGF0ZVRpbWUuaW52YWxpZCgnSW52YWxpZCBkYXRlJyk7XG4gICAgLy8gZGF0ZXMgYXJlIHBhc3NlZCB0byB0aW1lLXN5bmMudHMgYm90aCBpbiBJU08gODYwMSBmb3JtYXRcbiAgICAvLyBhbmQgYXMgYSBEYXRlIG9iamVjdCAoZnJvbSB0aGUgZGVzZXJpYWxpemF0aW9uIG9mIGEgWUFNTCBmaWxlKVxuICAgIC8vIGlmIHRoZSBZQU1MIHBhcnNlciBmYWlscyB0byBpZGVudGlmeSBhcyBhIGRhdGUsIGl0IHBhc3NlcyBhcyBhIHN0cmluZ1xuICAgIGlmIChpc0RhdGUoZGF0ZSkpIHtcbiAgICAgIHJldHVybiBEYXRlVGltZS5mcm9tSlNEYXRlKGRhdGUpO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIGRhdGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm4gRGF0ZVRpbWUuZnJvbUlTTyhkYXRlKTtcbiAgICB9XG4gICAgdGhyb3cgbmV3IElucHV0VmFsaWRhdGlvbkVycm9yKFxuICAgICAgYFVuZXhwZWN0ZWQgZGF0ZSBkYXRhdHlwZTogJHt0eXBlb2YgZGF0ZX06ICR7ZGF0ZX1gXG4gICAgKTtcbiAgfTtcblxuICAvKipcbiAgICogVmFsaWRhdGVzIGlucHV0IHBhcmFtZXRlcnMuXG4gICAqL1xuICBjb25zdCB2YWxpZGF0ZUlucHV0ID0gKGlucHV0OiBQbHVnaW5QYXJhbXMsIGluZGV4OiBudW1iZXIpID0+IHtcbiAgICBjb25zdCBzY2hlbWEgPSB6Lm9iamVjdCh7XG4gICAgICB0aW1lc3RhbXA6IHpcbiAgICAgICAgLnN0cmluZyh7XG4gICAgICAgICAgcmVxdWlyZWRfZXJyb3I6IGByZXF1aXJlZCBpbiBpbnB1dFske2luZGV4fV1gLFxuICAgICAgICB9KVxuICAgICAgICAuZGF0ZXRpbWUoe1xuICAgICAgICAgIG1lc3NhZ2U6IGBpbnZhbGlkIGRhdGV0aW1lIGluIGlucHV0WyR7aW5kZXh9XWAsXG4gICAgICAgIH0pXG4gICAgICAgIC5vcih6LmRhdGUoKSksXG4gICAgICBkdXJhdGlvbjogei5udW1iZXIoKSxcbiAgICB9KTtcblxuICAgIHJldHVybiB2YWxpZGF0ZTx6LmluZmVyPHR5cGVvZiBzY2hlbWE+PihzY2hlbWEsIGlucHV0KTtcbiAgfTtcblxuICAvKipcbiAgICogVmFsaWRhdGVzIGdsb2JhbCBjb25maWcgcGFyYW1ldGVycy5cbiAgICovXG4gIGNvbnN0IHZhbGlkYXRlR2xvYmFsQ29uZmlnID0gKCkgPT4ge1xuICAgIGlmIChnbG9iYWxDb25maWcgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhyb3cgbmV3IElucHV0VmFsaWRhdGlvbkVycm9yKElOVkFMSURfVElNRV9OT1JNQUxJWkFUSU9OKTtcbiAgICB9XG5cbiAgICBjb25zdCBzY2hlbWEgPSB6XG4gICAgICAub2JqZWN0KHtcbiAgICAgICAgJ3N0YXJ0LXRpbWUnOiB6LnN0cmluZygpLmRhdGV0aW1lKCksXG4gICAgICAgICdlbmQtdGltZSc6IHouc3RyaW5nKCkuZGF0ZXRpbWUoKSxcbiAgICAgICAgaW50ZXJ2YWw6IHoubnVtYmVyKCksXG4gICAgICAgICdhbGxvdy1wYWRkaW5nJzogei5ib29sZWFuKCksXG4gICAgICB9KVxuICAgICAgLnJlZmluZShkYXRhID0+IGRhdGFbJ3N0YXJ0LXRpbWUnXSA8IGRhdGFbJ2VuZC10aW1lJ10sIHtcbiAgICAgICAgbWVzc2FnZTogJ2BzdGFydC10aW1lYCBzaG91bGQgYmUgbG93ZXIgdGhhbiBgZW5kLXRpbWVgJyxcbiAgICAgIH0pO1xuXG4gICAgcmV0dXJuIHZhbGlkYXRlPHouaW5mZXI8dHlwZW9mIHNjaGVtYT4+KHNjaGVtYSwgZ2xvYmFsQ29uZmlnKTtcbiAgfTtcblxuICAvKipcbiAgICogQ2FsY3VsYXRlcyBtaW5pbWFsIGZhY3Rvci5cbiAgICovXG4gIGNvbnN0IGNvbnZlcnRQZXJJbnRlcnZhbCA9ICh2YWx1ZTogbnVtYmVyLCBkdXJhdGlvbjogbnVtYmVyKSA9PlxuICAgIHZhbHVlIC8gZHVyYXRpb247XG5cbiAgLyoqXG4gICAqIE5vcm1hbGl6ZSB0aW1lIHBlciBnaXZlbiBzZWNvbmQuXG4gICAqL1xuICBjb25zdCBub3JtYWxpemVUaW1lUGVyU2Vjb25kID0gKFxuICAgIGN1cnJlbnRSb3VuZE1vbWVudDogRGF0ZSB8IHN0cmluZyxcbiAgICBpOiBudW1iZXJcbiAgKSA9PiB7XG4gICAgY29uc3QgdGhpc01vbWVudCA9IHBhcnNlRGF0ZShjdXJyZW50Um91bmRNb21lbnQpLnN0YXJ0T2YoJ3NlY29uZCcpO1xuICAgIHJldHVybiB0aGlzTW9tZW50LnBsdXMoe3NlY29uZHM6IGl9KTtcbiAgfTtcbiAgLyoqXG4gICAqIEJyZWFrcyBkb3duIGlucHV0IHBlciBtaW5pbWFsIHRpbWUgdW5pdC5cbiAgICovXG4gIGNvbnN0IGJyZWFrRG93bklucHV0ID0gKGlucHV0OiBQbHVnaW5QYXJhbXMsIGk6IG51bWJlcikgPT4ge1xuICAgIGNvbnN0IGlucHV0S2V5cyA9IE9iamVjdC5rZXlzKGlucHV0KTtcblxuICAgIHJldHVybiBpbnB1dEtleXMucmVkdWNlKChhY2MsIGtleSkgPT4ge1xuICAgICAgY29uc3QgbWV0aG9kID0gcGFyYW1ldGVyaXplLmdldEFnZ3JlZ2F0aW9uTWV0aG9kKGtleSk7XG5cbiAgICAgIGlmIChrZXkgPT09ICd0aW1lc3RhbXAnKSB7XG4gICAgICAgIGNvbnN0IHBlclNlY29uZCA9IG5vcm1hbGl6ZVRpbWVQZXJTZWNvbmQoaW5wdXQudGltZXN0YW1wLCBpKTtcbiAgICAgICAgYWNjW2tleV0gPSBwZXJTZWNvbmQudG9VVEMoKS50b0lTTygpID8/ICcnO1xuXG4gICAgICAgIHJldHVybiBhY2M7XG4gICAgICB9XG5cbiAgICAgIC8qKiBAdG9kbyB1c2UgdXNlciBkZWZpbmVkIHJlc29sdXRpb24gbGF0ZXIgKi9cbiAgICAgIGlmIChrZXkgPT09ICdkdXJhdGlvbicpIHtcbiAgICAgICAgYWNjW2tleV0gPSAxO1xuXG4gICAgICAgIHJldHVybiBhY2M7XG4gICAgICB9XG5cbiAgICAgIGFjY1trZXldID1cbiAgICAgICAgbWV0aG9kID09PSAnc3VtJ1xuICAgICAgICAgID8gY29udmVydFBlckludGVydmFsKGlucHV0W2tleV0sIGlucHV0WydkdXJhdGlvbiddKVxuICAgICAgICAgIDogaW5wdXRba2V5XTtcblxuICAgICAgcmV0dXJuIGFjYztcbiAgICB9LCB7fSBhcyBQbHVnaW5QYXJhbXMpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBQb3B1bGF0ZXMgb2JqZWN0IHRvIGZpbGwgdGhlIGdhcHMgaW4gb2JzZXJ2YXRpb25hbCB0aW1lbGluZSB1c2luZyB6ZXJvaXNoIHZhbHVlcy5cbiAgICovXG4gIGNvbnN0IGZpbGxXaXRoWmVyb2lzaElucHV0ID0gKFxuICAgIGlucHV0OiBQbHVnaW5QYXJhbXMsXG4gICAgbWlzc2luZ1RpbWVzdGFtcDogRGF0ZVRpbWVNYXliZVZhbGlkXG4gICkgPT4ge1xuICAgIGNvbnN0IG1ldHJpY3MgPSBPYmplY3Qua2V5cyhpbnB1dCk7XG5cbiAgICByZXR1cm4gbWV0cmljcy5yZWR1Y2UoKGFjYywgbWV0cmljKSA9PiB7XG4gICAgICBpZiAobWV0cmljID09PSAndGltZXN0YW1wJykge1xuICAgICAgICBhY2NbbWV0cmljXSA9IG1pc3NpbmdUaW1lc3RhbXAuc3RhcnRPZignc2Vjb25kJykudG9VVEMoKS50b0lTTygpID8/ICcnO1xuXG4gICAgICAgIHJldHVybiBhY2M7XG4gICAgICB9XG5cbiAgICAgIC8qKiBAdG9kbyBsYXRlciB3aWxsIGJlIGNoYW5nZWQgdG8gdXNlciBkZWZpbmVkIGludGVydmFsICovXG4gICAgICBpZiAobWV0cmljID09PSAnZHVyYXRpb24nKSB7XG4gICAgICAgIGFjY1ttZXRyaWNdID0gMTtcblxuICAgICAgICByZXR1cm4gYWNjO1xuICAgICAgfVxuXG4gICAgICBpZiAobWV0cmljID09PSAndGltZS1yZXNlcnZlZCcpIHtcbiAgICAgICAgYWNjW21ldHJpY10gPSBhY2NbJ2R1cmF0aW9uJ107XG5cbiAgICAgICAgcmV0dXJuIGFjYztcbiAgICAgIH1cblxuICAgICAgY29uc3QgbWV0aG9kID0gcGFyYW1ldGVyaXplLmdldEFnZ3JlZ2F0aW9uTWV0aG9kKG1ldHJpYyk7XG5cbiAgICAgIGlmIChtZXRob2QgPT09ICdhdmcnIHx8IG1ldGhvZCA9PT0gJ3N1bScpIHtcbiAgICAgICAgYWNjW21ldHJpY10gPSAwO1xuXG4gICAgICAgIHJldHVybiBhY2M7XG4gICAgICB9XG5cbiAgICAgIGFjY1ttZXRyaWNdID0gaW5wdXRbbWV0cmljXTtcblxuICAgICAgcmV0dXJuIGFjYztcbiAgICB9LCB7fSBhcyBQbHVnaW5QYXJhbXMpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgYGVycm9yIG9uIHBhZGRpbmdgIGlzIGVuYWJsZWQgYW5kIHBhZGRpbmcgaXMgbmVlZGVkLiBJZiBzbywgdGhlbiB0aHJvd3MgZXJyb3IuXG4gICAqL1xuICBjb25zdCB2YWxpZGF0ZVBhZGRpbmcgPSAocGFkOiBQYWRkaW5nUmVjZWlwdCwgcGFyYW1zOiBUaW1lUGFyYW1zKTogdm9pZCA9PiB7XG4gICAgY29uc3Qge3N0YXJ0LCBlbmR9ID0gcGFkO1xuICAgIGNvbnN0IGlzUGFkZGluZ05lZWRlZCA9IHN0YXJ0IHx8IGVuZDtcbiAgICBpZiAoIXBhcmFtcy5hbGxvd1BhZGRpbmcgJiYgaXNQYWRkaW5nTmVlZGVkKSB7XG4gICAgICB0aHJvdyBuZXcgSW5wdXRWYWxpZGF0aW9uRXJyb3IoQVZPSURJTkdfUEFERElOR19CWV9FREdFUyhzdGFydCwgZW5kKSk7XG4gICAgfVxuICB9O1xuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgcGFkZGluZyBpcyBuZWVkZWQgZWl0aGVyIGF0IHN0YXJ0IG9mIHRoZSB0aW1lbGluZSBvciB0aGUgZW5kIGFuZCByZXR1cm5zIHN0YXR1cy5cbiAgICovXG4gIGNvbnN0IGNoZWNrRm9yUGFkZGluZyA9IChcbiAgICBpbnB1dHM6IFBsdWdpblBhcmFtc1tdLFxuICAgIHBhcmFtczogVGltZVBhcmFtc1xuICApOiBQYWRkaW5nUmVjZWlwdCA9PiB7XG4gICAgY29uc3Qgc3RhcnREaWZmSW5TZWNvbmRzID0gcGFyc2VEYXRlKGlucHV0c1swXS50aW1lc3RhbXApXG4gICAgICAuZGlmZihwYXJhbXMuc3RhcnRUaW1lKVxuICAgICAgLmFzKCdzZWNvbmRzJyk7XG5cbiAgICBjb25zdCBsYXN0SW5wdXQgPSBpbnB1dHNbaW5wdXRzLmxlbmd0aCAtIDFdO1xuXG4gICAgY29uc3QgZW5kRGlmZkluU2Vjb25kcyA9IHBhcnNlRGF0ZShsYXN0SW5wdXQudGltZXN0YW1wKVxuICAgICAgLnBsdXMoe3NlY29uZDogbGFzdElucHV0LmR1cmF0aW9ufSlcbiAgICAgIC5kaWZmKHBhcmFtcy5lbmRUaW1lKVxuICAgICAgLmFzKCdzZWNvbmRzJyk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgc3RhcnQ6IHN0YXJ0RGlmZkluU2Vjb25kcyA+IDAsXG4gICAgICBlbmQ6IGVuZERpZmZJblNlY29uZHMgPCAwLFxuICAgIH07XG4gIH07XG5cbiAgLyoqXG4gICAqIEl0ZXJhdGVzIG92ZXIgZ2l2ZW4gaW5wdXRzIGZyYW1lLCBtZWFud2hpbGUgY2hlY2tpbmcgaWYgYWdncmVnYXRpb24gbWV0aG9kIGlzIGBzdW1gLCB0aGVuIGNhbGN1bGF0ZXMgaXQuXG4gICAqIEZvciBtZXRob2RzIGlzIGBhdmdgIGFuZCBgbm9uZWAgY2FsY3VsYXRpbmcgYXZlcmFnZSBvZiB0aGUgZnJhbWUuXG4gICAqL1xuICBjb25zdCByZXNhbXBsZUlucHV0RnJhbWUgPSAoaW5wdXRzSW5UaW1lc2xvdDogUGx1Z2luUGFyYW1zW10pID0+IHtcbiAgICByZXR1cm4gaW5wdXRzSW5UaW1lc2xvdC5yZWR1Y2UoKGFjYywgaW5wdXQsIGluZGV4LCBpbnB1dHMpID0+IHtcbiAgICAgIGNvbnN0IG1ldHJpY3MgPSBPYmplY3Qua2V5cyhpbnB1dCk7XG5cbiAgICAgIG1ldHJpY3MuZm9yRWFjaChtZXRyaWMgPT4ge1xuICAgICAgICBjb25zdCBtZXRob2QgPSBwYXJhbWV0ZXJpemUuZ2V0QWdncmVnYXRpb25NZXRob2QobWV0cmljKTtcbiAgICAgICAgYWNjW21ldHJpY10gPSBhY2NbbWV0cmljXSA/PyAwO1xuXG4gICAgICAgIGlmIChtZXRyaWMgPT09ICd0aW1lc3RhbXAnKSB7XG4gICAgICAgICAgYWNjW21ldHJpY10gPSBpbnB1dHNbMF1bbWV0cmljXTtcblxuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChtZXRob2QgPT09ICdzdW0nKSB7XG4gICAgICAgICAgYWNjW21ldHJpY10gKz0gaW5wdXRbbWV0cmljXTtcblxuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChtZXRob2QgPT09ICdub25lJykge1xuICAgICAgICAgIGFjY1ttZXRyaWNdID0gaW5wdXRbbWV0cmljXTtcblxuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBJZiB0aW1lc2xvdCBjb250YWlucyByZWNvcmRzIG1vcmUgdGhhbiBvbmUsIHRoZW4gZGl2aWRlIGVhY2ggbWV0cmljIGJ5IHRoZSB0aW1lc2xvdCBsZW5ndGgsXG4gICAgICAgICAqICBzbyB0aGF0IHRoZWlyIHN1bSB5aWVsZHMgdGhlIHRpbWVzbG90IGF2ZXJhZ2UuXG4gICAgICAgICAqL1xuICAgICAgICBpZiAoXG4gICAgICAgICAgaW5wdXRzSW5UaW1lc2xvdC5sZW5ndGggPiAxICYmXG4gICAgICAgICAgaW5kZXggPT09IGlucHV0c0luVGltZXNsb3QubGVuZ3RoIC0gMVxuICAgICAgICApIHtcbiAgICAgICAgICBhY2NbbWV0cmljXSAvPSBpbnB1dHNJblRpbWVzbG90Lmxlbmd0aDtcblxuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGFjY1ttZXRyaWNdICs9IGlucHV0W21ldHJpY107XG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIGFjYztcbiAgICB9LCB7fSBhcyBQbHVnaW5QYXJhbXMpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBUYWtlcyBlYWNoIGFycmF5IGZyYW1lIHdpdGggaW50ZXJ2YWwgbGVuZ3RoLCB0aGVuIGFnZ3JlZ2F0aW5nIHRoZW0gdG9nZXRoZXIgYXMgZnJvbSB1bml0cy55YW1sIGZpbGUuXG4gICAqL1xuICBjb25zdCByZXNhbXBsZUlucHV0cyA9IChpbnB1dHM6IFBsdWdpblBhcmFtc1tdLCBwYXJhbXM6IFRpbWVQYXJhbXMpID0+IHtcbiAgICByZXR1cm4gaW5wdXRzLnJlZHVjZSgoYWNjOiBQbHVnaW5QYXJhbXNbXSwgX2lucHV0LCBpbmRleCwgaW5wdXRzKSA9PiB7XG4gICAgICBjb25zdCBmcmFtZVN0YXJ0ID0gaW5kZXggKiBwYXJhbXMuaW50ZXJ2YWw7XG4gICAgICBjb25zdCBmcmFtZUVuZCA9IChpbmRleCArIDEpICogcGFyYW1zLmludGVydmFsO1xuICAgICAgY29uc3QgaW5wdXRzRnJhbWUgPSBpbnB1dHMuc2xpY2UoZnJhbWVTdGFydCwgZnJhbWVFbmQpO1xuXG4gICAgICBjb25zdCByZXNhbXBsZWRJbnB1dCA9IHJlc2FtcGxlSW5wdXRGcmFtZShpbnB1dHNGcmFtZSk7XG5cbiAgICAgIC8qKiBDaGVja3MgaWYgcmVzYW1wbGVkIGlucHV0IGlzIG5vdCBlbXB0eSwgdGhlbiBpbmNsdWRlcyBpbiByZXN1bHQuICovXG4gICAgICBpZiAoT2JqZWN0LmtleXMocmVzYW1wbGVkSW5wdXQpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgYWNjLnB1c2gocmVzYW1wbGVkSW5wdXQpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gYWNjO1xuICAgIH0sIFtdIGFzIFBsdWdpblBhcmFtc1tdKTtcbiAgfTtcblxuICAvKipcbiAgICogUGFkcyB6ZXJvaXNoIGlucHV0cyBmcm9tIHRoZSBiZWdpbm5pbmcgb3IgYXQgdGhlIGVuZCBvZiB0aGUgaW5wdXRzIGlmIG5lZWRlZC5cbiAgICovXG4gIGNvbnN0IHBhZElucHV0cyA9IChcbiAgICBpbnB1dHM6IFBsdWdpblBhcmFtc1tdLFxuICAgIHBhZDogUGFkZGluZ1JlY2VpcHQsXG4gICAgcGFyYW1zOiBUaW1lUGFyYW1zXG4gICk6IFBsdWdpblBhcmFtc1tdID0+IHtcbiAgICBjb25zdCB7c3RhcnQsIGVuZH0gPSBwYWQ7XG4gICAgY29uc3QgcGFkZGVkRnJvbUJlZ2lubmluZyA9IFtdO1xuXG4gICAgaWYgKHN0YXJ0KSB7XG4gICAgICBwYWRkZWRGcm9tQmVnaW5uaW5nLnB1c2goXG4gICAgICAgIC4uLmdldFplcm9pc2hJbnB1dFBlclNlY29uZEJldHdlZW5SYW5nZShcbiAgICAgICAgICBwYXJhbXMuc3RhcnRUaW1lLFxuICAgICAgICAgIHBhcnNlRGF0ZShpbnB1dHNbMF0udGltZXN0YW1wKSxcbiAgICAgICAgICBpbnB1dHNbMF1cbiAgICAgICAgKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICBjb25zdCBwYWRkZWRBcnJheSA9IHBhZGRlZEZyb21CZWdpbm5pbmcuY29uY2F0KGlucHV0cyk7XG5cbiAgICBpZiAoZW5kKSB7XG4gICAgICBjb25zdCBsYXN0SW5wdXQgPSBpbnB1dHNbaW5wdXRzLmxlbmd0aCAtIDFdO1xuICAgICAgY29uc3QgbGFzdElucHV0RW5kID0gcGFyc2VEYXRlKGxhc3RJbnB1dC50aW1lc3RhbXApLnBsdXMoe1xuICAgICAgICBzZWNvbmRzOiBsYXN0SW5wdXQuZHVyYXRpb24sXG4gICAgICB9KTtcbiAgICAgIHBhZGRlZEFycmF5LnB1c2goXG4gICAgICAgIC4uLmdldFplcm9pc2hJbnB1dFBlclNlY29uZEJldHdlZW5SYW5nZShcbiAgICAgICAgICBsYXN0SW5wdXRFbmQsXG4gICAgICAgICAgcGFyYW1zLmVuZFRpbWUucGx1cyh7c2Vjb25kczogMX0pLFxuICAgICAgICAgIGxhc3RJbnB1dFxuICAgICAgICApXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gcGFkZGVkQXJyYXk7XG4gIH07XG5cbiAgY29uc3QgZ2V0WmVyb2lzaElucHV0UGVyU2Vjb25kQmV0d2VlblJhbmdlID0gKFxuICAgIHN0YXJ0RGF0ZTogRGF0ZVRpbWVNYXliZVZhbGlkLFxuICAgIGVuZERhdGU6IERhdGVUaW1lTWF5YmVWYWxpZCxcbiAgICB0ZW1wbGF0ZUlucHV0OiBQbHVnaW5QYXJhbXNcbiAgKSA9PiB7XG4gICAgY29uc3QgYXJyYXk6IFBsdWdpblBhcmFtc1tdID0gW107XG4gICAgY29uc3QgZGF0ZVJhbmdlID0gSW50ZXJ2YWwuZnJvbURhdGVUaW1lcyhzdGFydERhdGUsIGVuZERhdGUpO1xuICAgIGZvciAoY29uc3QgaW50ZXJ2YWwgb2YgZGF0ZVJhbmdlLnNwbGl0Qnkoe3NlY29uZDogMX0pKSB7XG4gICAgICBhcnJheS5wdXNoKFxuICAgICAgICBmaWxsV2l0aFplcm9pc2hJbnB1dChcbiAgICAgICAgICB0ZW1wbGF0ZUlucHV0LFxuICAgICAgICAgIC8vIGFzIGZhciBhcyBJIGNhbiB0ZWxsLCBzdGFydCB3aWxsIG5ldmVyIGJlIG51bGxcbiAgICAgICAgICAvLyBiZWNhdXNlIGlmIHdlIHBhc3MgYW4gaW52YWxpZCBzdGFydC9lbmREYXRlIHRvXG4gICAgICAgICAgLy8gSW50ZXJ2YWwsIHdlIGdldCBhIHplcm8gbGVuZ3RoIGFycmF5IGFzIHRoZSByYW5nZVxuICAgICAgICAgIGludGVydmFsLnN0YXJ0IHx8IERhdGVUaW1lLmludmFsaWQoJ25vdCBleHBlY3RlZCAtIHN0YXJ0IGlzIG51bGwnKVxuICAgICAgICApXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gYXJyYXk7XG4gIH07XG5cbiAgLypcbiAgICogQ2hlY2tzIGlmIGlucHV0J3MgdGltZXN0YW1wIGlzIGluY2x1ZGVkIGluIGdsb2JhbCBzcGVjaWZpZWQgcGVyaW9kIHRoZW4gbGVhdmVzIGl0LCBvdGhlcndpc2UuXG4gICAqL1xuICBjb25zdCB0cmltSW5wdXRzQnlHbG9iYWxUaW1lbGluZSA9IChcbiAgICBpbnB1dHM6IFBsdWdpblBhcmFtc1tdLFxuICAgIHBhcmFtczogVGltZVBhcmFtc1xuICApOiBQbHVnaW5QYXJhbXNbXSA9PiB7XG4gICAgcmV0dXJuIGlucHV0cy5yZWR1Y2UoKGFjYzogUGx1Z2luUGFyYW1zW10sIGl0ZW0pID0+IHtcbiAgICAgIGNvbnN0IHt0aW1lc3RhbXB9ID0gaXRlbTtcblxuICAgICAgaWYgKFxuICAgICAgICBwYXJzZURhdGUodGltZXN0YW1wKSA+PSBwYXJhbXMuc3RhcnRUaW1lICYmXG4gICAgICAgIHBhcnNlRGF0ZSh0aW1lc3RhbXApIDw9IHBhcmFtcy5lbmRUaW1lXG4gICAgICApIHtcbiAgICAgICAgYWNjLnB1c2goaXRlbSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBhY2M7XG4gICAgfSwgW10gYXMgUGx1Z2luUGFyYW1zW10pO1xuICB9O1xuXG4gIHJldHVybiB7bWV0YWRhdGEsIGV4ZWN1dGV9O1xufTtcbiJdfQ==
@@ -0,0 +1,3 @@
1
+ export type AggregationResult = Record<string, number>;
2
+ export declare const AGGREGATION_METHODS: readonly ["horizontal", "vertical", "both"];
3
+ export type AggregationMethodsNames = (typeof AGGREGATION_METHODS)[number];
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AGGREGATION_METHODS = void 0;
4
+ exports.AGGREGATION_METHODS = ['horizontal', 'vertical', 'both'];
5
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWdncmVnYXRpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdHlwZXMvYWdncmVnYXRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBRWEsUUFBQSxtQkFBbUIsR0FBRyxDQUFDLFlBQVksRUFBRSxVQUFVLEVBQUUsTUFBTSxDQUFVLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgdHlwZSBBZ2dyZWdhdGlvblJlc3VsdCA9IFJlY29yZDxzdHJpbmcsIG51bWJlcj47XG5cbmV4cG9ydCBjb25zdCBBR0dSRUdBVElPTl9NRVRIT0RTID0gWydob3Jpem9udGFsJywgJ3ZlcnRpY2FsJywgJ2JvdGgnXSBhcyBjb25zdDtcblxuZXhwb3J0IHR5cGUgQWdncmVnYXRpb25NZXRob2RzTmFtZXMgPSAodHlwZW9mIEFHR1JFR0FUSU9OX01FVEhPRFMpW251bWJlcl07XG4iXX0=
@@ -0,0 +1,25 @@
1
+ import { PluginsStorage } from './initialize';
2
+ import { PluginParams } from './interface';
3
+ import { Context } from './manifest';
4
+ export type NodeConfig = {
5
+ [key: string]: Record<string, any>;
6
+ };
7
+ export type Params = {
8
+ plugins: PluginsStorage;
9
+ context: Context;
10
+ pipeline?: string[];
11
+ config?: NodeConfig;
12
+ defaults?: PluginParams;
13
+ };
14
+ export type Node = {
15
+ children?: any;
16
+ pipeline?: string[];
17
+ config?: NodeConfig;
18
+ defaults?: PluginParams;
19
+ inputs?: PluginParams[];
20
+ outputs?: PluginParams[];
21
+ };
22
+ export type ComputeParams = {
23
+ context: Context;
24
+ plugins: PluginsStorage;
25
+ };
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcHV0ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90eXBlcy9jb21wdXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1BsdWdpbnNTdG9yYWdlfSBmcm9tICcuL2luaXRpYWxpemUnO1xuaW1wb3J0IHtQbHVnaW5QYXJhbXN9IGZyb20gJy4vaW50ZXJmYWNlJztcbmltcG9ydCB7Q29udGV4dH0gZnJvbSAnLi9tYW5pZmVzdCc7XG5cbmV4cG9ydCB0eXBlIE5vZGVDb25maWcgPSB7XG4gIFtrZXk6IHN0cmluZ106IFJlY29yZDxzdHJpbmcsIGFueT47XG59O1xuXG5leHBvcnQgdHlwZSBQYXJhbXMgPSB7XG4gIHBsdWdpbnM6IFBsdWdpbnNTdG9yYWdlO1xuICBjb250ZXh0OiBDb250ZXh0O1xuICBwaXBlbGluZT86IHN0cmluZ1tdO1xuICBjb25maWc/OiBOb2RlQ29uZmlnO1xuICBkZWZhdWx0cz86IFBsdWdpblBhcmFtcztcbn07XG5cbmV4cG9ydCB0eXBlIE5vZGUgPSB7XG4gIGNoaWxkcmVuPzogYW55O1xuICBwaXBlbGluZT86IHN0cmluZ1tdO1xuICBjb25maWc/OiBOb2RlQ29uZmlnO1xuICBkZWZhdWx0cz86IFBsdWdpblBhcmFtcztcbiAgaW5wdXRzPzogUGx1Z2luUGFyYW1zW107XG4gIG91dHB1dHM/OiBQbHVnaW5QYXJhbXNbXTtcbn07XG5cbmV4cG9ydCB0eXBlIENvbXB1dGVQYXJhbXMgPSB7XG4gIGNvbnRleHQ6IENvbnRleHQ7XG4gIHBsdWdpbnM6IFBsdWdpbnNTdG9yYWdlO1xufTtcbiJdfQ==
@@ -0,0 +1,7 @@
1
+ import { Context } from './manifest';
2
+ export interface ExhaustPluginInterface {
3
+ /**
4
+ * Execute exhaust based on `context` and `tree`, produce output to a file in `outputPath`.
5
+ */
6
+ execute(tree: any, context: Context, outputPath?: string): void;
7
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXhoYXVzdC1wbHVnaW4taW50ZXJmYWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3R5cGVzL2V4aGF1c3QtcGx1Z2luLWludGVyZmFjZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtDb250ZXh0fSBmcm9tICcuL21hbmlmZXN0JztcblxuZXhwb3J0IGludGVyZmFjZSBFeGhhdXN0UGx1Z2luSW50ZXJmYWNlIHtcbiAgLyoqXG4gICAqIEV4ZWN1dGUgZXhoYXVzdCBiYXNlZCBvbiBgY29udGV4dGAgYW5kIGB0cmVlYCwgcHJvZHVjZSBvdXRwdXQgdG8gYSBmaWxlIGluIGBvdXRwdXRQYXRoYC5cbiAgICovXG4gIGV4ZWN1dGUodHJlZTogYW55LCBjb250ZXh0OiBDb250ZXh0LCBvdXRwdXRQYXRoPzogc3RyaW5nKTogdm9pZDtcbn1cbiJdfQ==
@@ -0,0 +1,3 @@
1
+ export type GroupByConfig = {
2
+ group: string[];
3
+ };
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3JvdXAtYnkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdHlwZXMvZ3JvdXAtYnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCB0eXBlIEdyb3VwQnlDb25maWcgPSB7XG4gIGdyb3VwOiBzdHJpbmdbXTtcbn07XG4iXX0=