@esposter/shared 4.2.0 → 4.3.2

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.
package/dist/index.js ADDED
@@ -0,0 +1,2197 @@
1
+ import { z } from "zod";
2
+ import { ResultAsync, fromThrowable } from "neverthrow";
3
+ import { parse } from "node-html-parser";
4
+ import mimeDatabase from "mime-db/db.json" with { type: "json" };
5
+ import { defaultTreeAdapter, html as html$1, parseFragment } from "parse5";
6
+ //#region src/models/error/ForbiddenError.ts
7
+ var ForbiddenError = class extends Error {
8
+ constructor(message) {
9
+ super(message);
10
+ this.name = "ForbiddenError";
11
+ }
12
+ };
13
+ //#endregion
14
+ //#region src/models/error/InvalidOperationError.ts
15
+ var InvalidOperationError = class extends Error {
16
+ constructor(operation, name, message) {
17
+ super(`Invalid operation: ${operation}, name: ${name}, ${message}`);
18
+ this.name = "InvalidOperationError";
19
+ }
20
+ };
21
+ //#endregion
22
+ //#region src/models/error/NotFoundError.ts
23
+ var NotFoundError = class extends Error {
24
+ constructor(name, id) {
25
+ super(`${name} is not found for id: ${id}`);
26
+ this.name = "NotFoundError";
27
+ }
28
+ };
29
+ //#endregion
30
+ //#region src/models/error/NotInitializedError.ts
31
+ var NotInitializedError = class extends Error {
32
+ constructor(name) {
33
+ super(`${name} is not initialized`);
34
+ this.name = "NotInitializedError";
35
+ }
36
+ };
37
+ //#endregion
38
+ //#region src/models/error/WordFilteredError.ts
39
+ var WordFilteredError = class extends Error {
40
+ constructor(message) {
41
+ super(message);
42
+ this.name = "WordFilteredError";
43
+ }
44
+ };
45
+ //#endregion
46
+ //#region src/models/shared/Operation.ts
47
+ let Operation = /* @__PURE__ */ function(Operation) {
48
+ Operation["Create"] = "Create";
49
+ Operation["Delete"] = "Delete";
50
+ Operation["Push"] = "Push";
51
+ Operation["Read"] = "Read";
52
+ Operation["Unshift"] = "Unshift";
53
+ Operation["Update"] = "Update";
54
+ return Operation;
55
+ }({});
56
+ //#endregion
57
+ //#region src/models/eventEmitter/TypedEventEmitter.ts
58
+ var TypedEventEmitter = class {
59
+ #entriesMap = /* @__PURE__ */ new Map();
60
+ emit(event, ...args) {
61
+ const entries = this.#entriesMap.get(event) ?? [];
62
+ if (entries.length === 0) return false;
63
+ this.#setEntries(event, entries.filter((entry) => !entry.isOnce));
64
+ for (const { listener } of entries) listener(...args);
65
+ return true;
66
+ }
67
+ off(event, listener) {
68
+ this.#setEntries(event, (this.#entriesMap.get(event) ?? []).filter((entry) => entry.listener !== listener));
69
+ }
70
+ on(event, listener) {
71
+ this.#addEntry(event, listener, false);
72
+ }
73
+ once(event, listener) {
74
+ this.#addEntry(event, listener, true);
75
+ }
76
+ removeAllListeners(event) {
77
+ if (event === void 0) this.#entriesMap.clear();
78
+ else this.#entriesMap.delete(event);
79
+ }
80
+ #addEntry(event, listener, isOnce) {
81
+ if (typeof listener !== "function") throw new InvalidOperationError("Create", String(event), "The listener must be a function");
82
+ this.#setEntries(event, [...this.#entriesMap.get(event) ?? [], {
83
+ isOnce,
84
+ listener
85
+ }]);
86
+ }
87
+ #setEntries(event, entries) {
88
+ if (entries.length === 0) this.#entriesMap.delete(event);
89
+ else this.#entriesMap.set(event, entries);
90
+ }
91
+ };
92
+ //#endregion
93
+ //#region src/models/jsonPatch/JsonPatchOperationType.ts
94
+ let JsonPatchOperationType = /* @__PURE__ */ function(JsonPatchOperationType) {
95
+ JsonPatchOperationType["Add"] = "add";
96
+ JsonPatchOperationType["Copy"] = "copy";
97
+ JsonPatchOperationType["Move"] = "move";
98
+ JsonPatchOperationType["Remove"] = "remove";
99
+ JsonPatchOperationType["Replace"] = "replace";
100
+ JsonPatchOperationType["Test"] = "test";
101
+ return JsonPatchOperationType;
102
+ }({});
103
+ //#endregion
104
+ //#region src/models/message/MentionType.ts
105
+ let MentionType = /* @__PURE__ */ function(MentionType) {
106
+ MentionType["Role"] = "role";
107
+ MentionType["User"] = "user";
108
+ return MentionType;
109
+ }({});
110
+ //#endregion
111
+ //#region src/models/object/ObjectMethod.ts
112
+ let ObjectMethod = /* @__PURE__ */ function(ObjectMethod) {
113
+ ObjectMethod["ToString"] = "toString";
114
+ ObjectMethod["ValueOf"] = "valueOf";
115
+ return ObjectMethod;
116
+ }({});
117
+ //#endregion
118
+ //#region src/services/app/constants.ts
119
+ const MAX_READ_LIMIT = 1e3;
120
+ const SITE_NAME = "Esposter";
121
+ const KIBIBYTE = 1024;
122
+ const GIBIBYTE = KIBIBYTE ** 2 * KIBIBYTE;
123
+ //#endregion
124
+ //#region src/models/router/RoutePath.ts
125
+ const RoutePath = {
126
+ About: "/about",
127
+ Achievements: "/achievements",
128
+ Anime: "/anime",
129
+ Calls: (id) => `/calls/${id}`,
130
+ CallsIndex: "/calls",
131
+ Clicker: "/clicker",
132
+ Dungeons: "/dungeons",
133
+ FluidSimulator: "/fluid-simulator",
134
+ Genshin: "/genshin",
135
+ Github: `https://github.com/${SITE_NAME}/${SITE_NAME}`,
136
+ Index: "/",
137
+ Login: "/login",
138
+ Messages: (id) => `/messages/${id}`,
139
+ MessagesDraftsAndSent: "/messages/draftsandsent",
140
+ MessagesFriends: "/messages/friends",
141
+ MessagesIndex: "/messages",
142
+ MessagesInvite: (code) => `/messages/invite/${code}`,
143
+ MessagesMessage: (id, rowKey) => `/messages/${id}/${rowKey}`,
144
+ MessagesThread: (id, rowKey) => `/messages/${id}/thread/${rowKey}`,
145
+ Post: (id) => `/post/${id}`,
146
+ PostCreate: "/post/create",
147
+ PostUpdate: (id) => `/post/update/${id}`,
148
+ PrivacyPolicy: "/privacy-policy",
149
+ Resource: (id) => `/resource-explorer/${id}`,
150
+ ResourceExplorer: "/resource-explorer",
151
+ ResourceExplorerAll: "/resource-explorer/all",
152
+ ResourceExplorerCreate: "/resource-explorer/create",
153
+ ResourceExplorerCreateType: (type) => `/resource-explorer/create/${type}`,
154
+ ResourceExplorerFavorites: "/resource-explorer/favorites",
155
+ ResourceExplorerRecents: "/resource-explorer/recents",
156
+ ResourceExplorerRecycleBin: "/resource-explorer/recycle-bin",
157
+ ResourceExplorerTags: "/resource-explorer/tags",
158
+ ResourceItems: (id) => `/resource-explorer/${id}/items`,
159
+ User: (id) => `/user/${id}`,
160
+ UserSettings: "/user/settings",
161
+ View: (type, id) => `/view/${type}/${id}`
162
+ };
163
+ //#endregion
164
+ //#region src/models/shared/ItemEntityType.ts
165
+ const createItemEntityTypeSchema = (schema) => z.object({ type: schema });
166
+ //#endregion
167
+ //#region src/models/shared/ItemMetadata.ts
168
+ var ItemMetadata = class {
169
+ createdAt = /* @__PURE__ */ new Date();
170
+ deletedAt = null;
171
+ updatedAt = /* @__PURE__ */ new Date();
172
+ };
173
+ //#endregion
174
+ //#region src/util/reactivity/getRawData.ts
175
+ const getRawData = (data) => {
176
+ const raw = data && data.__v_raw;
177
+ return raw ? getRawData(raw) : data;
178
+ };
179
+ //#endregion
180
+ //#region src/util/reactivity/toRawDeep.ts
181
+ const toRawDeep = (data) => {
182
+ const rawData = getRawData(data);
183
+ for (const key in rawData) if (Object.hasOwn(rawData, key)) {
184
+ const value = rawData[key];
185
+ if (value !== null && typeof value === "object") rawData[key] = toRawDeep(value);
186
+ }
187
+ return rawData;
188
+ };
189
+ //#endregion
190
+ //#region src/models/shared/Serializable.ts
191
+ var Serializable = class {
192
+ toJSON() {
193
+ return structuredClone(toRawDeep(this));
194
+ }
195
+ };
196
+ //#endregion
197
+ //#region src/services/error/toAppError.ts
198
+ const toAppError = (error) => {
199
+ if (error instanceof Error) return error;
200
+ else if (typeof error === "object" && error !== null && "message" in error && typeof error.message === "string") return new Error(error.message, { cause: error });
201
+ else return new Error(String(error), { cause: error });
202
+ };
203
+ //#endregion
204
+ //#region src/services/error/getResult.ts
205
+ const getResult = (callback) => fromThrowable(callback, toAppError)();
206
+ //#endregion
207
+ //#region src/services/error/getResultAsync.ts
208
+ const getResultAsync = (callback) => ResultAsync.fromThrowable(callback, toAppError)();
209
+ //#endregion
210
+ //#region src/services/error/reportFinalizerError.ts
211
+ const reportFinalizerError = (callbackResult, finalizerError) => {
212
+ callbackResult.match(() => {
213
+ throw finalizerError;
214
+ }, () => {
215
+ console.error(finalizerError);
216
+ });
217
+ };
218
+ //#endregion
219
+ //#region src/util/function/noop.ts
220
+ const noop = () => {};
221
+ //#endregion
222
+ //#region src/services/error/withFinalizer.ts
223
+ const withFinalizer = (callback, finalizer) => {
224
+ const callbackResult = getResult(callback);
225
+ if (finalizer) getResult(finalizer).match(noop, (error) => {
226
+ reportFinalizerError(callbackResult, error);
227
+ });
228
+ return callbackResult.match((value) => value, (error) => {
229
+ throw error;
230
+ });
231
+ };
232
+ //#endregion
233
+ //#region src/services/error/withFinalizerAsync.ts
234
+ const withFinalizerAsync = async (callback, finalizer) => {
235
+ const callbackResult = await getResultAsync(async () => callback());
236
+ if (finalizer) await getResultAsync(async () => finalizer()).match(noop, (error) => {
237
+ reportFinalizerError(callbackResult, error);
238
+ });
239
+ return callbackResult.match((value) => value, (error) => {
240
+ throw error;
241
+ });
242
+ };
243
+ //#endregion
244
+ //#region src/services/history/createHistory.ts
245
+ const createHistory = (limit) => ({
246
+ future: [],
247
+ limit,
248
+ past: []
249
+ });
250
+ //#endregion
251
+ //#region src/services/history/pushHistory.ts
252
+ const pushHistory = (history, entry) => {
253
+ const past = [...history.past, entry];
254
+ return {
255
+ future: [],
256
+ limit: history.limit,
257
+ past: past.slice(Math.max(past.length - history.limit, 0))
258
+ };
259
+ };
260
+ //#endregion
261
+ //#region src/services/history/redoHistory.ts
262
+ const redoHistory = (history) => {
263
+ const [entry] = history.future;
264
+ if (entry === void 0) return { history };
265
+ return {
266
+ entry,
267
+ history: {
268
+ ...pushHistory(history, entry),
269
+ future: history.future.slice(1)
270
+ }
271
+ };
272
+ };
273
+ //#endregion
274
+ //#region src/services/history/undoHistory.ts
275
+ const undoHistory = (history) => {
276
+ const entry = history.past.at(-1);
277
+ if (entry === void 0) return { history };
278
+ return {
279
+ entry,
280
+ history: {
281
+ future: [entry, ...history.future],
282
+ limit: history.limit,
283
+ past: history.past.slice(0, -1)
284
+ }
285
+ };
286
+ };
287
+ //#endregion
288
+ //#region src/services/indexedDb/getRequestError.ts
289
+ const getRequestError = (request) => request.error ?? new DOMException("The request failed without an error", "UnknownError");
290
+ //#endregion
291
+ //#region src/services/indexedDb/getTransactionDone.ts
292
+ const getTransactionDone = (transaction) => new Promise((resolve, reject) => {
293
+ transaction.addEventListener("complete", () => {
294
+ resolve();
295
+ });
296
+ transaction.addEventListener("abort", () => {
297
+ reject(transaction.error ?? new DOMException("The transaction was aborted", "AbortError"));
298
+ });
299
+ });
300
+ //#endregion
301
+ //#region src/services/indexedDb/requestToPromise.ts
302
+ const requestToPromise = (request) => new Promise((resolve, reject) => {
303
+ request.addEventListener("success", () => {
304
+ resolve(request.result);
305
+ });
306
+ request.addEventListener("error", () => {
307
+ reject(getRequestError(request));
308
+ });
309
+ });
310
+ //#endregion
311
+ //#region src/services/indexedDb/wrapIndex.ts
312
+ const wrapIndex = (index) => ({
313
+ getAll: (query, count) => requestToPromise(index.getAll(query, count)),
314
+ getAllKeys: (query, count) => requestToPromise(index.getAllKeys(query, count))
315
+ });
316
+ //#endregion
317
+ //#region src/services/indexedDb/wrapObjectStore.ts
318
+ const wrapObjectStore = (objectStore) => {
319
+ const reader = {
320
+ get: (key) => requestToPromise(objectStore.get(key)),
321
+ getAll: (query, count) => requestToPromise(objectStore.getAll(query, count)),
322
+ getAllKeys: (query, count) => requestToPromise(objectStore.getAllKeys(query, count)),
323
+ index: (name) => wrapIndex(objectStore.index(name))
324
+ };
325
+ const writer = {
326
+ delete: (query) => requestToPromise(objectStore.delete(query)),
327
+ put: (value, key) => requestToPromise(objectStore.put(value, key))
328
+ };
329
+ const creator = { createIndex: (name, keyPath, options) => {
330
+ objectStore.createIndex(name, keyPath, options);
331
+ } };
332
+ return {
333
+ ...reader,
334
+ ...writer,
335
+ ...creator
336
+ };
337
+ };
338
+ //#endregion
339
+ //#region src/services/indexedDb/getTransactionObjectStore.ts
340
+ const getTransactionObjectStore = (transaction) => (name) => wrapObjectStore(transaction.objectStore(name));
341
+ //#endregion
342
+ //#region src/services/indexedDb/wrapTransaction.ts
343
+ const wrapTransaction = (transaction) => ({
344
+ done: getTransactionDone(transaction),
345
+ objectStore: getTransactionObjectStore(transaction)
346
+ });
347
+ //#endregion
348
+ //#region src/services/indexedDb/wrapDatabase.ts
349
+ const wrapDatabase = (database) => {
350
+ const getReadonlyObjectStore = (storeName) => wrapObjectStore(database.transaction(storeName, "readonly").objectStore(storeName));
351
+ const getReadwriteObjectStore = (storeName) => wrapObjectStore(database.transaction(storeName, "readwrite").objectStore(storeName));
352
+ const transaction = (storeNames, mode, options) => {
353
+ const names = typeof storeNames === "string" ? storeNames : [...storeNames];
354
+ return wrapTransaction(database.transaction(names, mode, options));
355
+ };
356
+ return {
357
+ close: () => {
358
+ database.close();
359
+ },
360
+ delete: (storeName, query) => getReadwriteObjectStore(storeName).delete(query),
361
+ get: (storeName, key) => getReadonlyObjectStore(storeName).get(key),
362
+ getAll: (storeName, query, count) => getReadonlyObjectStore(storeName).getAll(query, count),
363
+ getAllKeys: (storeName, query, count) => getReadonlyObjectStore(storeName).getAllKeys(query, count),
364
+ name: database.name,
365
+ put: (storeName, value, key) => getReadwriteObjectStore(storeName).put(value, key),
366
+ transaction
367
+ };
368
+ };
369
+ //#endregion
370
+ //#region src/services/indexedDb/wrapUpgradeDatabase.ts
371
+ const wrapUpgradeDatabase = (database) => ({
372
+ ...wrapDatabase(database),
373
+ createObjectStore: (name, options) => wrapObjectStore(database.createObjectStore(name, options))
374
+ });
375
+ //#endregion
376
+ //#region src/services/indexedDb/wrapUpgradeTransaction.ts
377
+ const wrapUpgradeTransaction = (transaction) => {
378
+ const done = getTransactionDone(transaction);
379
+ getResultAsync(() => done).match(noop, (error) => {
380
+ if (transaction.error) console.error(error);
381
+ });
382
+ return {
383
+ get done() {
384
+ return done;
385
+ },
386
+ objectStore: getTransactionObjectStore(transaction)
387
+ };
388
+ };
389
+ //#endregion
390
+ //#region src/services/indexedDb/openDatabase.ts
391
+ const openDatabase = (name, version, options = {}) => new Promise((resolve, reject) => {
392
+ const request = indexedDB.open(name, version);
393
+ request.addEventListener("blocked", (event) => {
394
+ options.blocked?.(event.oldVersion, event.newVersion);
395
+ });
396
+ request.addEventListener("upgradeneeded", (event) => {
397
+ const { transaction } = request;
398
+ if (!transaction) return;
399
+ getResult(() => options.upgrade?.(wrapUpgradeDatabase(request.result), event.oldVersion, event.newVersion, wrapUpgradeTransaction(transaction))).match(noop, (error) => {
400
+ console.error(error);
401
+ transaction.abort();
402
+ });
403
+ });
404
+ request.addEventListener("success", () => {
405
+ const database = request.result;
406
+ database.addEventListener("close", () => {
407
+ options.terminated?.();
408
+ });
409
+ database.addEventListener("versionchange", (event) => {
410
+ options.blocking?.(event.oldVersion, event.newVersion);
411
+ });
412
+ resolve(wrapDatabase(database));
413
+ });
414
+ request.addEventListener("error", () => {
415
+ reject(getRequestError(request));
416
+ });
417
+ });
418
+ //#endregion
419
+ //#region src/services/jsonPatch/constants.ts
420
+ const APPEND_SEGMENT = "-";
421
+ const JSON_POINTER_REGEX = /^(?:\/(?:[^/~]|~[01])*)*$/u;
422
+ //#endregion
423
+ //#region src/services/jsonPatch/parseArrayIndex.ts
424
+ const ARRAY_INDEX_REGEX = /^(?:0|[1-9]\d*)$/u;
425
+ const parseArrayIndex = (segment, maxIndex) => {
426
+ const index = Number(segment);
427
+ return ARRAY_INDEX_REGEX.test(segment) && index <= maxIndex ? index : void 0;
428
+ };
429
+ //#endregion
430
+ //#region src/services/jsonPatch/parseJsonPointer.ts
431
+ const parseJsonPointer = (pointer) => {
432
+ if (pointer === "") return [];
433
+ else if (!JSON_POINTER_REGEX.test(pointer)) throw new InvalidOperationError("Read", pointer, "not a JSON Pointer");
434
+ return pointer.slice(1).split("/").map((segment) => segment.replaceAll("~1", "/").replaceAll("~0", "~"));
435
+ };
436
+ //#endregion
437
+ //#region src/services/jsonPatch/toJsonPointer.ts
438
+ const toJsonPointer = (segments) => segments.map((segment) => `/${segment.replaceAll("~", "~0").replaceAll("/", "~1")}`).join("");
439
+ //#endregion
440
+ //#region src/util/object/checkIsPlainObject.ts
441
+ const checkIsPlainObject = (data) => {
442
+ if (typeof data !== "object" || data === null) return false;
443
+ const prototype = Object.getPrototypeOf(data);
444
+ return prototype === null || prototype === Object.prototype;
445
+ };
446
+ //#endregion
447
+ //#region src/services/jsonPatch/readJsonValue.ts
448
+ const readJsonValue = (document, segments) => {
449
+ let value = document;
450
+ for (const segment of segments) {
451
+ const index = Array.isArray(value) ? parseArrayIndex(segment, value.length - 1) : void 0;
452
+ if (Array.isArray(value) && index !== void 0) value = value[index];
453
+ else if (checkIsPlainObject(value) && Object.hasOwn(value, segment)) value = value[segment];
454
+ else throw new InvalidOperationError("Read", toJsonPointer(segments), "no such member");
455
+ }
456
+ return value;
457
+ };
458
+ //#endregion
459
+ //#region src/services/jsonPatch/updateJsonValue.ts
460
+ const updateJsonValue = (document, segments, update) => {
461
+ const [segment, ...restSegments] = segments;
462
+ if (segment === void 0) return update(document);
463
+ const index = Array.isArray(document) ? parseArrayIndex(segment, document.length - 1) : void 0;
464
+ if (Array.isArray(document) && index !== void 0) return document.with(index, updateJsonValue(document[index], restSegments, update));
465
+ else if (checkIsPlainObject(document) && Object.hasOwn(document, segment)) return {
466
+ ...document,
467
+ [segment]: updateJsonValue(document[segment], restSegments, update)
468
+ };
469
+ else throw new InvalidOperationError("Update", toJsonPointer(segments), "no such member");
470
+ };
471
+ //#endregion
472
+ //#region src/services/jsonPatch/addJsonValue.ts
473
+ const addJsonValue = (document, path, value) => {
474
+ const segments = parseJsonPointer(path);
475
+ const parentSegments = segments.slice(0, -1);
476
+ const key = segments.at(-1);
477
+ if (key === void 0) return {
478
+ document: value,
479
+ inverses: [{
480
+ op: "replace",
481
+ path,
482
+ value: document
483
+ }]
484
+ };
485
+ const parent = readJsonValue(document, parentSegments);
486
+ if (Array.isArray(parent)) {
487
+ const index = key === "-" ? parent.length : parseArrayIndex(key, parent.length);
488
+ if (index === void 0) throw new InvalidOperationError("Update", path, "no such index in the array");
489
+ return {
490
+ document: updateJsonValue(document, parentSegments, () => parent.toSpliced(index, 0, value)),
491
+ inverses: [{
492
+ op: "remove",
493
+ path: toJsonPointer([...parentSegments, `${index}`])
494
+ }]
495
+ };
496
+ } else if (checkIsPlainObject(parent)) return {
497
+ document: updateJsonValue(document, parentSegments, () => ({
498
+ ...parent,
499
+ [key]: value
500
+ })),
501
+ inverses: [Object.hasOwn(parent, key) ? {
502
+ op: "replace",
503
+ path,
504
+ value: parent[key]
505
+ } : {
506
+ op: "remove",
507
+ path
508
+ }]
509
+ };
510
+ else throw new InvalidOperationError("Update", path, "its parent holds no members");
511
+ };
512
+ //#endregion
513
+ //#region src/services/jsonPatch/removeJsonValue.ts
514
+ const removeJsonValue = (document, path) => {
515
+ const segments = parseJsonPointer(path);
516
+ const parentSegments = segments.slice(0, -1);
517
+ const key = segments.at(-1);
518
+ if (key === void 0) throw new InvalidOperationError("Delete", path, "the root cannot be removed");
519
+ const parent = readJsonValue(document, parentSegments);
520
+ const index = Array.isArray(parent) ? parseArrayIndex(key, parent.length - 1) : void 0;
521
+ if (Array.isArray(parent) && index !== void 0) return {
522
+ document: updateJsonValue(document, parentSegments, () => parent.toSpliced(index, 1)),
523
+ inverses: [{
524
+ op: "add",
525
+ path,
526
+ value: parent[index]
527
+ }]
528
+ };
529
+ else if (checkIsPlainObject(parent) && Object.hasOwn(parent, key)) {
530
+ const { [key]: removedValue, ...restParent } = parent;
531
+ return {
532
+ document: updateJsonValue(document, parentSegments, () => restParent),
533
+ inverses: [{
534
+ op: "add",
535
+ path,
536
+ value: removedValue
537
+ }]
538
+ };
539
+ } else throw new InvalidOperationError("Delete", path, "no such member");
540
+ };
541
+ //#endregion
542
+ //#region src/util/object/checkIsCustomMethod.ts
543
+ const checkIsCustomMethod = (value, methodName) => {
544
+ const method = Reflect.get(value, methodName);
545
+ return typeof method === "function" && method !== Object.prototype[methodName];
546
+ };
547
+ //#endregion
548
+ //#region src/util/object/checkIsSameBytes.ts
549
+ const toBytes = (view) => ArrayBuffer.isView(view) ? new Uint8Array(view.buffer, view.byteOffset, view.byteLength) : new Uint8Array(view);
550
+ const checkIsSameBytes = (first, second) => {
551
+ const firstBytes = toBytes(first);
552
+ const secondBytes = toBytes(second);
553
+ return firstBytes.length === secondBytes.length && firstBytes.every((byte, index) => byte === secondBytes[index]);
554
+ };
555
+ //#endregion
556
+ //#region src/util/object/checkIsSameValueZero.ts
557
+ const checkIsSameValueZero = (first, second) => first === second || Number.isNaN(first) && Number.isNaN(second);
558
+ //#endregion
559
+ //#region src/util/object/getEnumerableKeys.ts
560
+ const getEnumerableKeys = (value) => Reflect.ownKeys(value).filter((key) => Object.prototype.propertyIsEnumerable.call(value, key));
561
+ //#endregion
562
+ //#region src/util/object/checkIsDeepEqual.ts
563
+ const checkIsBinary = (value) => ArrayBuffer.isView(value) || value instanceof ArrayBuffer || typeof SharedArrayBuffer !== "undefined" && value instanceof SharedArrayBuffer;
564
+ const checkIsDeepEqual = (first, second) => {
565
+ if (first === second) return true;
566
+ if (typeof first !== "object" || typeof second !== "object" || first === null || second === null) return checkIsSameValueZero(first, second);
567
+ if (Object.getPrototypeOf(first) !== Object.getPrototypeOf(second)) return false;
568
+ if (Array.isArray(first) || Array.isArray(second)) {
569
+ if (!Array.isArray(first) || !Array.isArray(second) || first.length !== second.length) return false;
570
+ for (const [index, item] of first.entries()) if (!checkIsDeepEqual(item, second[index])) return false;
571
+ return true;
572
+ }
573
+ if (checkIsBinary(first) && checkIsBinary(second)) return checkIsSameBytes(first, second);
574
+ if (first instanceof RegExp && second instanceof RegExp) return first.source === second.source && first.flags === second.flags;
575
+ if (first instanceof WeakMap || first instanceof WeakSet || first instanceof Promise || first instanceof Blob) return false;
576
+ if (checkIsCustomMethod(first, "valueOf") && checkIsCustomMethod(second, "valueOf")) return checkIsSameValueZero(first.valueOf(), second.valueOf());
577
+ if (checkIsCustomMethod(first, "toString") && checkIsCustomMethod(second, "toString")) return first.toString() === second.toString();
578
+ if (first instanceof Map && second instanceof Map) {
579
+ if (first.size !== second.size) return false;
580
+ for (const [key, value] of first) if (!second.has(key) || !checkIsDeepEqual(value, second.get(key))) return false;
581
+ return true;
582
+ }
583
+ if (first instanceof Set && second instanceof Set) {
584
+ if (first.size !== second.size) return false;
585
+ for (const value of first) if (!second.has(value)) return false;
586
+ return true;
587
+ }
588
+ const firstKeys = getEnumerableKeys(first);
589
+ if (firstKeys.length !== getEnumerableKeys(second).length) return false;
590
+ return firstKeys.every((key) => Object.prototype.propertyIsEnumerable.call(second, key) && checkIsDeepEqual(Reflect.get(first, key), Reflect.get(second, key)));
591
+ };
592
+ //#endregion
593
+ //#region src/util/validation/exhaustiveGuard.ts
594
+ const exhaustiveGuard = (value) => {
595
+ throw new InvalidOperationError("Read", exhaustiveGuard.name, JSON.stringify(value));
596
+ };
597
+ //#endregion
598
+ //#region src/services/jsonPatch/applyPatch.ts
599
+ const applyPatch = (document, operation) => {
600
+ switch (operation.op) {
601
+ case "add": return addJsonValue(document, operation.path, operation.value);
602
+ case "copy": return addJsonValue(document, operation.path, readJsonValue(document, parseJsonPointer(operation.from)));
603
+ case "move": {
604
+ if (operation.from === operation.path) {
605
+ readJsonValue(document, parseJsonPointer(operation.from));
606
+ return {
607
+ document,
608
+ inverses: []
609
+ };
610
+ } else if (operation.path.startsWith(`${operation.from}/`)) throw new InvalidOperationError("Update", operation.path, "a value cannot move into itself");
611
+ const removed = removeJsonValue(document, operation.from);
612
+ const added = addJsonValue(removed.document, operation.path, readJsonValue(document, parseJsonPointer(operation.from)));
613
+ return {
614
+ document: added.document,
615
+ inverses: [...added.inverses, ...removed.inverses]
616
+ };
617
+ }
618
+ case "remove": return removeJsonValue(document, operation.path);
619
+ case "replace": {
620
+ const segments = parseJsonPointer(operation.path);
621
+ const replacedValue = readJsonValue(document, segments);
622
+ return {
623
+ document: updateJsonValue(document, segments, () => operation.value),
624
+ inverses: [{
625
+ op: "replace",
626
+ path: operation.path,
627
+ value: replacedValue
628
+ }]
629
+ };
630
+ }
631
+ case "test":
632
+ if (!checkIsDeepEqual(readJsonValue(document, parseJsonPointer(operation.path)), operation.value)) throw new InvalidOperationError("Read", operation.path, "the value differs from the test's");
633
+ return {
634
+ document,
635
+ inverses: []
636
+ };
637
+ default: return exhaustiveGuard(operation);
638
+ }
639
+ };
640
+ //#endregion
641
+ //#region src/services/jsonPatch/applyPatches.ts
642
+ const applyPatches = (document, operations) => {
643
+ let patchedDocument = document;
644
+ const inverseGroups = [];
645
+ for (const operation of operations) {
646
+ const result = applyPatch(patchedDocument, operation);
647
+ patchedDocument = result.document;
648
+ inverseGroups.push(result.inverses);
649
+ }
650
+ return {
651
+ document: patchedDocument,
652
+ inverses: inverseGroups.toReversed().flat()
653
+ };
654
+ };
655
+ //#endregion
656
+ //#region src/services/message/constants.ts
657
+ const MENTION_ID_ATTRIBUTE = "data-id";
658
+ const MENTION_ITEM_TYPE_ATTRIBUTE = "data-mention-type";
659
+ const MENTION_LABEL_ATTRIBUTE = "data-label";
660
+ const MENTION_TYPE_ATTRIBUTE = "data-type";
661
+ const MENTION_TYPE = "mention";
662
+ const MENTION_SELECTOR = `span[${MENTION_TYPE_ATTRIBUTE}='${MENTION_TYPE}']`;
663
+ const MENTION_HERE_ID = "@here";
664
+ const MENTION_EVERYONE_ID = "@everyone";
665
+ const CUSTOM_EMOJI_ID_ATTRIBUTE = "data-custom-emoji-id";
666
+ const CUSTOM_EMOJI_NAME_ATTRIBUTE = "data-custom-emoji-name";
667
+ const SPOILER_ATTRIBUTE = "data-spoiler";
668
+ const SPOILER_SELECTOR = `span[${SPOILER_ATTRIBUTE}]`;
669
+ //#endregion
670
+ //#region src/services/message/getMentions.ts
671
+ const getMentions = (message) => parse(message).querySelectorAll(MENTION_SELECTOR);
672
+ //#endregion
673
+ //#region src/services/mime/constants.ts
674
+ const MEDIA_TYPE_REGEX = /^\s*(?<mediaType>[^;\s]*)(?:;|\s|$)/u;
675
+ const PATH_SEPARATOR_REGEX = /[/\\]/u;
676
+ const TEXT_MEDIA_TYPE_REGEX = /^text\//iu;
677
+ const CHARSET_PARAMETER_REGEX = /;\s*charset=/iu;
678
+ const DEFAULT_TEXT_CHARSET = "UTF-8";
679
+ const FacetScoreMap = /* @__PURE__ */ new Map([
680
+ ["prs.", 100],
681
+ ["vnd.", 400],
682
+ ["x-", 200],
683
+ ["x.", 300]
684
+ ]);
685
+ const DEFAULT_FACET_SCORE = 900;
686
+ const SourceScoreMap = /* @__PURE__ */ new Map([
687
+ ["apache", 20],
688
+ ["iana", 40],
689
+ ["nginx", 10]
690
+ ]);
691
+ const DEFAULT_SOURCE_SCORE = 30;
692
+ const TypeScoreMap = /* @__PURE__ */ new Map([
693
+ ["application", 1],
694
+ ["audio", 2],
695
+ ["font", 2],
696
+ ["video", 3]
697
+ ]);
698
+ const DEFAULT_TYPE_SCORE = 0;
699
+ //#endregion
700
+ //#region src/services/mime/getMediaType.ts
701
+ const getMediaType = (value) => MEDIA_TYPE_REGEX.exec(value)?.groups?.mediaType ?? "";
702
+ //#endregion
703
+ //#region src/services/mime/getMimeTypeEntryMap.ts
704
+ let mimeTypeEntryMap;
705
+ const getMimeTypeEntryMap = () => {
706
+ mimeTypeEntryMap ??= new Map(Object.entries(mimeDatabase));
707
+ return mimeTypeEntryMap;
708
+ };
709
+ //#endregion
710
+ //#region src/services/mime/charset.ts
711
+ const charset = (type) => {
712
+ const mediaType = getMediaType(type);
713
+ const dataCharset = getMimeTypeEntryMap().get(mediaType.toLowerCase())?.charset;
714
+ if (dataCharset) return dataCharset;
715
+ return TEXT_MEDIA_TYPE_REGEX.test(mediaType) ? DEFAULT_TEXT_CHARSET : false;
716
+ };
717
+ //#endregion
718
+ //#region src/services/mime/getMimeScore.ts
719
+ const getMimeScore = (mimeType, source = "") => {
720
+ if (mimeType === "application/octet-stream") return 0;
721
+ const [type = "", subtype = ""] = mimeType.split("/");
722
+ const facet = subtype.replace(/(?<prefix>\.|x-).*/u, "$<prefix>");
723
+ const facetScore = FacetScoreMap.get(facet) ?? 900;
724
+ const sourceScore = SourceScoreMap.get(source) ?? 30;
725
+ const typeScore = TypeScoreMap.get(type) ?? 0;
726
+ const lengthScore = 1 - mimeType.length / 100;
727
+ return facetScore + sourceScore + typeScore + lengthScore;
728
+ };
729
+ //#endregion
730
+ //#region src/services/mime/getExtensionMimeTypeMap.ts
731
+ let extensionMimeTypeMap;
732
+ const getPreferredMimeType = (currentMimeType, candidateMimeType) => {
733
+ if (currentMimeType === void 0) return candidateMimeType;
734
+ const entryMap = getMimeTypeEntryMap();
735
+ return getMimeScore(currentMimeType, entryMap.get(currentMimeType)?.source) > getMimeScore(candidateMimeType, entryMap.get(candidateMimeType)?.source) ? currentMimeType : candidateMimeType;
736
+ };
737
+ const getExtensionMimeTypeMap = () => {
738
+ if (!extensionMimeTypeMap) {
739
+ const map = /* @__PURE__ */ new Map();
740
+ for (const [mimeType, { extensions = [] }] of getMimeTypeEntryMap()) for (const extension of extensions) map.set(extension, getPreferredMimeType(map.get(extension), mimeType));
741
+ extensionMimeTypeMap = map;
742
+ }
743
+ return extensionMimeTypeMap;
744
+ };
745
+ //#endregion
746
+ //#region src/services/mime/lookup.ts
747
+ const getExtension = (path) => {
748
+ const name = path.split(PATH_SEPARATOR_REGEX).at(-1) ?? "";
749
+ const dotIndex = name.lastIndexOf(".");
750
+ if (path === name) return name.slice(dotIndex + 1);
751
+ return dotIndex > 0 ? name.slice(dotIndex + 1) : "";
752
+ };
753
+ const lookup = (path) => {
754
+ const extension = getExtension(path).toLowerCase();
755
+ if (!extension) return false;
756
+ return getExtensionMimeTypeMap().get(extension) ?? false;
757
+ };
758
+ //#endregion
759
+ //#region src/services/mime/contentType.ts
760
+ const contentType = (value) => {
761
+ const mediaType = value.includes("/") ? value : lookup(value);
762
+ if (!mediaType) return false;
763
+ if (CHARSET_PARAMETER_REGEX.test(mediaType)) return mediaType;
764
+ const mediaCharset = charset(mediaType);
765
+ return mediaCharset ? `${mediaType}; charset=${mediaCharset.toLowerCase()}` : mediaType;
766
+ };
767
+ //#endregion
768
+ //#region src/services/mime/extension.ts
769
+ const extension = (type) => getMimeTypeEntryMap().get(getMediaType(type).toLowerCase())?.extensions?.[0] ?? false;
770
+ //#endregion
771
+ //#region src/services/prettier/css.ts
772
+ const css = String.raw;
773
+ //#endregion
774
+ //#region src/services/prettier/html.ts
775
+ const html = String.raw;
776
+ //#endregion
777
+ //#region src/services/profanity/englishProfaneWords.ts
778
+ const englishProfaneWords = [
779
+ "4r5e",
780
+ "5h1t",
781
+ "5hit",
782
+ "a55",
783
+ "anal",
784
+ "anus",
785
+ "ar5e",
786
+ "arrse",
787
+ "arse",
788
+ "arses",
789
+ "ass",
790
+ "ass-fucker",
791
+ "asses",
792
+ "assfucker",
793
+ "assfukka",
794
+ "asshole",
795
+ "assholes",
796
+ "asswhole",
797
+ "a_s_s",
798
+ "a$$",
799
+ "as$",
800
+ "a$s",
801
+ "b!tch",
802
+ "b00bs",
803
+ "b17ch",
804
+ "b1tch",
805
+ "ballbag",
806
+ "balls",
807
+ "ballsack",
808
+ "bastard",
809
+ "beastial",
810
+ "beastiality",
811
+ "bellend",
812
+ "bestial",
813
+ "bestiality",
814
+ "bi+ch",
815
+ "biatch",
816
+ "bitch",
817
+ "bitchboy",
818
+ "bitcher",
819
+ "bitchers",
820
+ "bitches",
821
+ "bitchin",
822
+ "bitching",
823
+ "bloody",
824
+ "blow job",
825
+ "blowjob",
826
+ "blowjobs",
827
+ "boiolas",
828
+ "bollock",
829
+ "bollok",
830
+ "boner",
831
+ "boob",
832
+ "boobs",
833
+ "booobs",
834
+ "boooobs",
835
+ "booooobs",
836
+ "booooooobs",
837
+ "breasts",
838
+ "buceta",
839
+ "bugger",
840
+ "bullshit",
841
+ "bum",
842
+ "butt",
843
+ "butts",
844
+ "butthole",
845
+ "buttmuch",
846
+ "buttplug",
847
+ "c0ck",
848
+ "c0cksucker",
849
+ "carpet muncher",
850
+ "cawk",
851
+ "chink",
852
+ "cipa",
853
+ "cl1t",
854
+ "clit",
855
+ "clitoris",
856
+ "clits",
857
+ "cnut",
858
+ "cock",
859
+ "cock-sucker",
860
+ "cockface",
861
+ "cockhead",
862
+ "cockmunch",
863
+ "cockmuncher",
864
+ "cocks",
865
+ "cocksuck",
866
+ "cocksucked",
867
+ "cocksucker",
868
+ "cocksucking",
869
+ "cocksucks",
870
+ "cocksuka",
871
+ "cocksukka",
872
+ "cok",
873
+ "cokmuncher",
874
+ "coksucka",
875
+ "coon",
876
+ "cox",
877
+ "crap",
878
+ "cum",
879
+ "cummer",
880
+ "cumming",
881
+ "cums",
882
+ "cumshot",
883
+ "cunilingus",
884
+ "cunillingus",
885
+ "cunnilingus",
886
+ "cunt",
887
+ "cuntlick",
888
+ "cuntlicker",
889
+ "cuntlicking",
890
+ "cunts",
891
+ "cyalis",
892
+ "cyberfuc",
893
+ "cyberfuck",
894
+ "cyberfucked",
895
+ "cyberfucker",
896
+ "cyberfuckers",
897
+ "cyberfucking",
898
+ "d1ck",
899
+ "damn",
900
+ "dick",
901
+ "dickhead",
902
+ "dildo",
903
+ "dildos",
904
+ "dink",
905
+ "dinks",
906
+ "dirsa",
907
+ "dlck",
908
+ "dog-fucker",
909
+ "doggin",
910
+ "dogging",
911
+ "donkeyribber",
912
+ "doosh",
913
+ "duche",
914
+ "dyke",
915
+ "ejaculate",
916
+ "ejaculated",
917
+ "ejaculates",
918
+ "ejaculating",
919
+ "ejaculatings",
920
+ "ejaculation",
921
+ "ejakulate",
922
+ "f u c k",
923
+ "f u c k e r",
924
+ "f4nny",
925
+ "fag",
926
+ "fagging",
927
+ "faggitt",
928
+ "faggot",
929
+ "faggs",
930
+ "fagot",
931
+ "fagots",
932
+ "fags",
933
+ "fanny",
934
+ "fannyflaps",
935
+ "fannyfucker",
936
+ "fanyy",
937
+ "fatass",
938
+ "fcuk",
939
+ "fcuker",
940
+ "fcuking",
941
+ "feck",
942
+ "fecker",
943
+ "felching",
944
+ "fellate",
945
+ "fellatio",
946
+ "fingerfuck",
947
+ "fingerfucked",
948
+ "fingerfucker",
949
+ "fingerfuckers",
950
+ "fingerfucking",
951
+ "fingerfucks",
952
+ "fistfuck",
953
+ "fistfucked",
954
+ "fistfucker",
955
+ "fistfuckers",
956
+ "fistfucking",
957
+ "fistfuckings",
958
+ "fistfucks",
959
+ "flange",
960
+ "fook",
961
+ "fooker",
962
+ "fuck",
963
+ "fucka",
964
+ "fucked",
965
+ "fucker",
966
+ "fuckers",
967
+ "fuckhead",
968
+ "fuckheads",
969
+ "fuckin",
970
+ "fucking",
971
+ "fuckings",
972
+ "fuckingshitmotherfucker",
973
+ "fuckme",
974
+ "fucks",
975
+ "fuckwhit",
976
+ "fuckwit",
977
+ "fudge packer",
978
+ "fudgepacker",
979
+ "fuk",
980
+ "fuker",
981
+ "fukker",
982
+ "fukkin",
983
+ "fuks",
984
+ "fukwhit",
985
+ "fukwit",
986
+ "fux",
987
+ "fux0r",
988
+ "f_u_c_k",
989
+ "gangbang",
990
+ "gangbanged",
991
+ "gangbangs",
992
+ "gaylord",
993
+ "gaysex",
994
+ "goatse",
995
+ "god-dam",
996
+ "god-damned",
997
+ "goddamn",
998
+ "goddamned",
999
+ "hardcoresex",
1000
+ "headass",
1001
+ "hoar",
1002
+ "hoare",
1003
+ "hoer",
1004
+ "hoes",
1005
+ "homo",
1006
+ "hore",
1007
+ "horniest",
1008
+ "horny",
1009
+ "hotsex",
1010
+ "jack-off",
1011
+ "jackoff",
1012
+ "jap",
1013
+ "jerk-off",
1014
+ "jism",
1015
+ "jiz",
1016
+ "jizm",
1017
+ "jizz",
1018
+ "kawk",
1019
+ "knobead",
1020
+ "knobed",
1021
+ "knobend",
1022
+ "knobhead",
1023
+ "knobjocky",
1024
+ "knobjokey",
1025
+ "kock",
1026
+ "kondum",
1027
+ "kondums",
1028
+ "kum",
1029
+ "kummer",
1030
+ "kumming",
1031
+ "kums",
1032
+ "kunilingus",
1033
+ "l3i+ch",
1034
+ "l3itch",
1035
+ "labia",
1036
+ "lust",
1037
+ "lusting",
1038
+ "m0f0",
1039
+ "m0fo",
1040
+ "m45terbate",
1041
+ "ma5terb8",
1042
+ "ma5terbate",
1043
+ "masochist",
1044
+ "master-bate",
1045
+ "masterb8",
1046
+ "masterbat*",
1047
+ "masterbat3",
1048
+ "masterbate",
1049
+ "masterbation",
1050
+ "masterbations",
1051
+ "masturbate",
1052
+ "mo-fo",
1053
+ "mof0",
1054
+ "mofo",
1055
+ "mothafuck",
1056
+ "mothafucka",
1057
+ "mothafuckas",
1058
+ "mothafuckaz",
1059
+ "mothafucked",
1060
+ "mothafucker",
1061
+ "mothafuckers",
1062
+ "mothafuckin",
1063
+ "mothafucking",
1064
+ "mothafuckings",
1065
+ "mothafucks",
1066
+ "motherfuck",
1067
+ "motherfucked",
1068
+ "motherfucker",
1069
+ "motherfuckers",
1070
+ "motherfuckin",
1071
+ "motherfucking",
1072
+ "motherfuckings",
1073
+ "motherfuckka",
1074
+ "motherfucks",
1075
+ "muff",
1076
+ "muthafecker",
1077
+ "muthafuckker",
1078
+ "mutherfucker",
1079
+ "n1gga",
1080
+ "n1gger",
1081
+ "nazi",
1082
+ "nigg3r",
1083
+ "nigg4h",
1084
+ "nigga",
1085
+ "niggah",
1086
+ "niggas",
1087
+ "niggaz",
1088
+ "nigger",
1089
+ "niggers",
1090
+ "nob",
1091
+ "nob jokey",
1092
+ "nobhead",
1093
+ "nobjocky",
1094
+ "nobjokey",
1095
+ "numbnuts",
1096
+ "nutsack",
1097
+ "orgasim",
1098
+ "orgasims",
1099
+ "orgasm",
1100
+ "orgasms",
1101
+ "p0rn",
1102
+ "pawn",
1103
+ "pecker",
1104
+ "penis",
1105
+ "penisfucker",
1106
+ "phonesex",
1107
+ "phuck",
1108
+ "phuk",
1109
+ "phuked",
1110
+ "phuking",
1111
+ "phukked",
1112
+ "phukking",
1113
+ "phuks",
1114
+ "phuq",
1115
+ "pigfucker",
1116
+ "pimpis",
1117
+ "piss",
1118
+ "pissed",
1119
+ "pisser",
1120
+ "pissers",
1121
+ "pisses",
1122
+ "pissflaps",
1123
+ "pissin",
1124
+ "pissing",
1125
+ "pissoff",
1126
+ "poop",
1127
+ "porn",
1128
+ "porno",
1129
+ "pornography",
1130
+ "pornos",
1131
+ "prick",
1132
+ "pricks",
1133
+ "pron",
1134
+ "pube",
1135
+ "pusse",
1136
+ "pussi",
1137
+ "pussies",
1138
+ "pussy",
1139
+ "pussys",
1140
+ "rectum",
1141
+ "retard",
1142
+ "rimjaw",
1143
+ "rimming",
1144
+ "s hit",
1145
+ "s.o.b.",
1146
+ "sadist",
1147
+ "schlong",
1148
+ "screwing",
1149
+ "scroat",
1150
+ "scrote",
1151
+ "scrotum",
1152
+ "semen",
1153
+ "sex",
1154
+ "sh!+",
1155
+ "sh!t",
1156
+ "sh1t",
1157
+ "shag",
1158
+ "shagger",
1159
+ "shaggin",
1160
+ "shagging",
1161
+ "shemale",
1162
+ "shi+",
1163
+ "shit",
1164
+ "shitdick",
1165
+ "shite",
1166
+ "shited",
1167
+ "shitey",
1168
+ "shitfuck",
1169
+ "shitfull",
1170
+ "shithead",
1171
+ "shiting",
1172
+ "shitings",
1173
+ "shits",
1174
+ "shitted",
1175
+ "shitter",
1176
+ "shitters",
1177
+ "shitting",
1178
+ "shittings",
1179
+ "shitty",
1180
+ "skank",
1181
+ "slut",
1182
+ "sluts",
1183
+ "smegma",
1184
+ "smut",
1185
+ "snatch",
1186
+ "son-of-a-bitch",
1187
+ "spac",
1188
+ "spunk",
1189
+ "s_h_i_t",
1190
+ "t1tt1e5",
1191
+ "t1tties",
1192
+ "teets",
1193
+ "teez",
1194
+ "testical",
1195
+ "testicle",
1196
+ "tit",
1197
+ "titfuck",
1198
+ "tits",
1199
+ "titt",
1200
+ "tittie5",
1201
+ "tittiefucker",
1202
+ "titties",
1203
+ "tittyfuck",
1204
+ "tittywank",
1205
+ "titwank",
1206
+ "tosser",
1207
+ "turd",
1208
+ "tw4t",
1209
+ "twat",
1210
+ "twathead",
1211
+ "twatty",
1212
+ "twunt",
1213
+ "twunter",
1214
+ "v14gra",
1215
+ "v1gra",
1216
+ "vagina",
1217
+ "viagra",
1218
+ "vulva",
1219
+ "w00se",
1220
+ "wang",
1221
+ "wank",
1222
+ "wanker",
1223
+ "wanky",
1224
+ "whoar",
1225
+ "whore",
1226
+ "willies",
1227
+ "willy"
1228
+ ];
1229
+ //#endregion
1230
+ //#region src/services/profanity/checkContainsProfanity.ts
1231
+ const WORD_CHARACTER_CLASS = String.raw`\p{L}\p{N}\p{M}`;
1232
+ const PROFANE_WORD_ALTERNATION = englishProfaneWords.map((word) => word.replaceAll(/[.*+?^${}()|[\]\\]/gu, String.raw`\$&`)).join("|");
1233
+ const WHOLE_WORD_PROFANITY_REGEX = new RegExp(`(?<![${WORD_CHARACTER_CLASS}])(?:${PROFANE_WORD_ALTERNATION})(?![${WORD_CHARACTER_CLASS}])`, "iu");
1234
+ const SUBSTRING_PROFANITY_REGEX = new RegExp(PROFANE_WORD_ALTERNATION, "iu");
1235
+ const checkContainsProfanity = (text, { isWholeWord = true } = {}) => {
1236
+ if (typeof text !== "string") return false;
1237
+ return (isWholeWord ? WHOLE_WORD_PROFANITY_REGEX : SUBSTRING_PROFANITY_REGEX).test(text);
1238
+ };
1239
+ //#endregion
1240
+ //#region src/services/sanitizeHtml/checkIsWhitespaceCharacter.ts
1241
+ const checkIsWhitespaceCharacter = (character) => character.trim() === "";
1242
+ //#endregion
1243
+ //#region src/services/sanitizeHtml/checkIsUnsafeUrlCharacter.ts
1244
+ const FIRST_PRINTABLE_CODE_POINT = 32;
1245
+ const DELETE_CODE_POINT = 127;
1246
+ const LAST_C1_CONTROL_CODE_POINT = 159;
1247
+ const GRAVE_ACCENT = "`";
1248
+ const checkIsUnsafeUrlCharacter = (character) => {
1249
+ const codePoint = character.codePointAt(0) ?? 0;
1250
+ return checkIsWhitespaceCharacter(character) || codePoint < FIRST_PRINTABLE_CODE_POINT || codePoint >= DELETE_CODE_POINT && codePoint <= LAST_C1_CONTROL_CODE_POINT || character === GRAVE_ACCENT;
1251
+ };
1252
+ //#endregion
1253
+ //#region src/util/array/takeOne.ts
1254
+ const takeOne = (values, index = 0) => {
1255
+ return values[index];
1256
+ };
1257
+ //#endregion
1258
+ //#region src/services/sanitizeHtml/checkIsAllowedUrl.ts
1259
+ const PATH_DELIMITER_REGEX = /[/?#]/u;
1260
+ const NON_SCHEME_CHARACTERS_REGEX = /[^a-z\d+.-]/giu;
1261
+ const SCHEME_SEPARATOR = ":";
1262
+ const checkIsAllowedUrl = (url, allowedSchemes) => {
1263
+ const normalizedUrl = url.split("").filter((character) => !checkIsUnsafeUrlCharacter(character)).join("");
1264
+ const beforePath = takeOne(normalizedUrl.split(PATH_DELIMITER_REGEX), 0);
1265
+ const separatorIndex = beforePath.indexOf(SCHEME_SEPARATOR);
1266
+ if (separatorIndex === -1) return true;
1267
+ const scheme = beforePath.slice(0, separatorIndex).replaceAll(NON_SCHEME_CHARACTERS_REGEX, "").toLowerCase();
1268
+ return allowedSchemes.includes(scheme);
1269
+ };
1270
+ //#endregion
1271
+ //#region src/services/sanitizeHtml/constants.ts
1272
+ const HTML_NAMESPACE = html$1.NS.HTML;
1273
+ const DEFAULT_ALLOWED_TAGS = [
1274
+ "address",
1275
+ "article",
1276
+ "aside",
1277
+ "footer",
1278
+ "header",
1279
+ "h1",
1280
+ "h2",
1281
+ "h3",
1282
+ "h4",
1283
+ "h5",
1284
+ "h6",
1285
+ "hgroup",
1286
+ "main",
1287
+ "nav",
1288
+ "section",
1289
+ "blockquote",
1290
+ "dd",
1291
+ "div",
1292
+ "dl",
1293
+ "dt",
1294
+ "figcaption",
1295
+ "figure",
1296
+ "hr",
1297
+ "li",
1298
+ "menu",
1299
+ "ol",
1300
+ "p",
1301
+ "pre",
1302
+ "ul",
1303
+ "a",
1304
+ "abbr",
1305
+ "b",
1306
+ "bdi",
1307
+ "bdo",
1308
+ "br",
1309
+ "cite",
1310
+ "code",
1311
+ "data",
1312
+ "dfn",
1313
+ "em",
1314
+ "i",
1315
+ "kbd",
1316
+ "mark",
1317
+ "q",
1318
+ "rb",
1319
+ "rp",
1320
+ "rt",
1321
+ "rtc",
1322
+ "ruby",
1323
+ "s",
1324
+ "samp",
1325
+ "small",
1326
+ "span",
1327
+ "strong",
1328
+ "sub",
1329
+ "sup",
1330
+ "time",
1331
+ "u",
1332
+ "var",
1333
+ "wbr",
1334
+ "caption",
1335
+ "col",
1336
+ "colgroup",
1337
+ "table",
1338
+ "tbody",
1339
+ "td",
1340
+ "tfoot",
1341
+ "th",
1342
+ "thead",
1343
+ "tr"
1344
+ ];
1345
+ const DEFAULT_LINK_ATTRIBUTES = [
1346
+ "href",
1347
+ "name",
1348
+ "target"
1349
+ ];
1350
+ const DEFAULT_ALLOWED_ATTRIBUTES = { a: DEFAULT_LINK_ATTRIBUTES };
1351
+ const DEFAULT_ALLOWED_SCHEMES = [
1352
+ "http",
1353
+ "https",
1354
+ "ftp",
1355
+ "mailto",
1356
+ "tel"
1357
+ ];
1358
+ const NON_TEXT_TAGS = [
1359
+ "iframe",
1360
+ "noembed",
1361
+ "noframes",
1362
+ "noscript",
1363
+ "option",
1364
+ "plaintext",
1365
+ "script",
1366
+ "style",
1367
+ "textarea",
1368
+ "title",
1369
+ "xmp"
1370
+ ];
1371
+ const VOID_TAGS = [
1372
+ "area",
1373
+ "base",
1374
+ "br",
1375
+ "col",
1376
+ "embed",
1377
+ "hr",
1378
+ "img",
1379
+ "input",
1380
+ "link",
1381
+ "meta",
1382
+ "source",
1383
+ "track",
1384
+ "wbr"
1385
+ ];
1386
+ const URL_ATTRIBUTES = [
1387
+ "action",
1388
+ "background",
1389
+ "cite",
1390
+ "data",
1391
+ "formaction",
1392
+ "href",
1393
+ "icon",
1394
+ "longdesc",
1395
+ "manifest",
1396
+ "poster",
1397
+ "src"
1398
+ ];
1399
+ const SRCSET_ATTRIBUTE = "srcset";
1400
+ const IMPORTANT_REGEX = /!\s*important$/iu;
1401
+ const MAX_NESTING_DEPTH = 256;
1402
+ const SRCSET_DESCRIPTOR_REGEX = /^(?:\d+w|\d*\.?\d+x|\d+h)$/u;
1403
+ const ESCAPED_TEXT_CHARACTERS_REGEX = /[&<>]/gu;
1404
+ const ESCAPED_ATTRIBUTE_CHARACTERS_REGEX = /[&"<>]/gu;
1405
+ const SANITIZER_ADVISORY_WATCH_SINCE = "2026-10-21";
1406
+ //#endregion
1407
+ //#region src/services/sanitizeHtml/getChildNodes.ts
1408
+ const getChildNodes = (element) => "content" in element ? element.content.childNodes : element.childNodes;
1409
+ //#endregion
1410
+ //#region src/services/sanitizeHtml/collectText.ts
1411
+ const collectText = (nodes, depth) => depth > 256 ? "" : nodes.map((node) => {
1412
+ if ("value" in node) return node.value;
1413
+ if (!("tagName" in node) || NON_TEXT_TAGS.includes(node.tagName)) return "";
1414
+ return collectText(getChildNodes(node), depth + 1);
1415
+ }).join("");
1416
+ //#endregion
1417
+ //#region src/services/sanitizeHtml/escapeCharacters.ts
1418
+ const NON_BREAKING_SPACE = String.fromCodePoint(160);
1419
+ const escapeCharacters = (value, charactersRegex, entities) => value.replace(charactersRegex, (character) => entities[character] ?? character).replaceAll(NON_BREAKING_SPACE, "&nbsp;");
1420
+ //#endregion
1421
+ //#region src/services/sanitizeHtml/escapeAttribute.ts
1422
+ const ESCAPED_ATTRIBUTE_CHARACTERS = {
1423
+ "\"": "&quot;",
1424
+ "&": "&amp;",
1425
+ "<": "&lt;",
1426
+ ">": "&gt;"
1427
+ };
1428
+ const escapeAttribute = (value) => escapeCharacters(value, ESCAPED_ATTRIBUTE_CHARACTERS_REGEX, ESCAPED_ATTRIBUTE_CHARACTERS);
1429
+ //#endregion
1430
+ //#region src/services/sanitizeHtml/escapeText.ts
1431
+ const ESCAPED_TEXT_CHARACTERS = {
1432
+ "&": "&amp;",
1433
+ "<": "&lt;",
1434
+ ">": "&gt;"
1435
+ };
1436
+ const escapeText = (text) => escapeCharacters(text, ESCAPED_TEXT_CHARACTERS_REGEX, ESCAPED_TEXT_CHARACTERS);
1437
+ //#endregion
1438
+ //#region src/services/sanitizeHtml/matchesClassPattern.ts
1439
+ const matchesClassPattern = (className, pattern) => pattern.endsWith("*") ? className.startsWith(pattern.slice(0, -1)) : className === pattern;
1440
+ //#endregion
1441
+ //#region src/services/sanitizeHtml/filterClasses.ts
1442
+ const filterClasses = (value, patterns) => {
1443
+ if (!patterns) return void 0;
1444
+ const classNames = value.split(/\s+/u).filter((className) => className && patterns.some((pattern) => matchesClassPattern(className, pattern)));
1445
+ return classNames.length > 0 ? classNames.join(" ") : void 0;
1446
+ };
1447
+ //#endregion
1448
+ //#region src/services/sanitizeHtml/filterSrcset.ts
1449
+ const COMMA = ",";
1450
+ const OPENING_PARENTHESIS = "(";
1451
+ const CLOSING_PARENTHESIS = ")";
1452
+ const filterSrcset = (value, allowedSchemes) => {
1453
+ const candidates = [];
1454
+ let position = 0;
1455
+ while (position < value.length) {
1456
+ while (position < value.length && (checkIsWhitespaceCharacter(value.charAt(position)) || value.charAt(position) === COMMA)) position++;
1457
+ const urlStart = position;
1458
+ while (position < value.length && !checkIsWhitespaceCharacter(value.charAt(position))) position++;
1459
+ let url = value.slice(urlStart, position);
1460
+ let descriptorText = "";
1461
+ if (url.endsWith(COMMA)) url = url.replace(/,+$/u, "");
1462
+ else {
1463
+ const descriptorStart = position;
1464
+ let isInParentheses = false;
1465
+ while (position < value.length && (isInParentheses || value.charAt(position) !== COMMA)) {
1466
+ if (value.charAt(position) === OPENING_PARENTHESIS) isInParentheses = true;
1467
+ else if (value.charAt(position) === CLOSING_PARENTHESIS) isInParentheses = false;
1468
+ position++;
1469
+ }
1470
+ descriptorText = value.slice(descriptorStart, position);
1471
+ position++;
1472
+ }
1473
+ const descriptors = descriptorText.trim().split(/\s+/u).filter(Boolean);
1474
+ if (!url || !checkIsAllowedUrl(url, allowedSchemes)) continue;
1475
+ if (descriptors.length > 1 || descriptors.some((descriptor) => !SRCSET_DESCRIPTOR_REGEX.test(descriptor))) continue;
1476
+ candidates.push([url, ...descriptors].join(" "));
1477
+ }
1478
+ return candidates.length > 0 ? candidates.join(", ") : void 0;
1479
+ };
1480
+ //#endregion
1481
+ //#region src/services/sanitizeHtml/filterStyle.ts
1482
+ const DECLARATION_SEPARATOR = ";";
1483
+ const PROPERTY_SEPARATOR = ":";
1484
+ const IMPORTANT_SUFFIX = "!important";
1485
+ const filterStyle = (value, rules) => {
1486
+ if (!rules) return void 0;
1487
+ const declarations = /* @__PURE__ */ new Map();
1488
+ for (const declaration of value.split(DECLARATION_SEPARATOR)) {
1489
+ const separatorIndex = declaration.indexOf(PROPERTY_SEPARATOR);
1490
+ if (separatorIndex === -1) continue;
1491
+ const property = declaration.slice(0, separatorIndex).trim().toLowerCase();
1492
+ if (!Object.hasOwn(rules, property)) continue;
1493
+ const rawValue = declaration.slice(separatorIndex + 1).trim();
1494
+ const important = IMPORTANT_REGEX.test(rawValue);
1495
+ const propertyValue = rawValue.replace(IMPORTANT_REGEX, "").trim();
1496
+ if (!(rules[property] ?? []).some((rule) => rule.test(propertyValue))) continue;
1497
+ if (declarations.get(property)?.important && !important) continue;
1498
+ declarations.set(property, {
1499
+ important,
1500
+ propertyValue
1501
+ });
1502
+ }
1503
+ if (declarations.size === 0) return void 0;
1504
+ return Array.from(declarations, ([property, { important, propertyValue }]) => `${property}${PROPERTY_SEPARATOR}${propertyValue}${important ? IMPORTANT_SUFFIX : ""}`).join(DECLARATION_SEPARATOR);
1505
+ };
1506
+ //#endregion
1507
+ //#region src/services/sanitizeHtml/filterAttributes.ts
1508
+ const getTagPolicy = (tagPolicies, tagName) => Object.hasOwn(tagPolicies, tagName) ? tagPolicies[tagName] : void 0;
1509
+ const checkIsMetaRefresh = (tagName, attributes) => tagName === "meta" && attributes["http-equiv"]?.trim().toLowerCase() === "refresh";
1510
+ const filterAttributes = (element, policy) => {
1511
+ const { tagName } = element;
1512
+ const allowedAttributes = getTagPolicy(policy.allowedAttributes, tagName) ?? [];
1513
+ const isClassAllowed = Object.hasOwn(policy.allowedClasses, tagName);
1514
+ const parsedAttributes = Object.fromEntries(element.attrs.map(({ name, value }) => [name, value]));
1515
+ const transform = getTagPolicy(policy.transformAttributes, tagName);
1516
+ const attributes = transform ? transform(parsedAttributes) : parsedAttributes;
1517
+ const kept = {};
1518
+ for (const [name, value] of Object.entries(attributes)) {
1519
+ if (name === "class" ? !isClassAllowed : !allowedAttributes.includes(name)) continue;
1520
+ if (name === "content" && checkIsMetaRefresh(tagName, attributes)) continue;
1521
+ const filteredValue = filterValue(tagName, name, value, policy);
1522
+ if (filteredValue !== void 0) kept[name] = filteredValue;
1523
+ }
1524
+ return kept;
1525
+ };
1526
+ const filterValue = (tagName, name, value, policy) => {
1527
+ if (name === "style") return filterStyle(value, getTagPolicy(policy.allowedStyles, tagName));
1528
+ if (name === "class") return filterClasses(value, getTagPolicy(policy.allowedClasses, tagName));
1529
+ if (name === "srcset") return filterSrcset(value, policy.allowedSchemes);
1530
+ if (URL_ATTRIBUTES.includes(name)) return checkIsAllowedUrl(value, policy.allowedSchemes) ? value : void 0;
1531
+ return value;
1532
+ };
1533
+ //#endregion
1534
+ //#region src/services/sanitizeHtml/renderNode.ts
1535
+ const renderNode = (node, policy, depth) => {
1536
+ if (node.nodeName === "#text") return escapeText(node.value);
1537
+ if (!("tagName" in node) || depth > 256) return "";
1538
+ const element = node;
1539
+ const children = getChildNodes(element).map((child) => renderNode(child, policy, depth + 1)).join("");
1540
+ if (!(element.namespaceURI === HTML_NAMESPACE && !NON_TEXT_TAGS.includes(element.tagName) && policy.allowedTags.includes(element.tagName))) return NON_TEXT_TAGS.includes(element.tagName) ? "" : children;
1541
+ const attributes = Object.entries(filterAttributes(element, policy)).map(([name, value]) => ` ${name}="${escapeAttribute(value)}"`).join("");
1542
+ const opening = `<${element.tagName}${attributes}>`;
1543
+ return VOID_TAGS.includes(element.tagName) ? opening : `${opening}${children}</${element.tagName}>`;
1544
+ };
1545
+ //#endregion
1546
+ //#region src/services/sanitizeHtml/filterHtml.ts
1547
+ const filterHtml = (html, policy) => {
1548
+ const context = defaultTreeAdapter.createElement("body", HTML_NAMESPACE, []);
1549
+ const childNodes = parseFragment(context, html, {}).childNodes;
1550
+ const output = childNodes.map((node) => renderNode(node, policy, 0)).join("");
1551
+ return parseFragment(context, output, {}).childNodes.map((node) => renderNode(node, policy, 0)).join("") === output ? output : escapeText(collectText(childNodes, 0));
1552
+ };
1553
+ //#endregion
1554
+ //#region src/services/sanitizeHtml/sanitizeHtml.ts
1555
+ const appendStyle = (style, declarations) => style ? `${style}; ${declarations}` : declarations;
1556
+ const transformCellAlign = ({ align, ...attributes }) => align ? {
1557
+ ...attributes,
1558
+ style: appendStyle(attributes.style, `text-align:${align}`)
1559
+ } : attributes;
1560
+ const transformLink = (attributes) => ({
1561
+ ...attributes,
1562
+ rel: "noopener noreferrer nofollow",
1563
+ target: "_blank"
1564
+ });
1565
+ const transformTable = (attributes) => ({
1566
+ ...attributes,
1567
+ style: appendStyle(attributes.style, "width:100%; border-collapse: collapse;")
1568
+ });
1569
+ const TEXT_ALIGN_REGEXES = [/^(?:left|right|center|justify)$/u];
1570
+ const TABLE_ALLOWED_STYLES = {
1571
+ table: {
1572
+ "border-collapse": [/^collapse$/u],
1573
+ width: [/^100%$/u]
1574
+ },
1575
+ td: { "text-align": TEXT_ALIGN_REGEXES },
1576
+ th: { "text-align": TEXT_ALIGN_REGEXES }
1577
+ };
1578
+ const sanitizeHtml = (html, options) => filterHtml(html, {
1579
+ allowedAttributes: {
1580
+ ...options?.allowedAttributes ?? DEFAULT_ALLOWED_ATTRIBUTES,
1581
+ a: [.../* @__PURE__ */ new Set([
1582
+ ...options?.allowedAttributes?.a ?? DEFAULT_LINK_ATTRIBUTES,
1583
+ "href",
1584
+ "rel",
1585
+ "target"
1586
+ ])],
1587
+ table: ["style"],
1588
+ td: ["style"],
1589
+ th: ["style"]
1590
+ },
1591
+ allowedClasses: options?.allowedClasses ?? {},
1592
+ allowedSchemes: DEFAULT_ALLOWED_SCHEMES,
1593
+ allowedStyles: {
1594
+ ...options?.allowedStyles,
1595
+ ...TABLE_ALLOWED_STYLES
1596
+ },
1597
+ allowedTags: options?.allowedTags ?? DEFAULT_ALLOWED_TAGS,
1598
+ transformAttributes: {
1599
+ ...options?.transformAttributes,
1600
+ a: transformLink,
1601
+ table: transformTable,
1602
+ td: transformCellAlign,
1603
+ th: transformCellAlign
1604
+ }
1605
+ });
1606
+ //#endregion
1607
+ //#region src/services/sanitizeHtml/sanitizeTextHtml.ts
1608
+ const COLOR_REGEXES = [
1609
+ /^#[\da-fA-F]{3,8}$/u,
1610
+ /^rgba?\(\d{1,3},\s*\d{1,3},\s*\d{1,3}(?:,\s*[\d.]+)?\)$/u,
1611
+ /^[a-z]+$/iu
1612
+ ];
1613
+ const sanitizeTextHtml = (html) => sanitizeHtml(html, {
1614
+ allowedAttributes: {
1615
+ input: [
1616
+ "checked",
1617
+ "disabled",
1618
+ "type"
1619
+ ],
1620
+ li: ["data-checked", "data-type"],
1621
+ span: [
1622
+ CUSTOM_EMOJI_ID_ATTRIBUTE,
1623
+ CUSTOM_EMOJI_NAME_ATTRIBUTE,
1624
+ MENTION_ID_ATTRIBUTE,
1625
+ MENTION_ITEM_TYPE_ATTRIBUTE,
1626
+ MENTION_LABEL_ATTRIBUTE,
1627
+ MENTION_TYPE_ATTRIBUTE,
1628
+ SPOILER_ATTRIBUTE,
1629
+ "style"
1630
+ ],
1631
+ ul: ["data-type"]
1632
+ },
1633
+ allowedClasses: {
1634
+ code: ["language-*"],
1635
+ pre: ["language-*"],
1636
+ span: ["hljs*"]
1637
+ },
1638
+ allowedStyles: { span: {
1639
+ "background-color": COLOR_REGEXES,
1640
+ "border-radius": [/^[\d.]+(?<unit>px|em|rem|%)$/u],
1641
+ color: COLOR_REGEXES
1642
+ } },
1643
+ allowedTags: [
1644
+ ...DEFAULT_ALLOWED_TAGS,
1645
+ "input",
1646
+ "label"
1647
+ ],
1648
+ transformAttributes: { input: ({ checked }) => ({
1649
+ ...checked === void 0 ? {} : { checked },
1650
+ disabled: "",
1651
+ type: "checkbox"
1652
+ }) }
1653
+ });
1654
+ //#endregion
1655
+ //#region src/services/shared/applyItemMetadataMixin.ts
1656
+ const applyItemMetadataMixin = (Base) => class ItemWithMetadata extends Base {
1657
+ createdAt = /* @__PURE__ */ new Date();
1658
+ deletedAt = null;
1659
+ updatedAt = /* @__PURE__ */ new Date();
1660
+ };
1661
+ //#endregion
1662
+ //#region src/util/text/normalizeString.ts
1663
+ const normalizeString = (value) => value?.trim() ?? "";
1664
+ //#endregion
1665
+ //#region src/services/zod/createNormalizedStringSchema.ts
1666
+ const createNormalizedStringSchema = (maxLength, schema = z.string()) => schema.transform(normalizeString).pipe(z.string().max(maxLength));
1667
+ //#endregion
1668
+ //#region src/util/id/constants.ts
1669
+ const ID_SEPARATOR = "|";
1670
+ //#endregion
1671
+ //#region src/services/zod/createUniqueArraySchema.ts
1672
+ const getItemKey = (item, key) => {
1673
+ const record = item;
1674
+ return typeof key === "string" ? record[key] : key.map((part) => record[part]).join("|");
1675
+ };
1676
+ const createUniqueArraySchema = (schema, key) => schema.array().refine((array) => new Set(key === void 0 ? array : array.map((item) => getItemKey(item, key))).size === array.length, { error: "Array items must be unique" });
1677
+ //#endregion
1678
+ //#region src/services/zstd/constants.ts
1679
+ const DEFAULT_COMPRESSION_LEVEL = 12;
1680
+ const MIN_WINDOW_LOG = 10;
1681
+ const MAX_WINDOW_LOG = 27;
1682
+ //#endregion
1683
+ //#region src/services/zstd/getWindowLog.ts
1684
+ const getWindowLog = (dictionaryByteCount, inputByteCount) => Math.min(27, Math.max(10, Math.ceil(Math.log2(dictionaryByteCount + inputByteCount + 1))));
1685
+ //#endregion
1686
+ //#region src/test/constants.ts
1687
+ const ALL_SPECIAL_VALUES = [
1688
+ {
1689
+ isPlainObject: true,
1690
+ value: {}
1691
+ },
1692
+ {
1693
+ isPlainObject: true,
1694
+ value: Object.create(null)
1695
+ },
1696
+ {
1697
+ isPlainObject: false,
1698
+ value: []
1699
+ },
1700
+ {
1701
+ isPlainObject: false,
1702
+ value: /* @__PURE__ */ new Date()
1703
+ },
1704
+ {
1705
+ isPlainObject: false,
1706
+ value: null
1707
+ },
1708
+ {
1709
+ isPlainObject: false,
1710
+ value: void 0
1711
+ },
1712
+ {
1713
+ isPlainObject: false,
1714
+ value: ""
1715
+ },
1716
+ {
1717
+ isPlainObject: false,
1718
+ value: 0
1719
+ },
1720
+ {
1721
+ isPlainObject: false,
1722
+ value: Symbol("")
1723
+ },
1724
+ {
1725
+ isPlainObject: false,
1726
+ value: noop
1727
+ },
1728
+ {
1729
+ isPlainObject: false,
1730
+ value: /(?:)/u
1731
+ }
1732
+ ];
1733
+ //#endregion
1734
+ //#region src/util/array/chunk.ts
1735
+ const chunk = (array, size) => {
1736
+ const chunks = [];
1737
+ for (let index = 0; index < array.length; index += size) chunks.push(array.slice(index, index + size));
1738
+ return chunks;
1739
+ };
1740
+ //#endregion
1741
+ //#region src/util/array/chunkBySerializedSize.ts
1742
+ const ARRAY_SERIALIZATION_BYTES = 1;
1743
+ const chunkBySerializedSize = (items, maxBytes, maxCount) => {
1744
+ const textEncoder = new TextEncoder();
1745
+ const chunks = [];
1746
+ let currentChunk = [];
1747
+ let currentBytes = ARRAY_SERIALIZATION_BYTES;
1748
+ for (const item of items) {
1749
+ const itemBytes = textEncoder.encode(JSON.stringify(item)).length + 1;
1750
+ if (currentChunk.length > 0 && (currentChunk.length === maxCount || currentBytes + itemBytes > maxBytes)) {
1751
+ chunks.push(currentChunk);
1752
+ currentChunk = [];
1753
+ currentBytes = ARRAY_SERIALIZATION_BYTES;
1754
+ }
1755
+ currentChunk.push(item);
1756
+ currentBytes += itemBytes;
1757
+ }
1758
+ if (currentChunk.length > 0) chunks.push(currentChunk);
1759
+ return chunks;
1760
+ };
1761
+ //#endregion
1762
+ //#region src/util/array/takeRandom.ts
1763
+ const takeRandom = (values, random) => takeOne(values, Math.floor(random() * values.length));
1764
+ //#endregion
1765
+ //#region src/util/date/getZonedDateTime.ts
1766
+ const getZonedDateTime = (date) => Temporal.Instant.fromEpochMilliseconds(date.getTime()).toZonedDateTimeISO(Temporal.Now.timeZoneId());
1767
+ //#endregion
1768
+ //#region src/util/date/getEndOfDay.ts
1769
+ const getEndOfDay = (date) => /* @__PURE__ */ new Date(getZonedDateTime(date).startOfDay().add({ days: 1 }).epochMilliseconds - 1);
1770
+ //#endregion
1771
+ //#region src/util/dom/checkIsNestedControl.ts
1772
+ const NESTED_INTERACTION_SELECTOR = [
1773
+ "a[href]",
1774
+ "button",
1775
+ "dialog",
1776
+ "input",
1777
+ "label",
1778
+ "select",
1779
+ "summary",
1780
+ "textarea",
1781
+ "[contenteditable='']",
1782
+ "[contenteditable='plaintext-only']",
1783
+ "[contenteditable='true']",
1784
+ "[data-nested-interaction]",
1785
+ "[role='button']",
1786
+ "[role='checkbox']",
1787
+ "[role='dialog']",
1788
+ "[role='link']",
1789
+ "[role='menu']",
1790
+ "[role='menuitem']",
1791
+ "[role='option']",
1792
+ "[role='switch']",
1793
+ "[role='tab']"
1794
+ ].join(", ");
1795
+ const checkIsNestedControl = (event) => {
1796
+ const { currentTarget, target } = event;
1797
+ if (!(currentTarget instanceof Element) || !(target instanceof Element)) return false;
1798
+ const interactiveElement = target.closest(NESTED_INTERACTION_SELECTOR);
1799
+ return Boolean(interactiveElement && interactiveElement !== currentTarget && currentTarget.contains(interactiveElement));
1800
+ };
1801
+ //#endregion
1802
+ //#region src/util/dom/checkIsNestedInteraction.ts
1803
+ const checkIsNestedInteraction = (event) => checkIsNestedControl(event) || Boolean(window.getSelection()?.toString());
1804
+ //#endregion
1805
+ //#region src/util/dom/downloadUrl.ts
1806
+ const downloadUrl = (url, filename) => {
1807
+ const anchor = window.document.createElement("a");
1808
+ anchor.href = url;
1809
+ anchor.download = filename;
1810
+ anchor.click();
1811
+ };
1812
+ //#endregion
1813
+ //#region src/util/dom/downloadFile.ts
1814
+ const downloadFile = (filename, blobPart, type) => {
1815
+ const url = URL.createObjectURL(new Blob([blobPart], { type }));
1816
+ downloadUrl(url, filename);
1817
+ window.setTimeout(() => {
1818
+ URL.revokeObjectURL(url);
1819
+ }, 0);
1820
+ };
1821
+ //#endregion
1822
+ //#region src/util/environment/checkIsServer.ts
1823
+ const checkIsServer = () => typeof window === "undefined";
1824
+ //#endregion
1825
+ //#region src/util/function/getSynchronizedFunction.ts
1826
+ const pendingPromises = /* @__PURE__ */ new Set();
1827
+ const getSynchronizedFunction = (asyncFunction) => (...args) => {
1828
+ const promise = asyncFunction(...args).finally(() => {
1829
+ pendingPromises.delete(promise);
1830
+ });
1831
+ pendingPromises.add(promise);
1832
+ };
1833
+ const waitForSynchronizedFunctions = async () => {
1834
+ await Promise.allSettled(pendingPromises);
1835
+ };
1836
+ //#endregion
1837
+ //#region src/util/id/uuid/constants.ts
1838
+ const UUIDV4_REGEX = /^[0-9A-F]{8}-[0-9A-F]{4}-[4][0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/iu;
1839
+ //#endregion
1840
+ //#region src/util/map/getOrCreate.ts
1841
+ const getOrCreate = (map, key, create) => {
1842
+ if (map.has(key)) return map.get(key);
1843
+ const value = create();
1844
+ map.set(key, value);
1845
+ return value;
1846
+ };
1847
+ //#endregion
1848
+ //#region src/util/object/clonePlainDeep.ts
1849
+ const clone = (data, copies) => {
1850
+ if (!Array.isArray(data) && !checkIsPlainObject(data)) return data;
1851
+ else if (copies.has(data)) return copies.get(data);
1852
+ else if (Array.isArray(data)) {
1853
+ const copy = [];
1854
+ copies.set(data, copy);
1855
+ for (const [index, item] of data.entries()) copy[index] = clone(item, copies);
1856
+ return copy;
1857
+ } else {
1858
+ const copy = {};
1859
+ copies.set(data, copy);
1860
+ for (const [key, value] of Object.entries(data)) copy[key] = clone(value, copies);
1861
+ return copy;
1862
+ }
1863
+ };
1864
+ const clonePlainDeep = (data) => clone(data, /* @__PURE__ */ new WeakMap());
1865
+ //#endregion
1866
+ //#region src/util/object/getPropertyNames.ts
1867
+ const getPropertyNames = () => new Proxy({}, { get: (_target, property) => property });
1868
+ //#endregion
1869
+ //#region src/util/object/jsonDateParse.ts
1870
+ const ISO_DATE_REGEX = /^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})T(?<hours>\d{2}):(?<minutes>\d{2}):(?<seconds>\d{2}(?:\.{0,1}\d*))(?:Z|(?<sign>\+|-)(?<offset>[\d|:]*))?$/u;
1871
+ const MS_AJAX_DATE_REGEX = /^\/Date\((?<timestamp>-?\d+(?:[-+]\d+)?)\)[/\\]$/u;
1872
+ const jsonDateParse = (text) => JSON.parse(text, (_key, value) => {
1873
+ if (typeof value !== "string") return value;
1874
+ else if (ISO_DATE_REGEX.test(value)) return new Date(value);
1875
+ const msAjaxDateMatch = MS_AJAX_DATE_REGEX.exec(value);
1876
+ if (!msAjaxDateMatch) return value;
1877
+ const timestampParts = takeOne(msAjaxDateMatch, 1).split(/[-+,.]/u);
1878
+ return new Date(timestampParts[0] ? Number(timestampParts[0]) : 0 - Number(timestampParts[1]));
1879
+ });
1880
+ //#endregion
1881
+ //#region src/util/object/mergeObjectsStrict.ts
1882
+ const mergeObjectsStrict = (...objects) => Object.assign({}, ...objects);
1883
+ //#endregion
1884
+ //#region src/util/object/omitDeep.ts
1885
+ const checkIsWalkable = (value) => Object.prototype.toString.call(value) === "[object Object]";
1886
+ const omitValue = (value, omittedKeys) => {
1887
+ if (Array.isArray(value)) return value.map((element) => omitValue(element, omittedKeys));
1888
+ if (!checkIsWalkable(value)) return value;
1889
+ const omittedValue = {};
1890
+ for (const [key, propertyValue] of Object.entries(value)) if (!omittedKeys.has(key)) omittedValue[key] = omitValue(propertyValue, omittedKeys);
1891
+ return omittedValue;
1892
+ };
1893
+ const omitDeep = (value, ...keys) => omitValue(value, new Set(keys));
1894
+ //#endregion
1895
+ //#region src/util/promise/createEvictingPromiseCache.ts
1896
+ const createEvictingPromiseCache = (getKey, load) => {
1897
+ const promiseMap = /* @__PURE__ */ new Map();
1898
+ return (...args) => {
1899
+ const key = getKey(...args);
1900
+ const promise = promiseMap.get(key) ?? load(...args);
1901
+ promiseMap.set(key, promise);
1902
+ return getResultAsync(() => promise).match((value) => value, (error) => {
1903
+ if (promiseMap.get(key) === promise) promiseMap.delete(key);
1904
+ throw error;
1905
+ });
1906
+ };
1907
+ };
1908
+ //#endregion
1909
+ //#region src/util/promise/settleAll.ts
1910
+ const settleAll = async (tasks, concurrencyLimit = tasks.length) => {
1911
+ if (tasks.length === 0) return [];
1912
+ const values = [];
1913
+ for (const tasksChunk of chunk(tasks, concurrencyLimit)) {
1914
+ const results = await Promise.allSettled(tasksChunk.map((task) => Promise.try(task)));
1915
+ const reasons = [];
1916
+ for (const result of results) if (result.status === "rejected") reasons.push(result.reason);
1917
+ else values.push(result.value);
1918
+ if (reasons.length === 1) throw takeOne(reasons);
1919
+ else if (reasons.length > 1) throw new AggregateError(reasons, toAppError(takeOne(reasons)).message);
1920
+ }
1921
+ return values;
1922
+ };
1923
+ //#endregion
1924
+ //#region src/util/text/capitalize.ts
1925
+ const capitalize = (string) => `${string.charAt(0).toUpperCase()}${string.slice(1)}`;
1926
+ //#endregion
1927
+ //#region src/util/text/dedent.ts
1928
+ const ESCAPE_CHARACTER = "\\";
1929
+ const LINE_FEED = "\n";
1930
+ const LINE_FEED_CHARACTER = {
1931
+ escapable: false,
1932
+ value: LINE_FEED
1933
+ };
1934
+ const HEXADECIMAL_REGEX = /^[\da-fA-F]$/u;
1935
+ const WHITESPACE_REGEX = /^\s$/u;
1936
+ const BRACED_CODE_POINT_MAXIMUM_DIGITS = 6;
1937
+ const CODE_POINT_MAXIMUM = 1114111;
1938
+ const HEXADECIMAL_BYTE_DIGITS = 2;
1939
+ const HEXADECIMAL_UNIT_DIGITS = 4;
1940
+ const escapeValueMap = {
1941
+ "0": "\0",
1942
+ $: "$",
1943
+ "\\": "\\",
1944
+ "`": "`",
1945
+ b: "\b",
1946
+ f: "\f",
1947
+ n: "\n",
1948
+ r: "\r",
1949
+ t: " ",
1950
+ v: "\v",
1951
+ "{": "{"
1952
+ };
1953
+ const toCharacters = (text, escapable) => text.split("").map((value) => ({
1954
+ escapable,
1955
+ value
1956
+ }));
1957
+ const isWhitespace = (character) => WHITESPACE_REGEX.test(character.value);
1958
+ const alignValue = (value, precedingText) => {
1959
+ const currentLine = precedingText.slice(precedingText.lastIndexOf(LINE_FEED) + 1);
1960
+ const indentation = /^\s+/u.exec(currentLine)?.[0];
1961
+ return indentation ? value.replaceAll(LINE_FEED, `${LINE_FEED}${indentation}`) : value;
1962
+ };
1963
+ const isEscapeStart = (characters, index) => {
1964
+ const character = characters[index];
1965
+ const next = characters[index + 1];
1966
+ return character?.escapable === true && character.value === ESCAPE_CHARACTER && next?.escapable === true;
1967
+ };
1968
+ const removeLineContinuations = (characters) => {
1969
+ const result = [];
1970
+ let index = 0;
1971
+ while (index < characters.length) {
1972
+ const character = characters[index];
1973
+ if (!character) break;
1974
+ if (isEscapeStart(characters, index)) {
1975
+ const next = characters[index + 1];
1976
+ if (next?.value === LINE_FEED) {
1977
+ index += 2;
1978
+ while (characters[index]?.escapable === true && (characters[index]?.value === " " || characters[index]?.value === " ")) index++;
1979
+ } else {
1980
+ result.push(character, ...next ? [next] : []);
1981
+ index += 2;
1982
+ }
1983
+ } else {
1984
+ result.push(character);
1985
+ index++;
1986
+ }
1987
+ }
1988
+ return result;
1989
+ };
1990
+ const splitLines = (characters) => {
1991
+ const lines = [];
1992
+ let line = [];
1993
+ for (const character of characters) if (character.value === LINE_FEED) {
1994
+ lines.push(line);
1995
+ line = [];
1996
+ } else line.push(character);
1997
+ lines.push(line);
1998
+ return lines;
1999
+ };
2000
+ const getIndentation = (line) => {
2001
+ const indentation = line.findIndex((character) => !isWhitespace(character));
2002
+ return indentation > 0 ? indentation : void 0;
2003
+ };
2004
+ const dedentCharacters = (characters) => {
2005
+ const lines = splitLines(characters);
2006
+ const indentations = lines.map((line) => getIndentation(line)).filter((indentation) => indentation !== void 0);
2007
+ if (indentations.length === 0) return characters;
2008
+ const minimumIndentation = Math.min(...indentations);
2009
+ const result = [];
2010
+ for (const [index, line] of lines.entries()) {
2011
+ if (index > 0) result.push(LINE_FEED_CHARACTER);
2012
+ const first = line[0]?.value;
2013
+ result.push(...first === " " || first === " " ? line.slice(minimumIndentation) : line);
2014
+ }
2015
+ return result;
2016
+ };
2017
+ const trimCharacters = (characters) => {
2018
+ const start = characters.findIndex((character) => !isWhitespace(character));
2019
+ if (start === -1) return [];
2020
+ return characters.slice(start, characters.findLastIndex((character) => !isWhitespace(character)) + 1);
2021
+ };
2022
+ const readHexadecimal = (characters, start, digits) => {
2023
+ let hexadecimal = "";
2024
+ for (let index = start; index < start + digits; index++) {
2025
+ const character = characters[index];
2026
+ if (character?.escapable !== true || !HEXADECIMAL_REGEX.test(character.value)) return void 0;
2027
+ hexadecimal += character.value;
2028
+ }
2029
+ return hexadecimal;
2030
+ };
2031
+ const readBracedCodePoint = (characters, index) => {
2032
+ if (characters[index + 2]?.value !== "{") return void 0;
2033
+ let digits = "";
2034
+ let cursor = index + 3;
2035
+ while (digits.length < BRACED_CODE_POINT_MAXIMUM_DIGITS && HEXADECIMAL_REGEX.test(characters[cursor]?.value ?? "")) {
2036
+ digits += characters[cursor]?.value;
2037
+ cursor++;
2038
+ }
2039
+ const closing = characters[cursor];
2040
+ if (digits.length === 0 || closing?.escapable !== true || closing.value !== "}") return void 0;
2041
+ const codePoint = Number.parseInt(digits, 16);
2042
+ if (codePoint > CODE_POINT_MAXIMUM) return void 0;
2043
+ return {
2044
+ length: cursor - index + 1,
2045
+ text: String.fromCodePoint(codePoint)
2046
+ };
2047
+ };
2048
+ const fromHexadecimal = (hexadecimal) => String.fromCodePoint(Number.parseInt(hexadecimal, 16));
2049
+ const readEscape = (characters, index) => {
2050
+ const character = characters[index];
2051
+ if (!character) return {
2052
+ length: 0,
2053
+ text: ""
2054
+ };
2055
+ if (!isEscapeStart(characters, index)) return {
2056
+ length: 1,
2057
+ text: character.value
2058
+ };
2059
+ const next = characters[index + 1];
2060
+ const escapeValue = next ? escapeValueMap[next.value] : void 0;
2061
+ if (escapeValue !== void 0) return {
2062
+ length: 2,
2063
+ text: escapeValue
2064
+ };
2065
+ if (next?.value === "x") {
2066
+ const hexadecimal = readHexadecimal(characters, index + 2, HEXADECIMAL_BYTE_DIGITS);
2067
+ if (hexadecimal !== void 0) return {
2068
+ length: 4,
2069
+ text: fromHexadecimal(hexadecimal)
2070
+ };
2071
+ }
2072
+ if (next?.value === "u") {
2073
+ const braced = readBracedCodePoint(characters, index);
2074
+ if (braced) return braced;
2075
+ const hexadecimal = readHexadecimal(characters, index + 2, HEXADECIMAL_UNIT_DIGITS);
2076
+ if (hexadecimal !== void 0) return {
2077
+ length: 6,
2078
+ text: fromHexadecimal(hexadecimal)
2079
+ };
2080
+ }
2081
+ return {
2082
+ length: 1,
2083
+ text: character.value
2084
+ };
2085
+ };
2086
+ const cookCharacters = (characters) => {
2087
+ let result = "";
2088
+ let index = 0;
2089
+ while (index < characters.length) {
2090
+ const cooked = readEscape(characters, index);
2091
+ result += cooked.text;
2092
+ index += cooked.length;
2093
+ }
2094
+ return result;
2095
+ };
2096
+ const createDedent = (options) => {
2097
+ const dedent = (strings, ...values) => {
2098
+ const isTemplate = typeof strings !== "string";
2099
+ const raws = isTemplate ? strings.raw : [strings];
2100
+ const { alignValues = false, escapeSpecialCharacters = isTemplate, trimWhitespace = true } = options;
2101
+ let precedingText = "";
2102
+ const parts = [];
2103
+ for (const [index, raw] of raws.entries()) {
2104
+ parts.push(toCharacters(raw, true));
2105
+ precedingText += raw;
2106
+ if (index < values.length) {
2107
+ const value = String(values[index]);
2108
+ const alignedValue = alignValues ? alignValue(value, precedingText) : value;
2109
+ parts.push(toCharacters(alignedValue, false));
2110
+ precedingText += alignedValue;
2111
+ }
2112
+ }
2113
+ let characters = parts.flat();
2114
+ if (escapeSpecialCharacters) characters = removeLineContinuations(characters);
2115
+ characters = dedentCharacters(characters);
2116
+ if (trimWhitespace) characters = trimCharacters(characters);
2117
+ return escapeSpecialCharacters ? cookCharacters(characters) : characters.map((character) => character.value).join("");
2118
+ };
2119
+ dedent.withOptions = (newOptions) => createDedent({
2120
+ ...options,
2121
+ ...newOptions
2122
+ });
2123
+ return dedent;
2124
+ };
2125
+ const dedent = createDedent({});
2126
+ //#endregion
2127
+ //#region src/util/text/encodeUrlSubDelimiters.ts
2128
+ const EncodedSubDelimiterMap = {
2129
+ "!": "%21",
2130
+ "'": "%27",
2131
+ "(": "%28",
2132
+ ")": "%29",
2133
+ "*": "%2A"
2134
+ };
2135
+ const encodeUrlSubDelimiters = (value) => Object.entries(EncodedSubDelimiterMap).reduce((encoded, [subDelimiter, encodedSubDelimiter]) => encoded.replaceAll(subDelimiter, encodedSubDelimiter), value);
2136
+ //#endregion
2137
+ //#region src/util/text/getDecodedUriComponent.ts
2138
+ const getDecodedUriComponent = (value, fallback) => getResult(() => decodeURIComponent(value)).unwrapOr(fallback);
2139
+ //#endregion
2140
+ //#region src/util/text/streamToText.ts
2141
+ const streamToText = async (readable) => {
2142
+ readable.setEncoding("utf8");
2143
+ let data = "";
2144
+ for await (const chunk of readable) data += chunk.toString();
2145
+ return data;
2146
+ };
2147
+ //#endregion
2148
+ //#region src/util/text/toKebabCase.ts
2149
+ const toKebabCase = (string) => string.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/gu)?.map((x) => x.toLowerCase()).join("-") ?? "";
2150
+ //#endregion
2151
+ //#region src/util/text/truncate.ts
2152
+ const SUFFIX = "...";
2153
+ const truncate = (string, length) => {
2154
+ if (string.length <= length) return string;
2155
+ else if (length < 3) return string.slice(0, length);
2156
+ else return `${string.slice(0, length - 3)}${SUFFIX}`;
2157
+ };
2158
+ //#endregion
2159
+ //#region src/util/text/uncapitalize.ts
2160
+ const uncapitalize = (string) => `${string.charAt(0).toLowerCase()}${string.slice(1)}`;
2161
+ //#endregion
2162
+ //#region src/util/time/constants.ts
2163
+ const MILLISECONDS_PER_SECOND = 1e3;
2164
+ //#endregion
2165
+ //#region src/util/time/hrtime.ts
2166
+ const hrtime = (previousHrTime) => {
2167
+ if (checkIsServer()) return process.hrtime(previousHrTime);
2168
+ const clocktime = performance.now() * .001;
2169
+ let seconds = Math.floor(clocktime);
2170
+ let nanoseconds = Math.floor(clocktime % 1 * 1e9);
2171
+ if (previousHrTime) {
2172
+ seconds -= previousHrTime[0];
2173
+ nanoseconds -= previousHrTime[1];
2174
+ if (nanoseconds < 0) {
2175
+ seconds--;
2176
+ nanoseconds += 1e9;
2177
+ }
2178
+ }
2179
+ return [seconds, nanoseconds];
2180
+ };
2181
+ //#endregion
2182
+ //#region src/util/time/now.ts
2183
+ const loadNanoseconds = hrtime();
2184
+ const loadMilliseconds = Date.now();
2185
+ const now = () => {
2186
+ const [seconds, nanoseconds] = hrtime(loadNanoseconds);
2187
+ return (BigInt(loadMilliseconds) * 10n ** 6n + (BigInt(seconds) * 10n ** 9n + BigInt(nanoseconds))).toString();
2188
+ };
2189
+ //#endregion
2190
+ //#region src/util/time/sleep.ts
2191
+ const sleep = (durationMs) => new Promise((resolve) => {
2192
+ setTimeout(() => {
2193
+ resolve();
2194
+ }, durationMs);
2195
+ });
2196
+ //#endregion
2197
+ export { ALL_SPECIAL_VALUES, APPEND_SEGMENT, CHARSET_PARAMETER_REGEX, CUSTOM_EMOJI_ID_ATTRIBUTE, CUSTOM_EMOJI_NAME_ATTRIBUTE, DEFAULT_ALLOWED_ATTRIBUTES, DEFAULT_ALLOWED_SCHEMES, DEFAULT_ALLOWED_TAGS, DEFAULT_COMPRESSION_LEVEL, DEFAULT_FACET_SCORE, DEFAULT_LINK_ATTRIBUTES, DEFAULT_SOURCE_SCORE, DEFAULT_TEXT_CHARSET, DEFAULT_TYPE_SCORE, ESCAPED_ATTRIBUTE_CHARACTERS_REGEX, ESCAPED_TEXT_CHARACTERS_REGEX, FacetScoreMap, ForbiddenError, GIBIBYTE, HTML_NAMESPACE, ID_SEPARATOR, IMPORTANT_REGEX, InvalidOperationError, ItemMetadata, JSON_POINTER_REGEX, JsonPatchOperationType, KIBIBYTE, MAX_NESTING_DEPTH, MAX_READ_LIMIT, MAX_WINDOW_LOG, MEDIA_TYPE_REGEX, MENTION_EVERYONE_ID, MENTION_HERE_ID, MENTION_ID_ATTRIBUTE, MENTION_ITEM_TYPE_ATTRIBUTE, MENTION_LABEL_ATTRIBUTE, MENTION_SELECTOR, MENTION_TYPE, MENTION_TYPE_ATTRIBUTE, MILLISECONDS_PER_SECOND, MIN_WINDOW_LOG, MentionType, NON_TEXT_TAGS, NotFoundError, NotInitializedError, ObjectMethod, Operation, PATH_SEPARATOR_REGEX, RoutePath, SANITIZER_ADVISORY_WATCH_SINCE, SITE_NAME, SPOILER_ATTRIBUTE, SPOILER_SELECTOR, SRCSET_ATTRIBUTE, SRCSET_DESCRIPTOR_REGEX, Serializable, SourceScoreMap, TEXT_MEDIA_TYPE_REGEX, TypeScoreMap, TypedEventEmitter, URL_ATTRIBUTES, UUIDV4_REGEX, VOID_TAGS, WordFilteredError, addJsonValue, applyItemMetadataMixin, applyPatch, applyPatches, capitalize, charset, checkContainsProfanity, checkIsAllowedUrl, checkIsCustomMethod, checkIsDeepEqual, checkIsNestedControl, checkIsNestedInteraction, checkIsPlainObject, checkIsSameBytes, checkIsSameValueZero, checkIsServer, checkIsUnsafeUrlCharacter, checkIsWhitespaceCharacter, chunk, chunkBySerializedSize, clonePlainDeep, collectText, contentType, createEvictingPromiseCache, createHistory, createItemEntityTypeSchema, createNormalizedStringSchema, createUniqueArraySchema, css, dedent, downloadFile, downloadUrl, encodeUrlSubDelimiters, englishProfaneWords, escapeAttribute, escapeCharacters, escapeText, exhaustiveGuard, extension, filterAttributes, filterClasses, filterHtml, filterSrcset, filterStyle, getChildNodes, getDecodedUriComponent, getEndOfDay, getEnumerableKeys, getExtensionMimeTypeMap, getMediaType, getMentions, getMimeScore, getMimeTypeEntryMap, getOrCreate, getPropertyNames, getRawData, getRequestError, getResult, getResultAsync, getSynchronizedFunction, getTransactionDone, getTransactionObjectStore, getWindowLog, getZonedDateTime, hrtime, html, jsonDateParse, lookup, matchesClassPattern, mergeObjectsStrict, noop, normalizeString, now, omitDeep, openDatabase, parseArrayIndex, parseJsonPointer, pushHistory, readJsonValue, redoHistory, removeJsonValue, renderNode, reportFinalizerError, requestToPromise, sanitizeHtml, sanitizeTextHtml, settleAll, sleep, streamToText, takeOne, takeRandom, toAppError, toJsonPointer, toKebabCase, toRawDeep, truncate, uncapitalize, undoHistory, updateJsonValue, waitForSynchronizedFunctions, withFinalizer, withFinalizerAsync, wrapDatabase, wrapIndex, wrapObjectStore, wrapTransaction, wrapUpgradeDatabase, wrapUpgradeTransaction };