@rudderstack/integrations-lib 0.1.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 (108) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1 -0
  3. package/build/constants.d.ts +96 -0
  4. package/build/constants.d.ts.map +1 -0
  5. package/build/constants.js +180 -0
  6. package/build/errors/aborted_error.d.ts +5 -0
  7. package/build/errors/aborted_error.d.ts.map +1 -0
  8. package/build/errors/aborted_error.js +16 -0
  9. package/build/errors/base.d.ts +8 -0
  10. package/build/errors/base.d.ts.map +1 -0
  11. package/build/errors/base.js +14 -0
  12. package/build/errors/configuration_error.d.ts +5 -0
  13. package/build/errors/configuration_error.d.ts.map +1 -0
  14. package/build/errors/configuration_error.js +17 -0
  15. package/build/errors/index.d.ts +17 -0
  16. package/build/errors/index.d.ts.map +1 -0
  17. package/build/errors/index.js +33 -0
  18. package/build/errors/instrumentation_error.d.ts +5 -0
  19. package/build/errors/instrumentation_error.d.ts.map +1 -0
  20. package/build/errors/instrumentation_error.js +16 -0
  21. package/build/errors/invalid_auth_token_error.d.ts +5 -0
  22. package/build/errors/invalid_auth_token_error.d.ts.map +1 -0
  23. package/build/errors/invalid_auth_token_error.js +17 -0
  24. package/build/errors/network_error.d.ts +7 -0
  25. package/build/errors/network_error.d.ts.map +1 -0
  26. package/build/errors/network_error.js +28 -0
  27. package/build/errors/network_instrumentation_error.d.ts +5 -0
  28. package/build/errors/network_instrumentation_error.d.ts.map +1 -0
  29. package/build/errors/network_instrumentation_error.js +17 -0
  30. package/build/errors/oauth_secret_error.d.ts +5 -0
  31. package/build/errors/oauth_secret_error.d.ts.map +1 -0
  32. package/build/errors/oauth_secret_error.js +16 -0
  33. package/build/errors/platform_error.d.ts +5 -0
  34. package/build/errors/platform_error.d.ts.map +1 -0
  35. package/build/errors/platform_error.js +15 -0
  36. package/build/errors/redis_error.d.ts +5 -0
  37. package/build/errors/redis_error.d.ts.map +1 -0
  38. package/build/errors/redis_error.js +16 -0
  39. package/build/errors/retryable_error.d.ts +5 -0
  40. package/build/errors/retryable_error.d.ts.map +1 -0
  41. package/build/errors/retryable_error.js +16 -0
  42. package/build/errors/throttled_error.d.ts +5 -0
  43. package/build/errors/throttled_error.d.ts.map +1 -0
  44. package/build/errors/throttled_error.js +16 -0
  45. package/build/errors/transformation_error.d.ts +5 -0
  46. package/build/errors/transformation_error.d.ts.map +1 -0
  47. package/build/errors/transformation_error.js +15 -0
  48. package/build/errors/unauthorized_error.d.ts +5 -0
  49. package/build/errors/unauthorized_error.d.ts.map +1 -0
  50. package/build/errors/unauthorized_error.js +17 -0
  51. package/build/errors/unhandled_status_code_error.d.ts +5 -0
  52. package/build/errors/unhandled_status_code_error.d.ts.map +1 -0
  53. package/build/errors/unhandled_status_code_error.js +17 -0
  54. package/build/errors/unsupported_event_error.d.ts +5 -0
  55. package/build/errors/unsupported_event_error.d.ts.map +1 -0
  56. package/build/errors/unsupported_event_error.js +16 -0
  57. package/build/index.d.ts +7 -0
  58. package/build/index.d.ts.map +1 -0
  59. package/build/index.js +23 -0
  60. package/build/logger.d.ts +7 -0
  61. package/build/logger.d.ts.map +1 -0
  62. package/build/logger.js +39 -0
  63. package/build/network/clients/axios.d.ts +38 -0
  64. package/build/network/clients/axios.d.ts.map +1 -0
  65. package/build/network/clients/axios.js +197 -0
  66. package/build/network/clients/axios.test.d.ts +2 -0
  67. package/build/network/clients/axios.test.d.ts.map +1 -0
  68. package/build/network/clients/axios.test.js +231 -0
  69. package/build/network/clients/types.d.ts +32 -0
  70. package/build/network/clients/types.d.ts.map +1 -0
  71. package/build/network/clients/types.js +3 -0
  72. package/build/network/factory.d.ts +30 -0
  73. package/build/network/factory.d.ts.map +1 -0
  74. package/build/network/factory.js +46 -0
  75. package/build/network/factory.test.d.ts +2 -0
  76. package/build/network/factory.test.d.ts.map +1 -0
  77. package/build/network/factory.test.js +50 -0
  78. package/build/network/index.d.ts +2 -0
  79. package/build/network/index.d.ts.map +1 -0
  80. package/build/network/index.js +18 -0
  81. package/build/tags.d.ts +56 -0
  82. package/build/tags.d.ts.map +1 -0
  83. package/build/tags.js +59 -0
  84. package/build/types.d.ts +275 -0
  85. package/build/types.d.ts.map +1 -0
  86. package/build/types.js +34 -0
  87. package/build/utils/index.d.ts +4 -0
  88. package/build/utils/index.d.ts.map +1 -0
  89. package/build/utils/index.js +20 -0
  90. package/build/utils/json.d.ts +51 -0
  91. package/build/utils/json.d.ts.map +1 -0
  92. package/build/utils/json.js +507 -0
  93. package/build/utils/json.test.d.ts +2 -0
  94. package/build/utils/json.test.d.ts.map +1 -0
  95. package/build/utils/json.test.js +588 -0
  96. package/build/utils/misc.d.ts +129 -0
  97. package/build/utils/misc.d.ts.map +1 -0
  98. package/build/utils/misc.js +362 -0
  99. package/build/utils/misc.test.d.ts +2 -0
  100. package/build/utils/misc.test.d.ts.map +1 -0
  101. package/build/utils/misc.test.js +2059 -0
  102. package/build/utils/sem.d.ts +29 -0
  103. package/build/utils/sem.d.ts.map +1 -0
  104. package/build/utils/sem.js +196 -0
  105. package/build/utils/sem.test.d.ts +2 -0
  106. package/build/utils/sem.test.d.ts.map +1 -0
  107. package/build/utils/sem.test.js +237 -0
  108. package/package.json +69 -0
@@ -0,0 +1,129 @@
1
+ /// <reference types="node" />
2
+ import { RudderStackEvent } from '../types';
3
+ import get from 'get-value';
4
+ import set from 'set-value';
5
+ export { get, set };
6
+ export declare const isDefined: (x: unknown) => boolean;
7
+ export declare const isNotEmpty: (x: unknown) => boolean;
8
+ export declare const isNotNull: (x: unknown) => boolean;
9
+ export declare const isDefinedAndNotNull: (x: unknown) => boolean;
10
+ export declare const isDefinedAndNotNullAndNotEmpty: (x: unknown) => boolean;
11
+ export declare const isBlank: (value: unknown) => boolean;
12
+ export declare const removeUndefinedValues: (obj: unknown) => unknown;
13
+ export declare const removeNullValues: (obj: unknown) => unknown;
14
+ export declare const removeUndefinedAndNullValues: (obj: unknown) => unknown;
15
+ export declare const removeUndefinedAndNullAndEmptyValues: (obj: unknown) => unknown;
16
+ /**
17
+ * The flattenMap function takes a collection as input and returns a flattened version of the collection. If the input is not an array or an object, it is returned as is. Otherwise, the function uses the flatMap function from the lodash library to flatten the collection.
18
+ * @param collection
19
+ * @returns
20
+ */
21
+ export declare const flattenMap: (collection: unknown) => unknown;
22
+ export declare const getEventTime: (message: RudderStackEvent) => Date;
23
+ export declare const base64Convertor: (string: string) => string;
24
+ export declare const isValidUrl: (url: string | URL) => URL | null;
25
+ export declare const stripTrailingSlash: (str: string) => string;
26
+ export declare const isPrimitive: (arg: unknown) => boolean;
27
+ /**
28
+ *
29
+ * @param {*} arg
30
+ * @returns {type}
31
+ *
32
+ * Returns type of passed arg
33
+ * for null argss returns "NULL" insted of "object"
34
+ *
35
+ */
36
+ export declare const getType: (arg: unknown) => "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" | "NULL" | "array";
37
+ export declare const isObject: (value: unknown) => boolean;
38
+ export declare const isEmpty: (input: unknown) => boolean;
39
+ /**
40
+ * Returns true for empty object {}
41
+ * @param {*} obj
42
+ * @returns
43
+ */
44
+ export declare const isEmptyObject: (obj: any) => boolean;
45
+ /**
46
+ * Function to check if value is Defined, Not null and Not Empty.
47
+ * Create this function, Because existing isDefinedAndNotNullAndNotEmpty(123) is returning false due to lodash _.isEmpty function.
48
+ * _.isEmpty is used to detect empty collections/objects and it will return true for Integer, Boolean values.
49
+ * ref: https://github.com/lodash/lodash/issues/496
50
+ * @param {*} value 123
51
+ * @returns yes
52
+ */
53
+ export declare const isDefinedNotNullNotEmpty: (value: unknown) => boolean;
54
+ export declare const removeUndefinedNullEmptyExclBoolInt: (obj: unknown) => unknown;
55
+ export declare const getHashFromArray: (arrays: any, fromKey?: string, toKey?: string, isLowerCase?: boolean) => {};
56
+ /**
57
+ * Format the destination.Config.dynamicMap arrays to hashMap
58
+ * where value is an array
59
+ * @param {} arrays [{"from":"prop1","to":"val1"},{"from":"prop1","to":"val2"},{"from":"prop2","to":"val2"}]
60
+ * @param {} fromKey="from"
61
+ * @param {} toKey="to"
62
+ * @param {} isLowerCase=true
63
+ * @param {} return hashmap {"prop1":["val1","val2"],"prop2":["val2"]}
64
+ */
65
+ export declare const getHashFromArrayWithDuplicate: (arrays: {
66
+ from: string;
67
+ to: string;
68
+ }[], fromKey?: string, toKey?: string, isLowerCase?: boolean) => {};
69
+ /**
70
+ * Format the arrays to hashMap with key as `fromKey` and value as Object
71
+ * @param {*} arrays [{"id":"a0b8efe1-c828-4c63-8850-0d0742888f9d","name":"Email","type":"email","type_config":{},"date_created":"1662225840284","hide_from_guests":false,"required":false}]
72
+ * @param {*} fromKey name
73
+ * @param {*} isLowerCase false
74
+ * @returns // {"Email":{"id":"a0b8efe1-c828-4c63-8850-0d0742888f9d","name":"Email","type":"email","type_config":{},"date_created":"1662225840284","hide_from_guests":false,"required":false}}
75
+ */
76
+ export declare const getHashFromArrayWithValueAsObject: (arrays: any, fromKey?: string, isLowerCase?: boolean) => {};
77
+ /**
78
+ * Retrieves a value from a message object based on a given key. It searches for the key in the properties, traits, and context.traits of the message object in that order.
79
+ *
80
+ * @param {Object} options - The options object.
81
+ * @param {Object} options.message - The message object containing properties, traits, and context.traits.
82
+ * @param {string} options.key - The key to search for in the message object.
83
+ * @returns {*} The value found in the message object for the given key, or null if the key is not found or the value is null.
84
+ */
85
+ export declare const getValueFromPropertiesOrTraits: ({ message, key }: {
86
+ message: any;
87
+ key: any;
88
+ }) => any;
89
+ /**
90
+ * Flattens a JSON object into a single-level object.
91
+ *
92
+ * @param data - The JSON object to be flattened.
93
+ * @param separator - The character used to separate the keys in the flattened object. Default is '.'.
94
+ * @param mode - The mode used to flatten arrays. If set to 'strict', the array indices will be included in the flattened keys. Default is 'normal'.
95
+ * @returns The flattened JSON object.
96
+ */
97
+ export declare const flattenJson: (data: unknown, separator?: string, mode?: string) => {};
98
+ /**
99
+ * Get the offset value in seconds for a given timezone.
100
+ *
101
+ * @param value - The timezone value for which the offset needs to be calculated.
102
+ * @returns The offset value in seconds for the given timezone. If the timezone is invalid or not found, it returns `undefined`.
103
+ *
104
+ * @example
105
+ * const offset = getOffsetInSec('America/New_York');
106
+ * console.log(offset); // Output: -18000
107
+ */
108
+ export declare const getOffsetInSec: (value: string) => number | undefined;
109
+ /**
110
+ * Converts a date string into a formatted timestamp.
111
+ * If a format string is provided, it uses the moment library to format the date.
112
+ * If no format string is provided, it returns the timestamp of the date.
113
+ * @param dateStr - The date string to be formatted.
114
+ * @param format - (Optional) The format string to be used for formatting the date.
115
+ * @returns The formatted date as a string if a format string is provided,
116
+ * otherwise the timestamp of the date as a number.
117
+ */
118
+ export declare const formatTimeStamp: (dateStr: string, format?: string) => string | number;
119
+ export declare const hashToSha256: (value: string | Buffer | number[]) => string;
120
+ /**
121
+ * Generates a Universally Unique Identifier (UUID) using the `crypto.randomUUID()` method.
122
+ * The `disableEntropyCache` option is set to `true` to prevent caching of generated UUIDs.
123
+ *
124
+ * @returns {string} A randomly generated UUID.
125
+ *
126
+ * @see {@link https://nodejs.org/api/crypto.html#cryptorandomuuidoptions:~:text=options%20%3CObject%3E-,disableEntropyCache,-%3Cboolean%3E%20By}
127
+ */
128
+ export declare const generateUUID: () => string;
129
+ //# sourceMappingURL=misc.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"misc.d.ts","sourceRoot":"","sources":["../../src/utils/misc.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAE5C,OAAO,GAAG,MAAM,WAAW,CAAC;AAC5B,OAAO,GAAG,MAAM,WAAW,CAAC;AAQ5B,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;AACpB,eAAO,MAAM,SAAS,MAAO,OAAO,YAAsB,CAAC;AAC3D,eAAO,MAAM,UAAU,MAAO,OAAO,YAAkB,CAAC;AACxD,eAAO,MAAM,SAAS,MAAO,OAAO,YAAc,CAAC;AACnD,eAAO,MAAM,mBAAmB,MAAO,OAAO,YAAiC,CAAC;AAChF,eAAO,MAAM,8BAA8B,MAAO,OAAO,YACV,CAAC;AAChD,eAAO,MAAM,OAAO,UAAW,OAAO,YAAiC,CAAC;AAGxE,eAAO,MAAM,qBAAqB,QAAS,OAAO,YAGjD,CAAC;AAEF,eAAO,MAAM,gBAAgB,QAAS,OAAO,YAG5C,CAAC;AACF,eAAO,MAAM,4BAA4B,QAAS,OAAO,YAGxD,CAAC;AACF,eAAO,MAAM,oCAAoC,QAAS,OAAO,YAGhE,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,UAAU,eAAgB,OAAO,YAG7C,CAAC;AAMF,eAAO,MAAM,YAAY,YAAa,gBAAgB,SASrD,CAAC;AAEF,eAAO,MAAM,eAAe,WAAY,MAAM,WAA2C,CAAC;AAG1F,eAAO,MAAM,UAAU,QAAS,MAAM,GAAG,GAAG,eAM3C,CAAC;AAEF,eAAO,MAAM,kBAAkB,QAAS,MAAM,WACK,CAAC;AAEpD,eAAO,MAAM,WAAW,QAAS,OAAO,YAGvC,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,OAAO,QAAS,OAAO,mHASnC,CAAC;AAEF,eAAO,MAAM,QAAQ,UAAW,OAAO,YAGtC,CAAC;AAEF,eAAO,MAAM,OAAO,UAAW,OAAO,YAErC,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,aAAa,QAAS,GAAG,YAMrC,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,wBAAwB,UAAW,OAAO,YAOpD,CAAC;AAEJ,eAAO,MAAM,mCAAmC,QAAS,OAAO,YAG/D,CAAC;AAGF,eAAO,MAAM,gBAAgB,8EAU5B,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,6BAA6B,WAChC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,EAAE,gEAsBvC,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,iCAAiC,8DAS7C,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,8BAA8B;;;SAQ1C,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW,SAAU,OAAO,0CA+BxC,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,cAAc,UAAW,MAAM,uBAY3C,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe,YAAa,MAAM,WAAW,MAAM,oBAS/D,CAAC;AAEF,eAAO,MAAM,YAAY,UAAW,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,WAAkB,CAAC;AAEjF;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,QAAO,MAE/B,CAAC"}
@@ -0,0 +1,362 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.generateUUID = exports.hashToSha256 = exports.formatTimeStamp = exports.getOffsetInSec = exports.flattenJson = exports.getValueFromPropertiesOrTraits = exports.getHashFromArrayWithValueAsObject = exports.getHashFromArrayWithDuplicate = exports.getHashFromArray = exports.removeUndefinedNullEmptyExclBoolInt = exports.isDefinedNotNullNotEmpty = exports.isEmptyObject = exports.isEmpty = exports.isObject = exports.getType = exports.isPrimitive = exports.stripTrailingSlash = exports.isValidUrl = exports.base64Convertor = exports.getEventTime = exports.flattenMap = exports.removeUndefinedAndNullAndEmptyValues = exports.removeUndefinedAndNullValues = exports.removeNullValues = exports.removeUndefinedValues = exports.isBlank = exports.isDefinedAndNotNullAndNotEmpty = exports.isDefinedAndNotNull = exports.isNotNull = exports.isNotEmpty = exports.isDefined = exports.set = exports.get = void 0;
30
+ const lodash_1 = __importDefault(require("lodash"));
31
+ const instrumentation_error_1 = require("../errors/instrumentation_error");
32
+ const logger = __importStar(require("../logger"));
33
+ const get_value_1 = __importDefault(require("get-value"));
34
+ exports.get = get_value_1.default;
35
+ const set_value_1 = __importDefault(require("set-value"));
36
+ exports.set = set_value_1.default;
37
+ const moment_timezone_1 = __importDefault(require("moment-timezone"));
38
+ const sha256_1 = __importDefault(require("sha256"));
39
+ const crypto_1 = __importDefault(require("crypto"));
40
+ const isDefined = (x) => !lodash_1.default.isUndefined(x);
41
+ exports.isDefined = isDefined;
42
+ const isNotEmpty = (x) => !lodash_1.default.isEmpty(x);
43
+ exports.isNotEmpty = isNotEmpty;
44
+ const isNotNull = (x) => x != null;
45
+ exports.isNotNull = isNotNull;
46
+ const isDefinedAndNotNull = (x) => (0, exports.isDefined)(x) && (0, exports.isNotNull)(x);
47
+ exports.isDefinedAndNotNull = isDefinedAndNotNull;
48
+ const isDefinedAndNotNullAndNotEmpty = (x) => (0, exports.isDefined)(x) && (0, exports.isNotNull)(x) && (0, exports.isNotEmpty)(x);
49
+ exports.isDefinedAndNotNullAndNotEmpty = isDefinedAndNotNullAndNotEmpty;
50
+ const isBlank = (value) => lodash_1.default.isEmpty(lodash_1.default.toString(value));
51
+ exports.isBlank = isBlank;
52
+ // ========================================================================
53
+ const removeUndefinedValues = (obj) => {
54
+ if (!lodash_1.default.isObject(obj))
55
+ return obj;
56
+ return lodash_1.default.pickBy(obj, exports.isDefined);
57
+ };
58
+ exports.removeUndefinedValues = removeUndefinedValues;
59
+ const removeNullValues = (obj) => {
60
+ if (!lodash_1.default.isObject(obj))
61
+ return obj;
62
+ return lodash_1.default.pickBy(obj, exports.isNotNull);
63
+ };
64
+ exports.removeNullValues = removeNullValues;
65
+ const removeUndefinedAndNullValues = (obj) => {
66
+ if (!lodash_1.default.isObject(obj))
67
+ return obj;
68
+ return lodash_1.default.pickBy(obj, exports.isDefinedAndNotNull);
69
+ };
70
+ exports.removeUndefinedAndNullValues = removeUndefinedAndNullValues;
71
+ const removeUndefinedAndNullAndEmptyValues = (obj) => {
72
+ if (!lodash_1.default.isObject(obj))
73
+ return obj;
74
+ return lodash_1.default.pickBy(obj, exports.isDefinedAndNotNullAndNotEmpty);
75
+ };
76
+ exports.removeUndefinedAndNullAndEmptyValues = removeUndefinedAndNullAndEmptyValues;
77
+ /**
78
+ * The flattenMap function takes a collection as input and returns a flattened version of the collection. If the input is not an array or an object, it is returned as is. Otherwise, the function uses the flatMap function from the lodash library to flatten the collection.
79
+ * @param collection
80
+ * @returns
81
+ */
82
+ const flattenMap = (collection) => {
83
+ if (!lodash_1.default.isArray(collection) && !lodash_1.default.isObject(collection))
84
+ return collection;
85
+ return lodash_1.default.flatMap(collection, (x) => x);
86
+ };
87
+ exports.flattenMap = flattenMap;
88
+ // ========================================================================
89
+ // GENERIC UTLITY
90
+ // ========================================================================
91
+ const getEventTime = (message) => {
92
+ if (!message.timestamp && !message.originalTimestamp)
93
+ throw new instrumentation_error_1.InstrumentationError('Event does not have timestamp or originalTimestamp');
94
+ try {
95
+ if (message.timestamp)
96
+ return new Date(message.timestamp);
97
+ }
98
+ catch (e) {
99
+ logger.error('Error in parsing timestamp', e);
100
+ }
101
+ return new Date(message.originalTimestamp);
102
+ };
103
+ exports.getEventTime = getEventTime;
104
+ const base64Convertor = (string) => Buffer.from(string).toString('base64');
105
+ exports.base64Convertor = base64Convertor;
106
+ // return a valid URL object if correct else null
107
+ const isValidUrl = (url) => {
108
+ try {
109
+ return new URL(url);
110
+ }
111
+ catch (err) {
112
+ return null;
113
+ }
114
+ };
115
+ exports.isValidUrl = isValidUrl;
116
+ const stripTrailingSlash = (str) => str && str.endsWith('/') ? str.slice(0, -1) : str;
117
+ exports.stripTrailingSlash = stripTrailingSlash;
118
+ const isPrimitive = (arg) => {
119
+ const type = typeof arg;
120
+ return arg == null || (type !== 'object' && type !== 'function');
121
+ };
122
+ exports.isPrimitive = isPrimitive;
123
+ /**
124
+ *
125
+ * @param {*} arg
126
+ * @returns {type}
127
+ *
128
+ * Returns type of passed arg
129
+ * for null argss returns "NULL" insted of "object"
130
+ *
131
+ */
132
+ const getType = (arg) => {
133
+ const type = typeof arg;
134
+ if (arg == null) {
135
+ return 'NULL';
136
+ }
137
+ if (Array.isArray(arg)) {
138
+ return 'array';
139
+ }
140
+ return type;
141
+ };
142
+ exports.getType = getType;
143
+ const isObject = (value) => {
144
+ const type = typeof value;
145
+ return value != null && (type === 'object' || type === 'function') && !Array.isArray(value);
146
+ };
147
+ exports.isObject = isObject;
148
+ const isEmpty = (input) => {
149
+ return lodash_1.default.isEmpty(lodash_1.default.toString(input).trim());
150
+ };
151
+ exports.isEmpty = isEmpty;
152
+ /**
153
+ * Returns true for empty object {}
154
+ * @param {*} obj
155
+ * @returns
156
+ */
157
+ const isEmptyObject = (obj) => {
158
+ if (!obj) {
159
+ logger.warn('input is undefined or null');
160
+ return true;
161
+ }
162
+ return Object.keys(obj).length === 0;
163
+ };
164
+ exports.isEmptyObject = isEmptyObject;
165
+ /**
166
+ * Function to check if value is Defined, Not null and Not Empty.
167
+ * Create this function, Because existing isDefinedAndNotNullAndNotEmpty(123) is returning false due to lodash _.isEmpty function.
168
+ * _.isEmpty is used to detect empty collections/objects and it will return true for Integer, Boolean values.
169
+ * ref: https://github.com/lodash/lodash/issues/496
170
+ * @param {*} value 123
171
+ * @returns yes
172
+ */
173
+ const isDefinedNotNullNotEmpty = (value) => !(value === undefined ||
174
+ value === null ||
175
+ Number.isNaN(value) ||
176
+ (typeof value === 'object' && Object.keys(value).length === 0) ||
177
+ (typeof value === 'string' && value.trim().length === 0));
178
+ exports.isDefinedNotNullNotEmpty = isDefinedNotNullNotEmpty;
179
+ const removeUndefinedNullEmptyExclBoolInt = (obj) => {
180
+ if (!lodash_1.default.isObject(obj))
181
+ return obj;
182
+ return lodash_1.default.pickBy(obj, exports.isDefinedNotNullNotEmpty);
183
+ };
184
+ exports.removeUndefinedNullEmptyExclBoolInt = removeUndefinedNullEmptyExclBoolInt;
185
+ // Format the destination.Config.dynamicMap arrays to hashMap
186
+ const getHashFromArray = (arrays, fromKey = 'from', toKey = 'to', isLowerCase = true) => {
187
+ const hashMap = {};
188
+ if (Array.isArray(arrays)) {
189
+ arrays.forEach((array) => {
190
+ if ((0, exports.isEmpty)(array[fromKey]))
191
+ return;
192
+ hashMap[isLowerCase ? array[fromKey].toString().toLowerCase() : array[fromKey]] =
193
+ array[toKey];
194
+ });
195
+ }
196
+ return hashMap;
197
+ };
198
+ exports.getHashFromArray = getHashFromArray;
199
+ /**
200
+ * Format the destination.Config.dynamicMap arrays to hashMap
201
+ * where value is an array
202
+ * @param {} arrays [{"from":"prop1","to":"val1"},{"from":"prop1","to":"val2"},{"from":"prop2","to":"val2"}]
203
+ * @param {} fromKey="from"
204
+ * @param {} toKey="to"
205
+ * @param {} isLowerCase=true
206
+ * @param {} return hashmap {"prop1":["val1","val2"],"prop2":["val2"]}
207
+ */
208
+ const getHashFromArrayWithDuplicate = (arrays, fromKey = 'from', toKey = 'to', isLowerCase = true) => {
209
+ const hashMap = {};
210
+ if (Array.isArray(arrays)) {
211
+ arrays.forEach((array) => {
212
+ if ((0, exports.isEmpty)(array[fromKey]))
213
+ return;
214
+ const key = isLowerCase
215
+ ? array[fromKey].toString().toLowerCase().trim()
216
+ : array[fromKey].toString().trim();
217
+ if (hashMap[key]) {
218
+ hashMap[key].add(array[toKey]);
219
+ }
220
+ else {
221
+ hashMap[key] = new Set();
222
+ hashMap[key].add(array[toKey]);
223
+ }
224
+ });
225
+ }
226
+ return hashMap;
227
+ };
228
+ exports.getHashFromArrayWithDuplicate = getHashFromArrayWithDuplicate;
229
+ /**
230
+ * Format the arrays to hashMap with key as `fromKey` and value as Object
231
+ * @param {*} arrays [{"id":"a0b8efe1-c828-4c63-8850-0d0742888f9d","name":"Email","type":"email","type_config":{},"date_created":"1662225840284","hide_from_guests":false,"required":false}]
232
+ * @param {*} fromKey name
233
+ * @param {*} isLowerCase false
234
+ * @returns // {"Email":{"id":"a0b8efe1-c828-4c63-8850-0d0742888f9d","name":"Email","type":"email","type_config":{},"date_created":"1662225840284","hide_from_guests":false,"required":false}}
235
+ */
236
+ const getHashFromArrayWithValueAsObject = (arrays, fromKey = 'from', isLowerCase = true) => {
237
+ const hashMap = {};
238
+ if (Array.isArray(arrays)) {
239
+ arrays.forEach((array) => {
240
+ if ((0, exports.isEmpty)(array[fromKey]))
241
+ return;
242
+ hashMap[isLowerCase ? array[fromKey].toLowerCase() : array[fromKey]] = array;
243
+ });
244
+ }
245
+ return hashMap;
246
+ };
247
+ exports.getHashFromArrayWithValueAsObject = getHashFromArrayWithValueAsObject;
248
+ /**
249
+ * Retrieves a value from a message object based on a given key. It searches for the key in the properties, traits, and context.traits of the message object in that order.
250
+ *
251
+ * @param {Object} options - The options object.
252
+ * @param {Object} options.message - The message object containing properties, traits, and context.traits.
253
+ * @param {string} options.key - The key to search for in the message object.
254
+ * @returns {*} The value found in the message object for the given key, or null if the key is not found or the value is null.
255
+ */
256
+ const getValueFromPropertiesOrTraits = ({ message, key }) => {
257
+ const keySet = ['properties', 'traits', 'context.traits'];
258
+ const val = lodash_1.default.find(lodash_1.default.map(keySet, (k) => (0, get_value_1.default)(message, `${k}.${key}`)), (v) => !lodash_1.default.isNil(v));
259
+ return !lodash_1.default.isNil(val) ? val : null;
260
+ };
261
+ exports.getValueFromPropertiesOrTraits = getValueFromPropertiesOrTraits;
262
+ /**
263
+ * Flattens a JSON object into a single-level object.
264
+ *
265
+ * @param data - The JSON object to be flattened.
266
+ * @param separator - The character used to separate the keys in the flattened object. Default is '.'.
267
+ * @param mode - The mode used to flatten arrays. If set to 'strict', the array indices will be included in the flattened keys. Default is 'normal'.
268
+ * @returns The flattened JSON object.
269
+ */
270
+ const flattenJson = (data, separator = '.', mode = 'normal') => {
271
+ const result = {};
272
+ // a recursive function to loop through the array of the data
273
+ const recurse = (cur, prop) => {
274
+ let i;
275
+ if (Object(cur) !== cur) {
276
+ result[prop] = cur;
277
+ }
278
+ else if (Array.isArray(cur)) {
279
+ for (i = 0; i < cur.length; i += 1) {
280
+ if (mode === 'strict') {
281
+ recurse(cur[i], `${prop}${separator}${i}`);
282
+ }
283
+ else {
284
+ recurse(cur[i], `${prop}[${i}]`);
285
+ }
286
+ }
287
+ if (cur.length === 0) {
288
+ result[prop] = [];
289
+ }
290
+ }
291
+ else {
292
+ let isEmptyFlag = true;
293
+ Object.keys(cur).forEach((key) => {
294
+ isEmptyFlag = false;
295
+ recurse(cur[key], prop ? `${prop}${separator}${key}` : key);
296
+ });
297
+ if (isEmptyFlag && prop)
298
+ result[prop] = {};
299
+ }
300
+ };
301
+ recurse(data, '');
302
+ return result;
303
+ };
304
+ exports.flattenJson = flattenJson;
305
+ /**
306
+ * Get the offset value in seconds for a given timezone.
307
+ *
308
+ * @param value - The timezone value for which the offset needs to be calculated.
309
+ * @returns The offset value in seconds for the given timezone. If the timezone is invalid or not found, it returns `undefined`.
310
+ *
311
+ * @example
312
+ * const offset = getOffsetInSec('America/New_York');
313
+ * console.log(offset); // Output: -18000
314
+ */
315
+ const getOffsetInSec = (value) => {
316
+ const name = moment_timezone_1.default.tz.zone(value);
317
+ if (name) {
318
+ const x = (0, moment_timezone_1.default)().tz(value).format('Z');
319
+ const split = x.split(':');
320
+ const hour = Number(split[0]);
321
+ const min = Number(split[1]);
322
+ let sec = 0;
323
+ sec = hour < 0 ? -1 * (hour * -60 * 60 + min * 60) : hour * 60 * 60 + min * 60;
324
+ return sec;
325
+ }
326
+ return undefined;
327
+ };
328
+ exports.getOffsetInSec = getOffsetInSec;
329
+ /**
330
+ * Converts a date string into a formatted timestamp.
331
+ * If a format string is provided, it uses the moment library to format the date.
332
+ * If no format string is provided, it returns the timestamp of the date.
333
+ * @param dateStr - The date string to be formatted.
334
+ * @param format - (Optional) The format string to be used for formatting the date.
335
+ * @returns The formatted date as a string if a format string is provided,
336
+ * otherwise the timestamp of the date as a number.
337
+ */
338
+ const formatTimeStamp = (dateStr, format) => {
339
+ const date = new Date(dateStr);
340
+ // moment format is passed. format accordingly
341
+ if (format) {
342
+ return moment_timezone_1.default.utc(date).format(format);
343
+ }
344
+ // return default format
345
+ return date.getTime();
346
+ };
347
+ exports.formatTimeStamp = formatTimeStamp;
348
+ const hashToSha256 = (value) => (0, sha256_1.default)(value);
349
+ exports.hashToSha256 = hashToSha256;
350
+ /**
351
+ * Generates a Universally Unique Identifier (UUID) using the `crypto.randomUUID()` method.
352
+ * The `disableEntropyCache` option is set to `true` to prevent caching of generated UUIDs.
353
+ *
354
+ * @returns {string} A randomly generated UUID.
355
+ *
356
+ * @see {@link https://nodejs.org/api/crypto.html#cryptorandomuuidoptions:~:text=options%20%3CObject%3E-,disableEntropyCache,-%3Cboolean%3E%20By}
357
+ */
358
+ const generateUUID = () => {
359
+ return crypto_1.default.randomUUID({ disableEntropyCache: true });
360
+ };
361
+ exports.generateUUID = generateUUID;
362
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWlzYy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlscy9taXNjLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsb0RBQXVCO0FBQ3ZCLDJFQUF1RTtBQUV2RSxrREFBb0M7QUFDcEMsMERBQTRCO0FBU25CLGNBVEYsbUJBQUcsQ0FTRTtBQVJaLDBEQUE0QjtBQVFkLGNBUlAsbUJBQUcsQ0FRTztBQVBqQixzRUFBcUM7QUFDckMsb0RBQTRCO0FBQzVCLG9EQUE0QjtBQU1yQixNQUFNLFNBQVMsR0FBRyxDQUFDLENBQVUsRUFBRSxFQUFFLENBQUMsQ0FBQyxnQkFBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUE5QyxRQUFBLFNBQVMsYUFBcUM7QUFDcEQsTUFBTSxVQUFVLEdBQUcsQ0FBQyxDQUFVLEVBQUUsRUFBRSxDQUFDLENBQUMsZ0JBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFBM0MsUUFBQSxVQUFVLGNBQWlDO0FBQ2pELE1BQU0sU0FBUyxHQUFHLENBQUMsQ0FBVSxFQUFFLEVBQUUsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDO0FBQXRDLFFBQUEsU0FBUyxhQUE2QjtBQUM1QyxNQUFNLG1CQUFtQixHQUFHLENBQUMsQ0FBVSxFQUFFLEVBQUUsQ0FBQyxJQUFBLGlCQUFTLEVBQUMsQ0FBQyxDQUFDLElBQUksSUFBQSxpQkFBUyxFQUFDLENBQUMsQ0FBQyxDQUFDO0FBQW5FLFFBQUEsbUJBQW1CLHVCQUFnRDtBQUN6RSxNQUFNLDhCQUE4QixHQUFHLENBQUMsQ0FBVSxFQUFFLEVBQUUsQ0FDM0QsSUFBQSxpQkFBUyxFQUFDLENBQUMsQ0FBQyxJQUFJLElBQUEsaUJBQVMsRUFBQyxDQUFDLENBQUMsSUFBSSxJQUFBLGtCQUFVLEVBQUMsQ0FBQyxDQUFDLENBQUM7QUFEbkMsUUFBQSw4QkFBOEIsa0NBQ0s7QUFDekMsTUFBTSxP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UUFDL0UsT0FBTyxHQUFHLENBQUM7S0FDWjtJQUNELE9BQU8sU0FBUyxDQUFDO0FBQ25CLENBQUMsQ0FBQztBQVpXLFFBQUEsY0FBYyxrQkFZekI7QUFFRjs7Ozs7Ozs7R0FRRztBQUNJLE1BQU0sZUFBZSxHQUFHLENBQUMsT0FBZSxFQUFFLE1BQWUsRUFBRSxFQUFFO0lBQ2xFLE1BQU0sSUFBSSxHQUFHLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQy9CLDhDQUE4QztJQUM5QyxJQUFJLE1BQU0sRUFBRTtRQUNWLE9BQU8seUJBQU0sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0tBQ3hDO0lBRUQsd0JBQXdCO0lBQ3hCLE9BQU8sSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO0FBQ3hCLENBQUMsQ0FBQztBQVRXLFFBQUEsZUFBZSxtQkFTMUI7QUFFSyxNQUFNLFlBQVksR0FBRyxDQUFDLEtBQWlDLEVBQUUsRUFBRSxDQUFDLElBQUEsZ0JBQU0sRUFBQyxLQUFLLENBQUMsQ0FBQztBQUFwRSxRQUFBLFlBQVksZ0JBQXdEO0FBRWpGOzs7Ozs7O0dBT0c7QUFDSSxNQUFNLFlBQVksR0FBRyxHQUFXLEVBQUU7SUFDdkMsT0FBTyxnQkFBTSxDQUFDLFVBQVUsQ0FBQyxFQUFFLG1CQUFtQixFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7QUFDMUQsQ0FBQyxDQUFDO0FBRlcsUUFBQSxZQUFZLGdCQUV2QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgeyBJbnN0cnVtZW50YXRpb25FcnJvciB9IGZyb20gJy4uL2Vycm9ycy9pbnN0cnVtZW50YXRpb25fZXJyb3InO1xuaW1wb3J0IHsgUnVkZGVyU3RhY2tFdmVudCB9IGZyb20gJy4uL3R5cGVzJztcbmltcG9ydCAqIGFzIGxvZ2dlciBmcm9tICcuLi9sb2dnZXInO1xuaW1wb3J0IGdldCBmcm9tICdnZXQtdmFsdWUnO1xuaW1wb3J0IHNldCBmcm9tICdzZXQtdmFsdWUnO1xuaW1wb3J0IG1vbWVudCBmcm9tICdtb21lbnQtdGltZXpvbmUnO1xuaW1wb3J0IHNoYTI1NiBmcm9tICdzaGEyNTYnO1xuaW1wb3J0IGNyeXB0byBmcm9tICdjcnlwdG8nO1xuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIElOTElORVJTXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbmV4cG9ydCB7IGdldCwgc2V0IH07XG5leHBvcnQgY29uc3QgaXNEZWZpbmVkID0gKHg6IHVua25vd24pID0+ICFfLmlzVW5kZWZpbmVkKHgpO1xuZXhwb3J0IGNvbnN0IGlzTm90RW1wdHkgPSAoeDogdW5rbm93bikgPT4gIV8uaXNFbXB0eSh4KTtcbmV4cG9ydCBjb25zdCBpc05vdE51bGwgPSAoeDogdW5rbm93bikgPT4geCAhPSBudWxsO1xuZXhwb3J0IGNvbnN0IGlzRGVmaW5lZEFuZE5vdE51bGwgPSAoeDogdW5rbm93bikgPT4gaXNEZWZpbmVkKHgpICYmIGlzTm90TnVsbCh4KTtcbmV4cG9ydCBjb25zdCBpc0RlZmluZWRBbmROb3ROdWxsQW5kTm90RW1wdHkgPSAoeDogdW5rbm93bikgPT5cbiAgaXNEZWZpbmVkKHgpICYmIGlzTm90TnVsbCh4KSAmJiBpc05vdEVtcHR5KHgpO1xuZXhwb3J0IGNvbnN0IGlzQmxhbmsgPSAodmFsdWU6IHVua25vd24pID0+IF8uaXNFbXB0eShfLnRvU3RyaW5nKHZhbHVlKSk7XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuZXhwb3J0IGNvbnN0IHJlbW92ZVVuZGVmaW5lZFZhbHVlcyA9IChvYmo6IHVua25vd24pID0+IHtcbiAgaWYgKCFfLmlzT2JqZWN0KG9iaikpIHJldHVybiBvYmo7XG4gIHJldHVybiBfLnBpY2tCeShvYmosIGlzRGVmaW5lZCk7XG59O1xuXG5leHBvcnQgY29uc3QgcmVtb3ZlTnVsbFZhbHVlcyA9IChvYmo6IHVua25vd24pID0+IHtcbiAgaWYgKCFfLmlzT2JqZWN0KG9iaikpIHJldHVybiBvYmo7XG4gIHJldHVybiBfLnBpY2tCeShvYmosIGlzTm90TnVsbCk7XG59O1xuZXhwb3J0IGNvbnN0IHJlbW92ZVVuZGVmaW5lZEFuZE51bGxWYWx1ZXMgPSAob2JqOiB1bmtub3duKSA9PiB7XG4gIGlmICghXy5pc09iamVjdChvYmopKSByZXR1cm4gb2JqO1xuICByZXR1cm4gXy5waWNrQnkob2JqLCBpc0RlZmluZWRBbmROb3ROdWxsKTtcbn07XG5leHBvcnQgY29uc3QgcmVtb3ZlVW5kZWZpbmVkQW5kTnVsbEFuZEVtcHR5VmFsdWVzID0gKG9iajogdW5rbm93bikgPT4ge1xuICBpZiAoIV8uaXNPYmplY3Qob2JqKSkgcmV0dXJuIG9iajtcbiAgcmV0dXJuIF8ucGlja0J5KG9iaiwgaXNEZWZpbmVkQW5kTm90TnVsbEFuZE5vdEVtcHR5KTtcbn07XG5cbi8qKlxuICogVGhlIGZsYXR0ZW5NYXAgZnVuY3Rpb24gdGFrZXMgYSBjb2xsZWN0aW9uIGFzIGlucHV0IGFuZCByZXR1cm5zIGEgZmxhdHRlbmVkIHZlcnNpb24gb2YgdGhlIGNvbGxlY3Rpb24uIElmIHRoZSBpbnB1dCBpcyBub3QgYW4gYXJyYXkgb3IgYW4gb2JqZWN0LCBpdCBpcyByZXR1cm5lZCBhcyBpcy4gT3RoZXJ3aXNlLCB0aGUgZnVuY3Rpb24gdXNlcyB0aGUgZmxhdE1hcCBmdW5jdGlvbiBmcm9tIHRoZSBsb2Rhc2ggbGlicmFyeSB0byBmbGF0dGVuIHRoZSBjb2xsZWN0aW9uLlxuICogQHBhcmFtIGNvbGxlY3Rpb25cbiAqIEByZXR1cm5zXG4gKi9cbmV4cG9ydCBjb25zdCBmbGF0dGVuTWFwID0gKGNvbGxlY3Rpb246IHVua25vd24pID0+IHtcbiAgaWYgKCFfLmlzQXJyYXkoY29sbGVjdGlvbikgJiYgIV8uaXNPYmplY3QoY29sbGVjdGlvbikpIHJldHVybiBjb2xsZWN0aW9uO1xuICByZXR1cm4gXy5mbGF0TWFwKGNvbGxlY3Rpb24sICh4KSA9PiB4KTtcbn07XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gR0VORVJJQyBVVExJVFlcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG5leHBvcnQgY29uc3QgZ2V0RXZlbnRUaW1lID0gKG1lc3NhZ2U6IFJ1ZGRlclN0YWNrRXZlbnQpID0+IHtcbiAgaWYgKCFtZXNzYWdlLnRpbWVzdGFtcCAmJiAhbWVzc2FnZS5vcmlnaW5hbFRpbWVzdGFtcClcbiAgICB0aHJvdyBuZXcgSW5zdHJ1bWVudGF0aW9uRXJyb3IoJ0V2ZW50IGRvZXMgbm90IGhhdmUgdGltZXN0YW1wIG9yIG9yaWdpbmFsVGltZXN0YW1wJyk7XG4gIHRyeSB7XG4gICAgaWYgKG1lc3NhZ2UudGltZXN0YW1wKSByZXR1cm4gbmV3IERhdGUobWVzc2FnZS50aW1lc3RhbXApO1xuICB9IGNhdGNoIChlKSB7XG4gICAgbG9nZ2VyLmVycm9yKCdFcnJvciBpbiBwYXJzaW5nIHRpbWVzdGFtcCcsIGUpO1xuICB9XG4gIHJldHVybiBuZXcgRGF0ZShtZXNzYWdlLm9yaWdpbmFsVGltZXN0YW1wKTtcbn07XG5cbmV4cG9ydCBjb25zdCBiYXNlNjRDb252ZXJ0b3IgPSAoc3RyaW5nOiBzdHJpbmcpID0+IEJ1ZmZlci5mcm9tKHN0cmluZykudG9TdHJpbmcoJ2Jhc2U2NCcpO1xuXG4vLyByZXR1cm4gYSB2YWxpZCBVUkwgb2JqZWN0IGlmIGNvcnJlY3QgZWxzZSBudWxsXG5leHBvcnQgY29uc3QgaXNWYWxpZFVybCA9ICh1cmw6IHN0cmluZyB8IFVSTCkgPT4ge1xuICB0cnkge1xuICAgIHJldHVybiBuZXcgVVJMKHVybCk7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIHJldHVybiBudWxsO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3Qgc3RyaXBUcmFpbGluZ1NsYXNoID0gKHN0cjogc3RyaW5nKSA9PlxuICBzdHIgJiYgc3RyLmVuZHNXaXRoKCcvJykgPyBzdHIuc2xpY2UoMCwgLTEpIDogc3RyO1xuXG5leHBvcnQgY29uc3QgaXNQcmltaXRpdmUgPSAoYXJnOiB1bmtub3duKSA9PiB7XG4gIGNvbnN0IHR5cGUgPSB0eXBlb2YgYXJnO1xuICByZXR1cm4gYXJnID09IG51bGwgfHwgKHR5cGUgIT09ICdvYmplY3QnICYmIHR5cGUgIT09ICdmdW5jdGlvbicpO1xufTtcblxuLyoqXG4gKlxuICogQHBhcmFtIHsqfSBhcmdcbiAqIEByZXR1cm5zIHt0eXBlfVxuICpcbiAqIFJldHVybnMgdHlwZSBvZiBwYXNzZWQgYXJnXG4gKiBmb3IgbnVsbCBhcmdzcyByZXR1cm5zIFwiTlVMTFwiIGluc3RlZCBvZiBcIm9iamVjdFwiXG4gKlxuICovXG5leHBvcnQgY29uc3QgZ2V0VHlwZSA9IChhcmc6IHVua25vd24pID0+IHtcbiAgY29uc3QgdHlwZSA9IHR5cGVvZiBhcmc7XG4gIGlmIChhcmcgPT0gbnVsbCkge1xuICAgIHJldHVybiAnTlVMTCc7XG4gIH1cbiAgaWYgKEFycmF5LmlzQXJyYXkoYXJnKSkge1xuICAgIHJldHVybiAnYXJyYXknO1xuICB9XG4gIHJldHVybiB0eXBlO1xufTtcblxuZXhwb3J0IGNvbnN0IGlzT2JqZWN0ID0gKHZhbHVlOiB1bmtub3duKSA9PiB7XG4gIGNvbnN0IHR5cGUgPSB0eXBlb2YgdmFsdWU7XG4gIHJldHVybiB2YWx1ZSAhPSBudWxsICYmICh0eXBlID09PSAnb2JqZWN0JyB8fCB0eXBlID09PSAnZnVuY3Rpb24nKSAmJiAhQXJyYXkuaXNBcnJheSh2YWx1ZSk7XG59O1xuXG5leHBvcnQgY29uc3QgaXNFbXB0eSA9IChpbnB1dDogdW5rbm93bikgPT4ge1xuICByZXR1cm4gXy5pc0VtcHR5KF8udG9TdHJpbmcoaW5wdXQpLnRyaW0oKSk7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSBmb3IgZW1wdHkgb2JqZWN0IHt9XG4gKiBAcGFyYW0geyp9IG9ialxuICogQHJldHVybnNcbiAqL1xuZXhwb3J0IGNvbnN0IGlzRW1wdHlPYmplY3QgPSAob2JqOiBhbnkpID0+IHtcbiAgaWYgKCFvYmopIHtcbiAgICBsb2dnZXIud2FybignaW5wdXQgaXMgdW5kZWZpbmVkIG9yIG51bGwnKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICByZXR1cm4gT2JqZWN0LmtleXMob2JqKS5sZW5ndGggPT09IDA7XG59O1xuXG4vKipcbiAqIEZ1bmN0aW9uIHRvIGNoZWNrIGlmIHZhbHVlIGlzIERlZmluZWQsIE5vdCBudWxsIGFuZCBOb3QgRW1wdHkuXG4gKiBDcmVhdGUgdGhpcyBmdW5jdGlvbiwgQmVjYXVzZSBleGlzdGluZyBpc0RlZmluZWRBbmROb3ROdWxsQW5kTm90RW1wdHkoMTIzKSBpcyByZXR1cm5pbmcgZmFsc2UgZHVlIHRvIGxvZGFzaCBfLmlzRW1wdHkgZnVuY3Rpb24uXG4gKiBfLmlzRW1wdHkgaXMgdXNlZCB0byBkZXRlY3QgZW1wdHkgY29sbGVjdGlvbnMvb2JqZWN0cyBhbmQgaXQgd2lsbCByZXR1cm4gdHJ1ZSBmb3IgSW50ZWdlciwgQm9vbGVhbiB2YWx1ZXMuXG4gKiByZWY6IGh0dHBzOi8vZ2l0aHViLmNvbS9sb2Rhc2gvbG9kYXNoL2lzc3Vlcy80OTZcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgMTIzXG4gKiBAcmV0dXJucyB5ZXNcbiAqL1xuZXhwb3J0IGNvbnN0IGlzRGVmaW5lZE5vdE51bGxOb3RFbXB0eSA9ICh2YWx1ZTogdW5rbm93bikgPT5cbiAgIShcbiAgICB2YWx1ZSA9PT0gdW5kZWZpbmVkIHx8XG4gICAgdmFsdWUgPT09IG51bGwgfHxcbiAgICBOdW1iZXIuaXNOYU4odmFsdWUpIHx8XG4gICAgKHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgT2JqZWN0LmtleXModmFsdWUpLmxlbmd0aCA9PT0gMCkgfHxcbiAgICAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyAmJiB2YWx1ZS50cmltKCkubGVuZ3RoID09PSAwKVxuICApO1xuXG5leHBvcnQgY29uc3QgcmVtb3ZlVW5kZWZpbmVkTnVsbEVtcHR5RXhjbEJvb2xJbnQgPSAob2JqOiB1bmtub3duKSA9PiB7XG4gIGlmICghXy5pc09iamVjdChvYmopKSByZXR1cm4gb2JqO1xuICByZXR1cm4gXy5waWNrQnkob2JqLCBpc0RlZmluZWROb3ROdWxsTm90RW1wdHkpO1xufTtcblxuLy8gRm9ybWF0IHRoZSBkZXN0aW5hdGlvbi5Db25maWcuZHluYW1pY01hcCBhcnJheXMgdG8gaGFzaE1hcFxuZXhwb3J0IGNvbnN0IGdldEhhc2hGcm9tQXJyYXkgPSAoYXJyYXlzLCBmcm9tS2V5ID0gJ2Zyb20nLCB0b0tleSA9ICd0bycsIGlzTG93ZXJDYXNlID0gdHJ1ZSkgPT4ge1xuICBjb25zdCBoYXNoTWFwID0ge307XG4gIGlmIChBcnJheS5pc0FycmF5KGFycmF5cykpIHtcbiAgICBhcnJheXMuZm9yRWFjaCgoYXJyYXkpID0+IHtcbiAgICAgIGlmIChpc0VtcHR5KGFycmF5W2Zyb21LZXldKSkgcmV0dXJuO1xuICAgICAgaGFzaE1hcFtpc0xvd2VyQ2FzZSA/IGFycmF5W2Zyb21LZXldLnRvU3RyaW5nKCkudG9Mb3dlckNhc2UoKSA6IGFycmF5W2Zyb21LZXldXSA9XG4gICAgICAgIGFycmF5W3RvS2V5XTtcbiAgICB9KTtcbiAgfVxuICByZXR1cm4gaGFzaE1hcDtcbn07XG5cbi8qKlxuICogRm9ybWF0IHRoZSBkZXN0aW5hdGlvbi5Db25maWcuZHluYW1pY01hcCBhcnJheXMgdG8gaGFzaE1hcFxuICogd2hlcmUgdmFsdWUgaXMgYW4gYXJyYXlcbiAqIEBwYXJhbSAge30gYXJyYXlzIFt7XCJmcm9tXCI6XCJwcm9wMVwiLFwidG9cIjpcInZhbDFcIn0se1wiZnJvbVwiOlwicHJvcDFcIixcInRvXCI6XCJ2YWwyXCJ9LHtcImZyb21cIjpcInByb3AyXCIsXCJ0b1wiOlwidmFsMlwifV1cbiAqIEBwYXJhbSAge30gZnJvbUtleT1cImZyb21cIlxuICogQHBhcmFtICB7fSB0b0tleT1cInRvXCJcbiAqIEBwYXJhbSAge30gaXNMb3dlckNhc2U9dHJ1ZVxuICogQHBhcmFtICB7fSByZXR1cm4gaGFzaG1hcCB7XCJwcm9wMVwiOltcInZhbDFcIixcInZhbDJcIl0sXCJwcm9wMlwiOltcInZhbDJcIl19XG4gKi9cbmV4cG9ydCBjb25zdCBnZXRIYXNoRnJvbUFycmF5V2l0aER1cGxpY2F0ZSA9IChcbiAgYXJyYXlzOiB7IGZyb206IHN0cmluZzsgdG86IHN0cmluZyB9W10sXG4gIGZyb21LZXkgPSAnZnJvbScsXG4gIHRvS2V5ID0gJ3RvJyxcbiAgaXNMb3dlckNhc2UgPSB0cnVlLFxuKSA9PiB7XG4gIGNvbnN0IGhhc2hNYXAgPSB7fTtcbiAgaWYgKEFycmF5LmlzQXJyYXkoYXJyYXlzKSkge1xuICAgIGFycmF5cy5mb3JFYWNoKChhcnJheSkgPT4ge1xuICAgICAgaWYgKGlzRW1wdHkoYXJyYXlbZnJvbUtleV0pKSByZXR1cm47XG4gICAgICBjb25zdCBrZXkgPSBpc0xvd2VyQ2FzZVxuICAgICAgICA/IGFycmF5W2Zyb21LZXldLnRvU3RyaW5nKCkudG9Mb3dlckNhc2UoKS50cmltKClcbiAgICAgICAgOiBhcnJheVtmcm9tS2V5XS50b1N0cmluZygpLnRyaW0oKTtcblxuICAgICAgaWYgKGhhc2hNYXBba2V5XSkge1xuICAgICAgICBoYXNoTWFwW2tleV0uYWRkKGFycmF5W3RvS2V5XSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBoYXNoTWFwW2tleV0gPSBuZXcgU2V0KCk7XG4gICAgICAgIGhhc2hNYXBba2V5XS5hZGQoYXJyYXlbdG9LZXldKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuICByZXR1cm4gaGFzaE1hcDtcbn07XG5cbi8qKlxuICogRm9ybWF0IHRoZSBhcnJheXMgdG8gaGFzaE1hcCB3aXRoIGtleSBhcyBgZnJvbUtleWAgYW5kIHZhbHVlIGFzIE9iamVjdFxuICogQHBhcmFtIHsqfSBhcnJheXMgW3tcImlkXCI6XCJhMGI4ZWZlMS1jODI4LTRjNjMtODg1MC0wZDA3NDI4ODhmOWRcIixcIm5hbWVcIjpcIkVtYWlsXCIsXCJ0eXBlXCI6XCJlbWFpbFwiLFwidHlwZV9jb25maWdcIjp7fSxcImRhdGVfY3JlYXRlZFwiOlwiMTY2MjIyNTg0MDI4NFwiLFwiaGlkZV9mcm9tX2d1ZXN0c1wiOmZhbHNlLFwicmVxdWlyZWRcIjpmYWxzZX1dXG4gKiBAcGFyYW0geyp9IGZyb21LZXkgbmFtZVxuICogQHBhcmFtIHsqfSBpc0xvd2VyQ2FzZSBmYWxzZVxuICogQHJldHVybnMgLy8ge1wiRW1haWxcIjp7XCJpZFwiOlwiYTBiOGVmZTEtYzgyOC00YzYzLTg4NTAtMGQwNzQyODg4ZjlkXCIsXCJuYW1lXCI6XCJFbWFpbFwiLFwidHlwZVwiOlwiZW1haWxcIixcInR5cGVfY29uZmlnXCI6e30sXCJkYXRlX2NyZWF0ZWRcIjpcIjE2NjIyMjU4NDAyODRcIixcImhpZGVfZnJvbV9ndWVzdHNcIjpmYWxzZSxcInJlcXVpcmVkXCI6ZmFsc2V9fVxuICovXG5leHBvcnQgY29uc3QgZ2V0SGFzaEZyb21BcnJheVdpdGhWYWx1ZUFzT2JqZWN0ID0gKGFycmF5cywgZnJvbUtleSA9ICdmcm9tJywgaXNMb3dlckNhc2UgPSB0cnVlKSA9PiB7XG4gIGNvbnN0IGhhc2hNYXAgPSB7fTtcbiAgaWYgKEFycmF5LmlzQXJyYXkoYXJyYXlzKSkge1xuICAgIGFycmF5cy5mb3JFYWNoKChhcnJheSkgPT4ge1xuICAgICAgaWYgKGlzRW1wdHkoYXJyYXlbZnJvbUtleV0pKSByZXR1cm47XG4gICAgICBoYXNoTWFwW2lzTG93ZXJDYXNlID8gYXJyYXlbZnJvbUtleV0udG9Mb3dlckNhc2UoKSA6IGFycmF5W2Zyb21LZXldXSA9IGFycmF5O1xuICAgIH0pO1xuICB9XG4gIHJldHVybiBoYXNoTWFwO1xufTtcblxuLyoqXG4gKiBSZXRyaWV2ZXMgYSB2YWx1ZSBmcm9tIGEgbWVzc2FnZSBvYmplY3QgYmFzZWQgb24gYSBnaXZlbiBrZXkuIEl0IHNlYXJjaGVzIGZvciB0aGUga2V5IGluIHRoZSBwcm9wZXJ0aWVzLCB0cmFpdHMsIGFuZCBjb250ZXh0LnRyYWl0cyBvZiB0aGUgbWVzc2FnZSBvYmplY3QgaW4gdGhhdCBvcmRlci5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyAtIFRoZSBvcHRpb25zIG9iamVjdC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zLm1lc3NhZ2UgLSBUaGUgbWVzc2FnZSBvYmplY3QgY29udGFpbmluZyBwcm9wZXJ0aWVzLCB0cmFpdHMsIGFuZCBjb250ZXh0LnRyYWl0cy5cbiAqIEBwYXJhbSB7c3RyaW5nfSBvcHRpb25zLmtleSAtIFRoZSBrZXkgdG8gc2VhcmNoIGZvciBpbiB0aGUgbWVzc2FnZSBvYmplY3QuXG4gKiBAcmV0dXJucyB7Kn0gVGhlIHZhbHVlIGZvdW5kIGluIHRoZSBtZXNzYWdlIG9iamVjdCBmb3IgdGhlIGdpdmVuIGtleSwgb3IgbnVsbCBpZiB0aGUga2V5IGlzIG5vdCBmb3VuZCBvciB0aGUgdmFsdWUgaXMgbnVsbC5cbiAqL1xuZXhwb3J0IGNvbnN0IGdldFZhbHVlRnJvbVByb3BlcnRpZXNPclRyYWl0cyA9ICh7IG1lc3NhZ2UsIGtleSB9KSA9PiB7XG4gIGNvbnN0IGtleVNldCA9IFsncHJvcGVydGllcycsICd0cmFpdHMnLCAnY29udGV4dC50cmFpdHMnXTtcblxuICBjb25zdCB2YWwgPSBfLmZpbmQoXG4gICAgXy5tYXAoa2V5U2V0LCAoaykgPT4gZ2V0KG1lc3NhZ2UsIGAke2t9LiR7a2V5fWApKSxcbiAgICAodikgPT4gIV8uaXNOaWwodiksXG4gICk7XG4gIHJldHVybiAhXy5pc05pbCh2YWwpID8gdmFsIDogbnVsbDtcbn07XG5cbi8qKlxuICogRmxhdHRlbnMgYSBKU09OIG9iamVjdCBpbnRvIGEgc2luZ2xlLWxldmVsIG9iamVjdC5cbiAqXG4gKiBAcGFyYW0gZGF0YSAtIFRoZSBKU09OIG9iamVjdCB0byBiZSBmbGF0dGVuZWQuXG4gKiBAcGFyYW0gc2VwYXJhdG9yIC0gVGhlIGNoYXJhY3RlciB1c2VkIHRvIHNlcGFyYXRlIHRoZSBrZXlzIGluIHRoZSBmbGF0dGVuZWQgb2JqZWN0LiBEZWZhdWx0IGlzICcuJy5cbiAqIEBwYXJhbSBtb2RlIC0gVGhlIG1vZGUgdXNlZCB0byBmbGF0dGVuIGFycmF5cy4gSWYgc2V0IHRvICdzdHJpY3QnLCB0aGUgYXJyYXkgaW5kaWNlcyB3aWxsIGJlIGluY2x1ZGVkIGluIHRoZSBmbGF0dGVuZWQga2V5cy4gRGVmYXVsdCBpcyAnbm9ybWFsJy5cbiAqIEByZXR1cm5zIFRoZSBmbGF0dGVuZWQgSlNPTiBvYmplY3QuXG4gKi9cbmV4cG9ydCBjb25zdCBmbGF0dGVuSnNvbiA9IChkYXRhOiB1bmtub3duLCBzZXBhcmF0b3IgPSAnLicsIG1vZGUgPSAnbm9ybWFsJykgPT4ge1xuICBjb25zdCByZXN1bHQgPSB7fTtcblxuICAvLyBhIHJlY3Vyc2l2ZSBmdW5jdGlvbiB0byBsb29wIHRocm91Z2ggdGhlIGFycmF5IG9mIHRoZSBkYXRhXG4gIGNvbnN0IHJlY3Vyc2UgPSAoY3VyLCBwcm9wKSA9PiB7XG4gICAgbGV0IGk7XG4gICAgaWYgKE9iamVjdChjdXIpICE9PSBjdXIpIHtcbiAgICAgIHJlc3VsdFtwcm9wXSA9IGN1cjtcbiAgICB9IGVsc2UgaWYgKEFycmF5LmlzQXJyYXkoY3VyKSkge1xuICAgICAgZm9yIChpID0gMDsgaSA8IGN1ci5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICBpZiAobW9kZSA9PT0gJ3N0cmljdCcpIHtcbiAgICAgICAgICByZWN1cnNlKGN1cltpXSwgYCR7cHJvcH0ke3NlcGFyYXRvcn0ke2l9YCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVjdXJzZShjdXJbaV0sIGAke3Byb3B9WyR7aX1dYCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChjdXIubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJlc3VsdFtwcm9wXSA9IFtdO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBsZXQgaXNFbXB0eUZsYWcgPSB0cnVlO1xuICAgICAgT2JqZWN0LmtleXMoY3VyKS5mb3JFYWNoKChrZXkpID0+IHtcbiAgICAgICAgaXNFbXB0eUZsYWcgPSBmYWxzZTtcbiAgICAgICAgcmVjdXJzZShjdXJba2V5XSwgcHJvcCA/IGAke3Byb3B9JHtzZXBhcmF0b3J9JHtrZXl9YCA6IGtleSk7XG4gICAgICB9KTtcbiAgICAgIGlmIChpc0VtcHR5RmxhZyAmJiBwcm9wKSByZXN1bHRbcHJvcF0gPSB7fTtcbiAgICB9XG4gIH07XG5cbiAgcmVjdXJzZShkYXRhLCAnJyk7XG4gIHJldHVybiByZXN1bHQ7XG59O1xuXG4vKipcbiAqIEdldCB0aGUgb2Zmc2V0IHZhbHVlIGluIHNlY29uZHMgZm9yIGEgZ2l2ZW4gdGltZXpvbmUuXG4gKlxuICogQHBhcmFtIHZhbHVlIC0gVGhlIHRpbWV6b25lIHZhbHVlIGZvciB3aGljaCB0aGUgb2Zmc2V0IG5lZWRzIHRvIGJlIGNhbGN1bGF0ZWQuXG4gKiBAcmV0dXJucyBUaGUgb2Zmc2V0IHZhbHVlIGluIHNlY29uZHMgZm9yIHRoZSBnaXZlbiB0aW1lem9uZS4gSWYgdGhlIHRpbWV6b25lIGlzIGludmFsaWQgb3Igbm90IGZvdW5kLCBpdCByZXR1cm5zIGB1bmRlZmluZWRgLlxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBvZmZzZXQgPSBnZXRPZmZzZXRJblNlYygnQW1lcmljYS9OZXdfWW9yaycpO1xuICogY29uc29sZS5sb2cob2Zmc2V0KTsgLy8gT3V0cHV0OiAtMTgwMDBcbiAqL1xuZXhwb3J0IGNvbnN0IGdldE9mZnNldEluU2VjID0gKHZhbHVlOiBzdHJpbmcpID0+IHtcbiAgY29uc3QgbmFtZSA9IG1vbWVudC50ei56b25lKHZhbHVlKTtcbiAgaWYgKG5hbWUpIHtcbiAgICBjb25zdCB4ID0gbW9tZW50KCkudHoodmFsdWUpLmZvcm1hdCgnWicpO1xuICAgIGNvbnN0IHNwbGl0ID0geC5zcGxpdCgnOicpO1xuICAgIGNvbnN0IGhvdXIgPSBOdW1iZXIoc3BsaXRbMF0pO1xuICAgIGNvbnN0IG1pbiA9IE51bWJlcihzcGxpdFsxXSk7XG4gICAgbGV0IHNlYyA9IDA7XG4gICAgc2VjID0gaG91ciA8IDAgPyAtMSAqIChob3VyICogLTYwICogNjAgKyBtaW4gKiA2MCkgOiBob3VyICogNjAgKiA2MCArIG1pbiAqIDYwO1xuICAgIHJldHVybiBzZWM7XG4gIH1cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn07XG5cbi8qKlxuICogQ29udmVydHMgYSBkYXRlIHN0cmluZyBpbnRvIGEgZm9ybWF0dGVkIHRpbWVzdGFtcC5cbiAqIElmIGEgZm9ybWF0IHN0cmluZyBpcyBwcm92aWRlZCwgaXQgdXNlcyB0aGUgbW9tZW50IGxpYnJhcnkgdG8gZm9ybWF0IHRoZSBkYXRlLlxuICogSWYgbm8gZm9ybWF0IHN0cmluZyBpcyBwcm92aWRlZCwgaXQgcmV0dXJucyB0aGUgdGltZXN0YW1wIG9mIHRoZSBkYXRlLlxuICogQHBhcmFtIGRhdGVTdHIgLSBUaGUgZGF0ZSBzdHJpbmcgdG8gYmUgZm9ybWF0dGVkLlxuICogQHBhcmFtIGZvcm1hdCAtIChPcHRpb25hbCkgVGhlIGZvcm1hdCBzdHJpbmcgdG8gYmUgdXNlZCBmb3IgZm9ybWF0dGluZyB0aGUgZGF0ZS5cbiAqIEByZXR1cm5zIFRoZSBmb3JtYXR0ZWQgZGF0ZSBhcyBhIHN0cmluZyBpZiBhIGZvcm1hdCBzdHJpbmcgaXMgcHJvdmlkZWQsXG4gKiAgICAgICAgICBvdGhlcndpc2UgdGhlIHRpbWVzdGFtcCBvZiB0aGUgZGF0ZSBhcyBhIG51bWJlci5cbiAqL1xuZXhwb3J0IGNvbnN0IGZvcm1hdFRpbWVTdGFtcCA9IChkYXRlU3RyOiBzdHJpbmcsIGZvcm1hdD86IHN0cmluZykgPT4ge1xuICBjb25zdCBkYXRlID0gbmV3IERhdGUoZGF0ZVN0cik7XG4gIC8vIG1vbWVudCBmb3JtYXQgaXMgcGFzc2VkLiBmb3JtYXQgYWNjb3JkaW5nbHlcbiAgaWYgKGZvcm1hdCkge1xuICAgIHJldHVybiBtb21lbnQudXRjKGRhdGUpLmZvcm1hdChmb3JtYXQpO1xuICB9XG5cbiAgLy8gcmV0dXJuIGRlZmF1bHQgZm9ybWF0XG4gIHJldHVybiBkYXRlLmdldFRpbWUoKTtcbn07XG5cbmV4cG9ydCBjb25zdCBoYXNoVG9TaGEyNTYgPSAodmFsdWU6IHN0cmluZyB8IEJ1ZmZlciB8IG51bWJlcltdKSA9PiBzaGEyNTYodmFsdWUpO1xuXG4vKipcbiAqIEdlbmVyYXRlcyBhIFVuaXZlcnNhbGx5IFVuaXF1ZSBJZGVudGlmaWVyIChVVUlEKSB1c2luZyB0aGUgYGNyeXB0by5yYW5kb21VVUlEKClgIG1ldGhvZC5cbiAqIFRoZSBgZGlzYWJsZUVudHJvcHlDYWNoZWAgb3B0aW9uIGlzIHNldCB0byBgdHJ1ZWAgdG8gcHJldmVudCBjYWNoaW5nIG9mIGdlbmVyYXRlZCBVVUlEcy5cbiAqXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBBIHJhbmRvbWx5IGdlbmVyYXRlZCBVVUlELlxuICpcbiAqIEBzZWUge0BsaW5rIGh0dHBzOi8vbm9kZWpzLm9yZy9hcGkvY3J5cHRvLmh0bWwjY3J5cHRvcmFuZG9tdXVpZG9wdGlvbnM6fjp0ZXh0PW9wdGlvbnMlMjAlM0NPYmplY3QlM0UtLGRpc2FibGVFbnRyb3B5Q2FjaGUsLSUzQ2Jvb2xlYW4lM0UlMjBCeX1cbiAqL1xuZXhwb3J0IGNvbnN0IGdlbmVyYXRlVVVJRCA9ICgpOiBzdHJpbmcgPT4ge1xuICByZXR1cm4gY3J5cHRvLnJhbmRvbVVVSUQoeyBkaXNhYmxlRW50cm9weUNhY2hlOiB0cnVlIH0pO1xufTtcbiJdfQ==
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=misc.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"misc.test.d.ts","sourceRoot":"","sources":["../../src/utils/misc.test.ts"],"names":[],"mappings":""}