@pi-r/chrome 0.7.3 → 0.8.1

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/index.js CHANGED
@@ -1,11 +1,12 @@
1
1
  "use strict";
2
2
  const path = require("path");
3
3
  const fs = require("fs");
4
- const asset_1 = require("@e-mc/document/asset");
5
- const util_1 = require("@e-mc/document/util");
6
- const types_1 = require("@e-mc/types");
4
+ const crypto_1 = require("crypto");
7
5
  const core_1 = require("@e-mc/core");
8
6
  const Cloud = require("@e-mc/cloud");
7
+ const types_1 = require("@e-mc/types");
8
+ const asset_1 = require("@e-mc/document/asset");
9
+ const util_1 = require("@e-mc/document/util");
9
10
  const dom_1 = require("@e-mc/document/parse/dom");
10
11
  const transform_1 = require("@e-mc/document/transform");
11
12
  const Document = require('@e-mc/document');
@@ -18,7 +19,6 @@ const CACHE_CONTENT = new Map();
18
19
  const CACHE_FORMAT = new Map();
19
20
  const CACHE_DATASET = {};
20
21
  const CACHE_ATRULES = {};
21
- let CACHE_TOTAL = 0;
22
22
  const [PATTERN_STRING_SOME, PATTERN_STRING_MANY] = (function () {
23
23
  const grouping = '(?:\\s|' + dom_1.DomWriter.PATTERN_COMMENT + '|`[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}`)';
24
24
  return [grouping + '*', grouping + '+'];
@@ -32,10 +32,10 @@ const [REGEXP_NTHCHILD, REGEXP_NTHCHILD_UNSAFE, REGEXP_REPLACECSS] = (function (
32
32
  ];
33
33
  })();
34
34
  const REGEXP_SRCSETSIZE = /~\s*([\d.]+)\s*([wx])/i;
35
- const REGEXP_TEMPLATECONDITIONAL = /(\n\s+)?\{\{if\s+((?:[^}]|}(?!}))+?)\}\}(\s*)([\S\s]*?)(?:\s*\{\{else(?:\s+if\s+((?:[^}]|}(?!}))+?))?\}\}(\s*)([\S\s]*?)\s*)?\s*\{\{end\}\}/g;
35
+ const REGEXP_TEMPLATECONDITIONAL = /(\n\s+)?\{\{if\s+((?:[^}]|}(?!}))+?)\}\}(\s*)(.*?)(?:\s*\{\{else(?:\s+if\s+((?:[^}]|}(?!}))+?))?\}\}(\s*)(.*?)\s*)?\s*\{\{end\}\}/gs;
36
36
  const REGEXP_TEMPLATECOMPARISON = /\s*\(\s*(?:\b(eq|ne|lt|le|gt|ge)\s+)?("[^"]+"|'[^']+'|[^\s)]+)(?:\s+("[^"]+"|'[^']+'|[^\s)]+))?\s*\)/g;
37
37
  const REGEXP_TEMPLATEMATCH = new RegExp(`^(?:\\b(and|or|not)\\s+)?((?:${REGEXP_TEMPLATECOMPARISON.source})+)|(!|not\\s+)?([^\\s][\\S\\s]*)$`);
38
- const REGEXP_IMPORTMODULE = /(?:(?:^|[\n;]+)\s*import\s+(?:("(?:[^"]|(?<=\\)")+"|'(?:[^']|(?<=\\)')+')|.+?from\s+("(?:[^"]|(?<=\\)")+"|'(?:[^']|(?<=\\)')+')(?:[ \t]+assert[ \t]+\{((?:"(?:[^"]|(?<=\\)")+"|'(?:[^']|(?<=\\)')+'|`(?:[^`]|(?<=\\)`)+`|{[^{]*{|{[^}]*}|}[^}]*}|[^"'`]+)+)\})?)|\bimport\(\s*("(?:[^"]|(?<=\\)")+"|'(?:[^']|(?<=\\)')+')\s*(?:,\s*\{((?:"(?:[^"]|(?<=\\)")+"|'(?:[^']|(?<=\\)')+'|`(?:[^`]|(?<=\\)`)+`|{[^{]*{|{[^}]*}|}[^}]*}|[^"'`]+)+)\}\s*)?\))/g;
38
+ const REGEXP_IMPORTMODULE = /(?:(?:^|[\n;]+)\s*import\s+(?:("(?:[^"]|(?<=\\)")+"|'(?:[^']|(?<=\\)')+')|.+?from\s+("(?:[^"]|(?<=\\)")+"|'(?:[^']|(?<=\\)')+')(?:[ \t]+assert[ \t]+\{((?:"(?:[^"]|(?<=\\)")+"|'(?:[^']|(?<=\\)')+'|`(?:[^`]|(?<=\\)`)+`|{[^{]*{|{[^}]*}|}[^}]*}|[^"'`]+)+)\})?)|\bimport\(\s*("(?:[^"]|(?<=\\)")+"|'(?:[^']|(?<=\\)')+')\s*(?:,\s*\{((?:"(?:[^"]|(?<=\\)")+"|'(?:[^']|(?<=\\)')+'|`(?:[^`]|(?<=\\)`)+`|{[^{]*{|{[^}]*}|}[^}]*}|[^"'`]+)+)\}\s*)?\))/gd;
39
39
  const REGEXP_BLOCKEXCLUDE = new RegExp(`(\\s*)<!--\\s*exclude\\s*:\\s*(?:start|end)\\s*-->` + dom_1.DomWriter.PATTERN_TRAILINGSPACE, 'gi');
40
40
  const REGEXP_COMMENT = new RegExp(dom_1.DomWriter.PATTERN_COMMENT, 'g');
41
41
  const REGEXP_QUOTEDVALUE = new RegExp(`\\b(?:@import${PATTERN_STRING_MANY}|content${PATTERN_STRING_SOME}:${PATTERN_STRING_SOME})(?:"[^"]*"|'[^']*')`, 'gi');
@@ -58,7 +58,8 @@ const REGEXP_URL = /(?:\b[Uu][Rr][Ll]\(|@import\s+(["'])|\b([Hh][Rr][Ee][Ff])\s*
58
58
  const REGEXP_URL_JS = /\bimport\(/g;
59
59
  const REGEXP_URL_SVG = /(?:\b[Uu][Rr][Ll]\(|@import\s+(["'])|\b([Hh][Rr][Ee][Ff])\s*=)/g;
60
60
  const REGEXP_IMAGESET = /\b(?:-webkit-)?image-set\(/gi;
61
- const REGEXP_IMAGESET_URL = /(?:^|[^(])\s*("(\s*[^)][^"]*)"|'(\s*[^)][^"]*)')\s*(?:,|$|[^)][^,]*,?)/g;
61
+ const REGEXP_IMAGESET_URL = /(?:^|[^(])\s*("(\s*[^)][^"]*)"|'(\s*[^)][^"]*)')\s*(?:,|$|[^)][^,]*,?)/gd;
62
+ const REGEXP_SANITIZEALL = new RegExp(`(?:\\s+|\\b)data-(?:pathname|filename|intl-locales|(?:use|exclude)-[^=\\s]+)\\s*${dom_1.DomWriter.PATTERN_ATTRVALUE}(?=(?:[^"<]+"[^"]*"|[^'<]+'[^']*')*[^<>]*>)`, 'g');
62
63
  function removeNamespace(name, source, newline, comments) {
63
64
  if (source.includes('-' + name)) {
64
65
  const [a, b, c, d, e] = CACHE_DATASET[name] ||= [
@@ -96,7 +97,7 @@ function getObjectValue(value, key) {
96
97
  }
97
98
  }
98
99
  }
99
- if (value !== undefined && value !== null) {
100
+ if (value != null) {
100
101
  found = true;
101
102
  continue;
102
103
  }
@@ -162,13 +163,12 @@ function getCacheItem(map, key) {
162
163
  }
163
164
  }
164
165
  function addCacheItem(map, key, data, timeout) {
165
- if (!map.has(key)) {
166
- ++CACHE_TOTAL;
167
- }
168
166
  map.set(key, [
169
167
  Date.now(),
170
168
  data,
171
- setTimeout(() => deleteCacheItem(map, key), timeout * 1000)
169
+ setTimeout(() => {
170
+ deleteCacheItem(map, key);
171
+ }, timeout * 1000)
172
172
  ]);
173
173
  }
174
174
  function deleteCacheItem(map, key) {
@@ -176,15 +176,23 @@ function deleteCacheItem(map, key) {
176
176
  if (item) {
177
177
  clearTimeout(item[2]);
178
178
  map.delete(key);
179
- --CACHE_TOTAL;
180
179
  }
181
180
  }
182
181
  function spliceSource(source, startIndex, endIndex, pattern, leading = '', trailing = '', content = '') {
183
182
  if (leading || trailing) {
184
183
  content += getNewlineString(leading, trailing);
185
184
  }
186
- pattern.lastIndex = startIndex + content.length;
187
- return spliceString(source, startIndex, endIndex, content);
185
+ return (0, util_1.spliceString)(source, startIndex, endIndex, content, pattern);
186
+ }
187
+ function parseArg(data, value) {
188
+ if (!isNaN(+value)) {
189
+ return +value;
190
+ }
191
+ const match = /^(["'])(.*)\1$/s.exec(value);
192
+ if (match) {
193
+ return match[2];
194
+ }
195
+ return getObjectValue(data, value);
188
196
  }
189
197
  function hasCondition(data, condition) {
190
198
  if (!condition) {
@@ -197,7 +205,7 @@ function hasCondition(data, condition) {
197
205
  const join = match[1];
198
206
  const items = [];
199
207
  while (match = REGEXP_TEMPLATECOMPARISON.exec(comparison)) {
200
- if (items.length && !isSpace(match[0][0])) {
208
+ if (items.length > 0 && !isSpace(match[0][0])) {
201
209
  return false;
202
210
  }
203
211
  items.push([match[1], match[2], match[3]]);
@@ -207,15 +215,6 @@ function hasCondition(data, condition) {
207
215
  if (length > 1 && !join) {
208
216
  return false;
209
217
  }
210
- const parseArg = (value) => {
211
- if (!isNaN(+value)) {
212
- return +value;
213
- }
214
- if (match = /^(["'])([\S\s]*)\1$/.exec(value)) {
215
- return match[2];
216
- }
217
- return getObjectValue(data, value);
218
- };
219
218
  for (let i = 0; i < length; ++i) {
220
219
  const item = items[i];
221
220
  const arg1 = item[1];
@@ -224,22 +223,22 @@ function hasCondition(data, condition) {
224
223
  if (arg2) {
225
224
  switch (item[0]) {
226
225
  case 'eq':
227
- valid = parseArg(arg1) == parseArg(arg2);
226
+ valid = parseArg(data, arg1) == parseArg(data, arg2);
228
227
  break;
229
228
  case 'ne':
230
- valid = parseArg(arg1) != parseArg(arg2);
229
+ valid = parseArg(data, arg1) != parseArg(data, arg2);
231
230
  break;
232
231
  case 'lt':
233
- valid = parseArg(arg1) < parseArg(arg2);
232
+ valid = parseArg(data, arg1) < parseArg(data, arg2);
234
233
  break;
235
234
  case 'le':
236
- valid = parseArg(arg1) <= parseArg(arg2);
235
+ valid = parseArg(data, arg1) <= parseArg(data, arg2);
237
236
  break;
238
237
  case 'gt':
239
- valid = parseArg(arg1) > parseArg(arg2);
238
+ valid = parseArg(data, arg1) > parseArg(data, arg2);
240
239
  break;
241
240
  case 'ge':
242
- valid = parseArg(arg1) >= parseArg(arg2);
241
+ valid = parseArg(data, arg1) >= parseArg(data, arg2);
243
242
  break;
244
243
  default:
245
244
  return false;
@@ -278,12 +277,17 @@ function isTruthy(data, attr, falsey) {
278
277
  return falsey ? !value : !!value;
279
278
  }
280
279
  function hasSameOrigin(value, ...other) {
280
+ if (typeof value === 'string') {
281
+ try {
282
+ value = new URL(value);
283
+ }
284
+ catch {
285
+ return null;
286
+ }
287
+ }
281
288
  for (let url of other) {
282
289
  if (url) {
283
290
  try {
284
- if (typeof value === 'string') {
285
- value = new URL(value);
286
- }
287
291
  if (typeof url === 'string') {
288
292
  url = new URL(url);
289
293
  }
@@ -300,7 +304,11 @@ function hasSameOrigin(value, ...other) {
300
304
  function restoreSearchParams(value, prefix = '__sqd') {
301
305
  if (value?.includes(prefix)) {
302
306
  const params = new URLSearchParams(value);
303
- params.forEach((_, key) => key.startsWith(prefix) && params.delete(key));
307
+ params.forEach((_, key) => {
308
+ if (key.startsWith(prefix)) {
309
+ params.delete(key);
310
+ }
311
+ });
304
312
  if (value = params.toString()) {
305
313
  return '?' + value;
306
314
  }
@@ -309,7 +317,7 @@ function restoreSearchParams(value, prefix = '__sqd') {
309
317
  }
310
318
  function getBaseURLs(asset, baseUrl) {
311
319
  const result = [];
312
- let parentUrl = asset ? asset.url || asset.uri : undefined;
320
+ let parentUrl = asset ? asset.url || asset.uri : null;
313
321
  try {
314
322
  if (parentUrl) {
315
323
  if (typeof parentUrl === 'string') {
@@ -320,15 +328,18 @@ function getBaseURLs(asset, baseUrl) {
320
328
  }
321
329
  }
322
330
  catch {
323
- parentUrl = undefined;
331
+ parentUrl = null;
324
332
  }
325
333
  if (baseUrl) {
326
334
  const url = new URL(baseUrl);
327
335
  if (!parentUrl) {
328
336
  result.push(parentUrl = url);
329
337
  }
330
- else if (parentUrl.origin !== url.origin) {
331
- result.push(new URL(parentUrl.href.replace(parentUrl.origin, url.origin)), url);
338
+ else {
339
+ const { href, origin } = parentUrl;
340
+ if (origin !== url.origin) {
341
+ result.push(new URL(href.replace(origin, url.origin)), url);
342
+ }
332
343
  }
333
344
  }
334
345
  return result;
@@ -340,11 +351,11 @@ function createHash(host, file, hash, bufferMap) {
340
351
  if (buffer) {
341
352
  const [algorithm, length] = (0, util_1.getHashData)(hash);
342
353
  let value;
343
- if (algorithm && (value = Document.asHash(buffer, { algorithm, encoding: file.encoding }))) {
354
+ if (algorithm && (value = Document.asHash(buffer, algorithm, { encoding: file.encoding }))) {
344
355
  if (localUri) {
345
356
  bufferMap[localUri] = buffer;
346
357
  }
347
- host.rename(file, (0, util_1.appendSuffix)(filename, length ? value.substring(0, length) : value));
358
+ host.rename(file, (0, util_1.appendSuffix)(filename, length > 0 ? value.substring(0, length) : value));
348
359
  return file.filename;
349
360
  }
350
361
  }
@@ -354,8 +365,8 @@ function createHash(host, file, hash, bufferMap) {
354
365
  host.writeFail(["Unable to read file", filename], err, 32);
355
366
  }
356
367
  }
357
- function getSrcURL(parent, file) {
358
- const relativeUrl = file.relativeUrl || this.host.removeCwd(file.localUri) && getRelativeURL(file);
368
+ function getSrcURL(instance, parent, file) {
369
+ const relativeUrl = file.relativeUrl || instance.host.removeCwd(file.localUri) && getRelativeURL(file);
359
370
  if (!relativeUrl) {
360
371
  return [''];
361
372
  }
@@ -363,31 +374,30 @@ function getSrcURL(parent, file) {
363
374
  return [relativeUrl];
364
375
  }
365
376
  let parentDir = parent.pathname, assetDir = file.pathname;
366
- if (!this.productionRelease) {
377
+ if (!instance.productionRelease) {
367
378
  if (parent.moveTo) {
368
- parentDir = joinPath(parent.moveTo, parentDir);
379
+ parentDir = Document.joinPath(parent.moveTo, parentDir);
369
380
  }
370
381
  if (file.moveTo) {
371
- assetDir = joinPath(file.moveTo, assetDir);
382
+ assetDir = Document.joinPath(file.moveTo, assetDir);
372
383
  }
373
384
  }
374
385
  if (parentDir === assetDir) {
375
386
  return [file.filename, true];
376
387
  }
377
- const splitPath = (value) => value.split(/[\\/]/).filter(segment => segment.trim());
378
388
  const prefix = splitPath(parentDir);
379
389
  const suffix = splitPath(assetDir);
380
390
  let found;
381
- while (prefix.length && suffix.length && prefix[0] === suffix[0]) {
391
+ while (prefix.length > 0 && suffix.length > 0 && prefix[0] === suffix[0]) {
382
392
  prefix.shift();
383
393
  suffix.shift();
384
394
  found = true;
385
395
  }
386
- return [found ? joinPath('../'.repeat(prefix.length), suffix.join('/'), file.filename) : '../'.repeat(prefix.length) + relativeUrl];
396
+ return [found ? Document.joinPath('../'.repeat(prefix.length), suffix.join('/'), file.filename) : '../'.repeat(prefix.length) + relativeUrl];
387
397
  }
388
- function transformURL(host, parent, type, source, importFile) {
398
+ function transformURL(instance, host, parent, type, source, importFile) {
389
399
  const related = [];
390
- const baseHref = getBaseURLs(importFile || parent, this.baseUrl);
400
+ const baseHref = getBaseURLs(importFile || parent, instance.baseUrl);
391
401
  const isHtml = type === 'html';
392
402
  const isJs = type === 'js';
393
403
  const pattern = isJs ? REGEXP_URL_JS : type === 'svg' ? REGEXP_URL_SVG : REGEXP_URL;
@@ -401,15 +411,15 @@ function transformURL(host, parent, type, source, importFile) {
401
411
  continue;
402
412
  }
403
413
  REGEXP_IMAGESET_URL.lastIndex = 0;
404
- const original = source.substring(startIndex, endIndex);
405
- let content = original, url;
406
- while (url = REGEXP_IMAGESET_URL.exec(original)) {
414
+ let content = source.substring(startIndex, endIndex), url;
415
+ while (url = REGEXP_IMAGESET_URL.exec(content)) {
407
416
  const quote = url[2] ? '"' : "'";
408
- content = content.replace(url[1], `url(${quote + (url[2] || url[3]).trim() + quote})`);
417
+ const [a, b] = url.indices[1];
418
+ content = (0, util_1.spliceString)(content, a, b, `url(${quote + (url[2] || url[3]).trim() + quote})`, REGEXP_IMAGESET_URL);
409
419
  modified = true;
410
420
  }
411
421
  if (modified) {
412
- source = spliceString(source, startIndex, REGEXP_IMAGESET.lastIndex = endIndex, content);
422
+ source = (0, util_1.spliceString)(source, startIndex, endIndex, content, REGEXP_IMAGESET);
413
423
  modified = false;
414
424
  }
415
425
  }
@@ -478,12 +488,12 @@ function transformURL(host, parent, type, source, importFile) {
478
488
  if (asset) {
479
489
  if (!asset.inlineBase64) {
480
490
  if (host.Cloud?.getStorage('upload', asset.cloudStorage)) {
481
- const inlineUrlCloud = asset.inlineUrlCloud ||= (0, types_1.generateUUID)();
491
+ const inlineUrlCloud = asset.inlineUrlCloud ||= (0, crypto_1.randomUUID)();
482
492
  (parent.inlineUrlCloudMap ||= {})[inlineUrlCloud] = value;
483
493
  value = inlineUrlCloud;
484
494
  }
485
- else if (asset.hash && this.productionRelease) {
486
- const inlineUrl = asset.inlineUrl ||= (0, types_1.generateUUID)();
495
+ else if (asset.hash && instance.productionRelease) {
496
+ const inlineUrl = asset.inlineUrl ||= (0, crypto_1.randomUUID)();
487
497
  (parent.inlineUrlMap ||= {})[inlineUrl] = value;
488
498
  value = inlineUrl;
489
499
  }
@@ -535,9 +545,8 @@ function transformURL(host, parent, type, source, importFile) {
535
545
  value = quote + value + quote;
536
546
  }
537
547
  const revised = isJs ? 'import(' + value + trailing + ')' : isHref ? 'href=' + value : (isText ? '@import ' + value : `url(${value})`) + trailing;
538
- source = spliceString(source, startIndex, i + 1, revised);
548
+ source = (0, util_1.spliceString)(source, startIndex, i + 1, revised, pattern);
539
549
  length = source.length;
540
- pattern.lastIndex = startIndex + revised.length;
541
550
  modified = true;
542
551
  };
543
552
  let url;
@@ -560,25 +569,25 @@ function transformURL(host, parent, type, source, importFile) {
560
569
  if (url.startsWith('data:')) {
561
570
  const base64 = url.split(',')[1]?.trim();
562
571
  if (base64) {
563
- for (const item of this.assets) {
572
+ for (const item of instance.assets) {
564
573
  if (item.base64 === base64) {
565
- setOutputURL(getSrcURL.call(this, parent, item)[0], item);
574
+ setOutputURL(getSrcURL(instance, parent, item)[0], item);
566
575
  break;
567
576
  }
568
577
  }
569
578
  }
570
579
  }
571
- else if (baseHref.length) {
580
+ else if (baseHref.length > 0) {
572
581
  let fullUrl, asset;
573
582
  for (const parentUrl of baseHref) {
574
- if (asset = host.findAsset(fullUrl = resolvePath(url, parentUrl), { replaced: true }) || (this.related.has(parent) ? host.findAsset(fullUrl, { assets: Array.from(this.related.get(parent)), replaced: true }) : undefined)) {
583
+ if (asset = host.findAsset(fullUrl = Document.resolvePath(url, parentUrl), { replaced: true }) || (instance.related.has(parent) ? host.findAsset(fullUrl, { assets: Array.from(instance.related.get(parent)), replaced: true }) : undefined)) {
575
584
  break;
576
585
  }
577
586
  }
578
587
  if (asset && asset !== importFile) {
579
588
  if (!(0, util_1.hasValue)(asset.format, 'base64')) {
580
589
  if (asset.bundleReplace) {
581
- let k, valid;
590
+ let k = 0, valid;
582
591
  if (!isText) {
583
592
  let j = startIndex;
584
593
  while (isSpace(source[--j])) { }
@@ -595,13 +604,13 @@ function transformURL(host, parent, type, source, importFile) {
595
604
  break;
596
605
  }
597
606
  }
598
- const layer = this.replaceContent(revised, source.substring(k, l + 1), 'text/css');
607
+ const layer = instance.replaceContent(revised, source.substring(k, l + 1), "text/css");
599
608
  if (layer) {
600
609
  revised = layer;
601
610
  }
602
- source = spliceString(source, k, l + 1, revised = transformURL.call(this, host, parent, type, this.removeServerRoot(revised), asset) || revised);
611
+ revised = transformURL(instance, host, parent, type, instance.removeServerRoot(revised), asset) || revised;
612
+ source = (0, util_1.spliceString)(source, k, l + 1, revised, pattern);
603
613
  length = source.length;
604
- pattern.lastIndex = k + revised.length;
605
614
  if (!parent.watch) {
606
615
  host.deleteFile(asset.localUri, { ignorePermission: true, emptyDir: true, all: true, id: asset.id });
607
616
  asset.invalid = true;
@@ -618,7 +627,7 @@ function transformURL(host, parent, type, source, importFile) {
618
627
  }
619
628
  if (hasSameOrigin(asset.url || fullUrl, ...baseHref)) {
620
629
  let sameDir;
621
- [fullUrl, sameDir] = getSrcURL.call(this, parent, asset);
630
+ [fullUrl, sameDir] = getSrcURL(instance, parent, asset);
622
631
  if (sameDir && isJs) {
623
632
  fullUrl = './' + fullUrl;
624
633
  }
@@ -630,7 +639,7 @@ function transformURL(host, parent, type, source, importFile) {
630
639
  }
631
640
  }
632
641
  else if (!asset.invalid) {
633
- fullUrl = asset.inlineBase64 ||= (0, types_1.generateUUID)();
642
+ fullUrl = asset.inlineBase64 ||= (0, crypto_1.randomUUID)();
634
643
  }
635
644
  if (url !== fullUrl) {
636
645
  setOutputURL(fullUrl, asset);
@@ -642,34 +651,33 @@ function transformURL(host, parent, type, source, importFile) {
642
651
  }
643
652
  }
644
653
  if (modified) {
645
- if (related.length) {
646
- const previous = this.related.get(parent);
654
+ if (related.length > 0) {
655
+ const previous = instance.related.get(parent);
647
656
  if (previous) {
648
- related.forEach(item => previous.add(item));
657
+ for (const item of related) {
658
+ previous.add(item);
659
+ }
649
660
  }
650
661
  else {
651
- this.related.set(parent, new Set(related));
662
+ instance.related.set(parent, new Set(related));
652
663
  }
653
664
  }
654
665
  return source;
655
666
  }
656
667
  }
657
- function getFormatUUID(attr, ext) {
658
- const format = 'formatMap' in this ? this.formatMap : this.module.format;
668
+ function getFormatUUID(instance, attr, ext) {
669
+ const format = 'formatMap' in instance ? instance.formatMap : instance.module.format;
659
670
  let pattern;
660
- if ((0, types_1.isObject)(format) && (0, types_1.isObject)(pattern = ext && ext in format ? format[ext] : format.uuid) && pattern[attr]) {
661
- return (0, types_1.randomString)(pattern[attr], pattern.dictionary);
662
- }
663
- return (0, types_1.generateUUID)();
671
+ return (0, types_1.isObject)(format) && (0, types_1.isObject)(pattern = ext && ext in format ? format[ext] : format.uuid) && pattern[attr] ? (0, types_1.randomString)(pattern[attr], pattern.dictionary) : (0, crypto_1.randomUUID)();
664
672
  }
665
- function setLocationUUID(data, file, ext) {
673
+ function setLocationUUID(instance, data, file, ext) {
666
674
  const { pathname, filename } = data;
667
675
  const assignUUID = ChromeDocument.INTERNAL_ASSIGNUUID;
668
- let index, modified;
676
+ let index = 0, modified;
669
677
  if (filename) {
670
678
  ext ||= path.extname(filename).substring(1);
671
679
  if ((index = filename.indexOf(assignUUID)) !== -1) {
672
- data.filename = spliceString(filename, index, index + assignUUID.length, getFormatUUID.call(this, 'filename', ext));
680
+ data.filename = (0, util_1.spliceString)(filename, index, index + assignUUID.length, getFormatUUID(instance, 'filename', ext));
673
681
  if (file) {
674
682
  file.inlineFilename = data.filename;
675
683
  }
@@ -677,7 +685,7 @@ function setLocationUUID(data, file, ext) {
677
685
  }
678
686
  }
679
687
  if (pathname && (index = pathname.indexOf(assignUUID)) !== -1) {
680
- data.pathname = spliceString(pathname, index, index + assignUUID.length, getFormatUUID.call(this, 'pathname', ext));
688
+ data.pathname = (0, util_1.spliceString)(pathname, index, index + assignUUID.length, getFormatUUID(instance, 'pathname', ext));
681
689
  modified = true;
682
690
  }
683
691
  if (file && modified) {
@@ -687,14 +695,14 @@ function setLocationUUID(data, file, ext) {
687
695
  }
688
696
  }
689
697
  }
690
- function transformOptions(file, mimeType, code, bundleContent) {
698
+ function transformOptions(instance, file, mimeType, code, bundleContent) {
691
699
  const { uri, localUri, exported } = file;
692
- const metadata = { userAgentData: this.userAgentData };
700
+ const metadata = { userAgentData: instance.userAgentData };
693
701
  switch (mimeType) {
694
- case 'text/html':
702
+ case "text/html":
695
703
  metadata.__fromhtml__ = true;
696
- case 'text/css':
697
- Object.assign(metadata, this.config);
704
+ case "text/css":
705
+ Object.assign(metadata, instance.config);
698
706
  default:
699
707
  if ((0, types_1.isObject)(file.metadata)) {
700
708
  Object.assign(metadata, file.metadata);
@@ -703,35 +711,35 @@ function transformOptions(file, mimeType, code, bundleContent) {
703
711
  }
704
712
  const [pathname, filename] = localUri ? [path.dirname(localUri), path.basename(localUri)] : ['', file.filename];
705
713
  const options = { pathname, filename, mimeType, metadata, imported: !!file.imports && file.imported !== false };
706
- const sourceFile = !exported && uri && this.findSourceRoot(uri);
714
+ const sourceFile = !exported && uri && instance.findSourceRoot(uri);
707
715
  if (sourceFile) {
708
- if (isPath(sourceFile)) {
716
+ if (Document.isPath(sourceFile)) {
709
717
  options.sourceFile = sourceFile;
710
718
  }
711
719
  options.sourceName = path.basename(sourceFile);
712
720
  options.sourcesRelativeTo = path.dirname(sourceFile);
713
- options.getMainFile = this.resolveSourceFile(file);
721
+ options.getMainFile = instance.resolveSourceFile(file);
714
722
  if (code) {
715
- options.getSourceFiles = this.locateSourceFiles(file, code, bundleContent);
723
+ options.getSourceFiles = instance.locateSourceFiles(file, code, bundleContent);
716
724
  }
717
725
  }
718
- if ((!this.productionRelease || this.productionIncremental) && !(0, types_1.modifiedFlag)(file.flags)) {
726
+ if ((!instance.productionRelease || instance.productionIncremental) && !(0, types_1.modifiedFlag)(file.flags)) {
719
727
  options.cacheData = { uri: !exported ? uri : undefined, etag: !file.modified ? file.etag : undefined, encoding: file.encoding };
720
728
  }
721
729
  return options;
722
730
  }
723
- function transformJs(host, file, output) {
731
+ function transformJs(instance, host, file, output) {
724
732
  const { sourceFiles, chunks, map } = output;
725
733
  const localUri = file.localUri;
726
- const emptySources = !!this.productionRelease;
734
+ const emptySources = !!instance.productionRelease;
727
735
  let uri;
728
- if (map && (uri = writeSourceMap(localUri, output, { hash: file.hash, emptySources, inlineMap: hasSourceMap(file.metadata, 'inline') }))) {
736
+ if (map && (uri = Document.writeSourceMap(localUri, output, { hash: file.hash, emptySources, inlineMap: hasSourceMap(file.metadata, 'inline') }))) {
729
737
  host.add(uri, file, types_1.FILE_TYPE.SOURCEMAP);
730
738
  }
731
739
  if (chunks) {
732
- const elements = this.elements;
740
+ const elements = instance.elements;
733
741
  const localDir = path.dirname(localUri);
734
- const relativeDir = joinPath(file.moveTo, file.pathname);
742
+ const relativeDir = Document.joinPath(file.moveTo, file.pathname);
735
743
  const element = file.element;
736
744
  let order = 0, index, appending;
737
745
  if (element) {
@@ -746,11 +754,11 @@ function transformJs(host, file, output) {
746
754
  for (const chunk of chunks) {
747
755
  let chunkName = chunk.filename;
748
756
  if (!chunkName) {
749
- chunkName = getFormatUUID.call(this, 'filename', 'js') + path.extname(localUri);
757
+ chunkName = getFormatUUID(instance, 'filename', 'js') + path.extname(localUri);
750
758
  chunk.entryPoint = true;
751
759
  }
752
760
  const chunkUri = path.join(localDir, chunkName);
753
- if (chunk.map && (uri = writeSourceMap(chunkUri, chunk, { emptySources, inlineMap: hasSourceMap(file.metadata, 'inline') }))) {
761
+ if (chunk.map && (uri = Document.writeSourceMap(chunkUri, chunk, { emptySources, inlineMap: hasSourceMap(file.metadata, 'inline') }))) {
754
762
  host.add(uri, file, types_1.FILE_TYPE.SOURCEMAP);
755
763
  }
756
764
  try {
@@ -758,7 +766,7 @@ function transformJs(host, file, output) {
758
766
  host.add(chunkUri, file);
759
767
  if (chunk.entryPoint) {
760
768
  if (element) {
761
- const attributes = { ...file.attributes, src: joinPath(relativeDir, chunkName) };
769
+ const attributes = { ...file.attributes, src: Document.joinPath(relativeDir, chunkName) };
762
770
  if (file.imports && file.imported !== false) {
763
771
  attributes.type ||= 'module';
764
772
  }
@@ -769,15 +777,17 @@ function transformJs(host, file, output) {
769
777
  });
770
778
  }
771
779
  else {
772
- this.writeFail(['Unable to create script entry point', path.basename(chunkUri)], (0, types_1.errorMessage)('js', 'Element not found', chunkUri), 4);
780
+ instance.writeFail(['Unable to create script entry point', path.basename(chunkUri)], (0, types_1.errorMessage)('js', 'Element not found', chunkUri), 4);
773
781
  }
774
782
  }
775
783
  }
776
784
  catch (err) {
777
- this.writeFail(["Unable to write file", path.basename(chunkUri)], err, 32);
785
+ instance.writeFail(["Unable to write file", path.basename(chunkUri)], err, 32);
778
786
  }
779
787
  }
780
- appending?.forEach(item => item.order += order);
788
+ appending?.forEach(item => {
789
+ item.order += order;
790
+ });
781
791
  }
782
792
  if ((0, types_1.isArray)(sourceFiles)) {
783
793
  file.sourceFiles = sourceFiles;
@@ -785,41 +795,40 @@ function transformJs(host, file, output) {
785
795
  file.modified = true;
786
796
  return file.sourceUTF8 = output.code;
787
797
  }
788
- function replaceCss(file) {
789
- const sanitize = (map) => {
790
- for (const id in map) {
791
- map[id] = this.removeServerRoot(map[id]);
792
- }
793
- };
794
- const { inlineUrlMap, inlineUrlCloudMap } = file;
795
- if (inlineUrlMap) {
796
- sanitize(inlineUrlMap);
798
+ function replaceCss(instance, file) {
799
+ if (file.inlineUrlMap) {
800
+ sanitizeCss(instance, file.inlineUrlMap);
797
801
  }
798
- if (inlineUrlCloudMap) {
799
- sanitize(inlineUrlCloudMap);
802
+ if (file.inlineUrlCloudMap) {
803
+ sanitizeCss(instance, file.inlineUrlCloudMap);
800
804
  }
801
805
  }
802
- function replaceHtml(source, { productionRelease, contentMap }, cssMap) {
803
- const finalize = (value, data) => {
804
- for (const id in data) {
805
- value = value.replace(new RegExp((0, types_1.escapePattern)(id), 'g'), data[id]);
806
- }
807
- return value;
808
- };
806
+ function sanitizeCss(instance, map) {
807
+ for (const id in map) {
808
+ map[id] = instance.removeServerRoot(map[id]);
809
+ }
810
+ }
811
+ function replaceHtml(instance, source, { productionRelease, contentMap }, cssMap) {
809
812
  if (cssMap) {
810
- source = finalize(source, cssMap);
813
+ source = finalizeHtml(source, cssMap);
814
+ }
815
+ source = finalizeHtml(source, contentMap);
816
+ return productionRelease ? instance.removeServerRoot(source) : source;
817
+ }
818
+ function finalizeHtml(value, data) {
819
+ for (const id in data) {
820
+ value = value.replace(new RegExp((0, types_1.escapePattern)(id), 'g'), data[id]);
811
821
  }
812
- source = finalize(source, contentMap);
813
- return productionRelease ? this.removeServerRoot(source) : source;
822
+ return value;
814
823
  }
815
- function isWatched(file) {
824
+ function isWatched(instance, file) {
816
825
  const { initialValue, format } = file;
817
- if (file.imported || file.bundleReplace || file.inlineContent || file.inlineBase64 || this.replaced.includes(file) || initialValue && (file.inlineFilename !== initialValue.inlineFilename || file.pathname !== initialValue.pathname || initialValue.cacheable === false) || format && ((0, util_1.hasValue)(format, 'base64') || (0, util_1.hasValue)(format, 'woff') || (0, util_1.hasValue)(format, 'woff2'))) {
826
+ if (file.imported || file.bundleReplace || file.inlineContent || file.inlineBase64 || instance.replaced.includes(file) || initialValue && (file.inlineFilename !== initialValue.inlineFilename || file.pathname !== initialValue.pathname || initialValue.cacheable === false) || format && ((0, util_1.hasValue)(format, 'base64') || (0, util_1.hasValue)(format, 'woff') || (0, util_1.hasValue)(format, 'woff2'))) {
818
827
  return true;
819
828
  }
820
829
  return false;
821
830
  }
822
- function loadLocalFile(item, pathname, cacheData, encoding, out) {
831
+ function loadLocalFile(instance, item, pathname, cacheData, encoding, out) {
823
832
  let content;
824
833
  encoding = (0, types_1.getEncoding)(encoding);
825
834
  if (out) {
@@ -831,16 +840,16 @@ function loadLocalFile(item, pathname, cacheData, encoding, out) {
831
840
  return require(pathname);
832
841
  }
833
842
  content ||= fs.readFileSync(pathname, encoding);
834
- const result = this.tryParse(content, ext);
835
- if (result !== undefined && result !== null) {
836
- setCacheData.call(this, item, result, pathname, cacheData, true);
843
+ const result = instance.tryParse(content, ext);
844
+ if (result != null) {
845
+ setCacheData(instance, item, result, pathname, cacheData, true);
837
846
  return result;
838
847
  }
839
848
  }
840
- function setCacheData(item, data, dataKey, cacheData, template) {
849
+ function setCacheData(instance, item, data, dataKey, cacheData, template) {
841
850
  if ((0, types_1.isObject)(data) || template) {
842
- const cache = this.settingsOf(item.source, template && item.source !== 'local' ? 'local_file' : 'cache');
843
- let timeout;
851
+ const cache = instance.settingsOf(item.source, template && item.source !== 'local' ? 'local_file' : 'cache');
852
+ let timeout = 0;
844
853
  if (cache && (timeout = core_1.ClientDb.getTimeout(cache)) && timeout > 0) {
845
854
  addCacheItem(template ? CACHE_LOCALFILE : CACHE_DBRESULT, dataKey, data, timeout);
846
855
  }
@@ -849,11 +858,11 @@ function setCacheData(item, data, dataKey, cacheData, template) {
849
858
  }
850
859
  }
851
860
  }
852
- async function checkData(item, name, result, validate) {
861
+ async function checkData(instance, item, name, result, validate) {
853
862
  let callback;
854
863
  if (typeof name === 'string') {
855
- const template = this.findDataValue(name) || name;
856
- callback = this.hasEval('userconfig') ? Document.parseFunction(template, this.hasEval('absolute')) : (0, types_1.asFunction)(template);
864
+ const template = instance.findDataValue(name) || name;
865
+ callback = instance.hasEval('userconfig') ? Document.parseFunction(template, instance.hasEval('absolute')) : (0, types_1.asFunction)(template);
857
866
  }
858
867
  else {
859
868
  callback = name;
@@ -873,32 +882,47 @@ async function checkData(item, name, result, validate) {
873
882
  }
874
883
  }
875
884
  catch (err) {
876
- this.writeFail(["Unable to parse inline method", name], err);
885
+ instance.writeFail(["Unable to parse inline method", name], err);
877
886
  }
878
887
  }
879
888
  }
880
- const getNewlineString = dom_1.DomWriter.getNewlineString.bind(dom_1.DomWriter);
889
+ function removeElement(instance, domBase, item, element) {
890
+ if (item.removeEmpty || item.type === 'display') {
891
+ (element ||= new dom_1.HtmlElement(instance.moduleName, item.element)).remove = true;
892
+ if (!domBase.write(element)) {
893
+ instance.writeFail('Unable to remove element', errorHtml(item.element), { type: 4 });
894
+ }
895
+ }
896
+ }
897
+ function removeWatchReload(item) {
898
+ if ((0, types_1.isObject)(item.watch) && 'reload' in item.watch) {
899
+ delete item.watch.reload;
900
+ }
901
+ }
902
+ function errorCredential(instance, domBase, item, err) {
903
+ removeElement(instance, domBase, item);
904
+ const pkg = getPackageName(err);
905
+ if (!(pkg && instance.checkPackage(err, pkg))) {
906
+ instance.writeFail(["Invalid credentials", item.source], err);
907
+ }
908
+ }
881
909
  const isSpace = dom_1.DomWriter.isSpace.bind(dom_1.DomWriter);
882
910
  const replaceMatch = dom_1.DomWriter.replaceMatch.bind(dom_1.DomWriter);
883
- const joinPath = Document.joinPath.bind(Document);
884
- const isPath = Document.isPath.bind(Document);
885
- const writeSourceMap = Document.writeSourceMap.bind(Document);
886
- const asString = Document.asString.bind(Document);
887
- const resolvePath = Document.resolvePath.bind(Document);
888
- const toPosix = Document.toPosix.bind(Document);
889
- const isDir = Document.isDir.bind(Document);
890
- const getBuffer = (item, localUri) => item.sourceUTF8 || item.buffer || ((localUri ||= item.localUri) && isPath(localUri) ? fs.readFileSync(localUri, item.encoding) : null);
911
+ const getNewlineString = dom_1.DomWriter.getNewlineString.bind(dom_1.DomWriter);
912
+ const getBuffer = (item, localUri) => item.sourceUTF8 || item.buffer || ((localUri ||= item.localUri) && Document.isPath(localUri) ? fs.readFileSync(localUri, item.encoding) : null);
891
913
  const hasSourceMap = (metadata, value) => (0, types_1.isObject)(metadata) && metadata.__sourcemap__ === value;
914
+ const splitPath = (value) => value.split(/[\\/]/).filter(segment => segment.trim());
892
915
  const isBundled = (value, main) => typeof value === 'number' && (value > 0 || main && value === 0);
893
916
  const isFont = (value) => value === 'truetype' || value === 'opentype' || value === 'woff' || value === 'woff2';
894
- const isImage = (value) => typeof value === 'string' && value.startsWith('image/') && value !== 'image/svg+xml';
917
+ const isImage = (value) => typeof value === 'string' && value.startsWith('image/') && value !== "image/svg+xml";
895
918
  const isRemoved = (item) => item.exclude === true || isBundled(item.bundleIndex);
896
919
  const isUnedited = (item) => !item.attributes && !item.inlineContent && !item.srcSet && !item.element.dynamic && item.element.textContent === undefined && (!item.uri && !isBundled(item.bundleIndex, true) || (0, util_1.hasValue)(item.format, 'crossorigin'));
897
920
  const isIgnored = (item, exists) => item.invalid || (0, types_1.ignoreFlag)(item.flags) || !exists && (0, types_1.existsFlag)(item.flags);
898
921
  const findFont = (value) => value && (Array.isArray(value) ? value : [value]).find(format => isFont(format));
899
- const spliceString = (source, startIndex, endIndex, content) => source.substring(0, startIndex) + content + source.substring(endIndex);
900
922
  const getEndIndex = (match) => match.index + match[0].length;
901
- const getRelativeURL = (file) => joinPath(file.moveTo, file.pathname, file.inlineFilename || file.filename) + (!file.static ? restoreSearchParams(file.url?.search) : '');
923
+ const getRelativeURL = (file) => Document.joinPath(file.moveTo, file.pathname, file.inlineFilename || file.filename) + (!file.static ? restoreSearchParams(file.url?.search) : '');
924
+ const validateDir = (value) => path.isAbsolute(value) && Document.isDir(value) ? value : '';
925
+ const valueAsString = (value, delimiter) => Array.isArray(value) && !value.some(child => typeof child === 'object') ? value.join(delimiter) : Document.asString(value);
902
926
  const errorHtml = ({ tagName, tagIndex = -1 }) => (0, types_1.errorMessage)('html', 'Location did not resolve', tagName.toLowerCase() + (tagIndex >= 0 ? ': ' + tagIndex : ''));
903
927
  const errorDataSource = (value, hint) => (0, types_1.errorMessage)('data-source', value, hint);
904
928
  const isHtmlOnly = (assets, items, htmlFile) => !items.find(item => item !== htmlFile && assets.includes(item));
@@ -910,13 +934,13 @@ class ChromeDocument extends Document {
910
934
  parent = limit;
911
935
  limit = 0;
912
936
  }
937
+ const total = CACHE_LOCALFILE.size + CACHE_DBRESULT.size;
913
938
  let result = 0;
914
- if ((limit === 0 || CACHE_TOTAL >= limit) && percent > 0) {
939
+ if ((limit === 0 || total >= limit) && percent > 0) {
915
940
  if (percent >= 1) {
916
- result += CACHE_DBRESULT.size + CACHE_LOCALFILE.size;
941
+ result += total;
917
942
  CACHE_DBRESULT.clear();
918
943
  CACHE_LOCALFILE.clear();
919
- CACHE_TOTAL = 0;
920
944
  }
921
945
  else {
922
946
  const stored = [];
@@ -931,7 +955,6 @@ class ChromeDocument extends Document {
931
955
  const [map, key] = stored[i];
932
956
  deleteCacheItem(map, key);
933
957
  }
934
- CACHE_TOTAL = stored.length - result;
935
958
  }
936
959
  CACHE_QUERY.clear();
937
960
  CACHE_SELECTOR.clear();
@@ -964,7 +987,7 @@ class ChromeDocument extends Document {
964
987
  if (outHtml) {
965
988
  const { etag, initialValue } = htmlFile;
966
989
  let buffer;
967
- if (!initialValue || !(etag && initialValue.etag === etag && (buffer = initialValue.buffer)) || fetched.find(item => item !== htmlFile && item.etag && CACHE_ETAG.get(item.localUri) !== item.etag && (item.inlineContent || item.bundleReplace && (!(0, types_1.isArray)(item.from) || item.from.includes('style'))))) {
990
+ if (!initialValue || !(etag && initialValue.etag === etag && (buffer = initialValue.buffer)) || fetched.find(item => item !== htmlFile && item.etag && CACHE_ETAG.get(item.localUri) !== item.etag && (item.inlineContent || item.bundleReplace && (!Array.isArray(item.from) || item.from.includes('style'))))) {
968
991
  const isValid = (item) => !!item.localUri && item !== htmlFile && !item.invalid;
969
992
  for (const item of fetched) {
970
993
  if (item.etag && !item.content && isValid(item)) {
@@ -1025,7 +1048,7 @@ class ChromeDocument extends Document {
1025
1048
  const js = instance.jsFiles.filter(item => wasModified(item) || !!item.imports);
1026
1049
  const css = instance.cssFiles.filter(wasModified);
1027
1050
  const svg = instance.svgFiles.filter(wasModified);
1028
- if (js.length || css.length || svg.length) {
1051
+ if (js.length > 0 || css.length > 0 || svg.length > 0) {
1029
1052
  instance.jsFiles = js;
1030
1053
  instance.cssFiles = css;
1031
1054
  instance.svgFiles = svg;
@@ -1044,7 +1067,7 @@ class ChromeDocument extends Document {
1044
1067
  }
1045
1068
  }
1046
1069
  instance.setInlinedAttributes(processing);
1047
- if (instance.editing.length) {
1070
+ if (instance.editing.length > 0) {
1048
1071
  await instance.applyTransforms(processing);
1049
1072
  if (instance.aborted) {
1050
1073
  return (0, types_1.createAbortError)(true);
@@ -1074,7 +1097,7 @@ class ChromeDocument extends Document {
1074
1097
  (function recurse(children) {
1075
1098
  for (const item of children) {
1076
1099
  if (!items.has(item)) {
1077
- if (isWatched.call(instance, item)) {
1100
+ if (isWatched(instance, item)) {
1078
1101
  item.flags |= 8;
1079
1102
  }
1080
1103
  items.add(item);
@@ -1089,40 +1112,126 @@ class ChromeDocument extends Document {
1089
1112
  }
1090
1113
  }
1091
1114
  }
1092
- let productionRelease = instance.productionRelease;
1115
+ const productionRelease = instance.productionRelease;
1093
1116
  if ((0, types_1.isString)(productionRelease)) {
1094
- if (path.isAbsolute(productionRelease = path.normalize(productionRelease)) && isDir(productionRelease)) {
1095
- if (this.canWrite(productionRelease)) {
1096
- const serverRoot = ChromeDocument.INTERNAL_SERVERROOT;
1097
- const srcDir = path.join(this.baseDirectory, serverRoot);
1098
- if (isDir(srcDir)) {
1099
- const result = await Document.copyDir(srcDir, productionRelease, this.incremental !== 'staging');
1117
+ const errorDirectory = (value) => {
1118
+ instance.writeFail(["Unable to read directory", instance.moduleName], (0, types_1.errorMessage)('production', 'Invalid directory', value), 32);
1119
+ };
1120
+ const errorAccess = (value) => {
1121
+ instance.writeFail(["Unable to write directory", instance.moduleName], (0, types_1.errorMessage)('production', "Unsupported access", value), 8192);
1122
+ };
1123
+ const errorMove = (err) => {
1124
+ instance.writeFail(["Unable to move file", instance.moduleName], err, { type: 32, fatal: true });
1125
+ };
1126
+ const outputDir = validateDir(productionRelease);
1127
+ if (outputDir) {
1128
+ if (this.canWrite(outputDir)) {
1129
+ const srcDir = path.join(this.baseDirectory, ChromeDocument.INTERNAL_SERVERROOT);
1130
+ if (Document.isDir(srcDir)) {
1131
+ const serverRootMapping = instance.serverRootMapping;
1132
+ const mapped = [];
1133
+ for (const localDir in serverRootMapping) {
1134
+ const subDir = serverRootMapping[localDir];
1135
+ const destDir = validateDir(Document.normalizePath(/[\\/]$/.test(subDir) ? path.join(outputDir, subDir, localDir) : path.join(outputDir, subDir), true));
1136
+ if (destDir.startsWith(outputDir)) {
1137
+ if (this.canWrite(destDir)) {
1138
+ mapped.push([Document.normalizePath(localDir, true), destDir, 0]);
1139
+ }
1140
+ else {
1141
+ errorAccess(localDir);
1142
+ return;
1143
+ }
1144
+ }
1145
+ else {
1146
+ errorDirectory(localDir);
1147
+ return;
1148
+ }
1149
+ }
1150
+ if (mapped.length > 0) {
1151
+ const emptyDir = new Set();
1152
+ for (const value of this.files) {
1153
+ if (value.startsWith(ChromeDocument.INTERNAL_SERVERROOT)) {
1154
+ const subDir = value.split(path.sep).slice(1);
1155
+ const start = subDir.length - 1;
1156
+ for (let i = start; i > 0; --i) {
1157
+ const localDir = subDir.slice(0, i).join(path.sep) + path.sep;
1158
+ const target = mapped.find(item => item[0] === localDir);
1159
+ if (target) {
1160
+ const src = path.join(this.baseDirectory, value);
1161
+ try {
1162
+ let destDir = target[1];
1163
+ if (i !== start && !Document.createDir(destDir = path.join(destDir, ...subDir.slice(i, start)))) {
1164
+ throw (0, types_1.errorMessage)('production', destDir, 'create');
1165
+ }
1166
+ const dest = path.join(destDir, subDir[subDir.length - 1]);
1167
+ Document.renameFile(src, dest);
1168
+ instance.addLog(types_1.STATUS_TYPE.INFO, `production: ${dest} (mapped)`, instance.moduleName, subDir.join(path.sep));
1169
+ emptyDir.add(path.dirname(src));
1170
+ if (i !== start) {
1171
+ for (let j = 0; j < i; ++j) {
1172
+ emptyDir.add(path.join(this.baseDirectory, ChromeDocument.INTERNAL_SERVERROOT, ...subDir.slice(0, j + 1)));
1173
+ }
1174
+ }
1175
+ ++target[2];
1176
+ }
1177
+ catch (err) {
1178
+ errorMove(err);
1179
+ if (Document.isPath(src)) {
1180
+ fs.unlink(src, error => {
1181
+ if (error) {
1182
+ instance.addLog(types_1.STATUS_TYPE.WARN, error);
1183
+ }
1184
+ });
1185
+ }
1186
+ }
1187
+ finally {
1188
+ this.delete(value);
1189
+ }
1190
+ break;
1191
+ }
1192
+ }
1193
+ }
1194
+ }
1195
+ for (const item of mapped) {
1196
+ if (item[2] === 0) {
1197
+ instance.addLog(types_1.STATUS_TYPE.INFO, `production: ${item[1]} (mapped: 0)`, instance.moduleName, item[0]);
1198
+ }
1199
+ }
1200
+ for (const pathname of Array.from(emptyDir).sort((a, b) => b.length - a.length)) {
1201
+ try {
1202
+ fs.rmdirSync(pathname);
1203
+ }
1204
+ catch {
1205
+ }
1206
+ }
1207
+ }
1208
+ const result = await Document.copyDir(srcDir, outputDir, this.incremental !== 'staging');
1100
1209
  const failed = result.failed.map(value => this.removeCwd(value));
1101
1210
  for (const value of this.files) {
1102
- if (value.startsWith(serverRoot)) {
1211
+ if (value.startsWith(ChromeDocument.INTERNAL_SERVERROOT)) {
1103
1212
  if (!failed.includes(value)) {
1104
1213
  this.delete(value);
1105
1214
  }
1106
1215
  else {
1107
- instance.writeFail(["Unable to move file", instance.moduleName], (0, types_1.errorMessage)('production', path.join(this.baseDirectory, value)), { fatal: true });
1216
+ errorMove((0, types_1.errorMessage)('production', path.join(this.baseDirectory, value), 'move'));
1108
1217
  }
1109
1218
  }
1110
1219
  }
1111
1220
  }
1112
1221
  }
1113
1222
  else {
1114
- instance.writeFail(["Unable to write directory", instance.moduleName], (0, types_1.errorMessage)('production', "Unsupported access", productionRelease));
1223
+ errorAccess(productionRelease);
1115
1224
  }
1116
1225
  }
1117
1226
  else {
1118
- instance.writeFail(["Unable to read directory", instance.moduleName], (0, types_1.errorMessage)('production', 'Invalid directory', productionRelease), 32);
1227
+ errorDirectory(productionRelease);
1119
1228
  }
1120
1229
  }
1121
1230
  }
1122
1231
  static sanitizeAssets(assets, exclusions = []) {
1123
- assets.forEach(item => {
1232
+ for (const item of assets) {
1124
1233
  if ((0, types_1.ignoreFlag)(item.flags)) {
1125
- return;
1234
+ continue;
1126
1235
  }
1127
1236
  for (const attr in item) {
1128
1237
  switch (attr) {
@@ -1140,7 +1249,8 @@ class ChromeDocument extends Document {
1140
1249
  break;
1141
1250
  }
1142
1251
  }
1143
- });
1252
+ }
1253
+ return assets;
1144
1254
  }
1145
1255
  config = {
1146
1256
  usedVariables: undefined,
@@ -1169,6 +1279,8 @@ class ChromeDocument extends Document {
1169
1279
  baseUrl = '';
1170
1280
  productionRelease = false;
1171
1281
  productionIncremental = false;
1282
+ serverRootMapping = undefined;
1283
+ sanitizeFramework = undefined;
1172
1284
  templateMap = {};
1173
1285
  userAgentData = {};
1174
1286
  related = new Map();
@@ -1182,7 +1294,7 @@ class ChromeDocument extends Document {
1182
1294
  _cloudUrlMap;
1183
1295
  _cloudUploaded;
1184
1296
  _cloudEndpoint;
1185
- _idMap = Object.create(null);
1297
+ _idMap = {};
1186
1298
  _editing = [];
1187
1299
  _queryMap = new Map();
1188
1300
  _selectorMap = new Map();
@@ -1206,7 +1318,7 @@ class ChromeDocument extends Document {
1206
1318
  }
1207
1319
  if (item.editing) {
1208
1320
  switch (item.mimeType) {
1209
- case 'text/html':
1321
+ case "text/html":
1210
1322
  if (!this.htmlFile) {
1211
1323
  this.htmlFile = item;
1212
1324
  item.editing = true;
@@ -1216,15 +1328,15 @@ class ChromeDocument extends Document {
1216
1328
  item.editing = false;
1217
1329
  }
1218
1330
  break;
1219
- case 'text/css':
1331
+ case "text/css":
1220
1332
  this.cssFiles.push(item);
1221
1333
  this._editing.push(item);
1222
1334
  break;
1223
- case 'text/javascript':
1224
- case 'application/javascript':
1335
+ case "text/javascript":
1336
+ item.mimeType = "application/javascript";
1337
+ case "application/javascript":
1225
1338
  this.jsFiles.push(item);
1226
1339
  this._editing.push(item);
1227
- item.mimeType = 'application/javascript';
1228
1340
  break;
1229
1341
  }
1230
1342
  }
@@ -1240,7 +1352,7 @@ class ChromeDocument extends Document {
1240
1352
  });
1241
1353
  let imports;
1242
1354
  if (config) {
1243
- const { useUnsafeReplace, baseUrl, productionRelease, productionIncremental, templateMap, userAgentData, cache } = config;
1355
+ const { useUnsafeReplace, baseUrl, productionRelease, productionIncremental, serverRootMapping, templateMap, sanitizeFramework, userAgentData, cache } = config;
1244
1356
  const target = this.config;
1245
1357
  for (const attr in config) {
1246
1358
  if (attr in target) {
@@ -1273,12 +1385,31 @@ class ChromeDocument extends Document {
1273
1385
  catch {
1274
1386
  }
1275
1387
  }
1276
- if (productionRelease === true || (0, types_1.isString)(productionRelease)) {
1277
- this.productionRelease = productionRelease;
1388
+ if ((0, types_1.isString)(productionRelease)) {
1389
+ this.productionRelease = Document.normalizePath(productionRelease, 2);
1390
+ const baseDir = Document.normalizePath(this.productionRelease, 1 | 2);
1391
+ let baseMap;
1392
+ found: {
1393
+ for (const map of [this.getUserSettings()?.server_root, this.settings.server_root]) {
1394
+ for (const pathname in map) {
1395
+ if (Document.normalizePath(pathname, 1 | 2) === baseDir && (0, types_1.isObject)(map[pathname])) {
1396
+ baseMap = map[pathname];
1397
+ break found;
1398
+ }
1399
+ }
1400
+ }
1401
+ }
1402
+ this.serverRootMapping = (0, types_1.isObject)(serverRootMapping) ? baseMap ? Object.assign(baseMap, serverRootMapping) : serverRootMapping : baseMap;
1403
+ }
1404
+ else if (productionRelease) {
1405
+ this.productionRelease = true;
1278
1406
  }
1279
1407
  if (productionIncremental) {
1280
1408
  this.productionIncremental = true;
1281
1409
  }
1410
+ if ((0, types_1.isArray)(sanitizeFramework)) {
1411
+ this.sanitizeFramework = sanitizeFramework;
1412
+ }
1282
1413
  if ((0, types_1.isObject)(templateMap)) {
1283
1414
  this.templateMap = templateMap;
1284
1415
  }
@@ -1319,10 +1450,10 @@ class ChromeDocument extends Document {
1319
1450
  for (const storage of cloud) {
1320
1451
  for (const { service, upload, download } of storage) {
1321
1452
  if (upload) {
1322
- setLocationUUID.call(this, upload, null, service);
1453
+ setLocationUUID(this, upload, null, service);
1323
1454
  }
1324
1455
  if (download) {
1325
- setLocationUUID.call(this, download, null, service);
1456
+ setLocationUUID(this, download, null, service);
1326
1457
  }
1327
1458
  }
1328
1459
  }
@@ -1374,22 +1505,22 @@ class ChromeDocument extends Document {
1374
1505
  const { localUri, mimeType, format } = file;
1375
1506
  const hash = productionRelease && file.hash;
1376
1507
  switch (mimeType) {
1377
- case 'text/html':
1508
+ case "text/html":
1378
1509
  if (format) {
1379
- const output = await this.transform('html', host.getUTF8String(file, localUri), format, transformOptions.call(this, file, mimeType));
1510
+ const output = await this.transform('html', host.getUTF8String(file, localUri), format, transformOptions(this, file, mimeType));
1380
1511
  if (output) {
1381
1512
  file.modified = true;
1382
1513
  file.sourceUTF8 = output.code;
1383
1514
  }
1384
1515
  }
1385
1516
  break;
1386
- case 'text/css':
1517
+ case "text/css":
1387
1518
  if (format) {
1388
1519
  const source = host.getUTF8String(file, localUri);
1389
- const output = await this.transform('css', source, format, transformOptions.call(this, file, mimeType, source));
1520
+ const output = await this.transform('css', source, format, transformOptions(this, file, mimeType, source));
1390
1521
  if (output) {
1391
1522
  if (output.map) {
1392
- const uri = writeSourceMap(localUri, output, { mimeType, hash, emptySources: productionRelease, inlineMap: hasSourceMap(file.metadata, 'inline') });
1523
+ const uri = Document.writeSourceMap(localUri, output, { mimeType, hash, emptySources: productionRelease, inlineMap: hasSourceMap(file.metadata, 'inline') });
1393
1524
  if (uri) {
1394
1525
  host.add(uri, file, types_1.FILE_TYPE.SOURCEMAP);
1395
1526
  }
@@ -1399,8 +1530,8 @@ class ChromeDocument extends Document {
1399
1530
  }
1400
1531
  }
1401
1532
  break;
1402
- case 'text/javascript':
1403
- case 'application/javascript': {
1533
+ case "text/javascript":
1534
+ case "application/javascript": {
1404
1535
  let source = host.getUTF8String(file, localUri);
1405
1536
  if (!(file.bundleIndex >= 0)) {
1406
1537
  source = host.setAssetContent(file, source);
@@ -1411,15 +1542,15 @@ class ChromeDocument extends Document {
1411
1542
  file.modified = true;
1412
1543
  }
1413
1544
  if (format) {
1414
- const output = await this.transform('js', source, format, transformOptions.call(this, file, mimeType, source, host.contentToAppend.get(localUri)));
1545
+ const output = await this.transform('js', source, format, transformOptions(this, file, mimeType, source, host.contentToAppend.get(localUri)));
1415
1546
  if (output) {
1416
- source = transformJs.call(this, host, file, output);
1547
+ source = transformJs(this, host, file, output);
1417
1548
  }
1418
1549
  }
1419
1550
  file.sourceUTF8 = source;
1420
1551
  break;
1421
1552
  }
1422
- case 'image/svg+xml': {
1553
+ case "image/svg+xml": {
1423
1554
  const source = host.getUTF8String(file, localUri);
1424
1555
  if (/\burl\(/i.test(source)) {
1425
1556
  file.editing = true;
@@ -1427,7 +1558,7 @@ class ChromeDocument extends Document {
1427
1558
  this.svgFiles.push(file);
1428
1559
  }
1429
1560
  else if (format) {
1430
- const output = await this.transform('html', source, format, transformOptions.call(this, file, mimeType, source));
1561
+ const output = await this.transform('html', source, format, transformOptions(this, file, mimeType, source));
1431
1562
  if (output) {
1432
1563
  file.modified = true;
1433
1564
  file.sourceUTF8 = output.code;
@@ -1523,7 +1654,7 @@ class ChromeDocument extends Document {
1523
1654
  this.replaced.push(file);
1524
1655
  }
1525
1656
  else {
1526
- setLocationUUID.call(this, file, file);
1657
+ setLocationUUID(this, file, file);
1527
1658
  }
1528
1659
  file.relativeUrl = getRelativeURL(file);
1529
1660
  }
@@ -1531,8 +1662,8 @@ class ChromeDocument extends Document {
1531
1662
  const host = this.host;
1532
1663
  if (host) {
1533
1664
  switch (file.mimeType) {
1534
- case 'text/javascript':
1535
- case 'application/javascript':
1665
+ case "text/javascript":
1666
+ case "application/javascript":
1536
1667
  if (file.imports) {
1537
1668
  [[file.uri, source], [this.baseUrl, trailing]].forEach(([uri, code], index) => {
1538
1669
  let localFile;
@@ -1544,24 +1675,26 @@ class ChromeDocument extends Document {
1544
1675
  output = this.resolveImports(file, code, bundleMain || file);
1545
1676
  }
1546
1677
  else if (index === 0 && !exported) {
1547
- if (!isDir(localFile)) {
1678
+ if (!Document.isDir(localFile)) {
1548
1679
  localFile = path.dirname(localFile);
1549
1680
  }
1681
+ output = code;
1550
1682
  let mainFile, pathname, match;
1551
- const ignorePath = bundleMain && (mainFile = this.findSourceRoot(bundleMain.uri)) && (isDir(mainFile) || (mainFile = path.dirname(mainFile))) && mainFile === localFile;
1552
- while (match = REGEXP_IMPORTMODULE.exec(code)) {
1553
- const value = match[1] || match[2] || match[4];
1683
+ const ignorePath = bundleMain && (mainFile = this.findSourceRoot(bundleMain.uri)) && (Document.isDir(mainFile) || (mainFile = path.dirname(mainFile))) && mainFile === localFile;
1684
+ while (match = REGEXP_IMPORTMODULE.exec(output)) {
1554
1685
  const assert = match[3] || match[5];
1555
- const from = trimQuote(value);
1686
+ const idx = match[1] ? 1 : match[2] ? 2 : 4;
1687
+ const [a, b] = match.indices[idx];
1688
+ const from = trimQuote(match[idx]);
1689
+ const quote = output[a];
1556
1690
  const relative = /^\.{0,2}\//.test(from);
1557
1691
  if (assert && /\btype\s*:\s*(["'`])css\1/.test(assert)) {
1558
1692
  try {
1559
1693
  const asset = host.findAsset(relative ? new URL(from, uri) : from);
1560
1694
  if (asset) {
1561
- const [relativeUrl, sameDir] = getSrcURL.call(this, bundleMain || file, asset);
1695
+ const [relativeUrl, sameDir] = getSrcURL(this, bundleMain || file, asset);
1562
1696
  if (relativeUrl) {
1563
- const quote = value[0];
1564
- output = (output || code).replace(value, quote + (sameDir ? './' : '') + relativeUrl + quote);
1697
+ output = (0, util_1.spliceString)(output, a, b, quote + (sameDir ? './' : '') + relativeUrl + quote, REGEXP_IMPORTMODULE);
1565
1698
  }
1566
1699
  }
1567
1700
  }
@@ -1575,23 +1708,20 @@ class ChromeDocument extends Document {
1575
1708
  }
1576
1709
  pathname = path.join(localFile, from);
1577
1710
  }
1578
- else if (!(pathname = this.findSourceRoot(from)) || !isPath(pathname)) {
1711
+ else if (!(pathname = this.findSourceRoot(from)) || !Document.isPath(pathname)) {
1579
1712
  const asset = host.findAsset(from);
1580
- if (asset && !asset.invalid) {
1581
- pathname = asset.localUri;
1582
- }
1583
- else {
1713
+ if (!asset || asset.invalid) {
1584
1714
  continue;
1585
1715
  }
1716
+ pathname = asset.localUri;
1586
1717
  }
1587
- if (pathname && isPath(pathname)) {
1588
- const quote = value[0];
1589
- output = (output || code).replace(value, quote + pathname + quote);
1718
+ if (pathname && Document.isPath(pathname)) {
1719
+ output = (0, util_1.spliceString)(output, a, b, quote + pathname + quote, REGEXP_IMPORTMODULE);
1590
1720
  }
1591
1721
  }
1592
1722
  REGEXP_IMPORTMODULE.lastIndex = 0;
1593
1723
  }
1594
- if (output) {
1724
+ if (output && output !== code) {
1595
1725
  if (index === 0) {
1596
1726
  source = output;
1597
1727
  }
@@ -1603,14 +1733,13 @@ class ChromeDocument extends Document {
1603
1733
  });
1604
1734
  }
1605
1735
  break;
1606
- case 'text/css':
1736
+ case "text/css":
1607
1737
  if (file.editing) {
1608
- const htmlFile = this.htmlFile;
1609
1738
  const bundleId = file.bundleId;
1610
1739
  if (!(0, types_1.isEmpty)(bundleId)) {
1611
1740
  for (const asset of this.assets) {
1612
1741
  if (asset.bundleIndex === 0 && asset.bundleId === bundleId) {
1613
- const output = transformURL.call(this, host, file, 'css', source, asset);
1742
+ const output = transformURL(this, host, file, 'css', source, asset);
1614
1743
  if (output) {
1615
1744
  source = output;
1616
1745
  file.modified = true;
@@ -1619,8 +1748,8 @@ class ChromeDocument extends Document {
1619
1748
  }
1620
1749
  }
1621
1750
  }
1622
- if (trailing && htmlFile) {
1623
- const output = transformURL.call(this, host, file, 'css', trailing, htmlFile);
1751
+ if (trailing && this.htmlFile) {
1752
+ const output = transformURL(this, host, file, 'css', trailing, this.htmlFile);
1624
1753
  if (output) {
1625
1754
  trailing = output;
1626
1755
  }
@@ -1661,7 +1790,7 @@ class ChromeDocument extends Document {
1661
1790
  if (hosted) {
1662
1791
  const asset = this.host?.findAsset(uri);
1663
1792
  if (asset) {
1664
- const [relativeUrl, sameDir] = getSrcURL.call(this, bundleMain || file, asset);
1793
+ const [relativeUrl, sameDir] = getSrcURL(this, bundleMain || file, asset);
1665
1794
  if (relativeUrl) {
1666
1795
  value = (sameDir ? './' : '') + relativeUrl;
1667
1796
  }
@@ -1677,7 +1806,7 @@ class ChromeDocument extends Document {
1677
1806
  }
1678
1807
  value = found || original;
1679
1808
  }
1680
- code = spliceString(code, index, index + placeholder.length, value);
1809
+ code = (0, util_1.spliceString)(code, index, index + placeholder.length, value);
1681
1810
  modified = true;
1682
1811
  break;
1683
1812
  }
@@ -1689,7 +1818,7 @@ class ChromeDocument extends Document {
1689
1818
  }
1690
1819
  replaceContent(source, statement, mimeType) {
1691
1820
  switch (mimeType) {
1692
- case 'text/css': {
1821
+ case "text/css": {
1693
1822
  const match = REGEXP_REPLACECSS.exec((typeof statement === 'string' ? statement : statement[0]).trim());
1694
1823
  if (match) {
1695
1824
  const layer = match[1];
@@ -1734,7 +1863,7 @@ class ChromeDocument extends Document {
1734
1863
  if (output && command && file.element?.outerXml) {
1735
1864
  const match = REGEXP_SRCSETSIZE.exec(command);
1736
1865
  if (match) {
1737
- (file.srcSet ||= []).push(toPosix(data.baseDirectory ? output.substring(data.baseDirectory.length + 1) : output), match[1] + match[2].toLowerCase());
1866
+ (file.srcSet ||= []).push(Document.toPosix(data.baseDirectory ? output.substring(data.baseDirectory.length + 1) : output), match[1] + match[2].toLowerCase());
1738
1867
  file.modified = true;
1739
1868
  return true;
1740
1869
  }
@@ -1745,11 +1874,10 @@ class ChromeDocument extends Document {
1745
1874
  this._cloudUrlMap = Object.create(null);
1746
1875
  this._cloudUploaded = new Set();
1747
1876
  this._cloudEndpoint = null;
1748
- const htmlFile = this.htmlFile;
1749
- if (htmlFile) {
1750
- const endpoint = instance.getStorage('upload', htmlFile.cloudStorage)?.upload?.endpoint;
1877
+ if (this.htmlFile) {
1878
+ const endpoint = instance.getStorage('upload', this.htmlFile.cloudStorage)?.upload?.endpoint;
1751
1879
  if (endpoint) {
1752
- this._cloudEndpoint = new RegExp((0, types_1.escapePattern)(toPosix(endpoint)) + '/', 'g');
1880
+ this._cloudEndpoint = new RegExp((0, types_1.escapePattern)(Document.toPosix(endpoint)) + '/', 'g');
1753
1881
  }
1754
1882
  }
1755
1883
  }
@@ -1786,7 +1914,7 @@ class ChromeDocument extends Document {
1786
1914
  if (this.aborted) {
1787
1915
  return (0, types_1.createAbortError)(true);
1788
1916
  }
1789
- const { host, instance, localStorage } = state;
1917
+ const { host, instance } = state;
1790
1918
  const htmlFile = this.htmlFile;
1791
1919
  const preferBuffer = process.env.EMC_CLOUD_UPLOAD_BUFFER === 'true';
1792
1920
  const checkDocument = (item) => {
@@ -1797,7 +1925,7 @@ class ChromeDocument extends Document {
1797
1925
  const inlineUrlCloud = item.inlineUrlCloudMap[id];
1798
1926
  if (inlineUrlCloud && !this._cloudUploaded.has(id)) {
1799
1927
  output = (output || source).replace(new RegExp((0, types_1.escapePattern)(id), 'g'), inlineUrlCloud);
1800
- localStorage.delete(this._cloudUrlMap[id]);
1928
+ state.localStorage.delete(this._cloudUrlMap[id]);
1801
1929
  }
1802
1930
  }
1803
1931
  if (output && output !== source) {
@@ -1834,7 +1962,7 @@ class ChromeDocument extends Document {
1834
1962
  const { admin, bucket, upload } = storage;
1835
1963
  const website = admin?.configBucket?.website;
1836
1964
  if ((0, types_1.isPlainObject)(website) && bucket && upload) {
1837
- let filename = joinPath(upload.pathname, upload.filename || path.basename(htmlFile.localUri));
1965
+ let filename = Document.joinPath(upload.pathname, upload.filename || path.basename(htmlFile.localUri));
1838
1966
  if (website.indexPage === true) {
1839
1967
  website.indexPage = filename;
1840
1968
  filename = '';
@@ -1850,14 +1978,14 @@ class ChromeDocument extends Document {
1850
1978
  if (website.errorPath === true) {
1851
1979
  website.errorPath = filename;
1852
1980
  }
1853
- instance.setBucketWebsite(storage.service, instance.getCredential(storage), bucket, website);
1981
+ void instance.setBucketWebsite(storage.service, instance.getCredential(storage), bucket, website);
1854
1982
  }
1855
1983
  }
1856
1984
  }
1857
1985
  if (htmlFile.compress) {
1858
1986
  await host.compressFile(htmlFile);
1859
1987
  }
1860
- return Promise.all(Cloud.uploadAsset(state, htmlFile, { preferBuffer, contentType: 'text/html', ignoreProcess: true }));
1988
+ return Promise.all(Cloud.uploadAsset(state, htmlFile, { preferBuffer, contentType: "text/html", ignoreProcess: true }));
1861
1989
  }
1862
1990
  }
1863
1991
  return [];
@@ -1868,7 +1996,7 @@ class ChromeDocument extends Document {
1868
1996
  }
1869
1997
  const main = watch.main;
1870
1998
  let result;
1871
- if (main?.editing && main.mimeType === 'text/html') {
1999
+ if (main?.editing && main.mimeType === "text/html") {
1872
2000
  const inlineUrlCloudMap = main.inlineUrlCloudMap || {};
1873
2001
  const using = [];
1874
2002
  let found;
@@ -1881,7 +2009,7 @@ class ChromeDocument extends Document {
1881
2009
  found = true;
1882
2010
  using.push(asset);
1883
2011
  }
1884
- else if (isWatched.call(this, asset) ||
2012
+ else if (isWatched(this, asset) ||
1885
2013
  (0, types_1.watchFlag)(asset.flags) ||
1886
2014
  asset.base64 && watch.related.find(item => (0, asset_1.isEqual)(item, asset)) ||
1887
2015
  (0, types_1.isArray)(asset.cloudStorage) && asset.cloudStorage.some(item => (upload = item.upload) && upload.active)) {
@@ -1910,8 +2038,9 @@ class ChromeDocument extends Document {
1910
2038
  }
1911
2039
  const asset = watch.bundleMain || watch.assets[0];
1912
2040
  const pathname = (asset.cloudUrl || asset.relativeUrl || '').split('?')[0];
1913
- let next, value, search;
1914
- if (assets && (next = assets.find(item => (0, asset_1.isEqual)(item, asset)))) {
2041
+ const next = assets?.find(item => (0, asset_1.isEqual)(item, asset));
2042
+ let value, search;
2043
+ if (next) {
1915
2044
  if (next.cloudUrl) {
1916
2045
  value = next.cloudUrl;
1917
2046
  asset.cloudUrl = value;
@@ -1959,16 +2088,15 @@ class ChromeDocument extends Document {
1959
2088
  if ((0, util_1.hasValue)(file.format, 'srcset')) {
1960
2089
  const srcset = element.getAttribute('srcset');
1961
2090
  if (srcset) {
1962
- const htmlFile = this.htmlFile;
1963
- const uri = toPosix(file.uri);
2091
+ const uri = Document.toPosix(file.uri);
1964
2092
  const items = new Set([uri]);
1965
- const baseHref = getBaseURLs(htmlFile, this.baseUrl);
2093
+ const baseHref = getBaseURLs(this.htmlFile, this.baseUrl);
1966
2094
  const sameOrigin = hasSameOrigin(file.url || uri, ...baseHref);
1967
2095
  if (sameOrigin) {
1968
2096
  const src = element.getAttribute('src');
1969
2097
  for (const baseUri of baseHref) {
1970
2098
  let url;
1971
- if (src && uri === resolvePath(url = toPosix(src), baseUri)) {
2099
+ if (src && uri === Document.resolvePath(url = Document.toPosix(src), baseUri)) {
1972
2100
  items.add(url);
1973
2101
  }
1974
2102
  items.add(uri.startsWith(this.baseDirectory) ? uri.substring(this.baseDirectory.length) : uri.replace(baseUri.origin, ''));
@@ -1981,7 +2109,7 @@ class ChromeDocument extends Document {
1981
2109
  const pattern = new RegExp(`(,?\\s*)(${(resolve && !url.startsWith('.') ? `(?:\\.\\.[\\\\/])*\\.\\.${pathname}|` : '') + pathname})(` + (!url.includes('?') ? '(?:(?!,)(?:[^?]|$)[^,]*)|(?!\\?)[^,]*)' : '[^,]*)'), 'g');
1982
2110
  while (match = pattern.exec(current)) {
1983
2111
  const partial = match[2];
1984
- if (!resolve || baseHref.some(baseUri => uri === resolvePath(partial, baseUri))) {
2112
+ if (!resolve || baseHref.some(baseUri => uri === Document.resolvePath(partial, baseUri))) {
1985
2113
  current = replaceMatch(match, current, match[1] + value + match[3], pattern);
1986
2114
  }
1987
2115
  }
@@ -2019,13 +2147,13 @@ class ChromeDocument extends Document {
2019
2147
  readBase64(item, item.inlineBase64);
2020
2148
  }
2021
2149
  else if (!item.invalid && (0, util_1.hasValue)(item.format, 'base64')) {
2022
- const uuid = (0, types_1.generateUUID)();
2150
+ const uuid = (0, crypto_1.randomUUID)();
2023
2151
  if (readBase64(item, uuid)) {
2024
2152
  item.inlineBase64 = uuid;
2025
2153
  }
2026
2154
  }
2027
2155
  if (productionRelease) {
2028
- const { inlineUrl, inlineUrlCloud, imported, hash } = item;
2156
+ const { inlineUrl, inlineUrlCloud, hash } = item;
2029
2157
  if (inlineUrl || inlineUrlCloud) {
2030
2158
  const filename = hash && createHash(host, item, hash, bufferMap);
2031
2159
  if (filename) {
@@ -2053,19 +2181,19 @@ class ChromeDocument extends Document {
2053
2181
  }
2054
2182
  hashed.add(item);
2055
2183
  }
2056
- else if (hash && (!item.editing || imported) && createHash(host, item, hash, bufferMap)) {
2184
+ else if (hash && (!item.editing || item.imported) && createHash(host, item, hash, bufferMap)) {
2057
2185
  hashed.add(item);
2058
2186
  }
2059
2187
  }
2060
2188
  }
2061
2189
  }
2062
2190
  async applyTransforms(processing) {
2063
- const { host, hashed, bufferMap, productionRelease } = processing;
2191
+ const host = processing.host;
2064
2192
  const sanitizeSource = (item, source) => {
2065
- if (productionRelease) {
2066
- replaceCss.call(this, item);
2193
+ if (processing.productionRelease) {
2194
+ replaceCss(this, item);
2067
2195
  }
2068
- const output = replaceHtml.call(this, source, processing, item.inlineUrlMap);
2196
+ const output = replaceHtml(this, source, processing, item.inlineUrlMap);
2069
2197
  if (source !== output) {
2070
2198
  item.modified = true;
2071
2199
  return output;
@@ -2094,7 +2222,7 @@ class ChromeDocument extends Document {
2094
2222
  continue;
2095
2223
  }
2096
2224
  let source = host.getUTF8String(item);
2097
- const output = transformURL.call(this, host, item, 'svg', source);
2225
+ const output = transformURL(this, host, item, 'svg', source);
2098
2226
  if (output) {
2099
2227
  source = output;
2100
2228
  item.modified = true;
@@ -2102,15 +2230,15 @@ class ChromeDocument extends Document {
2102
2230
  source = sanitizeSource(item, source);
2103
2231
  const format = item.format;
2104
2232
  if (format) {
2105
- const result = await this.transform('html', source, format, transformOptions.call(this, item, 'image/svg+xml'));
2233
+ const result = await this.transform('html', source, format, transformOptions(this, item, "image/svg+xml"));
2106
2234
  if (result) {
2107
2235
  item.modified = true;
2108
2236
  source = result.code;
2109
2237
  }
2110
2238
  }
2111
2239
  item.sourceUTF8 = source;
2112
- if (productionRelease && item.hash && !hashed.has(item) && createHash(host, item, item.hash, bufferMap)) {
2113
- hashed.add(item);
2240
+ if (processing.productionRelease && item.hash && !processing.hashed.has(item) && createHash(host, item, item.hash, processing.bufferMap)) {
2241
+ processing.hashed.add(item);
2114
2242
  }
2115
2243
  }
2116
2244
  for (const item of this.cssFiles) {
@@ -2129,7 +2257,7 @@ class ChromeDocument extends Document {
2129
2257
  source = output;
2130
2258
  item.modified = true;
2131
2259
  }
2132
- if (output = transformURL.call(this, host, item, 'css', source)) {
2260
+ if (output = transformURL(this, host, item, 'css', source)) {
2133
2261
  source = output;
2134
2262
  item.modified = true;
2135
2263
  }
@@ -2137,7 +2265,7 @@ class ChromeDocument extends Document {
2137
2265
  item.sourceUTF8 = source;
2138
2266
  if (item.format) {
2139
2267
  transforms.push(item);
2140
- tasks.push(this.transform('css', source, item.format, transformOptions.call(this, item, 'text/css', source, host.contentToAppend.get(item.localUri))));
2268
+ tasks.push(this.transform('css', source, item.format, transformOptions(this, item, "text/css", source, host.contentToAppend.get(item.localUri))));
2141
2269
  }
2142
2270
  }
2143
2271
  for (const item of this.jsFiles) {
@@ -2153,7 +2281,7 @@ class ChromeDocument extends Document {
2153
2281
  source = output;
2154
2282
  item.modified = true;
2155
2283
  }
2156
- if (output = transformURL.call(this, host, item, 'js', source)) {
2284
+ if (output = transformURL(this, host, item, 'js', source)) {
2157
2285
  source = output;
2158
2286
  item.modified = true;
2159
2287
  }
@@ -2161,17 +2289,18 @@ class ChromeDocument extends Document {
2161
2289
  item.sourceUTF8 = source;
2162
2290
  if (format) {
2163
2291
  transforms.push(item);
2164
- tasks.push(this.transform('js', source, format, transformOptions.call(this, item, 'application/javascript', source, host.contentToAppend.get(item.localUri))));
2292
+ tasks.push(this.transform('js', source, format, transformOptions(this, item, "application/javascript", source, host.contentToAppend.get(item.localUri))));
2165
2293
  }
2166
2294
  }
2167
2295
  return Promise.allSettled(tasks).then(items => {
2296
+ const productionRelease = processing.productionRelease;
2168
2297
  for (let i = 0, length = items.length, value; i < length; ++i) {
2169
2298
  const item = items[i];
2170
2299
  if (item.status === 'fulfilled' && (value = item.value)) {
2171
2300
  const target = transforms[i];
2172
2301
  if (value.type === 'css') {
2173
2302
  if (value.map && !target.bundleReplace) {
2174
- const output = writeSourceMap(target.localUri, value, { mimeType: 'text/css', hash: productionRelease ? target.hash : undefined, emptySources: productionRelease, inlineMap: hasSourceMap(target.metadata, 'inline') });
2303
+ const output = Document.writeSourceMap(target.localUri, value, { mimeType: "text/css", hash: productionRelease ? target.hash : undefined, emptySources: productionRelease, inlineMap: hasSourceMap(target.metadata, 'inline') });
2175
2304
  if (output) {
2176
2305
  host.add(output, target, types_1.FILE_TYPE.SOURCEMAP);
2177
2306
  }
@@ -2180,14 +2309,14 @@ class ChromeDocument extends Document {
2180
2309
  target.sourceUTF8 = value.code;
2181
2310
  }
2182
2311
  else {
2183
- transformJs.call(this, host, target, value);
2312
+ transformJs(this, host, target, value);
2184
2313
  }
2185
2314
  }
2186
2315
  }
2187
2316
  });
2188
2317
  }
2189
2318
  async rewriteHtml(processing) {
2190
- const { host, startTime, cacheMiss, productionRelease } = processing;
2319
+ const { host, startTime, cacheMiss } = processing;
2191
2320
  const { moduleName, config } = this;
2192
2321
  const htmlFile = this.htmlFile;
2193
2322
  const localUri = htmlFile.localUri;
@@ -2206,8 +2335,8 @@ class ChromeDocument extends Document {
2206
2335
  if ((0, types_1.isArray)(config.ignoreServerCodeBlocks)) {
2207
2336
  domBase.ignoreTag(config.ignoreServerCodeBlocks);
2208
2337
  }
2209
- if (productionRelease) {
2210
- replaceCss.call(this, htmlFile);
2338
+ if (processing.productionRelease) {
2339
+ replaceCss(this, htmlFile);
2211
2340
  }
2212
2341
  await this.setElementAttributes(processing, domBase);
2213
2342
  await this.applyDataSource(processing, domBase);
@@ -2222,6 +2351,11 @@ class ChromeDocument extends Document {
2222
2351
  }
2223
2352
  }
2224
2353
  source = removeNamespace(moduleName, domBase.modified ? domBase.close() : source, domBase.newline, domBase.getComments());
2354
+ if (this.sanitizeFramework) {
2355
+ for (const name of this.sanitizeFramework) {
2356
+ source = source.replace(name === '*' ? REGEXP_SANITIZEALL : new RegExp(`(?:\\s+|\\b)data-(?:${(0, types_1.escapePattern)(name)}-[^=\\s]+|.+?-${(0, types_1.escapePattern)(name)})\\s*${dom_1.DomWriter.PATTERN_ATTRVALUE}(?=(?:[^"<]+"[^"]*"|[^'<]+'[^']*')*[^<>]*>)`, 'g'), '');
2357
+ }
2358
+ }
2225
2359
  if (!htmlFile.preserve) {
2226
2360
  let match;
2227
2361
  while (match = REGEXP_STYLE.exec(source)) {
@@ -2231,22 +2365,21 @@ class ChromeDocument extends Document {
2231
2365
  }
2232
2366
  REGEXP_STYLE.lastIndex = 0;
2233
2367
  }
2234
- if (output = transformURL.call(this, host, htmlFile, 'html', source)) {
2368
+ if (output = transformURL(this, host, htmlFile, 'html', source)) {
2235
2369
  source = output;
2236
2370
  }
2237
- source = replaceHtml.call(this, source, processing, htmlFile.inlineUrlMap);
2371
+ source = replaceHtml(this, source, processing, htmlFile.inlineUrlMap);
2238
2372
  if ((0, types_1.isString)(config.stripCommentsAndCDATA)) {
2239
2373
  source = dom_1.DomWriter.getCommentsAndCDATA(source, config.stripCommentsAndCDATA, true, true);
2240
2374
  }
2241
- const format = htmlFile.format;
2242
- if (format) {
2375
+ if (htmlFile.format) {
2243
2376
  const { filename, uri, encoding, metadata } = htmlFile;
2244
- const result = await this.transform('html', source, format, {
2377
+ const result = await this.transform('html', source, htmlFile.format, {
2245
2378
  pathname: path.dirname(localUri),
2246
2379
  filename,
2247
- mimeType: 'text/html',
2380
+ mimeType: "text/html",
2248
2381
  metadata: Object.assign({ '__fromhtml__': true, ...this.config }, metadata),
2249
- cacheData: !productionRelease || this.productionIncremental ? { uri, encoding } : undefined
2382
+ cacheData: !processing.productionRelease || this.productionIncremental ? { uri, encoding } : undefined
2250
2383
  });
2251
2384
  if (result) {
2252
2385
  source = result.code;
@@ -2254,17 +2387,21 @@ class ChromeDocument extends Document {
2254
2387
  }
2255
2388
  if (domBase.hasErrors()) {
2256
2389
  const timeStamp = Date.now();
2257
- domBase.errors.forEach(err => this.addLog(types_1.STATUS_TYPE.WARN, 'dom-writer -> ' + err.message, timeStamp));
2390
+ for (const err of domBase.errors) {
2391
+ this.addLog(types_1.STATUS_TYPE.WARN, 'dom-writer: ' + err.message, timeStamp);
2392
+ }
2258
2393
  }
2259
2394
  if (domBase.failCount > 0) {
2260
2395
  this.writeFail(['Unable to update document', moduleName], (0, types_1.errorMessage)('html', 'DOM rewrite failed', domBase.failCount + ' errors'), { type: 4, startTime });
2261
2396
  }
2262
2397
  else {
2263
- this.writeTimeProcess('html', `dom-writer (${domBase.modifyCount} modified) -> ` + path.basename(localUri), startTime);
2264
- if (cacheMiss.length) {
2398
+ this.writeTimeProcess('html', `dom-writer: ${domBase.modifyCount} modified > ` + path.basename(localUri), startTime);
2399
+ if (cacheMiss.length > 0) {
2265
2400
  const data = {};
2266
2401
  const message = [];
2267
- cacheMiss.forEach(name => data[name] = (data[name] || 0) + 1);
2402
+ for (const name of cacheMiss) {
2403
+ data[name] = (data[name] || 0) + 1;
2404
+ }
2268
2405
  for (const name in data) {
2269
2406
  message.push(name + `(${data[name]})`);
2270
2407
  }
@@ -2275,20 +2412,17 @@ class ChromeDocument extends Document {
2275
2412
  htmlFile.sourceUTF8 = source;
2276
2413
  }
2277
2414
  async setElementAttributes({ host, startTime, productionRelease }, domBase) {
2278
- const { moduleName, htmlFile } = this;
2279
- const cloud = host.Cloud;
2280
- const removeWatchReload = (item) => (0, types_1.isObject)(item.watch) && delete item.watch.reload;
2281
2415
  for (const item of this.assets) {
2282
2416
  const { element, inlineContent } = item;
2283
2417
  if (!element || element.removed || isRemoved(item) || isUnedited(item) || (0, types_1.ignoreFlag)(item.flags) && !(0, types_1.processFlag)(item.flags)) {
2284
2418
  continue;
2285
2419
  }
2286
- const domElement = new dom_1.HtmlElement(moduleName, element, item.attributes);
2420
+ const domElement = new dom_1.HtmlElement(this.moduleName, element, item.attributes);
2287
2421
  if (inlineContent) {
2288
2422
  let [innerXml, sourceMappingURL, inlineMap] = transform_1.SourceMap.removeSourceMappingURL(host.getUTF8String(item).trim());
2289
2423
  if (sourceMappingURL && !inlineMap && item.localUri) {
2290
2424
  let mapUri = path.resolve(sourceMappingURL = decodeURIComponent(sourceMappingURL));
2291
- if (!isPath(mapUri)) {
2425
+ if (!Document.isPath(mapUri)) {
2292
2426
  mapUri = path.join(path.dirname(item.localUri), sourceMappingURL);
2293
2427
  }
2294
2428
  host.deleteFile(mapUri);
@@ -2309,10 +2443,10 @@ class ChromeDocument extends Document {
2309
2443
  uri = '';
2310
2444
  }
2311
2445
  }
2312
- if (uri && !(0, util_1.hasValue)(item.format, 'crossorigin') && item !== htmlFile) {
2313
- if (cloud?.getStorage('upload', item.cloudStorage)) {
2314
- const inlineUrlCloud = item.inlineUrlCloud ||= (0, types_1.generateUUID)();
2315
- (htmlFile.inlineUrlCloudMap ||= {})[inlineUrlCloud] = productionRelease ? this.removeServerRoot(uri) : uri;
2446
+ if (uri && !(0, util_1.hasValue)(item.format, 'crossorigin') && item !== this.htmlFile) {
2447
+ if (host.Cloud?.getStorage('upload', item.cloudStorage)) {
2448
+ const inlineUrlCloud = item.inlineUrlCloud ||= (0, crypto_1.randomUUID)();
2449
+ (this.htmlFile.inlineUrlCloudMap ||= {})[inlineUrlCloud] = productionRelease ? this.removeServerRoot(uri) : uri;
2316
2450
  uri = inlineUrlCloud;
2317
2451
  }
2318
2452
  if (!(0, util_1.hasValue)(item.format, 'webbundle')) {
@@ -2342,7 +2476,9 @@ class ChromeDocument extends Document {
2342
2476
  const detectHeight = domElement.getAttribute('height') === 'detect';
2343
2477
  if (detectWidth || detectHeight) {
2344
2478
  let width = 0, height = 0, buffer = null, packageName;
2345
- const addLog = (dimension) => this.addLog(types_1.STATUS_TYPE.WARN, 'Could not detect image ' + dimension, packageName || this.moduleName, item.localUri ? path.basename(item.localUri) : item.filename);
2479
+ const addLog = (dimension) => {
2480
+ this.addLog(types_1.STATUS_TYPE.WARN, 'Could not detect image ' + dimension, packageName || this.moduleName, item.localUri ? path.basename(item.localUri) : item.filename);
2481
+ };
2346
2482
  if (isImage(item.mimeType) && (buffer = host.getBuffer(item))) {
2347
2483
  try {
2348
2484
  ({ width, height } = require(packageName = 'image-size').imageSize(buffer));
@@ -2399,29 +2535,18 @@ class ChromeDocument extends Document {
2399
2535
  if (this.dataSource.length === 0) {
2400
2536
  return;
2401
2537
  }
2402
- const { moduleName, Db: db } = this;
2403
- const cloud = host.Cloud;
2404
- const sessionKey = (0, types_1.generateUUID)();
2538
+ const sessionKey = (0, crypto_1.randomUUID)();
2405
2539
  const cacheData = Object.create(null);
2406
- const coerceMap = {};
2407
2540
  const dataItems = [];
2408
2541
  const displayItems = [];
2409
- this.dataSource.forEach(item => item.type === 'display' ? displayItems.push(item) : dataItems.push(item));
2410
- const removeElement = (item, element) => {
2411
- if (item.removeEmpty || item.type === 'display') {
2412
- (element ||= new dom_1.HtmlElement(moduleName, item.element)).remove = true;
2413
- if (!domBase.write(element)) {
2414
- this.writeFail('Unable to remove element', errorHtml(item.element), { type: 4, startTime });
2415
- }
2542
+ for (const item of this.dataSource) {
2543
+ if (item.type === 'display') {
2544
+ displayItems.push(item);
2416
2545
  }
2417
- };
2418
- const errorCredential = (item, err) => {
2419
- removeElement(item);
2420
- const pkg = getPackageName(err);
2421
- if (!(pkg && this.checkPackage(err, pkg))) {
2422
- this.writeFail(["Invalid credentials", item.source], err);
2546
+ else {
2547
+ dataItems.push(item);
2423
2548
  }
2424
- };
2549
+ }
2425
2550
  const checkObject = (item, data, type) => {
2426
2551
  const { query, cascade } = item;
2427
2552
  if ((0, types_1.isString)(cascade)) {
@@ -2452,18 +2577,20 @@ class ChromeDocument extends Document {
2452
2577
  this.checkPackage(err, pkg, ["Unable to filter results", item.source]);
2453
2578
  }
2454
2579
  }
2455
- if (type && !item.ignoreCoerce && (coerceMap[type] ??= this.settingsOf(type, 'coerce') === true)) {
2580
+ if (type && !item.ignoreCoerce && this.settingsOf(type, 'coerce') === true) {
2456
2581
  (0, types_1.coerceObject)(data);
2457
2582
  }
2458
2583
  }
2459
2584
  return Array.isArray(data) ? data : (0, types_1.isObject)(data) ? [data] : null;
2460
2585
  };
2461
2586
  const setElements = async (sourceSet) => {
2587
+ const db = this.Db;
2588
+ const cloud = host.Cloud;
2462
2589
  const batchMap = Object.create(null);
2463
2590
  const batchGroup = [];
2464
2591
  for (const item of sourceSet) {
2465
2592
  if (!item.element) {
2466
- this.addLog(types_1.STATUS_TYPE.WARN, `Missing target element {${JSON.stringify(item)}}`);
2593
+ this.addLog(types_1.STATUS_TYPE.WARN, `dom-writer: Missing target element {${JSON.stringify(item)}}`);
2467
2594
  continue;
2468
2595
  }
2469
2596
  const type = item.source;
@@ -2471,11 +2598,11 @@ class ChromeDocument extends Document {
2471
2598
  case 'cloud': {
2472
2599
  const { service, credential } = item;
2473
2600
  if (cloud) {
2474
- const key = service + '_' + (service === 'atlas' && item.uri || '') + '_' + asString(credential, true);
2601
+ const key = service + '_' + (service === 'atlas' && item.uri || '') + '_' + Document.asString(credential, true);
2475
2602
  (batchMap[key] ||= []).push(item);
2476
2603
  }
2477
2604
  else {
2478
- errorCredential(item, (0, types_1.errorValue)("Cloud module not installed", service));
2605
+ errorCredential(this, domBase, item, (0, types_1.errorValue)("Cloud module not installed", service));
2479
2606
  }
2480
2607
  break;
2481
2608
  }
@@ -2505,11 +2632,11 @@ class ChromeDocument extends Document {
2505
2632
  (batchMap[key] ||= []).push(item);
2506
2633
  }
2507
2634
  catch (err) {
2508
- errorCredential(item, err);
2635
+ errorCredential(this, domBase, item, err);
2509
2636
  }
2510
2637
  }
2511
2638
  else {
2512
- errorCredential(item, (0, types_1.errorValue)(db ? "Database provider not found" : "Db module not installed", type));
2639
+ errorCredential(this, domBase, item, (0, types_1.errorValue)(db ? "Database provider not found" : "Db module not installed", type));
2513
2640
  }
2514
2641
  break;
2515
2642
  }
@@ -2520,11 +2647,11 @@ class ChromeDocument extends Document {
2520
2647
  return this.allSettled(batchGroup.map(async (batch) => {
2521
2648
  return new Promise(async (resolve, reject) => {
2522
2649
  const errorRemove = (item, reason) => {
2523
- removeElement(item);
2650
+ removeElement(this, domBase, item);
2524
2651
  reject(reason);
2525
2652
  };
2526
2653
  const errorClient = (item, reason) => {
2527
- removeElement(item);
2654
+ removeElement(this, domBase, item);
2528
2655
  if (reason) {
2529
2656
  this.writeFail(["Unable to configure client", item.source], reason);
2530
2657
  }
@@ -2576,7 +2703,7 @@ class ChromeDocument extends Document {
2576
2703
  }
2577
2704
  catch (err) {
2578
2705
  this.abort(type);
2579
- this.writeFail(["Unable to read file", path.basename(location)], err, { type: 32, startTime });
2706
+ this.writeFail(["Unable to read file", path.basename(location)], err, 32);
2580
2707
  errorRemove(current);
2581
2708
  return;
2582
2709
  }
@@ -2646,7 +2773,7 @@ class ChromeDocument extends Document {
2646
2773
  }
2647
2774
  catch (err) {
2648
2775
  this.abort(type);
2649
- this.writeFail(["Unable to read file", path.basename(pathname)], err, { type: 32, startTime });
2776
+ this.writeFail(["Unable to read file", path.basename(pathname)], err, 32);
2650
2777
  errorRemove(current);
2651
2778
  return;
2652
2779
  }
@@ -2663,7 +2790,7 @@ class ChromeDocument extends Document {
2663
2790
  }
2664
2791
  catch (err) {
2665
2792
  this.abort(type);
2666
- this.writeFail(["Unable to parse inline object", format], err, { type: 4, startTime });
2793
+ this.writeFail(["Unable to parse inline object", format], err, 4);
2667
2794
  errorRemove(current);
2668
2795
  return;
2669
2796
  }
@@ -2678,7 +2805,7 @@ class ChromeDocument extends Document {
2678
2805
  return;
2679
2806
  }
2680
2807
  if (cacheKey) {
2681
- setCacheData.call(this, current, data, cacheKey, cacheData);
2808
+ setCacheData(this, current, data, cacheKey, cacheData);
2682
2809
  }
2683
2810
  if ((result[0] = checkObject(current, data, type)) === null) {
2684
2811
  this.abort(type);
@@ -2688,7 +2815,7 @@ class ChromeDocument extends Document {
2688
2815
  break;
2689
2816
  }
2690
2817
  case 'export': {
2691
- const cacheKey = asString(current, true);
2818
+ const cacheKey = Document.asString(current, true);
2692
2819
  if (!current.ignoreCache && CACHE_DBRESULT.has(cacheKey)) {
2693
2820
  result[0] = getCacheItem(CACHE_DBRESULT, cacheKey);
2694
2821
  }
@@ -2713,7 +2840,7 @@ class ChromeDocument extends Document {
2713
2840
  target = pathname;
2714
2841
  hint = pathname;
2715
2842
  }
2716
- else if ((target = this.resolveDir(type, pathname)) && (getData = core_1.ClientDb.parseFunction(target, true))) {
2843
+ else if ((target = this.resolveDir(type, pathname)) && (getData = Document.parseFunction(target, true))) {
2717
2844
  hint = pathname;
2718
2845
  }
2719
2846
  else {
@@ -2763,7 +2890,7 @@ class ChromeDocument extends Document {
2763
2890
  });
2764
2891
  }
2765
2892
  }
2766
- setCacheData.call(this, current, data, cacheKey, cacheData);
2893
+ setCacheData(this, current, data, cacheKey, cacheData);
2767
2894
  }
2768
2895
  catch (err) {
2769
2896
  this.abort(type);
@@ -2808,10 +2935,10 @@ class ChromeDocument extends Document {
2808
2935
  }
2809
2936
  if (!(search.schema = cacheData[pathname])) {
2810
2937
  try {
2811
- search.schema = loadLocalFile.call(this, current, pathname, cacheData, cmd.encoding);
2938
+ search.schema = loadLocalFile(this, current, pathname, cacheData, cmd.encoding);
2812
2939
  }
2813
2940
  catch (err) {
2814
- this.writeFail(['Unable to parse document', path.basename(pathname)], err instanceof Error ? errors = err : err, { startTime });
2941
+ this.writeFail(['Unable to parse document', path.basename(pathname)], err instanceof Error ? errors = err : err, 32);
2815
2942
  search.schema = undefined;
2816
2943
  }
2817
2944
  }
@@ -2845,10 +2972,10 @@ class ChromeDocument extends Document {
2845
2972
  if (!(cmd.query = cacheData[pathname])) {
2846
2973
  const out = { content: '' };
2847
2974
  try {
2848
- cmd.query = loadLocalFile.call(this, current, pathname, cacheData, cmd.encoding, out);
2975
+ cmd.query = loadLocalFile(this, current, pathname, cacheData, cmd.encoding, out);
2849
2976
  }
2850
2977
  catch {
2851
- setCacheData.call(this, current, cmd.query = out.content, pathname, cacheData, true);
2978
+ setCacheData(this, current, cmd.query = out.content, pathname, cacheData, true);
2852
2979
  }
2853
2980
  }
2854
2981
  }
@@ -2859,7 +2986,7 @@ class ChromeDocument extends Document {
2859
2986
  }
2860
2987
  catch (err) {
2861
2988
  this.abort(type);
2862
- this.writeFail(["Unable to read file", pathname ? path.basename(pathname) : query], err, { startTime });
2989
+ this.writeFail(["Unable to read file", pathname ? path.basename(pathname) : query], err, 32);
2863
2990
  errorRemove(current);
2864
2991
  return;
2865
2992
  }
@@ -2876,7 +3003,7 @@ class ChromeDocument extends Document {
2876
3003
  }
2877
3004
  else if (db.hasSource(type, db.sourceType.KEYVALUE)) {
2878
3005
  aborting = commandType !== db.commandType.UPDATE;
2879
- message = asString(data.search || data.key);
3006
+ message = Document.asString(data.search || data.key);
2880
3007
  }
2881
3008
  else {
2882
3009
  const credential = data.credential;
@@ -2915,7 +3042,7 @@ class ChromeDocument extends Document {
2915
3042
  const empty = (items = result[i]) === null;
2916
3043
  if ((items ||= []).length === 0) {
2917
3044
  if (whenEmpty) {
2918
- const data = await checkData.call(this, item, whenEmpty, items, row => Array.isArray(row));
3045
+ const data = await checkData(this, item, whenEmpty, items, row => Array.isArray(row));
2919
3046
  if (data) {
2920
3047
  items = data;
2921
3048
  item.transactionFail = false;
@@ -2929,26 +3056,25 @@ class ChromeDocument extends Document {
2929
3056
  const data = items[index];
2930
3057
  items = data ? [data] : [];
2931
3058
  }
2932
- else if (limit !== undefined && limit > 0 && items.length > limit) {
3059
+ else if (typeof limit === 'number' && limit > 0 && items.length > limit) {
2933
3060
  items = items.slice(0, limit);
2934
3061
  }
2935
3062
  if (postQuery) {
2936
- const data = await checkData.call(this, item, postQuery, items = items.slice(0), row => Array.isArray(row));
3063
+ const data = await checkData(this, item, postQuery, items = items.slice(0), row => Array.isArray(row));
2937
3064
  if (data) {
2938
3065
  items = data;
2939
3066
  }
2940
3067
  }
2941
- if (items.length && !item.transactionFail) {
2942
- const { element, preRender } = item;
2943
- const domElement = new dom_1.HtmlElement(moduleName, element);
3068
+ if (items.length > 0 && !item.transactionFail) {
3069
+ const element = item.element;
3070
+ const domElement = new dom_1.HtmlElement(this.moduleName, element);
2944
3071
  let value = '';
2945
3072
  const checkValue = async (name) => {
2946
- const data = await checkData.call(this, item, name, value, row => typeof row === 'string');
3073
+ const data = await checkData(this, item, name, value, row => typeof row === 'string');
2947
3074
  if (data) {
2948
3075
  value = data;
2949
3076
  }
2950
3077
  };
2951
- const valueAsString = (data, joinString) => Array.isArray(data) && !data.some(child => typeof child === 'object') ? data.join(joinString) : asString(data);
2952
3078
  if (item.template) {
2953
3079
  const pathname = this.resolveDir('template', item.template);
2954
3080
  if (pathname) {
@@ -2962,10 +3088,10 @@ class ChromeDocument extends Document {
2962
3088
  if (!(item.value = cacheData[pathname])) {
2963
3089
  try {
2964
3090
  item.value = fs.readFileSync(pathname, item.encoding || 'utf-8');
2965
- setCacheData.call(this, item, item.value, pathname, cacheData, true);
3091
+ setCacheData(this, item, item.value, pathname, cacheData, true);
2966
3092
  }
2967
3093
  catch (err) {
2968
- this.writeFail(["Unable to read file", path.basename(pathname)], err, { type: 32, startTime });
3094
+ this.writeFail(["Unable to read file", path.basename(pathname)], err, 32);
2969
3095
  errors = true;
2970
3096
  }
2971
3097
  }
@@ -2984,7 +3110,7 @@ class ChromeDocument extends Document {
2984
3110
  const content = await this.parseTemplate(item.viewEngine, template, items);
2985
3111
  if (content === null) {
2986
3112
  ++domBase.failCount;
2987
- removeElement(item, domElement);
3113
+ removeElement(this, domBase, item, domElement);
2988
3114
  if (length === 1) {
2989
3115
  resolve();
2990
3116
  return;
@@ -3012,7 +3138,7 @@ class ChromeDocument extends Document {
3012
3138
  continue;
3013
3139
  }
3014
3140
  try {
3015
- let content = new Function('return ' + literal + ';').call(row);
3141
+ let content = new Function('return ' + literal + ';')(row);
3016
3142
  if (!segment.startsWith('`')) {
3017
3143
  content = segment.substring(0, segment.indexOf('`')) + content;
3018
3144
  }
@@ -3035,8 +3161,8 @@ class ChromeDocument extends Document {
3035
3161
  value += trimTemplate(segment);
3036
3162
  }
3037
3163
  }
3038
- if (preRender) {
3039
- await checkValue(preRender);
3164
+ if (item.preRender) {
3165
+ await checkValue(item.preRender);
3040
3166
  }
3041
3167
  const { leadingText, trailingText } = item;
3042
3168
  if (leadingText) {
@@ -3083,7 +3209,7 @@ class ChromeDocument extends Document {
3083
3209
  for (const row of items) {
3084
3210
  for (let seg of segment) {
3085
3211
  seg = seg.trim();
3086
- if (seg.startsWith(':') && (match = /^:join\(([\S\s]*)\)$/i.exec(seg))) {
3212
+ if (seg.startsWith(':') && (match = /^:join\((.*)\)$/is.exec(seg))) {
3087
3213
  joinString = match[1];
3088
3214
  continue;
3089
3215
  }
@@ -3092,7 +3218,7 @@ class ChromeDocument extends Document {
3092
3218
  valid = true;
3093
3219
  }
3094
3220
  if (seg) {
3095
- if (match = /^:text\(([\S\s]*)\)$/i.exec(seg)) {
3221
+ if (match = /^:text\((.*)\)$/is.exec(seg)) {
3096
3222
  value += (value ? joinString : '') + match[1];
3097
3223
  valid = true;
3098
3224
  }
@@ -3111,8 +3237,8 @@ class ChromeDocument extends Document {
3111
3237
  }
3112
3238
  }
3113
3239
  if (valid) {
3114
- if (preRender) {
3115
- await checkValue(preRender);
3240
+ if (item.preRender) {
3241
+ await checkValue(item.preRender);
3116
3242
  }
3117
3243
  domElement.setAttribute(attr, value);
3118
3244
  }
@@ -3229,7 +3355,7 @@ class ChromeDocument extends Document {
3229
3355
  break;
3230
3356
  }
3231
3357
  default:
3232
- removeElement(item, domElement);
3358
+ removeElement(this, domBase, item, domElement);
3233
3359
  if (length === 1) {
3234
3360
  reject(errorDataSource('Invalid action', item.type || "Unknown"));
3235
3361
  return;
@@ -3250,18 +3376,18 @@ class ChromeDocument extends Document {
3250
3376
  switch (item.source) {
3251
3377
  case 'cloud': {
3252
3378
  const { service, table, id, query } = item;
3253
- const queryString = (table ? 'table=' + table : '') + (id || query ? (table ? ';' : '') + (id ? 'id=' + id : 'query=' + asString(query)) : '');
3379
+ const queryString = (table ? 'table=' + table : '') + (id || query ? (table ? ';' : '') + (id ? 'id=' + id : 'query=' + Document.asString(query)) : '');
3254
3380
  (cloud || this).formatFail(64, service, ["Unable to execute query", queryString], emptyResponse(queryString, service), { ...Cloud.LOG_CLOUD_FAIL, startTime });
3255
3381
  break;
3256
3382
  }
3257
3383
  case 'uri': {
3258
3384
  const { uri, format = uri && path.extname(uri).substring(1) } = item;
3259
- this.formatFail(4, format || 'URI', ['No records were found', uri], emptyResponse(uri), { startTime });
3385
+ this.formatFail(4, format || 'URI', ['No records were found', uri], emptyResponse(uri));
3260
3386
  break;
3261
3387
  }
3262
3388
  case 'local': {
3263
3389
  const { pathname, format = pathname && path.extname(pathname).substring(1) } = item;
3264
- this.formatFail(4, format || 'LOCAL', ['No records were found', pathname], emptyResponse(pathname), { startTime });
3390
+ this.formatFail(4, format || 'LOCAL', ['No records were found', pathname], emptyResponse(pathname));
3265
3391
  break;
3266
3392
  }
3267
3393
  case 'export': {
@@ -3270,22 +3396,22 @@ class ChromeDocument extends Document {
3270
3396
  if (typeof target === 'function') {
3271
3397
  target = target.name;
3272
3398
  }
3273
- this.formatFail(4, 'EXPORT', ['No records were retrieved', target], emptyResponse(target), { startTime });
3399
+ this.formatFail(4, 'EXPORT', ['No records were retrieved', target], emptyResponse(target));
3274
3400
  break;
3275
3401
  }
3276
3402
  }
3277
3403
  }
3278
- removeElement(item);
3404
+ removeElement(this, domBase, item);
3279
3405
  }
3280
3406
  }
3281
3407
  resolve();
3282
3408
  });
3283
3409
  }), 'Element text or attribute replacement');
3284
3410
  };
3285
- if (dataItems.length) {
3411
+ if (dataItems.length > 0) {
3286
3412
  await setElements(dataItems);
3287
3413
  }
3288
- if (displayItems.length) {
3414
+ if (displayItems.length > 0) {
3289
3415
  await setElements(displayItems);
3290
3416
  }
3291
3417
  }
@@ -3342,14 +3468,13 @@ class ChromeDocument extends Document {
3342
3468
  }
3343
3469
  const queryMap = useSessionCache ? CACHE_QUERY : this._queryMap;
3344
3470
  const selectorMap = useSessionCache ? CACHE_SELECTOR : this._selectorMap;
3471
+ const [stringSome, stringMany] = useUnsafeCssReplace ? ['\\s*', '\\s+'] : [PATTERN_STRING_SOME, PATTERN_STRING_MANY];
3345
3472
  const replaceMap = [];
3346
- const getStringSome = () => useUnsafeCssReplace ? '\\s*' : PATTERN_STRING_SOME;
3347
- const getStringMany = () => useUnsafeCssReplace ? '\\s+' : PATTERN_STRING_MANY;
3348
3473
  let current = source, modified, checkEmpty, match;
3349
3474
  const parseSelector = (value) => {
3350
3475
  const items = [];
3351
3476
  const revised = value.replace(useUnsafeCssReplace ? REGEXP_NTHCHILD_UNSAFE : REGEXP_NTHCHILD, (...capture) => {
3352
- return '`%' + (items.push('\\(' + getStringSome() + (capture[1] === '-' ? '\\x2d' : '\\x2b?') + (capture[2] || '[01]?') + (capture[3] === '0' ? !capture[1] && !capture[2] && !capture[4] && !capture[5] ? '[+-]?0[nN]?' : '0' : '[nN]') + getStringSome() + (capture[5] ? (capture[4] === '-' ? '\\x2d' : '\\x2b') + getStringSome() + capture[5] : `(?:[+-]${getStringSome()}0)?`) + (capture[6] ? getStringMany() + '[oO][fF]' + getStringMany() + capture[6].trim() : '') + getStringSome() + '\\)') - 1) + '`';
3477
+ return '`%' + (items.push('\\(' + stringSome + (capture[1] === '-' ? '\\x2d' : '\\x2b?') + (capture[2] || '[01]?') + (capture[3] === '0' ? !capture[1] && !capture[2] && !capture[4] && !capture[5] ? '[+-]?0[nN]?' : '0' : '[nN]') + stringSome + (capture[5] ? (capture[4] === '-' ? '\\x2d' : '\\x2b') + stringSome + capture[5] : `(?:[+-]${stringSome}0)?`) + (capture[6] ? stringMany + '[oO][fF]' + stringMany + capture[6].trim() : '') + stringSome + '\\)') - 1) + '`';
3353
3478
  });
3354
3479
  let selector = '';
3355
3480
  for (let i = 0, length = revised.length, casing = false, attr = false, quote = false; i < length; i++) {
@@ -3425,13 +3550,13 @@ class ChromeDocument extends Document {
3425
3550
  selector += (space & 1 ? '`%%`' : '') + (!casing && ch >= 'a' && ch <= 'z' ? '`' + ch + ch.toUpperCase() + '`' : ch) + (space & 2 ? '`%%`' : '');
3426
3551
  }
3427
3552
  selector = (0, types_1.escapePattern)(selector)
3428
- .replace(/\s*(>|~(?!=)|\\\+|\\\*(?!=)])\s*/g, (...capture) => getStringSome() + capture[1] + getStringSome())
3553
+ .replace(/\s*(>|~(?!=)|\\\+|\\\*(?!=)])\s*/g, (...capture) => stringSome + capture[1] + stringSome)
3429
3554
  .replace(/`([a-z][A-Z]|%{2,4})`/g, (...capture) => {
3430
3555
  switch (capture[1]) {
3431
3556
  case '%%':
3432
- return getStringSome();
3557
+ return stringSome;
3433
3558
  case '%%%':
3434
- return `(?:["']|${getStringSome()})`;
3559
+ return `(?:["']|${stringSome})`;
3435
3560
  case '%%%%':
3436
3561
  return '\\\\{0,}';
3437
3562
  default:
@@ -3441,7 +3566,7 @@ class ChromeDocument extends Document {
3441
3566
  for (let i = 0, length = revised.length; i < length; ++i) {
3442
3567
  selector = selector.replace('`%' + i + '`', items[i]);
3443
3568
  }
3444
- return selector.replace(/ +/g, getStringMany()) + getStringSome();
3569
+ return selector.replace(/ +/g, stringMany) + stringSome;
3445
3570
  };
3446
3571
  const replaceUnunsed = (name, items, nesting, increment = 1) => {
3447
3572
  for (let i = 0; i < items.length; i += increment) {
@@ -3473,9 +3598,9 @@ class ChromeDocument extends Document {
3473
3598
  flags = 'g';
3474
3599
  }
3475
3600
  else if (name === 'scope') {
3476
- selector = `\\(${getStringSome() + parseSelector(value)}\\)`;
3601
+ selector = `\\(${stringSome + parseSelector(value)}\\)`;
3477
3602
  if (valueTo) {
3478
- selector += `${getStringMany()}[tT][oO]${getStringMany()}\\(${getStringSome() + parseSelector(valueTo)}\\)`;
3603
+ selector += `${stringMany}[tT][oO]${stringMany}\\(${stringSome + parseSelector(valueTo)}\\)`;
3479
3604
  }
3480
3605
  flags = 'g';
3481
3606
  revised = true;
@@ -3484,22 +3609,22 @@ class ChromeDocument extends Document {
3484
3609
  const startIndex = value.indexOf('(');
3485
3610
  const endIndex = value.lastIndexOf(')');
3486
3611
  if (startIndex !== -1 && endIndex !== -1) {
3487
- selector = '[sS][eE][lL][eE][cC][tT][oO][rR]\\(' + getStringSome() + parseSelector(value.substring(startIndex + 1, endIndex)) + '\\)';
3612
+ selector = '[sS][eE][lL][eE][cC][tT][oO][rR]\\(' + stringSome + parseSelector(value.substring(startIndex + 1, endIndex)) + '\\)';
3488
3613
  flags = 'g';
3489
3614
  revised = true;
3490
3615
  }
3491
3616
  }
3492
3617
  if (!revised) {
3493
3618
  selector = (0, types_1.escapePattern)(selector || value)
3494
- .replace(/\s*(\\[()])\s*/g, (...capture) => getStringSome() + capture[1] + getStringSome())
3495
- .replace(/:\s+/g, getStringSome() + ':' + getStringSome())
3496
- .replace(/\s+([<>/]|<=|>=|\\\*)\s+/g, (...capture) => getStringSome() + capture[1] + getStringSome())
3497
- .replace(/ +/g, getStringMany());
3619
+ .replace(/\s*(\\[()])\s*/g, (...capture) => stringSome + capture[1] + stringSome)
3620
+ .replace(/:\s+/g, stringSome + ':' + stringSome)
3621
+ .replace(/\s+([<>/]|<=|>=|\\\*)\s+/g, (...capture) => stringSome + capture[1] + stringSome)
3622
+ .replace(/ +/g, stringMany);
3498
3623
  if (flags === 'g') {
3499
3624
  selector = selector.replace(/`([a-z][A-Z])`/g, (...capture) => `[${capture[1]}]`);
3500
3625
  }
3501
3626
  }
3502
- pattern = new RegExp('(\\s*)@' + (flags === 'g' ? name.split('').map(ch => `[${ch + ch.toUpperCase()}]`).join('') : name) + getStringMany() + selector + getStringSome() + '{', flags);
3627
+ pattern = new RegExp('(\\s*)@' + (flags === 'g' ? name.split('').map(ch => `[${ch + ch.toUpperCase()}]`).join('') : name) + stringMany + selector + stringSome + '{', flags);
3503
3628
  queryMap.set(key, pattern);
3504
3629
  }
3505
3630
  else {
@@ -3527,7 +3652,7 @@ class ChromeDocument extends Document {
3527
3652
  while (bracket = pattern.exec(current)) {
3528
3653
  const segment = bracket[0];
3529
3654
  if (/[{}]/.test(segment)) {
3530
- const placeholder = '`' + (0, types_1.generateUUID)() + '`';
3655
+ const placeholder = '`' + (0, crypto_1.randomUUID)() + '`';
3531
3656
  replaceMap.push([placeholder, segment]);
3532
3657
  current = replaceMatch(bracket, current, placeholder, pattern);
3533
3658
  }
@@ -3539,11 +3664,11 @@ class ChromeDocument extends Document {
3539
3664
  const values = (0, util_1.splitEnclosing)(current, /\burl/gi);
3540
3665
  for (let i = 0, length = values.length; i < length; ++i) {
3541
3666
  const seg = values[i];
3542
- if (/^url\([^{}]*[{}][\S\s]*\)$/i.test(seg)) {
3543
- replaceMap.push([values[i] = (0, types_1.generateUUID)(), seg]);
3667
+ if (/^url\([^{}]*[{}].*\)$/is.test(seg)) {
3668
+ replaceMap.push([values[i] = (0, crypto_1.randomUUID)(), seg]);
3544
3669
  }
3545
3670
  }
3546
- if (replaceMap.length) {
3671
+ if (replaceMap.length > 0) {
3547
3672
  current = values.join('');
3548
3673
  }
3549
3674
  }
@@ -3574,9 +3699,9 @@ class ChromeDocument extends Document {
3574
3699
  const pattern = selectorMap.get(key);
3575
3700
  let single, group;
3576
3701
  if (!pattern) {
3577
- const selector = parseSelector(value) + (child ? `(?:${getStringSome()}&${getStringSome()})*` : '');
3578
- single = new RegExp(`(^|;)(${getStringSome()})(?<!${child ? '&|' : ''}@[^};]*)${selector}\\{$`);
3579
- group = new RegExp(`((?:^|;)[^{]*?${getStringSome()}(,${getStringSome()}|(?<!@[^};]*)))(${(child ? '(?:&\\s+|(?<!&))' : '') + selector})(,[^{]*)?\\{$`, 'g');
3702
+ const selector = parseSelector(value) + (child ? `(?:${stringSome}&${stringSome})*` : '');
3703
+ single = new RegExp(`(^|;)(${stringSome})(?<!${child ? '&|' : ''}@[^};]*)${selector}\\{$`);
3704
+ group = new RegExp(`((?:^|;)[^{]*?${stringSome}(,${stringSome}|(?<!@[^};]*)))(${(child ? '(?:&\\s+|(?<!&))' : '') + selector})(,[^{]*)?\\{$`, 'g');
3580
3705
  selectorMap.set(key, [single, group]);
3581
3706
  }
3582
3707
  else {
@@ -3612,7 +3737,7 @@ class ChromeDocument extends Document {
3612
3737
  invalid = 1;
3613
3738
  break;
3614
3739
  }
3615
- else if (leading !== -1 && empty[1] === ';') {
3740
+ if (leading !== -1 && empty[1] === ';') {
3616
3741
  content = target.substring(index, found).substring(0, leading).replace(/[^\n;]+$/, '');
3617
3742
  invalid = 1;
3618
3743
  break;
@@ -3688,7 +3813,7 @@ class ChromeDocument extends Document {
3688
3813
  const fontFamily = useUnsafeCssReplace ? REGEXP_FONTFAMILY_UNSAFE : REGEXP_FONTFAMILY;
3689
3814
  while (match = pattern.exec(current)) {
3690
3815
  const font = fontFamily.exec(match[0]);
3691
- if (font && !usedFontFace.includes(font[1].trim().replace(/^(["'])([\S\s]+)\1$/, (...content) => content[2]))) {
3816
+ if (font && !usedFontFace.includes(font[1].trim().replace(/^(["'])(.+)\1$/s, (...content) => content[2]))) {
3692
3817
  current = spliceSource(current, match.index, getEndIndex(match), pattern, match[1], match[3]);
3693
3818
  modified = true;
3694
3819
  }
@@ -3710,13 +3835,13 @@ class ChromeDocument extends Document {
3710
3835
  }
3711
3836
  if (modified) {
3712
3837
  for (const name in checkEmpty) {
3713
- const pattern = CACHE_ATRULES[name + (useUnsafeCssReplace ? '_1' : '')] ||= new RegExp(`(\\s*)@${name}[^{]*{${getStringSome()}}` + dom_1.DomWriter.PATTERN_TRAILINGSPACE, 'gi');
3838
+ const pattern = CACHE_ATRULES[name + (useUnsafeCssReplace ? '_1' : '')] ||= new RegExp(`(\\s*)@${name}[^{]*{${stringSome}}` + dom_1.DomWriter.PATTERN_TRAILINGSPACE, 'gi');
3714
3839
  while (match = pattern.exec(current)) {
3715
3840
  current = spliceSource(current, match.index, getEndIndex(match), pattern, match[1], match[2]);
3716
3841
  }
3717
3842
  pattern.lastIndex = 0;
3718
3843
  }
3719
- if (replaceMap.length) {
3844
+ if (replaceMap.length > 0) {
3720
3845
  for (const [placeholder, content] of replaceMap.reverse()) {
3721
3846
  current = current.replace(placeholder, content);
3722
3847
  }
@@ -3733,21 +3858,23 @@ class ChromeDocument extends Document {
3733
3858
  const host = this.host;
3734
3859
  const restartable = host ? host.restartable || this.watching : false;
3735
3860
  const idMap = this._idMap;
3736
- this.assets.forEach(item => {
3861
+ for (const item of this.assets) {
3737
3862
  const { element, id, flags } = item;
3738
3863
  if (element) {
3739
3864
  if (restartable && id && !(0, types_1.cloneFlag)(flags)) {
3740
3865
  const backup = idMap[id];
3741
3866
  if (backup) {
3742
3867
  elements.add(item.element = (0, types_1.cloneObject)(backup, true));
3743
- return;
3868
+ continue;
3744
3869
  }
3745
3870
  idMap[id] = (0, types_1.cloneObject)(element, true);
3746
3871
  }
3747
3872
  elements.add(element);
3748
3873
  }
3749
- });
3750
- this.dataSource.forEach(item => elements.add(item.element));
3874
+ }
3875
+ for (const item of this.dataSource) {
3876
+ elements.add(item.element);
3877
+ }
3751
3878
  return this._elements = Array.from(elements);
3752
3879
  }
3753
3880
  get editing() {
@@ -3759,18 +3886,13 @@ class ChromeDocument extends Document {
3759
3886
  }
3760
3887
  }
3761
3888
  get dataSource() {
3762
- const result = this._dataSource;
3763
- if (result) {
3764
- return result;
3889
+ if (this._dataSource) {
3890
+ return this._dataSource;
3765
3891
  }
3766
3892
  const host = this.host;
3767
3893
  if (host) {
3768
- try {
3769
- const items = host.getDataSourceItems(this);
3770
- return this._dataSource = host.restartable || this.watching ? items.map(item => (0, types_1.cloneObject)(item, true)) : items;
3771
- }
3772
- catch {
3773
- }
3894
+ const items = host.getDataSourceItems(this);
3895
+ return this._dataSource = host.restartable || this.watching ? items.map(item => (0, types_1.cloneObject)(item, true)) : items;
3774
3896
  }
3775
3897
  return [];
3776
3898
  }