@shapediver/viewer.shared.services 3.16.7 → 3.16.9

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 (94) hide show
  1. package/dist/converter/Converter.d.ts +77 -77
  2. package/dist/converter/Converter.js +424 -424
  3. package/dist/converter/Converter.js.map +1 -1
  4. package/dist/dom-event-engine/DomEventEngine.d.ts +56 -56
  5. package/dist/dom-event-engine/DomEventEngine.js +275 -275
  6. package/dist/dom-event-engine/DomEventEngine.js.map +1 -1
  7. package/dist/dom-event-engine/IDomEventListener.d.ts +10 -10
  8. package/dist/dom-event-engine/IDomEventListener.js +2 -2
  9. package/dist/event-engine/EventEngine.d.ts +35 -35
  10. package/dist/event-engine/EventEngine.js +107 -107
  11. package/dist/event-engine/EventEngine.js.map +1 -1
  12. package/dist/event-engine/interfaces/ICallback.d.ts +4 -4
  13. package/dist/event-engine/interfaces/ICallback.js +2 -2
  14. package/dist/event-engine/interfaces/IListener.d.ts +5 -5
  15. package/dist/event-engine/interfaces/IListener.js +2 -2
  16. package/dist/http-client/HttpClient.d.ts +106 -106
  17. package/dist/http-client/HttpClient.js +375 -375
  18. package/dist/http-client/HttpClient.js.map +1 -1
  19. package/dist/http-client/HttpResponse.d.ts +5 -5
  20. package/dist/http-client/HttpResponse.js +2 -2
  21. package/dist/index.d.ts +43 -43
  22. package/dist/index.js +102 -102
  23. package/dist/input-validator/InputValidator.d.ts +10 -10
  24. package/dist/input-validator/InputValidator.d.ts.map +1 -1
  25. package/dist/input-validator/InputValidator.js +169 -169
  26. package/dist/input-validator/InputValidator.js.map +1 -1
  27. package/dist/logger/ErrorTypeGuards.d.ts +41 -41
  28. package/dist/logger/ErrorTypeGuards.js +158 -159
  29. package/dist/logger/ErrorTypeGuards.js.map +1 -1
  30. package/dist/logger/Logger.d.ts +63 -63
  31. package/dist/logger/Logger.js +179 -179
  32. package/dist/logger/Logger.js.map +1 -1
  33. package/dist/logger/ShapeDiverBackendErrors.d.ts +14 -14
  34. package/dist/logger/ShapeDiverBackendErrors.js +28 -28
  35. package/dist/logger/ShapeDiverError.d.ts +33 -33
  36. package/dist/logger/ShapeDiverError.js +43 -43
  37. package/dist/logger/ShapeDiverError.js.map +1 -1
  38. package/dist/logger/ShapeDiverViewerErrors.d.ts +87 -87
  39. package/dist/logger/ShapeDiverViewerErrors.d.ts.map +1 -1
  40. package/dist/logger/ShapeDiverViewerErrors.js +119 -119
  41. package/dist/logger/ShapeDiverViewerErrors.js.map +1 -1
  42. package/dist/parameter-utils/ParameterUtils.d.ts +3 -3
  43. package/dist/parameter-utils/ParameterUtils.d.ts.map +1 -1
  44. package/dist/parameter-utils/ParameterUtils.js +161 -161
  45. package/dist/parameter-utils/ParameterUtils.js.map +1 -1
  46. package/dist/performance-evaluator/PerformanceEvaluator.d.ts +65 -65
  47. package/dist/performance-evaluator/PerformanceEvaluator.js +125 -125
  48. package/dist/settings-engine/SettingsEngine.d.ts +43 -43
  49. package/dist/settings-engine/SettingsEngine.d.ts.map +1 -1
  50. package/dist/settings-engine/SettingsEngine.js +162 -162
  51. package/dist/settings-engine/SettingsEngine.js.map +1 -1
  52. package/dist/settings-engine/defaults/Defaults.d.ts +2 -2
  53. package/dist/settings-engine/defaults/Defaults.js +102 -102
  54. package/dist/settings-engine/defaults/FurnitureDefaults.d.ts +2 -2
  55. package/dist/settings-engine/defaults/FurnitureDefaults.js +158 -158
  56. package/dist/settings-engine/defaults/HighPerformanceDefaults.d.ts +2 -2
  57. package/dist/settings-engine/defaults/HighPerformanceDefaults.js +114 -114
  58. package/dist/settings-engine/defaults/JewelryDefaults.d.ts +2 -2
  59. package/dist/settings-engine/defaults/JewelryDefaults.js +91 -91
  60. package/dist/settings-engine/defaults/MedicalDefaults.d.ts +2 -2
  61. package/dist/settings-engine/defaults/MedicalDefaults.js +102 -102
  62. package/dist/settings-engine/defaults/TwoDimensionalDefaults.d.ts +2 -2
  63. package/dist/settings-engine/defaults/TwoDimensionalDefaults.js +83 -83
  64. package/dist/state-engine/ISessionGlobalAccessObjectDefinition.d.ts +21 -21
  65. package/dist/state-engine/ISessionGlobalAccessObjectDefinition.js +2 -2
  66. package/dist/state-engine/IViewportGlobalAccessObjectDefinition.d.ts +33 -33
  67. package/dist/state-engine/IViewportGlobalAccessObjectDefinition.js +2 -2
  68. package/dist/state-engine/StateEngine.d.ts +18 -18
  69. package/dist/state-engine/StateEngine.js +32 -32
  70. package/dist/state-engine/StatePromise.d.ts +13 -13
  71. package/dist/state-engine/StatePromise.js +55 -55
  72. package/dist/system-info/SystemInfo.d.ts +57 -57
  73. package/dist/system-info/SystemInfo.js +127 -127
  74. package/dist/system-info/SystemInfo.js.map +1 -1
  75. package/dist/type-check/TypeChecker.d.ts +6 -6
  76. package/dist/type-check/TypeChecker.js +19 -19
  77. package/dist/utilities/ObservableArray.d.ts +25 -25
  78. package/dist/utilities/ObservableArray.d.ts.map +1 -1
  79. package/dist/utilities/ObservableArray.js +64 -64
  80. package/dist/utilities/ObservableArray.js.map +1 -1
  81. package/dist/utilities/base64.d.ts +2 -2
  82. package/dist/utilities/base64.d.ts.map +1 -1
  83. package/dist/utilities/base64.js +21 -21
  84. package/dist/utilities/base64.js.map +1 -1
  85. package/dist/utilities/hashCreator.d.ts +7 -7
  86. package/dist/utilities/hashCreator.d.ts.map +1 -1
  87. package/dist/utilities/hashCreator.js +29 -29
  88. package/dist/utilities/hashCreator.js.map +1 -1
  89. package/dist/utilities/numberCleaner.d.ts +1 -1
  90. package/dist/utilities/numberCleaner.d.ts.map +1 -1
  91. package/dist/utilities/numberCleaner.js +8 -8
  92. package/dist/uuid-generator/UuidGenerator.d.ts +28 -28
  93. package/dist/uuid-generator/UuidGenerator.js +46 -46
  94. package/package.json +6 -6
@@ -1,425 +1,425 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.Converter = void 0;
13
- const tinycolor_1 = require("@ctrl/tinycolor");
14
- const gl_matrix_1 = require("gl-matrix");
15
- const HttpClient_1 = require("../http-client/HttpClient");
16
- const base64_1 = require("../utilities/base64");
17
- class Converter {
18
- constructor() {
19
- // #region Properties (2)
20
- this._httpClient = HttpClient_1.HttpClient.instance;
21
- // #endregion Private Methods (1)
22
- }
23
- // #endregion Properties (2)
24
- // #region Public Static Getters And Setters (1)
25
- static get instance() {
26
- return this._instance || (this._instance = new this());
27
- }
28
- /**
29
- * Converts a data URL to a Blob object.
30
- *
31
- * @param dataURL
32
- * @returns
33
- */
34
- dataURLtoBlob(dataURL) {
35
- // Split the data URL to get the base64 data
36
- const arr = dataURL.split(",");
37
- const mime = arr[0].match(/:(.*?);/)[1];
38
- const bstr = window.atob(arr[1]);
39
- let n = bstr.length;
40
- const u8arr = new Uint8Array(n);
41
- // Convert the binary string to a Uint8Array
42
- while (n--)
43
- u8arr[n] = bstr.charCodeAt(n);
44
- // Create a Blob object from the Uint8Array
45
- return {
46
- blob: new Blob([u8arr], { type: mime }),
47
- arrayBuffer: u8arr.buffer,
48
- };
49
- }
50
- /**
51
- * Convert the given image to an ArrayBuffer and return the image data.
52
- *
53
- * @param image The image to convert.
54
- * @param arrayBuffer Optional: The ArrayBuffer of the image, if it was already converted.
55
- * @returns
56
- */
57
- constructImageData(image, arrayBuffer) {
58
- return __awaiter(this, void 0, void 0, function* () {
59
- if (image instanceof File) {
60
- return {
61
- imageData: {
62
- filename: image.name,
63
- format: image.type,
64
- size: image.size,
65
- },
66
- arrayBuffer: arrayBuffer || (yield image.arrayBuffer()),
67
- };
68
- }
69
- else {
70
- return {
71
- imageData: {
72
- format: image.type,
73
- size: image.size,
74
- },
75
- arrayBuffer: arrayBuffer || (yield image.arrayBuffer()),
76
- };
77
- }
78
- });
79
- }
80
- /**
81
- * Convert the given input to an ArrayBuffer.
82
- *
83
- * @param input
84
- * @returns
85
- */
86
- convertToArrayBuffer(input) {
87
- return __awaiter(this, void 0, void 0, function* () {
88
- if (input instanceof File) {
89
- return yield input.arrayBuffer();
90
- }
91
- else if (input instanceof Blob) {
92
- return yield input.arrayBuffer();
93
- }
94
- else if (input instanceof ArrayBuffer) {
95
- return input;
96
- }
97
- else {
98
- const result = yield input();
99
- if (result instanceof Blob) {
100
- return yield result.arrayBuffer();
101
- }
102
- else {
103
- return result;
104
- }
105
- }
106
- });
107
- }
108
- /**
109
- * Convert the given input to a Blob.
110
- *
111
- * @param input
112
- * @returns
113
- */
114
- convertToBlob(input) {
115
- return __awaiter(this, void 0, void 0, function* () {
116
- if (input instanceof File) {
117
- return input;
118
- }
119
- else if (input instanceof Blob) {
120
- return input;
121
- }
122
- else if (input instanceof ArrayBuffer) {
123
- return new Blob([input]);
124
- }
125
- else {
126
- const result = yield input();
127
- if (result instanceof Blob) {
128
- return result;
129
- }
130
- else {
131
- return new Blob([result]);
132
- }
133
- }
134
- });
135
- }
136
- // #endregion Public Static Getters And Setters (1)
137
- // #region Public Methods (8)
138
- processSVG(blob) {
139
- return __awaiter(this, void 0, void 0, function* () {
140
- let data = yield new Promise((resolve, reject) => {
141
- const reader = new FileReader();
142
- reader.onloadend = () => resolve(reader.result);
143
- reader.onerror = reject;
144
- reader.readAsDataURL(blob);
145
- });
146
- data = data.replace("data:image/svg+xml;base64,", "");
147
- data = (0, base64_1.atobCustom)(data);
148
- const svgC = document.createElement("DIV");
149
- svgC.id = "svgc";
150
- svgC.innerHTML = data;
151
- // now we can access the svg element as a DOM object
152
- const svgE = svgC.getElementsByTagName("svg");
153
- const childImageURIs = [];
154
- let styleURIs = [];
155
- // collect image urls
156
- for (let i = 0; i < svgE.length; ++i) {
157
- for (let j = 0; j < 2; ++j) {
158
- const childImages = (svgE[i].getElementsByTagName(["image", "img"][j]));
159
- for (let k = 0; k < childImages.length; ++k) {
160
- if (childImages[k].href.baseVal.substring(0, 5) != "data:") {
161
- childImageURIs.push(childImages[k].href.baseVal);
162
- }
163
- }
164
- }
165
- // collect potential font definitions
166
- // we assume styles are imported using the following syntax:
167
- // @import url(CSS_URL);
168
- const styleElements = (svgE[i].getElementsByTagName("style"));
169
- for (let j = 0; j < styleElements.length; ++j) {
170
- const regex = /@import\x20url\(\s*(.*?)\s*\);/g;
171
- let m;
172
- while ((m = regex.exec(styleElements[j].innerHTML)) !== null) {
173
- styleURIs.push(m[1]);
174
- }
175
- // make unique
176
- styleURIs = styleURIs.filter(function (value, index, self) {
177
- return self.indexOf(value) === index;
178
- });
179
- }
180
- }
181
- // creating a promise for each image which needs to be converted to a data URI
182
- const replacementPromises = [];
183
- const createImagePromise = (uri) => __awaiter(this, void 0, void 0, function* () {
184
- if (uri.length > 0) {
185
- const response = (yield this._httpClient.get(uri, undefined, true));
186
- const uInt8Array = new Uint8Array(response.data);
187
- let i = uInt8Array.length;
188
- const biStr = []; //new Array(i);
189
- while (i--)
190
- biStr[i] = String.fromCharCode(uInt8Array[i]);
191
- const base64Data = (0, base64_1.btoaCustom)(biStr.join(""));
192
- const imgDataUrl = "data:" +
193
- response.headers["content-type"] +
194
- ";base64," +
195
- base64Data;
196
- // replace url in SVG string
197
- // CAUTION theoretically this could cause unwanted replacements
198
- data = data.replace(uri, imgDataUrl);
199
- }
200
- });
201
- for (let i = 0; i < childImageURIs.length; ++i)
202
- replacementPromises.push(createImagePromise(childImageURIs[i]));
203
- // now we create promises for the google fonts to be imported
204
- const createStylePromise = (styleUrl) => __awaiter(this, void 0, void 0, function* () {
205
- const response = (yield this._httpClient.get(styleUrl, {
206
- responseType: "text",
207
- }));
208
- let cssString = response.data;
209
- // we assume that fonts are imported using the following syntax:
210
- // url(FONT_URI);
211
- const fontURLs = [];
212
- const regex = /url\(\s*(.*?)\s*\)/g;
213
- let m;
214
- while ((m = regex.exec(cssString)) !== null) {
215
- fontURLs.push(m[1]);
216
- }
217
- const fontPromises = [];
218
- const createFontPromise = (fUrl) => __awaiter(this, void 0, void 0, function* () {
219
- const response = (yield this._httpClient.get(fUrl, {
220
- responseType: "arraybuffer",
221
- }));
222
- const uInt8Array = new Uint8Array(response.data);
223
- let i = uInt8Array.length;
224
- const biStr = []; //new Array(i);
225
- while (i--)
226
- biStr[i] = String.fromCharCode(uInt8Array[i]);
227
- const base64Data = (0, base64_1.btoaCustom)(biStr.join(""));
228
- const fontDataUrl = "data:" +
229
- response.headers["content-type"] +
230
- ";base64," +
231
- base64Data;
232
- if (fUrl.length > 0)
233
- cssString = cssString.replace(fUrl, fontDataUrl);
234
- });
235
- for (let j = 0; j < fontURLs.length; ++j)
236
- fontPromises.push(createFontPromise(fontURLs[j]));
237
- yield Promise.all(fontPromises);
238
- data = data.replace("@import url(" + styleUrl + ");", cssString);
239
- });
240
- for (let i = 0; i < styleURIs.length; ++i)
241
- replacementPromises.push(createStylePromise(styleURIs[i]));
242
- yield Promise.all(replacementPromises);
243
- const du = "data:image/svg+xml," + encodeURIComponent(data);
244
- const img = new Image(); // same as document.createElement('img')
245
- img.crossOrigin = "Anonymous";
246
- const promise = new Promise((resolve, reject) => {
247
- img.onload = () => resolve();
248
- img.onerror = reject;
249
- });
250
- img.src = du;
251
- yield promise;
252
- return img;
253
- });
254
- }
255
- responseToImage(response) {
256
- return __awaiter(this, void 0, void 0, function* () {
257
- // if we already receive and image, this conversion already happened
258
- if (response.data instanceof HTMLImageElement)
259
- return response.data;
260
- if (response.headers["content-type"] === "image/svg+xml") {
261
- const img = yield this.processSVG(response.data.blob);
262
- return img;
263
- }
264
- else {
265
- const img = new Image();
266
- const promise = new Promise((resolve, reject) => {
267
- img.onload = () => resolve();
268
- img.onerror = reject;
269
- });
270
- img.crossOrigin = "anonymous";
271
- img.src = URL.createObjectURL(response.data.blob);
272
- yield promise;
273
- URL.revokeObjectURL(img.src);
274
- return img;
275
- }
276
- });
277
- }
278
- toAlpha(color) {
279
- const c = this.toHexColor(color);
280
- if (c.length <= 8)
281
- return 1;
282
- return parseInt(c.slice(c.length - 2, c.length), 16) / 255;
283
- }
284
- toColorArray(color) {
285
- if (typeof color !== "string" || !color.startsWith("#"))
286
- color = this.toHexColor(color);
287
- const tColor = new tinycolor_1.TinyColor(color);
288
- const rgb = tColor.toRgb();
289
- return [rgb.r / 255.0, rgb.g / 255.0, rgb.b / 255.0];
290
- }
291
- /**
292
- * @param color
293
- * @param defColor
294
- */
295
- toHex8Color(color, defColorString = "#000") {
296
- const c = this.toHexColor(color, defColorString);
297
- const tColor = new tinycolor_1.TinyColor(c);
298
- const cH8 = tColor.toHex8String();
299
- return cH8.replace("#", "0x");
300
- }
301
- /**
302
- * This color converter is mostly left 'as-is' from viewer v2.
303
- * I didn't want to break something that works.
304
- *
305
- * @param color
306
- * @param defColor
307
- */
308
- toHexColor(color, defColorString = "#000") {
309
- if (!color || color === "default")
310
- return defColorString;
311
- if (color.constructor === Float32Array)
312
- color = Array.from(color);
313
- const tColor = new tinycolor_1.TinyColor(color);
314
- if (color instanceof tinycolor_1.TinyColor)
315
- return this.tinyColorToString(tColor);
316
- // check if we got a number
317
- if (typeof color === "number") {
318
- let cs = color.toString(16);
319
- const cl = cs.length;
320
- if (cl < 3)
321
- cs = cs.padStart(3, "0");
322
- else if (cl < 6)
323
- cs = cs.padStart(6, "0");
324
- else if (cl < 8)
325
- cs = cs.padEnd(8, "0");
326
- const tc = new tinycolor_1.TinyColor(cs);
327
- return tc.isValid ? this.tinyColorToString(tc) : defColorString;
328
- }
329
- // check if the input is a THREE.Color
330
- if (typeof color === "object" &&
331
- "isColor" in color &&
332
- "getHexString" in color &&
333
- typeof color.getHexString ===
334
- "function") {
335
- const tc = new tinycolor_1.TinyColor(color.getHexString());
336
- return tc.isValid ? this.tinyColorToString(tc) : defColorString;
337
- }
338
- // check for array of numbers
339
- if (Array.isArray(color) && (color.length == 3 || color.length == 4)) {
340
- let isRGBArray = true;
341
- for (let i = 0; i < 3; ++i) {
342
- color[i] = parseFloat(color[i]);
343
- if (isNaN(color[i])) {
344
- isRGBArray = false;
345
- }
346
- }
347
- if (!isRGBArray)
348
- return defColorString;
349
- const tc = new tinycolor_1.TinyColor({
350
- r: Math.max(0, Math.min(color[0], 255)),
351
- g: Math.max(0, Math.min(color[1], 255)),
352
- b: Math.max(0, Math.min(color[2], 255)),
353
- });
354
- if (color.length == 4) {
355
- const a = parseFloat(color[3]);
356
- if (!isNaN(a)) {
357
- tc.setAlpha(Math.max(0, Math.min(a, 255)) / 255);
358
- }
359
- }
360
- return tc.isValid ? this.tinyColorToString(tc) : defColorString;
361
- }
362
- // if we got something other than a string, check if
363
- // tinycolor can work with it
364
- if (typeof color !== "string") {
365
- const tc = new tinycolor_1.TinyColor(color);
366
- return tc.isValid ? this.tinyColorToString(tc) : defColorString;
367
- }
368
- // tinycolor doesn't like 0x
369
- const tmpColor = color.replace("0x", "#");
370
- // if we got no alpha value, add full opacity
371
- if (tmpColor.match(/^#[a-f0-9]{6}$/i) !== null) {
372
- const tc = new tinycolor_1.TinyColor(tmpColor + "ff");
373
- return tc.isValid ? this.tinyColorToString(tc) : defColorString;
374
- }
375
- // standard case
376
- if (tmpColor.match(/^#[a-f0-9]{8}$/i) !== null) {
377
- const tc = new tinycolor_1.TinyColor(tmpColor);
378
- return tc.isValid ? this.tinyColorToString(tc) : defColorString;
379
- }
380
- // correct number which have the alpha value defined as a single hex digit
381
- if (tmpColor.match(/^#[a-f0-9]{7}$/i) !== null) {
382
- const tc = new tinycolor_1.TinyColor(tmpColor.slice(0, 7) + "0" + tmpColor.slice(-1));
383
- return tc.isValid ? this.tinyColorToString(tc) : defColorString;
384
- }
385
- // check if tinycolor understands the string
386
- const tc = new tinycolor_1.TinyColor(tmpColor);
387
- return tc.isValid ? this.tinyColorToString(tc) : defColorString;
388
- }
389
- toThreeJsColorInput(color) {
390
- const c = this.toHexColor(color);
391
- return c.slice(0, c.length - 2);
392
- }
393
- toVec3(point) {
394
- if (Array.isArray(point) &&
395
- point.length >= 3 &&
396
- typeof point[0] === "number" &&
397
- typeof point[1] === "number" &&
398
- typeof point[2] === "number")
399
- return gl_matrix_1.vec3.fromValues(point[0], point[1], point[2]);
400
- const pointCast1 = point;
401
- if ((pointCast1.x || pointCast1.x === 0) &&
402
- typeof pointCast1.x === "number" &&
403
- (pointCast1.y || pointCast1.y === 0) &&
404
- typeof pointCast1.y === "number" &&
405
- (pointCast1.z || pointCast1.z === 0) &&
406
- typeof pointCast1.z === "number")
407
- return gl_matrix_1.vec3.fromValues(pointCast1.x, pointCast1.y, pointCast1.z);
408
- const pointCast2 = point;
409
- if ((pointCast2.X || pointCast2.X === 0) &&
410
- typeof pointCast2.X === "number" &&
411
- (pointCast2.Y || pointCast2.Y === 0) &&
412
- typeof pointCast2.Y === "number" &&
413
- (pointCast2.Z || pointCast2.Z === 0) &&
414
- typeof pointCast2.Z === "number")
415
- return gl_matrix_1.vec3.fromValues(pointCast2.X, pointCast2.Y, pointCast2.Z);
416
- return gl_matrix_1.vec3.create();
417
- }
418
- // #endregion Public Methods (8)
419
- // #region Private Methods (1)
420
- tinyColorToString(color) {
421
- return color.toHex8String();
422
- }
423
- }
424
- exports.Converter = Converter;
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.Converter = void 0;
13
+ const tinycolor_1 = require("@ctrl/tinycolor");
14
+ const gl_matrix_1 = require("gl-matrix");
15
+ const HttpClient_1 = require("../http-client/HttpClient");
16
+ const base64_1 = require("../utilities/base64");
17
+ class Converter {
18
+ constructor() {
19
+ // #region Properties (2)
20
+ this._httpClient = HttpClient_1.HttpClient.instance;
21
+ // #endregion Private Methods (1)
22
+ }
23
+ // #endregion Properties (2)
24
+ // #region Public Static Getters And Setters (1)
25
+ static get instance() {
26
+ return this._instance || (this._instance = new this());
27
+ }
28
+ /**
29
+ * Converts a data URL to a Blob object.
30
+ *
31
+ * @param dataURL
32
+ * @returns
33
+ */
34
+ dataURLtoBlob(dataURL) {
35
+ // Split the data URL to get the base64 data
36
+ const arr = dataURL.split(",");
37
+ const mime = arr[0].match(/:(.*?);/)[1];
38
+ const bstr = window.atob(arr[1]);
39
+ let n = bstr.length;
40
+ const u8arr = new Uint8Array(n);
41
+ // Convert the binary string to a Uint8Array
42
+ while (n--)
43
+ u8arr[n] = bstr.charCodeAt(n);
44
+ // Create a Blob object from the Uint8Array
45
+ return {
46
+ blob: new Blob([u8arr], { type: mime }),
47
+ arrayBuffer: u8arr.buffer,
48
+ };
49
+ }
50
+ /**
51
+ * Convert the given image to an ArrayBuffer and return the image data.
52
+ *
53
+ * @param image The image to convert.
54
+ * @param arrayBuffer Optional: The ArrayBuffer of the image, if it was already converted.
55
+ * @returns
56
+ */
57
+ constructImageData(image, arrayBuffer) {
58
+ return __awaiter(this, void 0, void 0, function* () {
59
+ if (image instanceof File) {
60
+ return {
61
+ imageData: {
62
+ filename: image.name,
63
+ format: image.type,
64
+ size: image.size,
65
+ },
66
+ arrayBuffer: arrayBuffer || (yield image.arrayBuffer()),
67
+ };
68
+ }
69
+ else {
70
+ return {
71
+ imageData: {
72
+ format: image.type,
73
+ size: image.size,
74
+ },
75
+ arrayBuffer: arrayBuffer || (yield image.arrayBuffer()),
76
+ };
77
+ }
78
+ });
79
+ }
80
+ /**
81
+ * Convert the given input to an ArrayBuffer.
82
+ *
83
+ * @param input
84
+ * @returns
85
+ */
86
+ convertToArrayBuffer(input) {
87
+ return __awaiter(this, void 0, void 0, function* () {
88
+ if (input instanceof File) {
89
+ return yield input.arrayBuffer();
90
+ }
91
+ else if (input instanceof Blob) {
92
+ return yield input.arrayBuffer();
93
+ }
94
+ else if (input instanceof ArrayBuffer) {
95
+ return input;
96
+ }
97
+ else {
98
+ const result = yield input();
99
+ if (result instanceof Blob) {
100
+ return yield result.arrayBuffer();
101
+ }
102
+ else {
103
+ return result;
104
+ }
105
+ }
106
+ });
107
+ }
108
+ /**
109
+ * Convert the given input to a Blob.
110
+ *
111
+ * @param input
112
+ * @returns
113
+ */
114
+ convertToBlob(input) {
115
+ return __awaiter(this, void 0, void 0, function* () {
116
+ if (input instanceof File) {
117
+ return input;
118
+ }
119
+ else if (input instanceof Blob) {
120
+ return input;
121
+ }
122
+ else if (input instanceof ArrayBuffer) {
123
+ return new Blob([input]);
124
+ }
125
+ else {
126
+ const result = yield input();
127
+ if (result instanceof Blob) {
128
+ return result;
129
+ }
130
+ else {
131
+ return new Blob([result]);
132
+ }
133
+ }
134
+ });
135
+ }
136
+ // #endregion Public Static Getters And Setters (1)
137
+ // #region Public Methods (8)
138
+ processSVG(blob) {
139
+ return __awaiter(this, void 0, void 0, function* () {
140
+ let data = yield new Promise((resolve, reject) => {
141
+ const reader = new FileReader();
142
+ reader.onloadend = () => resolve(reader.result);
143
+ reader.onerror = reject;
144
+ reader.readAsDataURL(blob);
145
+ });
146
+ data = data.replace("data:image/svg+xml;base64,", "");
147
+ data = (0, base64_1.atobCustom)(data);
148
+ const svgC = document.createElement("DIV");
149
+ svgC.id = "svgc";
150
+ svgC.innerHTML = data;
151
+ // now we can access the svg element as a DOM object
152
+ const svgE = svgC.getElementsByTagName("svg");
153
+ const childImageURIs = [];
154
+ let styleURIs = [];
155
+ // collect image urls
156
+ for (let i = 0; i < svgE.length; ++i) {
157
+ for (let j = 0; j < 2; ++j) {
158
+ const childImages = (svgE[i].getElementsByTagName(["image", "img"][j]));
159
+ for (let k = 0; k < childImages.length; ++k) {
160
+ if (childImages[k].href.baseVal.substring(0, 5) != "data:") {
161
+ childImageURIs.push(childImages[k].href.baseVal);
162
+ }
163
+ }
164
+ }
165
+ // collect potential font definitions
166
+ // we assume styles are imported using the following syntax:
167
+ // @import url(CSS_URL);
168
+ const styleElements = (svgE[i].getElementsByTagName("style"));
169
+ for (let j = 0; j < styleElements.length; ++j) {
170
+ const regex = /@import\x20url\(\s*(.*?)\s*\);/g;
171
+ let m;
172
+ while ((m = regex.exec(styleElements[j].innerHTML)) !== null) {
173
+ styleURIs.push(m[1]);
174
+ }
175
+ // make unique
176
+ styleURIs = styleURIs.filter(function (value, index, self) {
177
+ return self.indexOf(value) === index;
178
+ });
179
+ }
180
+ }
181
+ // creating a promise for each image which needs to be converted to a data URI
182
+ const replacementPromises = [];
183
+ const createImagePromise = (uri) => __awaiter(this, void 0, void 0, function* () {
184
+ if (uri.length > 0) {
185
+ const response = (yield this._httpClient.get(uri, undefined, true));
186
+ const uInt8Array = new Uint8Array(response.data);
187
+ let i = uInt8Array.length;
188
+ const biStr = []; //new Array(i);
189
+ while (i--)
190
+ biStr[i] = String.fromCharCode(uInt8Array[i]);
191
+ const base64Data = (0, base64_1.btoaCustom)(biStr.join(""));
192
+ const imgDataUrl = "data:" +
193
+ response.headers["content-type"] +
194
+ ";base64," +
195
+ base64Data;
196
+ // replace url in SVG string
197
+ // CAUTION theoretically this could cause unwanted replacements
198
+ data = data.replace(uri, imgDataUrl);
199
+ }
200
+ });
201
+ for (let i = 0; i < childImageURIs.length; ++i)
202
+ replacementPromises.push(createImagePromise(childImageURIs[i]));
203
+ // now we create promises for the google fonts to be imported
204
+ const createStylePromise = (styleUrl) => __awaiter(this, void 0, void 0, function* () {
205
+ const response = (yield this._httpClient.get(styleUrl, {
206
+ responseType: "text",
207
+ }));
208
+ let cssString = response.data;
209
+ // we assume that fonts are imported using the following syntax:
210
+ // url(FONT_URI);
211
+ const fontURLs = [];
212
+ const regex = /url\(\s*(.*?)\s*\)/g;
213
+ let m;
214
+ while ((m = regex.exec(cssString)) !== null) {
215
+ fontURLs.push(m[1]);
216
+ }
217
+ const fontPromises = [];
218
+ const createFontPromise = (fUrl) => __awaiter(this, void 0, void 0, function* () {
219
+ const response = (yield this._httpClient.get(fUrl, {
220
+ responseType: "arraybuffer",
221
+ }));
222
+ const uInt8Array = new Uint8Array(response.data);
223
+ let i = uInt8Array.length;
224
+ const biStr = []; //new Array(i);
225
+ while (i--)
226
+ biStr[i] = String.fromCharCode(uInt8Array[i]);
227
+ const base64Data = (0, base64_1.btoaCustom)(biStr.join(""));
228
+ const fontDataUrl = "data:" +
229
+ response.headers["content-type"] +
230
+ ";base64," +
231
+ base64Data;
232
+ if (fUrl.length > 0)
233
+ cssString = cssString.replace(fUrl, fontDataUrl);
234
+ });
235
+ for (let j = 0; j < fontURLs.length; ++j)
236
+ fontPromises.push(createFontPromise(fontURLs[j]));
237
+ yield Promise.all(fontPromises);
238
+ data = data.replace("@import url(" + styleUrl + ");", cssString);
239
+ });
240
+ for (let i = 0; i < styleURIs.length; ++i)
241
+ replacementPromises.push(createStylePromise(styleURIs[i]));
242
+ yield Promise.all(replacementPromises);
243
+ const du = "data:image/svg+xml," + encodeURIComponent(data);
244
+ const img = new Image(); // same as document.createElement('img')
245
+ img.crossOrigin = "Anonymous";
246
+ const promise = new Promise((resolve, reject) => {
247
+ img.onload = () => resolve();
248
+ img.onerror = reject;
249
+ });
250
+ img.src = du;
251
+ yield promise;
252
+ return img;
253
+ });
254
+ }
255
+ responseToImage(response) {
256
+ return __awaiter(this, void 0, void 0, function* () {
257
+ // if we already receive and image, this conversion already happened
258
+ if (response.data instanceof HTMLImageElement)
259
+ return response.data;
260
+ if (response.headers["content-type"] === "image/svg+xml") {
261
+ const img = yield this.processSVG(response.data.blob);
262
+ return img;
263
+ }
264
+ else {
265
+ const img = new Image();
266
+ const promise = new Promise((resolve, reject) => {
267
+ img.onload = () => resolve();
268
+ img.onerror = reject;
269
+ });
270
+ img.crossOrigin = "anonymous";
271
+ img.src = URL.createObjectURL(response.data.blob);
272
+ yield promise;
273
+ URL.revokeObjectURL(img.src);
274
+ return img;
275
+ }
276
+ });
277
+ }
278
+ toAlpha(color) {
279
+ const c = this.toHexColor(color);
280
+ if (c.length <= 8)
281
+ return 1;
282
+ return parseInt(c.slice(c.length - 2, c.length), 16) / 255;
283
+ }
284
+ toColorArray(color) {
285
+ if (typeof color !== "string" || !color.startsWith("#"))
286
+ color = this.toHexColor(color);
287
+ const tColor = new tinycolor_1.TinyColor(color);
288
+ const rgb = tColor.toRgb();
289
+ return [rgb.r / 255.0, rgb.g / 255.0, rgb.b / 255.0];
290
+ }
291
+ /**
292
+ * @param color
293
+ * @param defColor
294
+ */
295
+ toHex8Color(color, defColorString = "#000") {
296
+ const c = this.toHexColor(color, defColorString);
297
+ const tColor = new tinycolor_1.TinyColor(c);
298
+ const cH8 = tColor.toHex8String();
299
+ return cH8.replace("#", "0x");
300
+ }
301
+ /**
302
+ * This color converter is mostly left 'as-is' from viewer v2.
303
+ * I didn't want to break something that works.
304
+ *
305
+ * @param color
306
+ * @param defColor
307
+ */
308
+ toHexColor(color, defColorString = "#000") {
309
+ if (!color || color === "default")
310
+ return defColorString;
311
+ if (color.constructor === Float32Array)
312
+ color = Array.from(color);
313
+ const tColor = new tinycolor_1.TinyColor(color);
314
+ if (color instanceof tinycolor_1.TinyColor)
315
+ return this.tinyColorToString(tColor);
316
+ // check if we got a number
317
+ if (typeof color === "number") {
318
+ let cs = color.toString(16);
319
+ const cl = cs.length;
320
+ if (cl < 3)
321
+ cs = cs.padStart(3, "0");
322
+ else if (cl < 6)
323
+ cs = cs.padStart(6, "0");
324
+ else if (cl < 8)
325
+ cs = cs.padEnd(8, "0");
326
+ const tc = new tinycolor_1.TinyColor(cs);
327
+ return tc.isValid ? this.tinyColorToString(tc) : defColorString;
328
+ }
329
+ // check if the input is a THREE.Color
330
+ if (typeof color === "object" &&
331
+ "isColor" in color &&
332
+ "getHexString" in color &&
333
+ typeof color.getHexString ===
334
+ "function") {
335
+ const tc = new tinycolor_1.TinyColor(color.getHexString());
336
+ return tc.isValid ? this.tinyColorToString(tc) : defColorString;
337
+ }
338
+ // check for array of numbers
339
+ if (Array.isArray(color) && (color.length == 3 || color.length == 4)) {
340
+ let isRGBArray = true;
341
+ for (let i = 0; i < 3; ++i) {
342
+ color[i] = parseFloat(color[i]);
343
+ if (isNaN(color[i])) {
344
+ isRGBArray = false;
345
+ }
346
+ }
347
+ if (!isRGBArray)
348
+ return defColorString;
349
+ const tc = new tinycolor_1.TinyColor({
350
+ r: Math.max(0, Math.min(color[0], 255)),
351
+ g: Math.max(0, Math.min(color[1], 255)),
352
+ b: Math.max(0, Math.min(color[2], 255)),
353
+ });
354
+ if (color.length == 4) {
355
+ const a = parseFloat(color[3]);
356
+ if (!isNaN(a)) {
357
+ tc.setAlpha(Math.max(0, Math.min(a, 255)) / 255);
358
+ }
359
+ }
360
+ return tc.isValid ? this.tinyColorToString(tc) : defColorString;
361
+ }
362
+ // if we got something other than a string, check if
363
+ // tinycolor can work with it
364
+ if (typeof color !== "string") {
365
+ const tc = new tinycolor_1.TinyColor(color);
366
+ return tc.isValid ? this.tinyColorToString(tc) : defColorString;
367
+ }
368
+ // tinycolor doesn't like 0x
369
+ const tmpColor = color.replace("0x", "#");
370
+ // if we got no alpha value, add full opacity
371
+ if (tmpColor.match(/^#[a-f0-9]{6}$/i) !== null) {
372
+ const tc = new tinycolor_1.TinyColor(tmpColor + "ff");
373
+ return tc.isValid ? this.tinyColorToString(tc) : defColorString;
374
+ }
375
+ // standard case
376
+ if (tmpColor.match(/^#[a-f0-9]{8}$/i) !== null) {
377
+ const tc = new tinycolor_1.TinyColor(tmpColor);
378
+ return tc.isValid ? this.tinyColorToString(tc) : defColorString;
379
+ }
380
+ // correct number which have the alpha value defined as a single hex digit
381
+ if (tmpColor.match(/^#[a-f0-9]{7}$/i) !== null) {
382
+ const tc = new tinycolor_1.TinyColor(tmpColor.slice(0, 7) + "0" + tmpColor.slice(-1));
383
+ return tc.isValid ? this.tinyColorToString(tc) : defColorString;
384
+ }
385
+ // check if tinycolor understands the string
386
+ const tc = new tinycolor_1.TinyColor(tmpColor);
387
+ return tc.isValid ? this.tinyColorToString(tc) : defColorString;
388
+ }
389
+ toThreeJsColorInput(color) {
390
+ const c = this.toHexColor(color);
391
+ return c.slice(0, c.length - 2);
392
+ }
393
+ toVec3(point) {
394
+ if (Array.isArray(point) &&
395
+ point.length >= 3 &&
396
+ typeof point[0] === "number" &&
397
+ typeof point[1] === "number" &&
398
+ typeof point[2] === "number")
399
+ return gl_matrix_1.vec3.fromValues(point[0], point[1], point[2]);
400
+ const pointCast1 = point;
401
+ if ((pointCast1.x || pointCast1.x === 0) &&
402
+ typeof pointCast1.x === "number" &&
403
+ (pointCast1.y || pointCast1.y === 0) &&
404
+ typeof pointCast1.y === "number" &&
405
+ (pointCast1.z || pointCast1.z === 0) &&
406
+ typeof pointCast1.z === "number")
407
+ return gl_matrix_1.vec3.fromValues(pointCast1.x, pointCast1.y, pointCast1.z);
408
+ const pointCast2 = point;
409
+ if ((pointCast2.X || pointCast2.X === 0) &&
410
+ typeof pointCast2.X === "number" &&
411
+ (pointCast2.Y || pointCast2.Y === 0) &&
412
+ typeof pointCast2.Y === "number" &&
413
+ (pointCast2.Z || pointCast2.Z === 0) &&
414
+ typeof pointCast2.Z === "number")
415
+ return gl_matrix_1.vec3.fromValues(pointCast2.X, pointCast2.Y, pointCast2.Z);
416
+ return gl_matrix_1.vec3.create();
417
+ }
418
+ // #endregion Public Methods (8)
419
+ // #region Private Methods (1)
420
+ tinyColorToString(color) {
421
+ return color.toHex8String();
422
+ }
423
+ }
424
+ exports.Converter = Converter;
425
425
  //# sourceMappingURL=Converter.js.map