@mnaoumov/typescript-lib 0.0.0 → 1.0.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 (180) hide show
  1. package/@types/debug/package.json +4 -0
  2. package/LICENSE +21 -0
  3. package/README.md +7 -1
  4. package/dist/lib/cjs/@types/debug.d.cts +21 -0
  5. package/dist/lib/cjs/abort-controller.cjs +202 -0
  6. package/dist/lib/cjs/abort-controller.d.cts +135 -0
  7. package/dist/lib/cjs/aggregate-error.cjs +98 -0
  8. package/dist/lib/cjs/aggregate-error.d.cts +24 -0
  9. package/dist/lib/cjs/array-buffer.cjs +96 -0
  10. package/dist/lib/cjs/array-buffer.d.cts +16 -0
  11. package/dist/lib/cjs/array.cjs +134 -0
  12. package/dist/lib/cjs/array.d.cts +46 -0
  13. package/dist/lib/cjs/async-events.cjs +466 -0
  14. package/dist/lib/cjs/async-events.d.cts +456 -0
  15. package/dist/lib/cjs/async-operation-hook.cjs +113 -0
  16. package/dist/lib/cjs/async-operation-hook.d.cts +59 -0
  17. package/dist/lib/cjs/async.cjs +521 -0
  18. package/dist/lib/cjs/async.d.cts +414 -0
  19. package/dist/lib/cjs/beeper.cjs +126 -0
  20. package/dist/lib/cjs/beeper.d.cts +21 -0
  21. package/dist/lib/cjs/blob.cjs +160 -0
  22. package/dist/lib/cjs/blob.d.cts +59 -0
  23. package/dist/lib/cjs/bytes.cjs +114 -0
  24. package/dist/lib/cjs/bytes.d.cts +17 -0
  25. package/dist/lib/cjs/debug-controller.cjs +80 -0
  26. package/dist/lib/cjs/debug-controller.d.cts +87 -0
  27. package/dist/lib/cjs/debug.cjs +235 -0
  28. package/dist/lib/cjs/debug.d.cts +66 -0
  29. package/dist/lib/cjs/desktop-zip-extractor.cjs +215 -0
  30. package/dist/lib/cjs/desktop-zip-extractor.d.cts +95 -0
  31. package/dist/lib/cjs/disposable.cjs +414 -0
  32. package/dist/lib/cjs/disposable.d.cts +387 -0
  33. package/dist/lib/cjs/enum.cjs +100 -0
  34. package/dist/lib/cjs/enum.d.cts +24 -0
  35. package/dist/lib/cjs/error.cjs +297 -0
  36. package/dist/lib/cjs/error.d.cts +181 -0
  37. package/dist/lib/cjs/function.cjs +141 -0
  38. package/dist/lib/cjs/function.d.cts +128 -0
  39. package/dist/lib/cjs/html-element.cjs +341 -0
  40. package/dist/lib/cjs/html-element.d.cts +199 -0
  41. package/dist/lib/cjs/index.cjs +195 -0
  42. package/dist/lib/cjs/index.d.cts +33 -0
  43. package/dist/lib/cjs/jpeg-metadata.cjs +228 -0
  44. package/dist/lib/cjs/jpeg-metadata.d.cts +42 -0
  45. package/dist/lib/cjs/library.cjs +158 -0
  46. package/dist/lib/cjs/library.d.cts +96 -0
  47. package/dist/lib/cjs/object-utils.cjs +617 -0
  48. package/dist/lib/cjs/object-utils.d.cts +298 -0
  49. package/dist/lib/cjs/path.cjs +202 -0
  50. package/dist/lib/cjs/path.d.cts +154 -0
  51. package/dist/lib/cjs/reg-exp.cjs +254 -0
  52. package/dist/lib/cjs/reg-exp.d.cts +87 -0
  53. package/dist/lib/cjs/string.cjs +326 -0
  54. package/dist/lib/cjs/string.d.cts +361 -0
  55. package/dist/lib/cjs/transformers/date-transformer.cjs +129 -0
  56. package/dist/lib/cjs/transformers/date-transformer.d.cts +39 -0
  57. package/dist/lib/cjs/transformers/group-transformer.cjs +173 -0
  58. package/dist/lib/cjs/transformers/group-transformer.d.cts +70 -0
  59. package/dist/lib/cjs/transformers/index.cjs +123 -0
  60. package/dist/lib/cjs/transformers/index.d.cts +9 -0
  61. package/dist/lib/cjs/transformers/map-transformer.cjs +129 -0
  62. package/dist/lib/cjs/transformers/map-transformer.d.cts +41 -0
  63. package/dist/lib/cjs/transformers/set-transformer.cjs +129 -0
  64. package/dist/lib/cjs/transformers/set-transformer.d.cts +39 -0
  65. package/dist/lib/cjs/transformers/skip-private-property-transformer.cjs +127 -0
  66. package/dist/lib/cjs/transformers/skip-private-property-transformer.d.cts +36 -0
  67. package/dist/lib/cjs/transformers/transformer.cjs +170 -0
  68. package/dist/lib/cjs/transformers/transformer.d.cts +70 -0
  69. package/dist/lib/cjs/transformers/two-way-map-transformer.cjs +130 -0
  70. package/dist/lib/cjs/transformers/two-way-map-transformer.d.cts +42 -0
  71. package/dist/lib/cjs/transformers/typed-transformer.cjs +94 -0
  72. package/dist/lib/cjs/transformers/typed-transformer.d.cts +39 -0
  73. package/dist/lib/cjs/two-way-map.cjs +208 -0
  74. package/dist/lib/cjs/two-way-map.d.cts +101 -0
  75. package/dist/lib/cjs/type-guards.cjs +128 -0
  76. package/dist/lib/cjs/type-guards.d.cts +84 -0
  77. package/dist/lib/cjs/type.cjs +121 -0
  78. package/dist/lib/cjs/type.d.cts +122 -0
  79. package/dist/lib/cjs/typescript-lib-state.cjs +126 -0
  80. package/dist/lib/cjs/typescript-lib-state.d.cts +56 -0
  81. package/dist/lib/cjs/url.cjs +136 -0
  82. package/dist/lib/cjs/url.d.cts +74 -0
  83. package/dist/lib/cjs/value-provider.cjs +100 -0
  84. package/dist/lib/cjs/value-provider.d.cts +28 -0
  85. package/dist/lib/cjs/value-wrapper.cjs +144 -0
  86. package/dist/lib/cjs/value-wrapper.d.cts +47 -0
  87. package/dist/lib/esm/@types/debug.d.mts +21 -0
  88. package/dist/lib/esm/abort-controller.d.mts +135 -0
  89. package/dist/lib/esm/abort-controller.mjs +159 -0
  90. package/dist/lib/esm/aggregate-error.d.mts +24 -0
  91. package/dist/lib/esm/aggregate-error.mjs +60 -0
  92. package/dist/lib/esm/array-buffer.d.mts +16 -0
  93. package/dist/lib/esm/array-buffer.mjs +58 -0
  94. package/dist/lib/esm/array.d.mts +46 -0
  95. package/dist/lib/esm/array.mjs +93 -0
  96. package/dist/lib/esm/async-events.d.mts +456 -0
  97. package/dist/lib/esm/async-events.mjs +427 -0
  98. package/dist/lib/esm/async-operation-hook.d.mts +59 -0
  99. package/dist/lib/esm/async-operation-hook.mjs +71 -0
  100. package/dist/lib/esm/async.d.mts +414 -0
  101. package/dist/lib/esm/async.mjs +479 -0
  102. package/dist/lib/esm/beeper.d.mts +21 -0
  103. package/dist/lib/esm/beeper.mjs +88 -0
  104. package/dist/lib/esm/blob.d.mts +59 -0
  105. package/dist/lib/esm/blob.mjs +121 -0
  106. package/dist/lib/esm/bytes.d.mts +17 -0
  107. package/dist/lib/esm/bytes.mjs +76 -0
  108. package/dist/lib/esm/debug-controller.d.mts +87 -0
  109. package/dist/lib/esm/debug-controller.mjs +50 -0
  110. package/dist/lib/esm/debug.d.mts +66 -0
  111. package/dist/lib/esm/debug.mjs +185 -0
  112. package/dist/lib/esm/desktop-zip-extractor.d.mts +95 -0
  113. package/dist/lib/esm/desktop-zip-extractor.mjs +180 -0
  114. package/dist/lib/esm/disposable.d.mts +387 -0
  115. package/dist/lib/esm/disposable.mjs +360 -0
  116. package/dist/lib/esm/enum.d.mts +24 -0
  117. package/dist/lib/esm/enum.mjs +61 -0
  118. package/dist/lib/esm/error.d.mts +181 -0
  119. package/dist/lib/esm/error.mjs +248 -0
  120. package/dist/lib/esm/function.d.mts +128 -0
  121. package/dist/lib/esm/function.mjs +96 -0
  122. package/dist/lib/esm/html-element.d.mts +199 -0
  123. package/dist/lib/esm/html-element.mjs +291 -0
  124. package/dist/lib/esm/index.d.mts +33 -0
  125. package/dist/lib/esm/index.mjs +116 -0
  126. package/dist/lib/esm/jpeg-metadata.d.mts +42 -0
  127. package/dist/lib/esm/jpeg-metadata.mjs +189 -0
  128. package/dist/lib/esm/library.d.mts +96 -0
  129. package/dist/lib/esm/library.mjs +118 -0
  130. package/dist/lib/esm/object-utils.d.mts +298 -0
  131. package/dist/lib/esm/object-utils.mjs +567 -0
  132. package/dist/lib/esm/path.d.mts +154 -0
  133. package/dist/lib/esm/path.mjs +139 -0
  134. package/dist/lib/esm/reg-exp.d.mts +87 -0
  135. package/dist/lib/esm/reg-exp.mjs +213 -0
  136. package/dist/lib/esm/string.d.mts +361 -0
  137. package/dist/lib/esm/string.mjs +274 -0
  138. package/dist/lib/esm/transformers/date-transformer.d.mts +39 -0
  139. package/dist/lib/esm/transformers/date-transformer.mjs +91 -0
  140. package/dist/lib/esm/transformers/group-transformer.d.mts +70 -0
  141. package/dist/lib/esm/transformers/group-transformer.mjs +138 -0
  142. package/dist/lib/esm/transformers/index.d.mts +9 -0
  143. package/dist/lib/esm/transformers/index.mjs +68 -0
  144. package/dist/lib/esm/transformers/map-transformer.d.mts +41 -0
  145. package/dist/lib/esm/transformers/map-transformer.mjs +91 -0
  146. package/dist/lib/esm/transformers/set-transformer.d.mts +39 -0
  147. package/dist/lib/esm/transformers/set-transformer.mjs +91 -0
  148. package/dist/lib/esm/transformers/skip-private-property-transformer.d.mts +36 -0
  149. package/dist/lib/esm/transformers/skip-private-property-transformer.mjs +89 -0
  150. package/dist/lib/esm/transformers/transformer.d.mts +70 -0
  151. package/dist/lib/esm/transformers/transformer.mjs +132 -0
  152. package/dist/lib/esm/transformers/two-way-map-transformer.d.mts +42 -0
  153. package/dist/lib/esm/transformers/two-way-map-transformer.mjs +92 -0
  154. package/dist/lib/esm/transformers/typed-transformer.d.mts +39 -0
  155. package/dist/lib/esm/transformers/typed-transformer.mjs +56 -0
  156. package/dist/lib/esm/two-way-map.d.mts +101 -0
  157. package/dist/lib/esm/two-way-map.mjs +170 -0
  158. package/dist/lib/esm/type-guards.d.mts +84 -0
  159. package/dist/lib/esm/type-guards.mjs +85 -0
  160. package/dist/lib/esm/type.d.mts +122 -0
  161. package/dist/lib/esm/type.mjs +83 -0
  162. package/dist/lib/esm/typescript-lib-state.d.mts +56 -0
  163. package/dist/lib/esm/typescript-lib-state.mjs +84 -0
  164. package/dist/lib/esm/url.d.mts +74 -0
  165. package/dist/lib/esm/url.mjs +94 -0
  166. package/dist/lib/esm/value-provider.d.mts +28 -0
  167. package/dist/lib/esm/value-provider.mjs +62 -0
  168. package/dist/lib/esm/value-wrapper.d.mts +47 -0
  169. package/dist/lib/esm/value-wrapper.mjs +106 -0
  170. package/package.json +111 -13
  171. package/transformers/date-transformer/package.json +6 -0
  172. package/transformers/group-transformer/package.json +6 -0
  173. package/transformers/index/package.json +6 -0
  174. package/transformers/map-transformer/package.json +6 -0
  175. package/transformers/package.json +6 -0
  176. package/transformers/set-transformer/package.json +6 -0
  177. package/transformers/skip-private-property-transformer/package.json +6 -0
  178. package/transformers/transformer/package.json +6 -0
  179. package/transformers/two-way-map-transformer/package.json +6 -0
  180. package/transformers/typed-transformer/package.json +6 -0
@@ -0,0 +1,33 @@
1
+ /// <reference path="./library.d.mts" />
2
+ export * as 'abort-controller' from './abort-controller.mjs';
3
+ export * as 'aggregate-error' from './aggregate-error.mjs';
4
+ export * as 'array-buffer' from './array-buffer.mjs';
5
+ export * as 'array' from './array.mjs';
6
+ export * as 'async-events' from './async-events.mjs';
7
+ export * as 'async-operation-hook' from './async-operation-hook.mjs';
8
+ export * as 'async' from './async.mjs';
9
+ export * as 'beeper' from './beeper.mjs';
10
+ export * as 'blob' from './blob.mjs';
11
+ export * as 'bytes' from './bytes.mjs';
12
+ export * as 'debug-controller' from './debug-controller.mjs';
13
+ export * as 'debug' from './debug.mjs';
14
+ export * as 'desktop-zip-extractor' from './desktop-zip-extractor.mjs';
15
+ export * as 'disposable' from './disposable.mjs';
16
+ export * as 'enum' from './enum.mjs';
17
+ export * as 'error' from './error.mjs';
18
+ export * as 'function' from './function.mjs';
19
+ export * as 'html-element' from './html-element.mjs';
20
+ export * as 'jpeg-metadata' from './jpeg-metadata.mjs';
21
+ export * as 'library' from './library.mjs';
22
+ export * as 'object-utils' from './object-utils.mjs';
23
+ export * as 'path' from './path.mjs';
24
+ export * as 'reg-exp' from './reg-exp.mjs';
25
+ export * as 'string' from './string.mjs';
26
+ export * as 'transformers' from './transformers/index.mjs';
27
+ export * as 'two-way-map' from './two-way-map.mjs';
28
+ export * as 'type-guards' from './type-guards.mjs';
29
+ export * as 'type' from './type.mjs';
30
+ export * as 'typescript-lib-state' from './typescript-lib-state.mjs';
31
+ export * as 'url' from './url.mjs';
32
+ export * as 'value-provider' from './value-provider.mjs';
33
+ export * as 'value-wrapper' from './value-wrapper.mjs';
@@ -0,0 +1,116 @@
1
+ /*
2
+ THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
3
+ if you want to view the source, please visit the github repository of this plugin
4
+ */
5
+
6
+ (function () {
7
+ function ensureDisposeSymbols(symbolConstructor = Symbol) {
8
+ symbolConstructor.asyncDispose ??= symbolConstructor.for('Symbol.asyncDispose');
9
+ symbolConstructor.dispose ??= symbolConstructor.for('Symbol.dispose');
10
+ }
11
+
12
+ function ensureBrowserProcess() {
13
+ const browserProcess = {
14
+ browser: true,
15
+ cwd() {
16
+ return '/';
17
+ },
18
+ env: {},
19
+ platform: 'android'
20
+ };
21
+
22
+ // eslint-disable-next-line obsidianmd/no-global-this, unicorn/no-unnecessary-global-this -- Must stay `globalThis`-qualified: in the emitted banner a bare `process` is a free identifier, so reading it where the host has none throws a ReferenceError instead of yielding `undefined`. That is the very case this function exists to handle.
23
+ const existingProcess = globalThis.process;
24
+
25
+ if (!existingProcess) {
26
+ // eslint-disable-next-line obsidianmd/no-global-this -- Actively use globalThis.
27
+ globalThis.process = browserProcess;
28
+ return;
29
+ }
30
+
31
+ if (existingProcess.versions?.node) {
32
+ return;
33
+ }
34
+
35
+ const existingProcessRecord = existingProcess;
36
+
37
+ for (const [key, value] of Object.entries(browserProcess)) {
38
+ existingProcessRecord[key] ??= value;
39
+ }
40
+
41
+ existingProcessRecord['browser'] = true;
42
+ }
43
+
44
+ (function initEsm() {
45
+ ensureDisposeSymbols();
46
+ ensureBrowserProcess();
47
+ })();
48
+ })();
49
+
50
+ import * as abort_controller from "./abort-controller.mjs";
51
+ import * as aggregate_error from "./aggregate-error.mjs";
52
+ import * as array_buffer from "./array-buffer.mjs";
53
+ import * as array from "./array.mjs";
54
+ import * as async_events from "./async-events.mjs";
55
+ import * as async_operation_hook from "./async-operation-hook.mjs";
56
+ import * as async from "./async.mjs";
57
+ import * as beeper from "./beeper.mjs";
58
+ import * as blob from "./blob.mjs";
59
+ import * as bytes from "./bytes.mjs";
60
+ import * as debug_controller from "./debug-controller.mjs";
61
+ import * as debug from "./debug.mjs";
62
+ import * as desktop_zip_extractor from "./desktop-zip-extractor.mjs";
63
+ import * as disposable from "./disposable.mjs";
64
+ import * as enum2 from "./enum.mjs";
65
+ import * as error from "./error.mjs";
66
+ import * as function2 from "./function.mjs";
67
+ import * as html_element from "./html-element.mjs";
68
+ import * as jpeg_metadata from "./jpeg-metadata.mjs";
69
+ import * as library from "./library.mjs";
70
+ import * as object_utils from "./object-utils.mjs";
71
+ import * as path from "./path.mjs";
72
+ import * as reg_exp from "./reg-exp.mjs";
73
+ import * as string from "./string.mjs";
74
+ import * as transformers from "./transformers/index.mjs";
75
+ import * as two_way_map from "./two-way-map.mjs";
76
+ import * as type_guards from "./type-guards.mjs";
77
+ import * as type from "./type.mjs";
78
+ import * as typescript_lib_state from "./typescript-lib-state.mjs";
79
+ import * as url from "./url.mjs";
80
+ import * as value_provider from "./value-provider.mjs";
81
+ import * as value_wrapper from "./value-wrapper.mjs";
82
+ export {
83
+ abort_controller as "abort-controller",
84
+ aggregate_error as "aggregate-error",
85
+ array,
86
+ array_buffer as "array-buffer",
87
+ async,
88
+ async_events as "async-events",
89
+ async_operation_hook as "async-operation-hook",
90
+ beeper,
91
+ blob,
92
+ bytes,
93
+ debug,
94
+ debug_controller as "debug-controller",
95
+ desktop_zip_extractor as "desktop-zip-extractor",
96
+ disposable,
97
+ enum2 as enum,
98
+ error,
99
+ function2 as function,
100
+ html_element as "html-element",
101
+ jpeg_metadata as "jpeg-metadata",
102
+ library,
103
+ object_utils as "object-utils",
104
+ path,
105
+ reg_exp as "reg-exp",
106
+ string,
107
+ transformers,
108
+ two_way_map as "two-way-map",
109
+ type,
110
+ type_guards as "type-guards",
111
+ typescript_lib_state as "typescript-lib-state",
112
+ url,
113
+ value_provider as "value-provider",
114
+ value_wrapper as "value-wrapper"
115
+ };
116
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2luZGV4LnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKiBUSElTIElTIEEgR0VORVJBVEVEL0JVTkRMRUQgRklMRSBCWSBCVUlMRCBTQ1JJUFQgKi9cblxuZXhwb3J0ICogYXMgJ2Fib3J0LWNvbnRyb2xsZXInIGZyb20gJy4vYWJvcnQtY29udHJvbGxlci50cyc7XG5leHBvcnQgKiBhcyAnYWdncmVnYXRlLWVycm9yJyBmcm9tICcuL2FnZ3JlZ2F0ZS1lcnJvci50cyc7XG5leHBvcnQgKiBhcyAnYXJyYXktYnVmZmVyJyBmcm9tICcuL2FycmF5LWJ1ZmZlci50cyc7XG5leHBvcnQgKiBhcyAnYXJyYXknIGZyb20gJy4vYXJyYXkudHMnO1xuZXhwb3J0ICogYXMgJ2FzeW5jLWV2ZW50cycgZnJvbSAnLi9hc3luYy1ldmVudHMudHMnO1xuZXhwb3J0ICogYXMgJ2FzeW5jLW9wZXJhdGlvbi1ob29rJyBmcm9tICcuL2FzeW5jLW9wZXJhdGlvbi1ob29rLnRzJztcbmV4cG9ydCAqIGFzICdhc3luYycgZnJvbSAnLi9hc3luYy50cyc7XG5leHBvcnQgKiBhcyAnYmVlcGVyJyBmcm9tICcuL2JlZXBlci50cyc7XG5leHBvcnQgKiBhcyAnYmxvYicgZnJvbSAnLi9ibG9iLnRzJztcbmV4cG9ydCAqIGFzICdieXRlcycgZnJvbSAnLi9ieXRlcy50cyc7XG5leHBvcnQgKiBhcyAnZGVidWctY29udHJvbGxlcicgZnJvbSAnLi9kZWJ1Zy1jb250cm9sbGVyLnRzJztcbmV4cG9ydCAqIGFzICdkZWJ1ZycgZnJvbSAnLi9kZWJ1Zy50cyc7XG5leHBvcnQgKiBhcyAnZGVza3RvcC16aXAtZXh0cmFjdG9yJyBmcm9tICcuL2Rlc2t0b3AtemlwLWV4dHJhY3Rvci50cyc7XG5leHBvcnQgKiBhcyAnZGlzcG9zYWJsZScgZnJvbSAnLi9kaXNwb3NhYmxlLnRzJztcbmV4cG9ydCAqIGFzICdlbnVtJyBmcm9tICcuL2VudW0udHMnO1xuZXhwb3J0ICogYXMgJ2Vycm9yJyBmcm9tICcuL2Vycm9yLnRzJztcbmV4cG9ydCAqIGFzICdmdW5jdGlvbicgZnJvbSAnLi9mdW5jdGlvbi50cyc7XG5leHBvcnQgKiBhcyAnaHRtbC1lbGVtZW50JyBmcm9tICcuL2h0bWwtZWxlbWVudC50cyc7XG5leHBvcnQgKiBhcyAnanBlZy1tZXRhZGF0YScgZnJvbSAnLi9qcGVnLW1ldGFkYXRhLnRzJztcbmV4cG9ydCAqIGFzICdsaWJyYXJ5JyBmcm9tICcuL2xpYnJhcnkudHMnO1xuZXhwb3J0ICogYXMgJ29iamVjdC11dGlscycgZnJvbSAnLi9vYmplY3QtdXRpbHMudHMnO1xuZXhwb3J0ICogYXMgJ3BhdGgnIGZyb20gJy4vcGF0aC50cyc7XG5leHBvcnQgKiBhcyAncmVnLWV4cCcgZnJvbSAnLi9yZWctZXhwLnRzJztcbmV4cG9ydCAqIGFzICdzdHJpbmcnIGZyb20gJy4vc3RyaW5nLnRzJztcbmV4cG9ydCAqIGFzICd0cmFuc2Zvcm1lcnMnIGZyb20gJy4vdHJhbnNmb3JtZXJzL2luZGV4LnRzJztcbmV4cG9ydCAqIGFzICd0d28td2F5LW1hcCcgZnJvbSAnLi90d28td2F5LW1hcC50cyc7XG5leHBvcnQgKiBhcyAndHlwZS1ndWFyZHMnIGZyb20gJy4vdHlwZS1ndWFyZHMudHMnO1xuZXhwb3J0ICogYXMgJ3R5cGUnIGZyb20gJy4vdHlwZS50cyc7XG5leHBvcnQgKiBhcyAndHlwZXNjcmlwdC1saWItc3RhdGUnIGZyb20gJy4vdHlwZXNjcmlwdC1saWItc3RhdGUudHMnO1xuZXhwb3J0ICogYXMgJ3VybCcgZnJvbSAnLi91cmwudHMnO1xuZXhwb3J0ICogYXMgJ3ZhbHVlLXByb3ZpZGVyJyBmcm9tICcuL3ZhbHVlLXByb3ZpZGVyLnRzJztcbmV4cG9ydCAqIGFzICd2YWx1ZS13cmFwcGVyJyBmcm9tICcuL3ZhbHVlLXdyYXBwZXIudHMnO1xuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUVBLFlBQVlBLHNCQUF3QjtBQUNwQyxZQUFZQyxxQkFBdUI7QUFDbkMsWUFBWUMsa0JBQW9CO0FBQ2hDLFlBQVksV0FBYTtBQUN6QixZQUFZQyxrQkFBb0I7QUFDaEMsWUFBWUMsMEJBQTRCO0FBQ3hDLFlBQVksV0FBYTtBQUN6QixZQUFZLFlBQWM7QUFDMUIsWUFBWSxVQUFZO0FBQ3hCLFlBQVksV0FBYTtBQUN6QixZQUFZQyxzQkFBd0I7QUFDcEMsWUFBWSxXQUFhO0FBQ3pCLFlBQVlDLDJCQUE2QjtBQUN6QyxZQUFZLGdCQUFrQjtBQUM5QixZQUFZQyxXQUFZO0FBQ3hCLFlBQVksV0FBYTtBQUN6QixZQUFZQyxlQUFnQjtBQUM1QixZQUFZQyxrQkFBb0I7QUFDaEMsWUFBWUMsbUJBQXFCO0FBQ2pDLFlBQVksYUFBZTtBQUMzQixZQUFZQyxrQkFBb0I7QUFDaEMsWUFBWSxVQUFZO0FBQ3hCLFlBQVlDLGFBQWU7QUFDM0IsWUFBWSxZQUFjO0FBQzFCLFlBQVksa0JBQW9CO0FBQ2hDLFlBQVlDLGlCQUFtQjtBQUMvQixZQUFZQyxpQkFBbUI7QUFDL0IsWUFBWSxVQUFZO0FBQ3hCLFlBQVlDLDBCQUE0QjtBQUN4QyxZQUFZLFNBQVc7QUFDdkIsWUFBWUMsb0JBQXNCO0FBQ2xDLFlBQVlDLG1CQUFxQjsiLAogICJuYW1lcyI6IFsiYWJvcnQtY29udHJvbGxlciIsICJhZ2dyZWdhdGUtZXJyb3IiLCAiYXJyYXktYnVmZmVyIiwgImFzeW5jLWV2ZW50cyIsICJhc3luYy1vcGVyYXRpb24taG9vayIsICJkZWJ1Zy1jb250cm9sbGVyIiwgImRlc2t0b3AtemlwLWV4dHJhY3RvciIsICJlbnVtIiwgImZ1bmN0aW9uIiwgImh0bWwtZWxlbWVudCIsICJqcGVnLW1ldGFkYXRhIiwgIm9iamVjdC11dGlscyIsICJyZWctZXhwIiwgInR3by13YXktbWFwIiwgInR5cGUtZ3VhcmRzIiwgInR5cGVzY3JpcHQtbGliLXN0YXRlIiwgInZhbHVlLXByb3ZpZGVyIiwgInZhbHVlLXdyYXBwZXIiXQp9Cg==
@@ -0,0 +1,42 @@
1
+ /// <reference path="./library.d.mts" />
2
+ /**
3
+ * @file
4
+ *
5
+ * Reads and re-attaches a JPEG's metadata segments.
6
+ *
7
+ * Re-encoding an image through a canvas keeps only pixels: EXIF, GPS, XMP and the ICC profile are all
8
+ * dropped by construction, because the canvas holds decoded samples and nothing else. These helpers
9
+ * lift the metadata segments off the original bytes so they can be spliced back into the re-encoded
10
+ * JPEG.
11
+ */
12
+ /**
13
+ * Extracts the metadata segments of a JPEG.
14
+ *
15
+ * Returns each matching segment whole — marker, length and payload — so
16
+ * {@link injectJpegMetadataSegments} can splice it into another JPEG untouched. Only the segments that
17
+ * carry metadata are returned: the EXIF and XMP `APP1`s and the ICC profile `APP2`. `APP0` (JFIF) is
18
+ * deliberately left behind, because the re-encoded JPEG writes its own.
19
+ *
20
+ * Returns an empty array for anything that is not a JPEG, including a truncated or malformed one — a
21
+ * caller that cannot preserve metadata should carry on without it rather than fail.
22
+ *
23
+ * @param bytes - The bytes of the source image.
24
+ * @returns The metadata segments, in the order they appeared.
25
+ */
26
+ export declare function extractJpegMetadataSegments(bytes: Uint8Array): Uint8Array[];
27
+ /**
28
+ * Splices metadata segments into a JPEG.
29
+ *
30
+ * The segments go directly after the `SOI` and the re-encoded JPEG's own `APP0`, which is where a
31
+ * reader expects to find them.
32
+ *
33
+ * Every copied EXIF block has its orientation tag reset to upright. The canvas decode already applied
34
+ * the original orientation to the pixels, so carrying the tag across verbatim would rotate the image a
35
+ * second time — the one piece of metadata that is wrong to preserve as-is.
36
+ *
37
+ * @param jpegBytes - The bytes of the re-encoded JPEG.
38
+ * @param segments - The segments returned by {@link extractJpegMetadataSegments}.
39
+ * @returns The JPEG with the segments spliced in, or the input unchanged when there is nothing to add
40
+ * or the input is not a JPEG.
41
+ */
42
+ export declare function injectJpegMetadataSegments(jpegBytes: Uint8Array, segments: readonly Uint8Array[]): Uint8Array;
@@ -0,0 +1,189 @@
1
+ /*
2
+ THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
3
+ if you want to view the source, please visit the github repository of this plugin
4
+ */
5
+
6
+ (function () {
7
+ function ensureDisposeSymbols(symbolConstructor = Symbol) {
8
+ symbolConstructor.asyncDispose ??= symbolConstructor.for('Symbol.asyncDispose');
9
+ symbolConstructor.dispose ??= symbolConstructor.for('Symbol.dispose');
10
+ }
11
+
12
+ function ensureBrowserProcess() {
13
+ const browserProcess = {
14
+ browser: true,
15
+ cwd() {
16
+ return '/';
17
+ },
18
+ env: {},
19
+ platform: 'android'
20
+ };
21
+
22
+ // eslint-disable-next-line obsidianmd/no-global-this, unicorn/no-unnecessary-global-this -- Must stay `globalThis`-qualified: in the emitted banner a bare `process` is a free identifier, so reading it where the host has none throws a ReferenceError instead of yielding `undefined`. That is the very case this function exists to handle.
23
+ const existingProcess = globalThis.process;
24
+
25
+ if (!existingProcess) {
26
+ // eslint-disable-next-line obsidianmd/no-global-this -- Actively use globalThis.
27
+ globalThis.process = browserProcess;
28
+ return;
29
+ }
30
+
31
+ if (existingProcess.versions?.node) {
32
+ return;
33
+ }
34
+
35
+ const existingProcessRecord = existingProcess;
36
+
37
+ for (const [key, value] of Object.entries(browserProcess)) {
38
+ existingProcessRecord[key] ??= value;
39
+ }
40
+
41
+ existingProcessRecord['browser'] = true;
42
+ }
43
+
44
+ (function initEsm() {
45
+ ensureDisposeSymbols();
46
+ ensureBrowserProcess();
47
+ })();
48
+ })();
49
+
50
+ const APP0_MARKER = 224;
51
+ const APP1_MARKER = 225;
52
+ const APP2_MARKER = 226;
53
+ const EOI_MARKER = 217;
54
+ const MARKER_PREFIX = 255;
55
+ const SOI_MARKER = 216;
56
+ const SOS_MARKER = 218;
57
+ const EXIF_HEADER = "Exif\0\0";
58
+ const ICC_PROFILE_HEADER = "ICC_PROFILE\0";
59
+ const XMP_HEADER = "http://ns.adobe.com/xap/1.0/\0";
60
+ const SEGMENT_HEADER_SIZE = 4;
61
+ const SEGMENT_LENGTH_SIZE = 2;
62
+ const SOI_SIZE = 2;
63
+ const BIG_ENDIAN_TIFF_BYTE_ORDER = 19789;
64
+ const IFD_ENTRY_SIZE = 12;
65
+ const IFD_ENTRY_VALUE_OFFSET = 8;
66
+ const IFD_ENTRY_COUNT_SIZE = 2;
67
+ const LITTLE_ENDIAN_TIFF_BYTE_ORDER = 18761;
68
+ const ORIENTATION_TAG = 274;
69
+ const ORIENTATION_UPRIGHT = 1;
70
+ const TIFF_HEADER_SIZE = 8;
71
+ const TIFF_IFD_POINTER_OFFSET = 4;
72
+ const TIFF_MAGIC = 42;
73
+ const TIFF_MAGIC_OFFSET = 2;
74
+ function extractJpegMetadataSegments(bytes) {
75
+ if (!checkIsJpeg(bytes)) {
76
+ return [];
77
+ }
78
+ const view = createView(bytes);
79
+ const segments = [];
80
+ let offset = SOI_SIZE;
81
+ while (offset + SEGMENT_HEADER_SIZE <= bytes.length) {
82
+ if (bytes[offset] !== MARKER_PREFIX) {
83
+ break;
84
+ }
85
+ const marker = bytes[offset + 1];
86
+ if (marker === SOS_MARKER || marker === EOI_MARKER) {
87
+ break;
88
+ }
89
+ const segmentLength = view.getUint16(offset + SEGMENT_LENGTH_SIZE);
90
+ const segmentEnd = offset + SEGMENT_LENGTH_SIZE + segmentLength;
91
+ if (segmentLength < SEGMENT_LENGTH_SIZE || segmentEnd > bytes.length) {
92
+ break;
93
+ }
94
+ if (checkIsMetadataSegment(bytes, offset, marker)) {
95
+ segments.push(bytes.slice(offset, segmentEnd));
96
+ }
97
+ offset = segmentEnd;
98
+ }
99
+ return segments;
100
+ }
101
+ function injectJpegMetadataSegments(jpegBytes, segments) {
102
+ if (segments.length === 0 || !checkIsJpeg(jpegBytes)) {
103
+ return jpegBytes;
104
+ }
105
+ const normalizedSegments = segments.map((segment) => normalizeOrientation(segment));
106
+ const insertAt = findInsertOffset(jpegBytes);
107
+ const addedLength = normalizedSegments.reduce((total, segment) => total + segment.length, 0);
108
+ const result = new Uint8Array(jpegBytes.length + addedLength);
109
+ result.set(jpegBytes.subarray(0, insertAt), 0);
110
+ let writeAt = insertAt;
111
+ for (const segment of normalizedSegments) {
112
+ result.set(segment, writeAt);
113
+ writeAt += segment.length;
114
+ }
115
+ result.set(jpegBytes.subarray(insertAt), writeAt);
116
+ return result;
117
+ }
118
+ function checkIsJpeg(bytes) {
119
+ return bytes.length >= SOI_SIZE && bytes[0] === MARKER_PREFIX && bytes[1] === SOI_MARKER;
120
+ }
121
+ function checkIsMetadataSegment(bytes, offset, marker) {
122
+ const payloadOffset = offset + SEGMENT_HEADER_SIZE;
123
+ return marker === APP1_MARKER ? checkMatchesHeader(bytes, payloadOffset, EXIF_HEADER) || checkMatchesHeader(bytes, payloadOffset, XMP_HEADER) : marker === APP2_MARKER && checkMatchesHeader(bytes, payloadOffset, ICC_PROFILE_HEADER);
124
+ }
125
+ function checkMatchesHeader(bytes, offset, header) {
126
+ if (offset + header.length > bytes.length) {
127
+ return false;
128
+ }
129
+ for (let index = 0; index < header.length; index++) {
130
+ if (bytes[offset + index] !== header.codePointAt(index)) {
131
+ return false;
132
+ }
133
+ }
134
+ return true;
135
+ }
136
+ function createView(bytes) {
137
+ return new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
138
+ }
139
+ function findInsertOffset(jpegBytes) {
140
+ if (SOI_SIZE + SEGMENT_HEADER_SIZE > jpegBytes.length) {
141
+ return SOI_SIZE;
142
+ }
143
+ if (jpegBytes[SOI_SIZE] !== MARKER_PREFIX || jpegBytes[SOI_SIZE + 1] !== APP0_MARKER) {
144
+ return SOI_SIZE;
145
+ }
146
+ const app0End = SOI_SIZE + SEGMENT_LENGTH_SIZE + createView(jpegBytes).getUint16(SOI_SIZE + SEGMENT_LENGTH_SIZE);
147
+ return app0End > jpegBytes.length ? SOI_SIZE : app0End;
148
+ }
149
+ function normalizeOrientation(segment) {
150
+ if (segment[1] !== APP1_MARKER || !checkMatchesHeader(segment, SEGMENT_HEADER_SIZE, EXIF_HEADER)) {
151
+ return segment;
152
+ }
153
+ const tiffOffset = SEGMENT_HEADER_SIZE + EXIF_HEADER.length;
154
+ if (tiffOffset + TIFF_HEADER_SIZE > segment.length) {
155
+ return segment;
156
+ }
157
+ const view = createView(segment);
158
+ const byteOrder = view.getUint16(tiffOffset);
159
+ const isLittleEndian = byteOrder === LITTLE_ENDIAN_TIFF_BYTE_ORDER;
160
+ if (!isLittleEndian && byteOrder !== BIG_ENDIAN_TIFF_BYTE_ORDER) {
161
+ return segment;
162
+ }
163
+ if (view.getUint16(tiffOffset + TIFF_MAGIC_OFFSET, isLittleEndian) !== TIFF_MAGIC) {
164
+ return segment;
165
+ }
166
+ const ifdOffset = tiffOffset + view.getUint32(tiffOffset + TIFF_IFD_POINTER_OFFSET, isLittleEndian);
167
+ if (ifdOffset + IFD_ENTRY_COUNT_SIZE > segment.length) {
168
+ return segment;
169
+ }
170
+ const entryCount = view.getUint16(ifdOffset, isLittleEndian);
171
+ const entriesOffset = ifdOffset + IFD_ENTRY_COUNT_SIZE;
172
+ if (entriesOffset + entryCount * IFD_ENTRY_SIZE > segment.length) {
173
+ return segment;
174
+ }
175
+ const result = new Uint8Array(segment);
176
+ const resultView = createView(result);
177
+ for (let index = 0; index < entryCount; index++) {
178
+ const entryOffset = entriesOffset + index * IFD_ENTRY_SIZE;
179
+ if (resultView.getUint16(entryOffset, isLittleEndian) === ORIENTATION_TAG) {
180
+ resultView.setUint16(entryOffset + IFD_ENTRY_VALUE_OFFSET, ORIENTATION_UPRIGHT, isLittleEndian);
181
+ }
182
+ }
183
+ return result;
184
+ }
185
+ export {
186
+ extractJpegMetadataSegments,
187
+ injectJpegMetadataSegments
188
+ };
189
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2pwZWctbWV0YWRhdGEudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBSZWFkcyBhbmQgcmUtYXR0YWNoZXMgYSBKUEVHJ3MgbWV0YWRhdGEgc2VnbWVudHMuXG4gKlxuICogUmUtZW5jb2RpbmcgYW4gaW1hZ2UgdGhyb3VnaCBhIGNhbnZhcyBrZWVwcyBvbmx5IHBpeGVsczogRVhJRiwgR1BTLCBYTVAgYW5kIHRoZSBJQ0MgcHJvZmlsZSBhcmUgYWxsXG4gKiBkcm9wcGVkIGJ5IGNvbnN0cnVjdGlvbiwgYmVjYXVzZSB0aGUgY2FudmFzIGhvbGRzIGRlY29kZWQgc2FtcGxlcyBhbmQgbm90aGluZyBlbHNlLiBUaGVzZSBoZWxwZXJzXG4gKiBsaWZ0IHRoZSBtZXRhZGF0YSBzZWdtZW50cyBvZmYgdGhlIG9yaWdpbmFsIGJ5dGVzIHNvIHRoZXkgY2FuIGJlIHNwbGljZWQgYmFjayBpbnRvIHRoZSByZS1lbmNvZGVkXG4gKiBKUEVHLlxuICovXG5cbmNvbnN0IEFQUDBfTUFSS0VSID0gMHhFMDtcbmNvbnN0IEFQUDFfTUFSS0VSID0gMHhFMTtcbmNvbnN0IEFQUDJfTUFSS0VSID0gMHhFMjtcbmNvbnN0IEVPSV9NQVJLRVIgPSAweEQ5O1xuY29uc3QgTUFSS0VSX1BSRUZJWCA9IDB4RkY7XG5jb25zdCBTT0lfTUFSS0VSID0gMHhEODtcbmNvbnN0IFNPU19NQVJLRVIgPSAweERBO1xuXG5jb25zdCBFWElGX0hFQURFUiA9ICdFeGlmXFwwXFwwJztcbmNvbnN0IElDQ19QUk9GSUxFX0hFQURFUiA9ICdJQ0NfUFJPRklMRVxcMCc7XG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgdW5pY29ybi9wcmVmZXItaHR0cHMgLS0gVGhlIGxpdGVyYWwgYnl0ZXMgQWRvYmUgd3JpdGVzIGludG8gdGhlIGBBUFAxYCBzZWdtZW50LiBJdCBpcyBhIG5hbWVzcGFjZSBpZGVudGlmaWVyLCBuZXZlciBmZXRjaGVkLCBhbmQgcmV3cml0aW5nIGl0IHRvIGBodHRwc2Agd291bGQgc3RvcCBYTVAgZnJvbSBldmVyIG1hdGNoaW5nLlxuY29uc3QgWE1QX0hFQURFUiA9ICdodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvXFwwJztcblxuLyoqXG4gKiBCeXRlcyBmcm9tIHRoZSBzdGFydCBvZiBhIHNlZ21lbnQgdG8gaXRzIHBheWxvYWQ6IHRoZSB0d28gbWFya2VyIGJ5dGVzIHBsdXMgdGhlIHR3byBsZW5ndGggYnl0ZXMuXG4gKi9cbmNvbnN0IFNFR01FTlRfSEVBREVSX1NJWkUgPSA0O1xuXG4vKipcbiAqIFRoZSBzZWdtZW50IGxlbmd0aCBmaWVsZCBpdHNlbGYgY291bnRzIHRoZSB0d28gYnl0ZXMgaXQgb2NjdXBpZXMuXG4gKi9cbmNvbnN0IFNFR01FTlRfTEVOR1RIX1NJWkUgPSAyO1xuXG4vKipcbiAqIFRoZSBgU09JYCBtYXJrZXIgdGhhdCBvcGVucyBldmVyeSBKUEVHLlxuICovXG5jb25zdCBTT0lfU0laRSA9IDI7XG5cbmNvbnN0IEJJR19FTkRJQU5fVElGRl9CWVRFX09SREVSID0gMHg0RF80RDtcbmNvbnN0IElGRF9FTlRSWV9TSVpFID0gMTI7XG4vKipcbiAqIEJ5dGVzIGZyb20gdGhlIHN0YXJ0IG9mIGFuIElGRCBlbnRyeSB0byBpdHMgaW5saW5lIHZhbHVlOiB0YWcgKDIpICsgdHlwZSAoMikgKyBjb3VudCAoNCkuXG4gKi9cbmNvbnN0IElGRF9FTlRSWV9WQUxVRV9PRkZTRVQgPSA4O1xuY29uc3QgSUZEX0VOVFJZX0NPVU5UX1NJWkUgPSAyO1xuY29uc3QgTElUVExFX0VORElBTl9USUZGX0JZVEVfT1JERVIgPSAweDQ5XzQ5O1xuY29uc3QgT1JJRU5UQVRJT05fVEFHID0gMHgwMV8xMjtcbmNvbnN0IE9SSUVOVEFUSU9OX1VQUklHSFQgPSAxO1xuY29uc3QgVElGRl9IRUFERVJfU0laRSA9IDg7XG5jb25zdCBUSUZGX0lGRF9QT0lOVEVSX09GRlNFVCA9IDQ7XG5jb25zdCBUSUZGX01BR0lDID0gMHgwMF8yQTtcbmNvbnN0IFRJRkZfTUFHSUNfT0ZGU0VUID0gMjtcblxuLyoqXG4gKiBFeHRyYWN0cyB0aGUgbWV0YWRhdGEgc2VnbWVudHMgb2YgYSBKUEVHLlxuICpcbiAqIFJldHVybnMgZWFjaCBtYXRjaGluZyBzZWdtZW50IHdob2xlIFx1MjAxNCBtYXJrZXIsIGxlbmd0aCBhbmQgcGF5bG9hZCBcdTIwMTQgc29cbiAqIHtAbGluayBpbmplY3RKcGVnTWV0YWRhdGFTZWdtZW50c30gY2FuIHNwbGljZSBpdCBpbnRvIGFub3RoZXIgSlBFRyB1bnRvdWNoZWQuIE9ubHkgdGhlIHNlZ21lbnRzIHRoYXRcbiAqIGNhcnJ5IG1ldGFkYXRhIGFyZSByZXR1cm5lZDogdGhlIEVYSUYgYW5kIFhNUCBgQVBQMWBzIGFuZCB0aGUgSUNDIHByb2ZpbGUgYEFQUDJgLiBgQVBQMGAgKEpGSUYpIGlzXG4gKiBkZWxpYmVyYXRlbHkgbGVmdCBiZWhpbmQsIGJlY2F1c2UgdGhlIHJlLWVuY29kZWQgSlBFRyB3cml0ZXMgaXRzIG93bi5cbiAqXG4gKiBSZXR1cm5zIGFuIGVtcHR5IGFycmF5IGZvciBhbnl0aGluZyB0aGF0IGlzIG5vdCBhIEpQRUcsIGluY2x1ZGluZyBhIHRydW5jYXRlZCBvciBtYWxmb3JtZWQgb25lIFx1MjAxNCBhXG4gKiBjYWxsZXIgdGhhdCBjYW5ub3QgcHJlc2VydmUgbWV0YWRhdGEgc2hvdWxkIGNhcnJ5IG9uIHdpdGhvdXQgaXQgcmF0aGVyIHRoYW4gZmFpbC5cbiAqXG4gKiBAcGFyYW0gYnl0ZXMgLSBUaGUgYnl0ZXMgb2YgdGhlIHNvdXJjZSBpbWFnZS5cbiAqIEByZXR1cm5zIFRoZSBtZXRhZGF0YSBzZWdtZW50cywgaW4gdGhlIG9yZGVyIHRoZXkgYXBwZWFyZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBleHRyYWN0SnBlZ01ldGFkYXRhU2VnbWVudHMoYnl0ZXM6IFVpbnQ4QXJyYXkpOiBVaW50OEFycmF5W10ge1xuICBpZiAoIWNoZWNrSXNKcGVnKGJ5dGVzKSkge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIGNvbnN0IHZpZXcgPSBjcmVhdGVWaWV3KGJ5dGVzKTtcbiAgY29uc3Qgc2VnbWVudHM6IFVpbnQ4QXJyYXlbXSA9IFtdO1xuICBsZXQgb2Zmc2V0ID0gU09JX1NJWkU7XG5cbiAgd2hpbGUgKG9mZnNldCArIFNFR01FTlRfSEVBREVSX1NJWkUgPD0gYnl0ZXMubGVuZ3RoKSB7XG4gICAgaWYgKGJ5dGVzW29mZnNldF0gIT09IE1BUktFUl9QUkVGSVgpIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIGNvbnN0IG1hcmtlciA9IGJ5dGVzW29mZnNldCArIDFdO1xuICAgIGlmIChtYXJrZXIgPT09IFNPU19NQVJLRVIgfHwgbWFya2VyID09PSBFT0lfTUFSS0VSKSB7XG4gICAgICBicmVhaztcbiAgICB9XG5cbiAgICBjb25zdCBzZWdtZW50TGVuZ3RoID0gdmlldy5nZXRVaW50MTYob2Zmc2V0ICsgU0VHTUVOVF9MRU5HVEhfU0laRSk7XG4gICAgY29uc3Qgc2VnbWVudEVuZCA9IG9mZnNldCArIFNFR01FTlRfTEVOR1RIX1NJWkUgKyBzZWdtZW50TGVuZ3RoO1xuICAgIGlmIChzZWdtZW50TGVuZ3RoIDwgU0VHTUVOVF9MRU5HVEhfU0laRSB8fCBzZWdtZW50RW5kID4gYnl0ZXMubGVuZ3RoKSB7XG4gICAgICBicmVhaztcbiAgICB9XG5cbiAgICBpZiAoY2hlY2tJc01ldGFkYXRhU2VnbWVudChieXRlcywgb2Zmc2V0LCBtYXJrZXIpKSB7XG4gICAgICBzZWdtZW50cy5wdXNoKGJ5dGVzLnNsaWNlKG9mZnNldCwgc2VnbWVudEVuZCkpO1xuICAgIH1cblxuICAgIG9mZnNldCA9IHNlZ21lbnRFbmQ7XG4gIH1cblxuICByZXR1cm4gc2VnbWVudHM7XG59XG5cbi8qKlxuICogU3BsaWNlcyBtZXRhZGF0YSBzZWdtZW50cyBpbnRvIGEgSlBFRy5cbiAqXG4gKiBUaGUgc2VnbWVudHMgZ28gZGlyZWN0bHkgYWZ0ZXIgdGhlIGBTT0lgIGFuZCB0aGUgcmUtZW5jb2RlZCBKUEVHJ3Mgb3duIGBBUFAwYCwgd2hpY2ggaXMgd2hlcmUgYVxuICogcmVhZGVyIGV4cGVjdHMgdG8gZmluZCB0aGVtLlxuICpcbiAqIEV2ZXJ5IGNvcGllZCBFWElGIGJsb2NrIGhhcyBpdHMgb3JpZW50YXRpb24gdGFnIHJlc2V0IHRvIHVwcmlnaHQuIFRoZSBjYW52YXMgZGVjb2RlIGFscmVhZHkgYXBwbGllZFxuICogdGhlIG9yaWdpbmFsIG9yaWVudGF0aW9uIHRvIHRoZSBwaXhlbHMsIHNvIGNhcnJ5aW5nIHRoZSB0YWcgYWNyb3NzIHZlcmJhdGltIHdvdWxkIHJvdGF0ZSB0aGUgaW1hZ2UgYVxuICogc2Vjb25kIHRpbWUgXHUyMDE0IHRoZSBvbmUgcGllY2Ugb2YgbWV0YWRhdGEgdGhhdCBpcyB3cm9uZyB0byBwcmVzZXJ2ZSBhcy1pcy5cbiAqXG4gKiBAcGFyYW0ganBlZ0J5dGVzIC0gVGhlIGJ5dGVzIG9mIHRoZSByZS1lbmNvZGVkIEpQRUcuXG4gKiBAcGFyYW0gc2VnbWVudHMgLSBUaGUgc2VnbWVudHMgcmV0dXJuZWQgYnkge0BsaW5rIGV4dHJhY3RKcGVnTWV0YWRhdGFTZWdtZW50c30uXG4gKiBAcmV0dXJucyBUaGUgSlBFRyB3aXRoIHRoZSBzZWdtZW50cyBzcGxpY2VkIGluLCBvciB0aGUgaW5wdXQgdW5jaGFuZ2VkIHdoZW4gdGhlcmUgaXMgbm90aGluZyB0byBhZGRcbiAqICAgb3IgdGhlIGlucHV0IGlzIG5vdCBhIEpQRUcuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbmplY3RKcGVnTWV0YWRhdGFTZWdtZW50cyhqcGVnQnl0ZXM6IFVpbnQ4QXJyYXksIHNlZ21lbnRzOiByZWFkb25seSBVaW50OEFycmF5W10pOiBVaW50OEFycmF5IHtcbiAgaWYgKHNlZ21lbnRzLmxlbmd0aCA9PT0gMCB8fCAhY2hlY2tJc0pwZWcoanBlZ0J5dGVzKSkge1xuICAgIHJldHVybiBqcGVnQnl0ZXM7XG4gIH1cblxuICBjb25zdCBub3JtYWxpemVkU2VnbWVudHMgPSBzZWdtZW50cy5tYXAoKHNlZ21lbnQpID0+IG5vcm1hbGl6ZU9yaWVudGF0aW9uKHNlZ21lbnQpKTtcbiAgY29uc3QgaW5zZXJ0QXQgPSBmaW5kSW5zZXJ0T2Zmc2V0KGpwZWdCeXRlcyk7XG4gIGNvbnN0IGFkZGVkTGVuZ3RoID0gbm9ybWFsaXplZFNlZ21lbnRzLnJlZHVjZSgodG90YWwsIHNlZ21lbnQpID0+IHRvdGFsICsgc2VnbWVudC5sZW5ndGgsIDApO1xuICBjb25zdCByZXN1bHQgPSBuZXcgVWludDhBcnJheShqcGVnQnl0ZXMubGVuZ3RoICsgYWRkZWRMZW5ndGgpO1xuXG4gIHJlc3VsdC5zZXQoanBlZ0J5dGVzLnN1YmFycmF5KDAsIGluc2VydEF0KSwgMCk7XG4gIGxldCB3cml0ZUF0ID0gaW5zZXJ0QXQ7XG4gIGZvciAoY29uc3Qgc2VnbWVudCBvZiBub3JtYWxpemVkU2VnbWVudHMpIHtcbiAgICByZXN1bHQuc2V0KHNlZ21lbnQsIHdyaXRlQXQpO1xuICAgIHdyaXRlQXQgKz0gc2VnbWVudC5sZW5ndGg7XG4gIH1cbiAgcmVzdWx0LnNldChqcGVnQnl0ZXMuc3ViYXJyYXkoaW5zZXJ0QXQpLCB3cml0ZUF0KTtcblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5mdW5jdGlvbiBjaGVja0lzSnBlZyhieXRlczogVWludDhBcnJheSk6IGJvb2xlYW4ge1xuICByZXR1cm4gYnl0ZXMubGVuZ3RoID49IFNPSV9TSVpFICYmIGJ5dGVzWzBdID09PSBNQVJLRVJfUFJFRklYICYmIGJ5dGVzWzFdID09PSBTT0lfTUFSS0VSO1xufVxuXG5mdW5jdGlvbiBjaGVja0lzTWV0YWRhdGFTZWdtZW50KGJ5dGVzOiBVaW50OEFycmF5LCBvZmZzZXQ6IG51bWJlciwgbWFya2VyOiBudW1iZXIgfCB1bmRlZmluZWQpOiBib29sZWFuIHtcbiAgY29uc3QgcGF5bG9hZE9mZnNldCA9IG9mZnNldCArIFNFR01FTlRfSEVBREVSX1NJWkU7XG4gIHJldHVybiBtYXJrZXIgPT09IEFQUDFfTUFSS0VSXG4gICAgPyBjaGVja01hdGNoZXNIZWFkZXIoYnl0ZXMsIHBheWxvYWRPZmZzZXQsIEVYSUZfSEVBREVSKSB8fCBjaGVja01hdGNoZXNIZWFkZXIoYnl0ZXMsIHBheWxvYWRPZmZzZXQsIFhNUF9IRUFERVIpXG4gICAgOiBtYXJrZXIgPT09IEFQUDJfTUFSS0VSICYmIGNoZWNrTWF0Y2hlc0hlYWRlcihieXRlcywgcGF5bG9hZE9mZnNldCwgSUNDX1BST0ZJTEVfSEVBREVSKTtcbn1cblxuZnVuY3Rpb24gY2hlY2tNYXRjaGVzSGVhZGVyKGJ5dGVzOiBVaW50OEFycmF5LCBvZmZzZXQ6IG51bWJlciwgaGVhZGVyOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgaWYgKG9mZnNldCArIGhlYWRlci5sZW5ndGggPiBieXRlcy5sZW5ndGgpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IGhlYWRlci5sZW5ndGg7IGluZGV4KyspIHtcbiAgICBpZiAoYnl0ZXNbb2Zmc2V0ICsgaW5kZXhdICE9PSBoZWFkZXIuY29kZVBvaW50QXQoaW5kZXgpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVWaWV3KGJ5dGVzOiBVaW50OEFycmF5KTogRGF0YVZpZXcge1xuICByZXR1cm4gbmV3IERhdGFWaWV3KGJ5dGVzLmJ1ZmZlciwgYnl0ZXMuYnl0ZU9mZnNldCwgYnl0ZXMuYnl0ZUxlbmd0aCk7XG59XG5cbmZ1bmN0aW9uIGZpbmRJbnNlcnRPZmZzZXQoanBlZ0J5dGVzOiBVaW50OEFycmF5KTogbnVtYmVyIHtcbiAgaWYgKFNPSV9TSVpFICsgU0VHTUVOVF9IRUFERVJfU0laRSA+IGpwZWdCeXRlcy5sZW5ndGgpIHtcbiAgICByZXR1cm4gU09JX1NJWkU7XG4gIH1cbiAgaWYgKGpwZWdCeXRlc1tTT0lfU0laRV0gIT09IE1BUktFUl9QUkVGSVggfHwganBlZ0J5dGVzW1NPSV9TSVpFICsgMV0gIT09IEFQUDBfTUFSS0VSKSB7XG4gICAgcmV0dXJuIFNPSV9TSVpFO1xuICB9XG5cbiAgY29uc3QgYXBwMEVuZCA9IFNPSV9TSVpFICsgU0VHTUVOVF9MRU5HVEhfU0laRSArIGNyZWF0ZVZpZXcoanBlZ0J5dGVzKS5nZXRVaW50MTYoU09JX1NJWkUgKyBTRUdNRU5UX0xFTkdUSF9TSVpFKTtcbiAgcmV0dXJuIGFwcDBFbmQgPiBqcGVnQnl0ZXMubGVuZ3RoID8gU09JX1NJWkUgOiBhcHAwRW5kO1xufVxuXG5mdW5jdGlvbiBub3JtYWxpemVPcmllbnRhdGlvbihzZWdtZW50OiBVaW50OEFycmF5KTogVWludDhBcnJheSB7XG4gIGlmIChzZWdtZW50WzFdICE9PSBBUFAxX01BUktFUiB8fCAhY2hlY2tNYXRjaGVzSGVhZGVyKHNlZ21lbnQsIFNFR01FTlRfSEVBREVSX1NJWkUsIEVYSUZfSEVBREVSKSkge1xuICAgIHJldHVybiBzZWdtZW50O1xuICB9XG5cbiAgY29uc3QgdGlmZk9mZnNldCA9IFNFR01FTlRfSEVBREVSX1NJWkUgKyBFWElGX0hFQURFUi5sZW5ndGg7XG4gIGlmICh0aWZmT2Zmc2V0ICsgVElGRl9IRUFERVJfU0laRSA+IHNlZ21lbnQubGVuZ3RoKSB7XG4gICAgcmV0dXJuIHNlZ21lbnQ7XG4gIH1cblxuICBjb25zdCB2aWV3ID0gY3JlYXRlVmlldyhzZWdtZW50KTtcbiAgY29uc3QgYnl0ZU9yZGVyID0gdmlldy5nZXRVaW50MTYodGlmZk9mZnNldCk7XG4gIGNvbnN0IGlzTGl0dGxlRW5kaWFuID0gYnl0ZU9yZGVyID09PSBMSVRUTEVfRU5ESUFOX1RJRkZfQllURV9PUkRFUjtcbiAgaWYgKCFpc0xpdHRsZUVuZGlhbiAmJiBieXRlT3JkZXIgIT09IEJJR19FTkRJQU5fVElGRl9CWVRFX09SREVSKSB7XG4gICAgcmV0dXJuIHNlZ21lbnQ7XG4gIH1cblxuICBpZiAodmlldy5nZXRVaW50MTYodGlmZk9mZnNldCArIFRJRkZfTUFHSUNfT0ZGU0VULCBpc0xpdHRsZUVuZGlhbikgIT09IFRJRkZfTUFHSUMpIHtcbiAgICByZXR1cm4gc2VnbWVudDtcbiAgfVxuXG4gIGNvbnN0IGlmZE9mZnNldCA9IHRpZmZPZmZzZXQgKyB2aWV3LmdldFVpbnQzMih0aWZmT2Zmc2V0ICsgVElGRl9JRkRfUE9JTlRFUl9PRkZTRVQsIGlzTGl0dGxlRW5kaWFuKTtcbiAgaWYgKGlmZE9mZnNldCArIElGRF9FTlRSWV9DT1VOVF9TSVpFID4gc2VnbWVudC5sZW5ndGgpIHtcbiAgICByZXR1cm4gc2VnbWVudDtcbiAgfVxuXG4gIGNvbnN0IGVudHJ5Q291bnQgPSB2aWV3LmdldFVpbnQxNihpZmRPZmZzZXQsIGlzTGl0dGxlRW5kaWFuKTtcbiAgY29uc3QgZW50cmllc09mZnNldCA9IGlmZE9mZnNldCArIElGRF9FTlRSWV9DT1VOVF9TSVpFO1xuICBpZiAoZW50cmllc09mZnNldCArIGVudHJ5Q291bnQgKiBJRkRfRU5UUllfU0laRSA+IHNlZ21lbnQubGVuZ3RoKSB7XG4gICAgcmV0dXJuIHNlZ21lbnQ7XG4gIH1cblxuICBjb25zdCByZXN1bHQgPSBuZXcgVWludDhBcnJheShzZWdtZW50KTtcbiAgY29uc3QgcmVzdWx0VmlldyA9IGNyZWF0ZVZpZXcocmVzdWx0KTtcbiAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IGVudHJ5Q291bnQ7IGluZGV4KyspIHtcbiAgICBjb25zdCBlbnRyeU9mZnNldCA9IGVudHJpZXNPZmZzZXQgKyBpbmRleCAqIElGRF9FTlRSWV9TSVpFO1xuICAgIGlmIChyZXN1bHRWaWV3LmdldFVpbnQxNihlbnRyeU9mZnNldCwgaXNMaXR0bGVFbmRpYW4pID09PSBPUklFTlRBVElPTl9UQUcpIHtcbiAgICAgIHJlc3VsdFZpZXcuc2V0VWludDE2KGVudHJ5T2Zmc2V0ICsgSUZEX0VOVFJZX1ZBTFVFX09GRlNFVCwgT1JJRU5UQVRJT05fVVBSSUdIVCwgaXNMaXR0bGVFbmRpYW4pO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG4iXSwKICAibWFwcGlu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
@@ -0,0 +1,96 @@
1
+ /// <reference lib="dom" />
2
+ /// <reference lib="dom.iterable" />
3
+ /// <reference lib="es2022" />
4
+ /// <reference lib="esnext.disposable" />
5
+ /// <reference types="node" />
6
+ /**
7
+ * @file
8
+ *
9
+ * Helpers for working with the `@mnaoumov/typescript-lib` library.
10
+ */
11
+ /**
12
+ * A name of the `@mnaoumov/typescript-lib` library.
13
+ */
14
+ export declare const LIBRARY_NAME = "@mnaoumov/typescript-lib";
15
+ /**
16
+ * The debug namespace the library's own debuggers live under until {@link Library.init} supplies another.
17
+ */
18
+ export declare const DEFAULT_DEBUG_NAMESPACE = "typescript-lib";
19
+ /**
20
+ * Parameters for {@link Library.init}.
21
+ *
22
+ * These are purely cosmetic values the host injects once at initialization, so the library itself carries
23
+ * no knowledge of who hosts it.
24
+ */
25
+ export interface LibraryInitParams {
26
+ /**
27
+ * The URL of the guide explaining how to turn debug messages on and off, named in the library's debug messages.
28
+ * Without one, the messages name no guide.
29
+ */
30
+ readonly debugGuideUrl?: string;
31
+ /**
32
+ * The namespace the library's own debuggers live under. Defaults to {@link DEFAULT_DEBUG_NAMESPACE}.
33
+ * A host that publishes its own debug namespace to its users passes it here, so their filters keep matching.
34
+ */
35
+ readonly debugNamespace?: string;
36
+ /**
37
+ * The namespace prefix prepended to the library's debug namespaces (e.g. `${pluginId}:`).
38
+ */
39
+ readonly debugPrefixNamespace: string;
40
+ /**
41
+ * Whether debug logging should append a rich DevTools stack trace.
42
+ */
43
+ readonly shouldPrintStackTrace: boolean;
44
+ }
45
+ /**
46
+ * The single, deterministic initialization entry point for the `@mnaoumov/typescript-lib` library.
47
+ *
48
+ * The host calls {@link Library.init} exactly once to push its cosmetic configuration; the library only
49
+ * reads it through the getters. Calling {@link Library.init} more than once throws —
50
+ * {@link Library.resetToDefault} clears the state (e.g. between tests, or on unload) and allows
51
+ * re-initialization.
52
+ */
53
+ declare class LibraryContext {
54
+ /**
55
+ * The URL of the guide explaining how to turn debug messages on and off. Empty until {@link init} is called with one.
56
+ *
57
+ * @returns The debug guide URL.
58
+ */
59
+ get debugGuideUrl(): string;
60
+ /**
61
+ * The namespace the library's own debuggers live under.
62
+ *
63
+ * @returns The debug namespace.
64
+ */
65
+ get debugNamespace(): string;
66
+ /**
67
+ * The namespace prefix prepended to the library's debug namespaces. Empty until {@link init} is called.
68
+ *
69
+ * @returns The debug namespace prefix.
70
+ */
71
+ get debugPrefixNamespace(): string;
72
+ /**
73
+ * Whether debug logging should append a rich DevTools stack trace. `false` until {@link init} is called.
74
+ *
75
+ * @returns Whether to print stack traces.
76
+ */
77
+ get shouldPrintStackTrace(): boolean;
78
+ private isInitialized;
79
+ private params;
80
+ /**
81
+ * Initializes the library with the host's cosmetic configuration. Must be called exactly once; calling it
82
+ * again before {@link resetToDefault} throws.
83
+ *
84
+ * @param params - The cosmetic configuration to inject.
85
+ */
86
+ init(params: LibraryInitParams): void;
87
+ /**
88
+ * Resets the library back to its default (uninitialized) state, allowing {@link init} to be called again.
89
+ */
90
+ resetToDefault(): void;
91
+ }
92
+ /**
93
+ * The single {@link LibraryContext} instance — the library's deterministic initialization entry point.
94
+ */
95
+ export declare const Library: LibraryContext;
96
+ export {};
@@ -0,0 +1,118 @@
1
+ /*
2
+ THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
3
+ if you want to view the source, please visit the github repository of this plugin
4
+ */
5
+
6
+ (function () {
7
+ function ensureDisposeSymbols(symbolConstructor = Symbol) {
8
+ symbolConstructor.asyncDispose ??= symbolConstructor.for('Symbol.asyncDispose');
9
+ symbolConstructor.dispose ??= symbolConstructor.for('Symbol.dispose');
10
+ }
11
+
12
+ function ensureBrowserProcess() {
13
+ const browserProcess = {
14
+ browser: true,
15
+ cwd() {
16
+ return '/';
17
+ },
18
+ env: {},
19
+ platform: 'android'
20
+ };
21
+
22
+ // eslint-disable-next-line obsidianmd/no-global-this, unicorn/no-unnecessary-global-this -- Must stay `globalThis`-qualified: in the emitted banner a bare `process` is a free identifier, so reading it where the host has none throws a ReferenceError instead of yielding `undefined`. That is the very case this function exists to handle.
23
+ const existingProcess = globalThis.process;
24
+
25
+ if (!existingProcess) {
26
+ // eslint-disable-next-line obsidianmd/no-global-this -- Actively use globalThis.
27
+ globalThis.process = browserProcess;
28
+ return;
29
+ }
30
+
31
+ if (existingProcess.versions?.node) {
32
+ return;
33
+ }
34
+
35
+ const existingProcessRecord = existingProcess;
36
+
37
+ for (const [key, value] of Object.entries(browserProcess)) {
38
+ existingProcessRecord[key] ??= value;
39
+ }
40
+
41
+ existingProcessRecord['browser'] = true;
42
+ }
43
+
44
+ (function initEsm() {
45
+ ensureDisposeSymbols();
46
+ ensureBrowserProcess();
47
+ })();
48
+ })();
49
+
50
+ const LIBRARY_NAME = "@mnaoumov/typescript-lib";
51
+ const DEFAULT_DEBUG_NAMESPACE = "typescript-lib";
52
+ const DEFAULT_PARAMS = {
53
+ debugPrefixNamespace: "",
54
+ shouldPrintStackTrace: false
55
+ };
56
+ class LibraryContext {
57
+ /**
58
+ * The URL of the guide explaining how to turn debug messages on and off. Empty until {@link init} is called with one.
59
+ *
60
+ * @returns The debug guide URL.
61
+ */
62
+ get debugGuideUrl() {
63
+ return this.params.debugGuideUrl ?? "";
64
+ }
65
+ /**
66
+ * The namespace the library's own debuggers live under.
67
+ *
68
+ * @returns The debug namespace.
69
+ */
70
+ get debugNamespace() {
71
+ return this.params.debugNamespace ?? DEFAULT_DEBUG_NAMESPACE;
72
+ }
73
+ /**
74
+ * The namespace prefix prepended to the library's debug namespaces. Empty until {@link init} is called.
75
+ *
76
+ * @returns The debug namespace prefix.
77
+ */
78
+ get debugPrefixNamespace() {
79
+ return this.params.debugPrefixNamespace;
80
+ }
81
+ /**
82
+ * Whether debug logging should append a rich DevTools stack trace. `false` until {@link init} is called.
83
+ *
84
+ * @returns Whether to print stack traces.
85
+ */
86
+ get shouldPrintStackTrace() {
87
+ return this.params.shouldPrintStackTrace;
88
+ }
89
+ isInitialized = false;
90
+ params = { ...DEFAULT_PARAMS };
91
+ /**
92
+ * Initializes the library with the host's cosmetic configuration. Must be called exactly once; calling it
93
+ * again before {@link resetToDefault} throws.
94
+ *
95
+ * @param params - The cosmetic configuration to inject.
96
+ */
97
+ init(params) {
98
+ if (this.isInitialized) {
99
+ throw new Error(`${LIBRARY_NAME} is already initialized. Call Library.resetToDefault() before initializing again.`);
100
+ }
101
+ this.isInitialized = true;
102
+ this.params = { ...params };
103
+ }
104
+ /**
105
+ * Resets the library back to its default (uninitialized) state, allowing {@link init} to be called again.
106
+ */
107
+ resetToDefault() {
108
+ this.isInitialized = false;
109
+ this.params = { ...DEFAULT_PARAMS };
110
+ }
111
+ }
112
+ const Library = new LibraryContext();
113
+ export {
114
+ DEFAULT_DEBUG_NAMESPACE,
115
+ LIBRARY_NAME,
116
+ Library
117
+ };
118
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2xpYnJhcnkudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBIZWxwZXJzIGZvciB3b3JraW5nIHdpdGggdGhlIGBAbW5hb3Vtb3YvdHlwZXNjcmlwdC1saWJgIGxpYnJhcnkuXG4gKi9cblxuLyoqXG4gKiBBIG5hbWUgb2YgdGhlIGBAbW5hb3Vtb3YvdHlwZXNjcmlwdC1saWJgIGxpYnJhcnkuXG4gKi9cbmV4cG9ydCBjb25zdCBMSUJSQVJZX05BTUUgPSAnQG1uYW91bW92L3R5cGVzY3JpcHQtbGliJztcblxuLyoqXG4gKiBUaGUgZGVidWcgbmFtZXNwYWNlIHRoZSBsaWJyYXJ5J3Mgb3duIGRlYnVnZ2VycyBsaXZlIHVuZGVyIHVudGlsIHtAbGluayBMaWJyYXJ5LmluaXR9IHN1cHBsaWVzIGFub3RoZXIuXG4gKi9cbmV4cG9ydCBjb25zdCBERUZBVUxUX0RFQlVHX05BTUVTUEFDRSA9ICd0eXBlc2NyaXB0LWxpYic7XG5cbi8qKlxuICogUGFyYW1ldGVycyBmb3Ige0BsaW5rIExpYnJhcnkuaW5pdH0uXG4gKlxuICogVGhlc2UgYXJlIHB1cmVseSBjb3NtZXRpYyB2YWx1ZXMgdGhlIGhvc3QgaW5qZWN0cyBvbmNlIGF0IGluaXRpYWxpemF0aW9uLCBzbyB0aGUgbGlicmFyeSBpdHNlbGYgY2Fycmllc1xuICogbm8ga25vd2xlZGdlIG9mIHdobyBob3N0cyBpdC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBMaWJyYXJ5SW5pdFBhcmFtcyB7XG4gIC8qKlxuICAgKiBUaGUgVVJMIG9mIHRoZSBndWlkZSBleHBsYWluaW5nIGhvdyB0byB0dXJuIGRlYnVnIG1lc3NhZ2VzIG9uIGFuZCBvZmYsIG5hbWVkIGluIHRoZSBsaWJyYXJ5J3MgZGVidWcgbWVzc2FnZXMuXG4gICAqIFdpdGhvdXQgb25lLCB0aGUgbWVzc2FnZXMgbmFtZSBubyBndWlkZS5cbiAgICovXG4gIHJlYWRvbmx5IGRlYnVnR3VpZGVVcmw/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBuYW1lc3BhY2UgdGhlIGxpYnJhcnkncyBvd24gZGVidWdnZXJzIGxpdmUgdW5kZXIuIERlZmF1bHRzIHRvIHtAbGluayBERUZBVUxUX0RFQlVHX05BTUVTUEFDRX0uXG4gICAqIEEgaG9zdCB0aGF0IHB1Ymxpc2hlcyBpdHMgb3duIGRlYnVnIG5hbWVzcGFjZSB0byBpdHMgdXNlcnMgcGFzc2VzIGl0IGhlcmUsIHNvIHRoZWlyIGZpbHRlcnMga2VlcCBtYXRjaGluZy5cbiAgICovXG4gIHJlYWRvbmx5IGRlYnVnTmFtZXNwYWNlPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgbmFtZXNwYWNlIHByZWZpeCBwcmVwZW5kZWQgdG8gdGhlIGxpYnJhcnkncyBkZWJ1ZyBuYW1lc3BhY2VzIChlLmcuIGAke3BsdWdpbklkfTpgKS5cbiAgICovXG4gIHJlYWRvbmx5IGRlYnVnUHJlZml4TmFtZXNwYWNlOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgZGVidWcgbG9nZ2luZyBzaG91bGQgYXBwZW5kIGEgcmljaCBEZXZUb29scyBzdGFjayB0cmFjZS5cbiAgICovXG4gIHJlYWRvbmx5IHNob3VsZFByaW50U3RhY2tUcmFjZTogYm9vbGVhbjtcbn1cblxuY29uc3QgREVGQVVMVF9QQVJBTVM6IExpYnJhcnlJbml0UGFyYW1zID0ge1xuICBkZWJ1Z1ByZWZpeE5hbWVzcGFjZTogJycsXG4gIHNob3VsZFByaW50U3RhY2tUcmFjZTogZmFsc2Vcbn07XG5cbi8qKlxuICogVGhlIHNpbmdsZSwgZGV0ZXJtaW5pc3RpYyBpbml0aWFsaXphdGlvbiBlbnRyeSBwb2ludCBmb3IgdGhlIGBAbW5hb3Vtb3YvdHlwZXNjcmlwdC1saWJgIGxpYnJhcnkuXG4gKlxuICogVGhlIGhvc3QgY2FsbHMge0BsaW5rIExpYnJhcnkuaW5pdH0gZXhhY3RseSBvbmNlIHRvIHB1c2ggaXRzIGNvc21ldGljIGNvbmZpZ3VyYXRpb247IHRoZSBsaWJyYXJ5IG9ubHlcbiAqIHJlYWRzIGl0IHRocm91Z2ggdGhlIGdldHRlcnMuIENhbGxpbmcge0BsaW5rIExpYnJhcnkuaW5pdH0gbW9yZSB0aGFuIG9uY2UgdGhyb3dzIFx1MjAxNFxuICoge0BsaW5rIExpYnJhcnkucmVzZXRUb0RlZmF1bHR9IGNsZWFycyB0aGUgc3RhdGUgKGUuZy4gYmV0d2VlbiB0ZXN0cywgb3Igb24gdW5sb2FkKSBhbmQgYWxsb3dzXG4gKiByZS1pbml0aWFsaXphdGlvbi5cbiAqL1xuY2xhc3MgTGlicmFyeUNvbnRleHQge1xuICAvKipcbiAgICogVGhlIFVSTCBvZiB0aGUgZ3VpZGUgZXhwbGFpbmluZyBob3cgdG8gdHVybiBkZWJ1ZyBtZXNzYWdlcyBvbiBhbmQgb2ZmLiBFbXB0eSB1bnRpbCB7QGxpbmsgaW5pdH0gaXMgY2FsbGVkIHdpdGggb25lLlxuICAgKlxuICAgKiBAcmV0dXJucyBUaGUgZGVidWcgZ3VpZGUgVVJMLlxuICAgKi9cbiAgcHVibGljIGdldCBkZWJ1Z0d1aWRlVXJsKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMucGFyYW1zLmRlYnVnR3VpZGVVcmwgPz8gJyc7XG4gIH1cblxuICAvKipcbiAgICogVGhlIG5hbWVzcGFjZSB0aGUgbGlicmFyeSdzIG93biBkZWJ1Z2dlcnMgbGl2ZSB1bmRlci5cbiAgICpcbiAgICogQHJldHVybnMgVGhlIGRlYnVnIG5hbWVzcGFjZS5cbiAgICovXG4gIHB1YmxpYyBnZXQgZGVidWdOYW1lc3BhY2UoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5wYXJhbXMuZGVidWdOYW1lc3BhY2UgPz8gREVGQVVMVF9ERUJVR19OQU1FU1BBQ0U7XG4gIH1cblxuICAvKipcbiAgICogVGhlIG5hbWVzcGFjZSBwcmVmaXggcHJlcGVuZGVkIHRvIHRoZSBsaWJyYXJ5J3MgZGVidWcgbmFtZXNwYWNlcy4gRW1wdHkgdW50aWwge0BsaW5rIGluaXR9IGlzIGNhbGxlZC5cbiAgICpcbiAgICogQHJldHVybnMgVGhlIGRlYnVnIG5hbWVzcGFjZSBwcmVmaXguXG4gICAqL1xuICBwdWJsaWMgZ2V0IGRlYnVnUHJlZml4TmFtZXNwYWNlKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMucGFyYW1zLmRlYnVnUHJlZml4TmFtZXNwYWNlO1xuICB9XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgZGVidWcgbG9nZ2luZyBzaG91bGQgYXBwZW5kIGEgcmljaCBEZXZUb29scyBzdGFjayB0cmFjZS4gYGZhbHNlYCB1bnRpbCB7QGxpbmsgaW5pdH0gaXMgY2FsbGVkLlxuICAgKlxuICAgKiBAcmV0dXJucyBXaGV0aGVyIHRvIHByaW50IHN0YWNrIHRyYWNlcy5cbiAgICovXG4gIHB1YmxpYyBnZXQgc2hvdWxkUHJpbnRTdGFja1RyYWNlKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnBhcmFtcy5zaG91bGRQcmludFN0YWNrVHJhY2U7XG4gIH1cblxuICBwcml2YXRlIGlzSW5pdGlhbGl6ZWQgPSBmYWxzZTtcblxuICBwcml2YXRlIHBhcmFtczogTGlicmFyeUluaXRQYXJhbXMgPSB7IC4uLkRFRkFVTFRfUEFSQU1TIH07XG5cbiAgLyoqXG4gICAqIEluaXRpYWxpemVzIHRoZSBsaWJyYXJ5IHdpdGggdGhlIGhvc3QncyBjb3NtZXRpYyBjb25maWd1cmF0aW9uLiBNdXN0IGJlIGNhbGxlZCBleGFjdGx5IG9uY2U7IGNhbGxpbmcgaXRcbiAgICogYWdhaW4gYmVmb3JlIHtAbGluayByZXNldFRvRGVmYXVsdH0gdGhyb3dzLlxuICAgKlxuICAgKiBAcGFyYW0gcGFyYW1zIC0gVGhlIGNvc21ldGljIGNvbmZpZ3VyYXRpb24gdG8gaW5qZWN0LlxuICAgKi9cbiAgcHVibGljIGluaXQocGFyYW1zOiBMaWJyYXJ5SW5pdFBhcmFtcyk6IHZvaWQge1xuICAgIGlmICh0aGlzLmlzSW5pdGlhbGl6ZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgJHtMSUJSQVJZX05BTUV9IGlzIGFscmVhZHkgaW5pdGlhbGl6ZWQuIENhbGwgTGlicmFyeS5yZXNldFRvRGVmYXVsdCgpIGJlZm9yZSBpbml0aWFsaXppbmcgYWdhaW4uYCk7XG4gICAgfVxuICAgIHRoaXMuaXNJbml0aWFsaXplZCA9IHRydWU7XG4gICAgdGhpcy5wYXJhbXMgPSB7IC4uLnBhcmFtcyB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFJlc2V0cyB0aGUgbGlicmFyeSBiYWNrIHRvIGl0cyBkZWZhdWx0ICh1bmluaXRpYWxpemVkKSBzdGF0ZSwgYWxsb3dpbmcge0BsaW5rIGluaXR9IHRvIGJlIGNhbGxlZCBhZ2Fpbi5cbiAgICovXG4gIHB1YmxpYyByZXNldFRvRGVmYXVsdCgpOiB2b2lkIHtcbiAgICB0aGlzLmlzSW5pdGlhbGl6ZWQgPSBmYWxzZTtcbiAgICB0aGlzLnBhcmFtcyA9IHsgLi4uREVGQVVMVF9QQVJBTVMgfTtcbiAgfVxufVxuXG4vKipcbiAqIFRoZSBzaW5nbGUge0BsaW5rIExpYnJhcnlDb250ZXh0fSBpbnN0YW5jZSBcdTIwMTQgdGhlIGxpYnJhcnkncyBkZXRlcm1pbmlzdGljIGluaXRpYWxpemF0aW9uIGVudHJ5IHBvaW50LlxuICovXG5leHBvcnQgY29uc3QgTGlicmFyeSA9IG5ldyBMaWJyYXJ5Q29udGV4dCgpO1xuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQVNPLE1BQU0sZUFBZTtBQUtyQixNQUFNLDBCQUEwQjtBQWdDdkMsTUFBTSxpQkFBb0M7QUFBQSxFQUN4QyxzQkFBc0I7QUFBQSxFQUN0Qix1QkFBdUI7QUFDekI7QUFVQSxNQUFNLGVBQWU7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFNbkIsSUFBVyxnQkFBd0I7QUFDakMsV0FBTyxLQUFLLE9BQU8saUJBQWlCO0FBQUEsRUFDdEM7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFPQSxJQUFXLGlCQUF5QjtBQUNsQyxXQUFPLEtBQUssT0FBTyxrQkFBa0I7QUFBQSxFQUN2QztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQU9BLElBQVcsdUJBQStCO0FBQ3hDLFdBQU8sS0FBSyxPQUFPO0FBQUEsRUFDckI7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFPQSxJQUFXLHdCQUFpQztBQUMxQyxXQUFPLEtBQUssT0FBTztBQUFBLEVBQ3JCO0FBQUEsRUFFUSxnQkFBZ0I7QUFBQSxFQUVoQixTQUE0QixFQUFFLEdBQUcsZUFBZTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBUWpELEtBQUssUUFBaUM7QUFDM0MsUUFBSSxLQUFLLGVBQWU7QUFDdEIsWUFBTSxJQUFJLE1BQU0sR0FBRyxZQUFZLG1GQUFtRjtBQUFBLElBQ3BIO0FBQ0EsU0FBSyxnQkFBZ0I7QUFDckIsU0FBSyxTQUFTLEVBQUUsR0FBRyxPQUFPO0FBQUEsRUFDNUI7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQUtPLGlCQUF1QjtBQUM1QixTQUFLLGdCQUFnQjtBQUNyQixTQUFLLFNBQVMsRUFBRSxHQUFHLGVBQWU7QUFBQSxFQUNwQztBQUNGO0FBS08sTUFBTSxVQUFVLElBQUksZUFBZTsiLAogICJuYW1lcyI6IFtdCn0K