@3dsource/utils 1.0.9 → 1.0.10

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 (140) hide show
  1. package/eslint.config.js +37 -0
  2. package/ng-package.json +7 -0
  3. package/package.json +4 -14
  4. package/{lib/color/CMYKtoRGB.d.ts → src/lib/color/CMYKtoRGB.ts} +11 -1
  5. package/src/lib/color/HEXtoRGB.ts +9 -0
  6. package/src/lib/color/HSVtoRGB.ts +82 -0
  7. package/{lib/color/RGBtoCMYK.d.ts → src/lib/color/RGBtoCMYK.ts} +31 -1
  8. package/src/lib/color/RGBtoHEX.ts +17 -0
  9. package/src/lib/color/RGBtoHSV.ts +53 -0
  10. package/src/lib/color/hsv.ts +14 -0
  11. package/src/lib/color/max.ts +18 -0
  12. package/src/lib/color/min.ts +18 -0
  13. package/src/lib/color/overlay.ts +25 -0
  14. package/{lib/color/rgb.d.ts → src/lib/color/rgb.ts} +3 -1
  15. package/src/lib/color/sub.ts +18 -0
  16. package/src/lib/color/subtract.ts +27 -0
  17. package/src/lib/color/sum.ts +19 -0
  18. package/{lib/color/toRGB.d.ts → src/lib/color/toRGB.ts} +7 -1
  19. package/src/lib/color/toRGBA.ts +8 -0
  20. package/src/lib/constants/color-codes.constant.ts +9 -0
  21. package/src/lib/csv/CSV2Array.ts +66 -0
  22. package/src/lib/csv/CSV2Records.ts +56 -0
  23. package/src/lib/csv/ObjectToCSV.ts +21 -0
  24. package/src/lib/dev/dev3d.ts +1 -0
  25. package/src/lib/dev/logger.ts +94 -0
  26. package/src/lib/dev/timeToString.ts +16 -0
  27. package/src/lib/filenaming/cleanupFileName.ts +18 -0
  28. package/src/lib/filenaming/makePath.ts +5 -0
  29. package/src/lib/filenaming/normalizePath.ts +9 -0
  30. package/src/lib/geom/expandOverRectangle.ts +17 -0
  31. package/src/lib/geom/fitIntoRectangle.ts +43 -0
  32. package/{lib/geom/interfaces/area.interface.d.ts → src/lib/geom/interfaces/area.interface.ts} +2 -1
  33. package/{lib/geom/interfaces/rect.interface.d.ts → src/lib/geom/interfaces/rect.interface.ts} +2 -2
  34. package/src/lib/geom/interfaces/size.interface.ts +4 -0
  35. package/src/lib/geom/interfaces//321/201oords.interface.ts +4 -0
  36. package/src/lib/helpers/BatchLoader.ts +243 -0
  37. package/src/lib/helpers/KeyboardNumericCode.ts +118 -0
  38. package/src/lib/helpers/debounce.ts +10 -0
  39. package/src/lib/helpers/generate-uuid.ts +5 -0
  40. package/{lib/helpers/index.d.ts → src/lib/helpers/index.ts} +1 -0
  41. package/src/lib/helpers/save-to-local-drive.ts +31 -0
  42. package/src/lib/helpers/serialize.ts +11 -0
  43. package/src/lib/helpers/short-hash.ts +20 -0
  44. package/src/lib/helpers/signal.ts +46 -0
  45. package/src/lib/helpers/sleep.ts +3 -0
  46. package/src/lib/helpers/trimLastSlashFromUrl.ts +9 -0
  47. package/src/lib/image/SaveImage.ts +65 -0
  48. package/src/lib/image/getCanvasCached.ts +16 -0
  49. package/src/lib/image/getSnapshot.ts +99 -0
  50. package/src/lib/image/loadImage.ts +13 -0
  51. package/src/lib/interfaces/image-output.ts +8 -0
  52. package/{lib/interfaces/load-args-tmp.interface.d.ts → src/lib/interfaces/load-args-tmp.interface.ts} +2 -1
  53. package/src/lib/interfaces/load-args.interface.ts +15 -0
  54. package/{lib/math/baseSortedIndex.d.ts → src/lib/math/baseSortedIndex.ts} +19 -1
  55. package/{lib/math/calculateMedian.d.ts → src/lib/math/calculateMedian.ts} +17 -1
  56. package/{lib/math/circularIndex.d.ts → src/lib/math/circularIndex.ts} +5 -1
  57. package/src/lib/math/clampf.ts +14 -0
  58. package/src/lib/math/degrees.ts +7 -0
  59. package/{lib/math/floatCompare.d.ts → src/lib/math/floatCompare.ts} +30 -3
  60. package/{lib/math/inverseLerp.d.ts → src/lib/math/inverseLerp.ts} +22 -1
  61. package/src/lib/math/lerp.ts +12 -0
  62. package/{lib/mutex/Mutex.d.ts → src/lib/mutex/Mutex.ts} +15 -8
  63. package/{lib/mutex/Semaphore.d.ts → src/lib/mutex/Semaphore.ts} +27 -7
  64. package/src/lib/mutex/TaskRunner.ts +26 -0
  65. package/src/lib/predicates/operators.ts +75 -0
  66. package/{lib/predicates/textForSearch.d.ts → src/lib/predicates/textForSearch.ts} +17 -1
  67. package/{lib/predicates/where.d.ts → src/lib/predicates/where.ts} +32 -2
  68. package/src/lib/rxjs/leadingTrailingDebounceTime.ts +86 -0
  69. package/{lib/rxjs/smoothTransition.d.ts → src/lib/rxjs/smoothTransition.ts} +19 -1
  70. package/src/lib/rxjs/tapLog.ts +13 -0
  71. package/src/lib/strings/pad.ts +18 -0
  72. package/tsconfig.lib.json +13 -0
  73. package/tsconfig.lib.prod.json +11 -0
  74. package/fesm2022/3dsource-utils.mjs +0 -1886
  75. package/fesm2022/3dsource-utils.mjs.map +0 -1
  76. package/index.d.ts +0 -5
  77. package/lib/color/HEXtoRGB.d.ts +0 -5
  78. package/lib/color/HSVtoRGB.d.ts +0 -21
  79. package/lib/color/RGBtoHEX.d.ts +0 -1
  80. package/lib/color/RGBtoHSV.d.ts +0 -19
  81. package/lib/color/hsv.d.ts +0 -1
  82. package/lib/color/max.d.ts +0 -1
  83. package/lib/color/min.d.ts +0 -1
  84. package/lib/color/overlay.d.ts +0 -1
  85. package/lib/color/sub.d.ts +0 -1
  86. package/lib/color/subtract.d.ts +0 -1
  87. package/lib/color/sum.d.ts +0 -1
  88. package/lib/color/toRGBA.d.ts +0 -1
  89. package/lib/constants/color-codes.constant.d.ts +0 -9
  90. package/lib/csv/CSV2Array.d.ts +0 -1
  91. package/lib/csv/CSV2Records.d.ts +0 -1
  92. package/lib/csv/ObjectToCSV.d.ts +0 -1
  93. package/lib/dev/dev3d.d.ts +0 -1
  94. package/lib/dev/logger.d.ts +0 -11
  95. package/lib/dev/timeToString.d.ts +0 -5
  96. package/lib/filenaming/cleanupFileName.d.ts +0 -1
  97. package/lib/filenaming/makePath.d.ts +0 -1
  98. package/lib/filenaming/normalizePath.d.ts +0 -1
  99. package/lib/geom/expandOverRectangle.d.ts +0 -2
  100. package/lib/geom/fitIntoRectangle.d.ts +0 -2
  101. package/lib/geom/interfaces/size.interface.d.ts +0 -4
  102. package/lib/geom/interfaces//321/201oords.interface.d.ts +0 -4
  103. package/lib/helpers/BatchLoader.d.ts +0 -47
  104. package/lib/helpers/KeyboardNumericCode.d.ts +0 -103
  105. package/lib/helpers/debounce.d.ts +0 -1
  106. package/lib/helpers/generate-uuid.d.ts +0 -1
  107. package/lib/helpers/save-to-local-drive.d.ts +0 -1
  108. package/lib/helpers/serialize.d.ts +0 -1
  109. package/lib/helpers/signal.d.ts +0 -23
  110. package/lib/helpers/sleep.d.ts +0 -1
  111. package/lib/helpers/trimLastSlashFromUrl.d.ts +0 -1
  112. package/lib/image/SaveImage.d.ts +0 -18
  113. package/lib/image/getCanvasCached.d.ts +0 -4
  114. package/lib/image/getSnapshot.d.ts +0 -2
  115. package/lib/image/loadImage.d.ts +0 -1
  116. package/lib/interfaces/image-output.d.ts +0 -7
  117. package/lib/interfaces/load-args.interface.d.ts +0 -15
  118. package/lib/math/clampf.d.ts +0 -8
  119. package/lib/math/degrees.d.ts +0 -2
  120. package/lib/math/lerp.d.ts +0 -7
  121. package/lib/mutex/TaskRunner.d.ts +0 -5
  122. package/lib/predicates/operators.d.ts +0 -32
  123. package/lib/rxjs/leadingTrailingDebounceTime.d.ts +0 -15
  124. package/lib/rxjs/tapLog.d.ts +0 -2
  125. package/lib/strings/pad.d.ts +0 -8
  126. /package/{lib/color/index.d.ts → src/lib/color/index.ts} +0 -0
  127. /package/{lib/constants/index.d.ts → src/lib/constants/index.ts} +0 -0
  128. /package/{lib/csv/index.d.ts → src/lib/csv/index.ts} +0 -0
  129. /package/{lib/dev/index.d.ts → src/lib/dev/index.ts} +0 -0
  130. /package/{lib/filenaming/index.d.ts → src/lib/filenaming/index.ts} +0 -0
  131. /package/{lib/geom/index.d.ts → src/lib/geom/index.ts} +0 -0
  132. /package/{lib/geom/interfaces/index.d.ts → src/lib/geom/interfaces/index.ts} +0 -0
  133. /package/{lib/image/index.d.ts → src/lib/image/index.ts} +0 -0
  134. /package/{lib/interfaces/index.d.ts → src/lib/interfaces/index.ts} +0 -0
  135. /package/{lib/math/index.d.ts → src/lib/math/index.ts} +0 -0
  136. /package/{lib/mutex/index.d.ts → src/lib/mutex/index.ts} +0 -0
  137. /package/{lib/predicates/index.d.ts → src/lib/predicates/index.ts} +0 -0
  138. /package/{lib/rxjs/index.d.ts → src/lib/rxjs/index.ts} +0 -0
  139. /package/{lib/strings/index.d.ts → src/lib/strings/index.ts} +0 -0
  140. /package/{public-api.d.ts → src/public-api.ts} +0 -0
@@ -0,0 +1,94 @@
1
+ import { timeUTCToString } from './timeToString';
2
+ import { Truthy } from '../predicates';
3
+
4
+ export class Logger {
5
+ static isDevMode = Truthy(localStorage.getItem('devMode'));
6
+
7
+ static colored(color: string, background: string, ...args: unknown[]) {
8
+ if (!Logger.isDevMode) {
9
+ return;
10
+ }
11
+
12
+ const [first, ...rest] = args;
13
+ console.log.apply(console, [
14
+ `%c ${timeUTCToString()} ${first} `,
15
+ `color: ${color}; background: ${background};`,
16
+ ...rest,
17
+ ]);
18
+ }
19
+
20
+ static log(...args: unknown[]) {
21
+ if (!Logger.isDevMode) {
22
+ return;
23
+ }
24
+
25
+ console.log.apply(console, [
26
+ `%c ${timeUTCToString()} [ LOG ] `,
27
+ 'color: black; background: #80ff80;',
28
+ ...args,
29
+ ]);
30
+ }
31
+
32
+ static warn(...args: unknown[]) {
33
+ if (!Logger.isDevMode) {
34
+ return;
35
+ }
36
+
37
+ console.warn.apply(console, [
38
+ `%c ${timeUTCToString()} WARN `,
39
+ 'color: black; background: #ffd500;',
40
+ ...args,
41
+ ]);
42
+ }
43
+
44
+ static info(...args: unknown[]) {
45
+ if (!Logger.isDevMode) {
46
+ return;
47
+ }
48
+
49
+ console.log.apply(console, [
50
+ `%c ${timeUTCToString()} [ INFO ] `,
51
+ 'color: white; background: blue;',
52
+ ...args,
53
+ ]);
54
+ }
55
+
56
+ static error(...args: unknown[]) {
57
+ if (!Logger.isDevMode) {
58
+ return;
59
+ }
60
+
61
+ console.error.apply(console, [
62
+ `%c ${timeUTCToString()} ERROR `,
63
+ 'color: white; background: red;',
64
+ ...args,
65
+ ]);
66
+ }
67
+
68
+ static table(...args: unknown[]) {
69
+ if (!Logger.isDevMode) {
70
+ return;
71
+ }
72
+
73
+ // eslint-disable-next-line no-console
74
+ console.table.apply(console, [args]);
75
+ }
76
+
77
+ static time(...args: any) {
78
+ if (!Logger.isDevMode) {
79
+ return;
80
+ }
81
+
82
+ // eslint-disable-next-line no-console,prefer-spread
83
+ console.time.apply(console, args);
84
+ }
85
+
86
+ static timeEnd(...args: any) {
87
+ if (!Logger.isDevMode) {
88
+ return;
89
+ }
90
+
91
+ // eslint-disable-next-line no-console,prefer-spread
92
+ console.timeEnd.apply(console, args);
93
+ }
94
+ }
@@ -0,0 +1,16 @@
1
+ import { pad } from '../strings';
2
+
3
+ /**
4
+ * Create a string of the form 'HOURS.MINUTES.SECONDS.MILLISECONDS'.
5
+ */
6
+ export function timeToString() {
7
+ const date = new Date();
8
+
9
+ return `${pad(date.getHours(), 2)}:${pad(date.getMinutes(), 2)}:${pad(date.getSeconds(), 2)}.${pad(date.getMilliseconds(), 3)}`;
10
+ }
11
+
12
+ export function timeUTCToString() {
13
+ const date = new Date();
14
+
15
+ return `${pad(date.getUTCHours(), 2)}:${pad(date.getUTCMinutes(), 2)}:${pad(date.getUTCSeconds(), 2)}.${pad(date.getUTCMilliseconds(), 3)}`;
16
+ }
@@ -0,0 +1,18 @@
1
+ export function cleanupFileName(value: string): string {
2
+ if (!value) {
3
+ return value;
4
+ }
5
+
6
+ value = value
7
+ .toString()
8
+ .replace(/undefined/g, '')
9
+ .trim()
10
+ .replace(/\//g, '-')
11
+ .replace(/[-]+/g, '-')
12
+ .replace(/[^\w^.-]+/gi, '_')
13
+ .replace(/[\^]+/gi, '_');
14
+
15
+ value = value.split('_').filter(Boolean).join('_').toLowerCase();
16
+
17
+ return value;
18
+ }
@@ -0,0 +1,5 @@
1
+ import { cleanupFileName } from './cleanupFileName';
2
+
3
+ export function makePath(...value: string[]): string {
4
+ return [...value].map((el) => cleanupFileName(el)).join('/');
5
+ }
@@ -0,0 +1,9 @@
1
+ import { cleanupFileName } from './cleanupFileName';
2
+
3
+ export function normalizePath(value: string): string {
4
+ const re = new RegExp('[/\\\\]+', 'g');
5
+ return value
6
+ .split(re)
7
+ .map((el) => cleanupFileName(el))
8
+ .join('/');
9
+ }
@@ -0,0 +1,17 @@
1
+ import type { Area, Rect } from './interfaces';
2
+
3
+ export function expandOverRectangle(objectRect: Rect, areaRect: Rect): Area {
4
+ const ratio: number = objectRect.w / objectRect.h;
5
+ const result: Area = { x: 0, y: 0, w: 0, h: 0, scale: 1 };
6
+ if (areaRect.w / ratio < areaRect.h) {
7
+ result.w = areaRect.h * ratio;
8
+ result.h = areaRect.h;
9
+ } else {
10
+ result.w = areaRect.w;
11
+ result.h = areaRect.w / ratio;
12
+ }
13
+ result.x = areaRect.x + (areaRect.w - result.w) / 2;
14
+ result.y = areaRect.y + (areaRect.h - result.h) / 2;
15
+ result.scale = result.w / objectRect.w;
16
+ return result;
17
+ }
@@ -0,0 +1,43 @@
1
+ import type { Area, Rect } from './interfaces';
2
+
3
+ export function fitIntoRectangle(
4
+ objectRect: Rect,
5
+ areaRect: Rect,
6
+ round = true,
7
+ fixedRatio: number | null = null,
8
+ ): Area {
9
+ const result: Area = { x: 0, y: 0, w: 0, h: 0, scale: 1 };
10
+ const ratio: number = objectRect.h / objectRect.w;
11
+
12
+ if (objectRect.h > objectRect.w) {
13
+ result.h = areaRect.h;
14
+ result.w = areaRect.h / ratio;
15
+
16
+ if (result.w > areaRect.w) {
17
+ result.w = areaRect.w;
18
+ result.h = areaRect.w * ratio;
19
+ }
20
+ } else {
21
+ result.w = areaRect.w;
22
+ result.h = areaRect.w * ratio;
23
+
24
+ if (result.h > areaRect.h) {
25
+ result.h = areaRect.h;
26
+ result.w = areaRect.h / ratio;
27
+ }
28
+ }
29
+
30
+ if (fixedRatio) {
31
+ result.w = objectRect.w * fixedRatio;
32
+ result.h = objectRect.h * fixedRatio;
33
+ }
34
+ const wOut: number = round ? Math.floor(result.w) : result.w;
35
+ const hOut: number = round ? Math.floor(result.h) : result.h;
36
+ return {
37
+ x: areaRect.x + (areaRect.w - wOut) / 2,
38
+ y: areaRect.y + (areaRect.h - hOut) / 2,
39
+ w: wOut,
40
+ h: hOut,
41
+ scale: wOut / objectRect.w,
42
+ };
43
+ }
@@ -1,4 +1,5 @@
1
1
  import type { Rect } from './rect.interface';
2
+
2
3
  export interface Area extends Rect {
3
- scale: number;
4
+ scale: number;
4
5
  }
@@ -1,4 +1,4 @@
1
1
  import type { Size } from './size.interface';
2
2
  import type { Coords } from './сoords.interface';
3
- export interface Rect extends Size, Coords {
4
- }
3
+
4
+ export interface Rect extends Size, Coords {}
@@ -0,0 +1,4 @@
1
+ export interface Size {
2
+ w: number;
3
+ h: number;
4
+ }
@@ -0,0 +1,4 @@
1
+ export interface Coords {
2
+ x: number;
3
+ y: number;
4
+ }
@@ -0,0 +1,243 @@
1
+ import type { LoadArgs, LoadArgsTmp } from '../interfaces';
2
+ import { loadImage } from '../image';
3
+
4
+ export class BatchLoader {
5
+ private maximumSlotsNumber = 1;
6
+ private queue: LoadArgsTmp[] = [];
7
+ private slots: LoadArgsTmp[] = [];
8
+ private _whenDone!: () => any;
9
+
10
+ clear() {
11
+ this.queue.forEach((item) => {
12
+ try {
13
+ if (item.img) {
14
+ item.img.src = '';
15
+ }
16
+ } catch (e) {
17
+ console.warn(e);
18
+ }
19
+
20
+ try {
21
+ item.xhr?.abort();
22
+ } catch (e) {
23
+ console.warn(e);
24
+ }
25
+ });
26
+
27
+ this.slots.forEach((item) => {
28
+ try {
29
+ if (item.img) {
30
+ item.img.src = '';
31
+ }
32
+ } catch (e) {
33
+ console.warn(e);
34
+ }
35
+
36
+ try {
37
+ item.xhr?.abort();
38
+ } catch (e) {
39
+ console.warn(e);
40
+ }
41
+ });
42
+ this.slots.length = 0;
43
+ this.queue.length = 0;
44
+ }
45
+
46
+ /**
47
+ * new settings
48
+ * you must pass new settings
49
+ * @param sett
50
+ */
51
+ setSettings(sett: any) {
52
+ this.maximumSlotsNumber =
53
+ sett.maximumSlotsNumber !== undefined
54
+ ? sett.maximumSlotsNumber
55
+ : this.maximumSlotsNumber;
56
+ }
57
+
58
+ /**
59
+ * execute with a chosen file
60
+ * @param id
61
+ * @param func
62
+ */
63
+ withItem(id: string, func: (item: LoadArgs) => any): boolean {
64
+ let item = this.getById(id);
65
+ if (!item) {
66
+ return false;
67
+ }
68
+ item = func(item);
69
+ this.queue.sort(this.sortByOrder);
70
+ return true;
71
+ }
72
+
73
+ remove(id: string): LoadArgs[] {
74
+ this.queue = this.queue.filter((arg) => arg.id !== id);
75
+ return this.queue;
76
+ }
77
+
78
+ /**
79
+ * executes when all files are downloaded
80
+ * @param cb
81
+ */
82
+ whenDone(cb: any) {
83
+ this._whenDone = cb;
84
+ }
85
+
86
+ // order {number} lower will execute first, default *100*
87
+ load(args: LoadArgs[]) {
88
+ const out: { path: string; self?: any; id: string }[] = args
89
+ .filter((arg) => !!arg.path)
90
+ .map((arg) => ({
91
+ path: arg.path,
92
+ id: this.add(arg),
93
+ }));
94
+
95
+ this.queue.sort(this.sortByOrder);
96
+ this.checkSlots();
97
+
98
+ return out;
99
+ }
100
+
101
+ /**
102
+ * operates with one file
103
+ * @param item
104
+ * @private
105
+ */
106
+ private add(item: LoadArgs): string {
107
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
108
+ const that = this;
109
+ const temp: LoadArgsTmp = {
110
+ id: item.id,
111
+ resolutionId: null,
112
+ useXhr: item.useXhr,
113
+ order: item.order !== undefined ? item.order : 100,
114
+ fallBack: item.fallBack,
115
+ path: item.path,
116
+ onLoadEnd: item.onLoadEnd,
117
+ onProgress: item.onProgress,
118
+ onLoadStart: item.onLoadStart,
119
+ extra: item.extra,
120
+ };
121
+
122
+ let retryCount = 1;
123
+ if (temp.useXhr) {
124
+ temp.xhr = this.getXmlHttp();
125
+ temp.xhr.onloadstart = (data: ProgressEvent) => item.onLoadStart(data);
126
+ temp.xhr.onprogress = (data: ProgressEvent) => item.onProgress(data);
127
+ temp.xhr.onreadystatechange = async function (data: any) {
128
+ if (this.readyState === 1 && this.status === 0) {
129
+ return;
130
+ }
131
+ if (
132
+ this.readyState === 4 &&
133
+ (this.status === 404 || this.status === 0)
134
+ ) {
135
+ temp.error = true;
136
+ that.loadEnd(temp);
137
+ return;
138
+ }
139
+ if (this.readyState === 4 && this.status === 200) {
140
+ const urlCreator = window.URL;
141
+ const imageUrl = urlCreator.createObjectURL(data.target.response);
142
+ temp.img = await loadImage(imageUrl);
143
+ that.loadEnd(temp);
144
+ return;
145
+ }
146
+ };
147
+ } else {
148
+ temp.img = new Image();
149
+ temp.img.crossOrigin = 'anonymous';
150
+ temp.img.onload = () => {
151
+ that.loadEnd(temp);
152
+ };
153
+ temp.img.onerror = () => {
154
+ if (temp.fallBack && retryCount-- > 0) {
155
+ console.warn('Fallback used =>', temp.path, '=>', temp.fallBack);
156
+ if (temp.img) {
157
+ temp.img.onload = null;
158
+ temp.img.src = temp.fallBack;
159
+ }
160
+
161
+ that.loadEnd(temp);
162
+ } else {
163
+ temp.error = true;
164
+ that.loadEnd(temp);
165
+ }
166
+ };
167
+ }
168
+ this.queue.push(temp);
169
+ return temp.id as string;
170
+ }
171
+
172
+ private sortByOrder(a: LoadArgs, b: LoadArgs): number {
173
+ return a.order > b.order ? 1 : a.order < b.order ? -1 : 0;
174
+ }
175
+
176
+ private loadEnd(item: LoadArgs) {
177
+ if (item.onLoadEnd !== undefined) {
178
+ for (let i = 0, len = this.slots.length; i < len; i += 1) {
179
+ if (this.slots[i].id === item.id) {
180
+ this.slots.splice(i, 1);
181
+ break;
182
+ }
183
+ }
184
+ item.onLoadEnd(item);
185
+ }
186
+ this.checkSlots();
187
+ }
188
+
189
+ private checkSlots() {
190
+ while (
191
+ (this.slots.length < this.maximumSlotsNumber ||
192
+ this.maximumSlotsNumber === -1) &&
193
+ this.queue.length
194
+ ) {
195
+ this.slots.push(this.queue.shift() as LoadArgsTmp);
196
+ const slot: LoadArgsTmp = this.slots[
197
+ this.slots.length - 1
198
+ ] as LoadArgsTmp;
199
+ if (slot.useXhr) {
200
+ slot.xhr?.open('GET', slot.path, true);
201
+ slot.xhr?.send(null);
202
+ } else {
203
+ if (slot.img) {
204
+ slot.img.src = slot.path;
205
+ }
206
+ }
207
+ }
208
+
209
+ if (
210
+ this.slots.length === 0 &&
211
+ this.queue.length === 0 &&
212
+ this._whenDone !== undefined
213
+ ) {
214
+ this._whenDone();
215
+ }
216
+ }
217
+
218
+ /**
219
+ * get Item By id for interaction with files in this.queue
220
+ * @param id
221
+ * @private
222
+ */
223
+ private getById(id: string): LoadArgs | null {
224
+ for (let i = 0, len = this.queue.length; i < len; i += 1) {
225
+ if (this.queue[i].id === id) {
226
+ return this.queue[i];
227
+ }
228
+ }
229
+ return null;
230
+ }
231
+
232
+ private getXmlHttp(): XMLHttpRequest {
233
+ let xhr = null;
234
+ try {
235
+ xhr = new XMLHttpRequest();
236
+ xhr.responseType = 'blob';
237
+ } catch (e) {
238
+ console.warn(e);
239
+ }
240
+
241
+ return xhr as any;
242
+ }
243
+ }
@@ -0,0 +1,118 @@
1
+ const KeyboardNumericCode = {
2
+ Backspace: 8,
3
+ Tab: 9,
4
+ Numpad5: 12,
5
+ NumpadEnter: 13,
6
+ ShiftRight: 16,
7
+ ControlRight: 17,
8
+ ControlLeft: 17,
9
+ AltRight: 18,
10
+ Escape: 27,
11
+ Space: 32,
12
+ Numpad9: 33,
13
+ Numpad3: 34,
14
+ Numpad1: 35,
15
+ Numpad7: 36,
16
+ Numpad4: 37,
17
+ Numpad8: 38,
18
+ Numpad6: 39,
19
+ Numpad2: 40,
20
+ Numpad0: 45,
21
+ NumpadDecimal: 46,
22
+ Digit0: 48,
23
+ Digit1: 49,
24
+ Digit2: 50,
25
+ Digit3: 51,
26
+ Digit4: 52,
27
+ Digit5: 53,
28
+ Digit6: 54,
29
+ Digit7: 55,
30
+ Digit8: 56,
31
+ Digit9: 57,
32
+ KeyA: 65,
33
+ KeyB: 66,
34
+ KeyC: 67,
35
+ KeyD: 68,
36
+ KeyE: 69,
37
+ KeyF: 70,
38
+ KeyG: 71,
39
+ KeyH: 72,
40
+ KeyI: 73,
41
+ KeyJ: 74,
42
+ KeyK: 75,
43
+ KeyL: 76,
44
+ KeyM: 77,
45
+ KeyN: 78,
46
+ KeyO: 79,
47
+ KeyP: 80,
48
+ KeyQ: 81,
49
+ KeyR: 82,
50
+ KeyS: 83,
51
+ KeyT: 84,
52
+ KeyU: 85,
53
+ KeyV: 86,
54
+ KeyW: 87,
55
+ KeyX: 88,
56
+ KeyY: 89,
57
+ KeyZ: 90,
58
+ MetaLeft: 91,
59
+ ContextMenu: 93,
60
+ NumpadMultiply: 106,
61
+ NumpadAdd: 107,
62
+ NumpadSubtract: 109,
63
+ NumpadDivide: 111,
64
+ F1: 112,
65
+ F2: 113,
66
+ F3: 114,
67
+ F4: 115,
68
+ F5: 116,
69
+ F6: 117,
70
+ F7: 118,
71
+ F8: 119,
72
+ F9: 120,
73
+ F10: 121,
74
+ F11: 122,
75
+ F12: 123,
76
+ NumLock: 144,
77
+ ScrollLock: 145,
78
+ Semicolon: 186,
79
+ Equal: 187,
80
+ Comma: 188,
81
+ Minus: 189,
82
+ Period: 190,
83
+ Slash: 191,
84
+ Backquote: 192,
85
+ BracketLeft: 219,
86
+ Backslash: 220,
87
+ BracketRight: 221,
88
+ Quote: 222,
89
+ IntlBackslash: 226,
90
+ ArrowUp: 38,
91
+ ArrowDown: 40,
92
+ ArrowLeft: 37,
93
+ ArrowRight: 39,
94
+ } as const;
95
+
96
+ type IKeyName = keyof typeof KeyboardNumericCode;
97
+ type IKeyCode = (typeof KeyboardNumericCode)[IKeyName];
98
+
99
+ type InvertedKeyMapType = {
100
+ [K in IKeyName as (typeof KeyboardNumericCode)[K]]: K;
101
+ };
102
+ const InvertedKeyMapValues = {} as { [K in IKeyCode]: IKeyName[K] };
103
+
104
+ //For use for InvertedKeyMap[32] will return 'Space' and so on
105
+ const InvertedKeyMap = InvertedKeyMapValues as InvertedKeyMapType;
106
+
107
+ const KeyboardStringCode = {} as { [K in IKeyName]: K };
108
+
109
+ Object.entries(KeyboardNumericCode).forEach(
110
+ // @ts-expect-error @typescript-eslint/ban-ts-comment
111
+ ([key, value]: [IKeyName, IKeyCode]) => {
112
+ InvertedKeyMapValues[value] = key;
113
+ // @ts-expect-error @typescript-eslint/ban-ts-comment
114
+ KeyboardStringCode[key] = key;
115
+ },
116
+ );
117
+ export type { IKeyName, IKeyCode };
118
+ export { KeyboardStringCode, InvertedKeyMap, KeyboardNumericCode };
@@ -0,0 +1,10 @@
1
+ export const debounce = <T extends (...args: any[]) => any>(
2
+ fn: T,
3
+ ms = 300,
4
+ ) => {
5
+ let timeoutId: ReturnType<typeof setTimeout>;
6
+ return function (this: any, ...args: any[]) {
7
+ clearTimeout(timeoutId);
8
+ timeoutId = setTimeout(() => fn.apply(this, args), ms);
9
+ };
10
+ };
@@ -0,0 +1,5 @@
1
+ import { v4 as uuidv4 } from 'uuid';
2
+
3
+ export function generateUuid() {
4
+ return uuidv4();
5
+ }
@@ -7,3 +7,4 @@ export * from './sleep';
7
7
  export * from './trimLastSlashFromUrl';
8
8
  export * from './signal';
9
9
  export * from './generate-uuid';
10
+ export * from './short-hash';
@@ -0,0 +1,31 @@
1
+ export const saveToLocalDrive = (uri: string, name: string) => {
2
+ if (!uri) {
3
+ return;
4
+ }
5
+
6
+ if ((navigator as any).msSaveBlob) {
7
+ // IE10+
8
+ try {
9
+ return (navigator as any).msSaveBlob(uri, name);
10
+ } catch (e) {
11
+ console.warn(e);
12
+ }
13
+ } else {
14
+ const link = document.createElement('a');
15
+ link.target = '_blank';
16
+ link.href = uri;
17
+ link.download = name;
18
+
19
+ document.body.appendChild(link);
20
+
21
+ if (link.click) {
22
+ link.click();
23
+ } else {
24
+ const event = document.createEvent('MouseEvents');
25
+ (event as any).initMouseEvent('click', true, true, window);
26
+ link.dispatchEvent(event);
27
+ }
28
+
29
+ document.body.removeChild(link);
30
+ }
31
+ };
@@ -0,0 +1,11 @@
1
+ export function serialize(obj: any): string {
2
+ const str = [];
3
+
4
+ for (const p in obj) {
5
+ if (Object.prototype.hasOwnProperty.call(obj, p)) {
6
+ str.push(encodeURIComponent(p) + '=' + encodeURIComponent(obj[p]));
7
+ }
8
+ }
9
+
10
+ return str.join('&');
11
+ }
@@ -0,0 +1,20 @@
1
+ import { Md5 } from 'ts-md5';
2
+
3
+ export function shortHash<T>(data: T, shorten?: boolean): string;
4
+ export function shortHash(data: null | undefined, shorten?: boolean): null;
5
+ export function shortHash<T>(
6
+ data: T | null | undefined,
7
+ shorten = true,
8
+ ): string | null {
9
+ if (!data) {
10
+ return null;
11
+ }
12
+
13
+ const stringify: string = Md5.hashStr(JSON.stringify(data));
14
+
15
+ if (shorten) {
16
+ return parseInt('0x' + stringify.substring(0, 10), 16).toString(32);
17
+ }
18
+
19
+ return stringify;
20
+ }